diff options
Diffstat (limited to '')
127 files changed, 46043 insertions, 0 deletions
diff --git a/libraries/LuaJIT-1.1.7/COPYRIGHT b/libraries/LuaJIT-1.1.7/COPYRIGHT new file mode 100644 index 0000000..0ab5523 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/COPYRIGHT | |||
@@ -0,0 +1,40 @@ | |||
1 | Lua License | ||
2 | ----------- | ||
3 | |||
4 | Lua is licensed under the terms of the MIT license reproduced below. | ||
5 | This means that Lua is free software and can be used for both academic | ||
6 | and commercial purposes at absolutely no cost. | ||
7 | |||
8 | For details and rationale, see http://www.lua.org/license.html . | ||
9 | |||
10 | *** | ||
11 | LuaJIT is a derivative work, heavily based on Lua. The JIT extensions | ||
12 | are licensed under the same conditions (except by a different author). | ||
13 | The LuaJIT license can be found in: src/luajit.h | ||
14 | *** | ||
15 | |||
16 | =============================================================================== | ||
17 | |||
18 | Copyright (C) 1994-2008 Lua.org, PUC-Rio. | ||
19 | |||
20 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
21 | of this software and associated documentation files (the "Software"), to deal | ||
22 | in the Software without restriction, including without limitation the rights | ||
23 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
24 | copies of the Software, and to permit persons to whom the Software is | ||
25 | furnished to do so, subject to the following conditions: | ||
26 | |||
27 | The above copyright notice and this permission notice shall be included in | ||
28 | all copies or substantial portions of the Software. | ||
29 | |||
30 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
31 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
32 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
33 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
34 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
35 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
36 | THE SOFTWARE. | ||
37 | |||
38 | =============================================================================== | ||
39 | |||
40 | (end of COPYRIGHT) | ||
diff --git a/libraries/LuaJIT-1.1.7/Makefile b/libraries/LuaJIT-1.1.7/Makefile new file mode 100644 index 0000000..727ccc4 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/Makefile | |||
@@ -0,0 +1,130 @@ | |||
1 | # makefile for installing Lua | ||
2 | # see INSTALL for installation instructions | ||
3 | # see src/Makefile and src/luaconf.h for further customization | ||
4 | |||
5 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= | ||
6 | |||
7 | # Your platform. See PLATS for possible values. | ||
8 | PLAT= none | ||
9 | |||
10 | # Where to install. The installation starts in the src and doc directories, | ||
11 | # so take care if INSTALL_TOP is not an absolute path. | ||
12 | INSTALL_TOP= /usr/local | ||
13 | INSTALL_BIN= $(INSTALL_TOP)/bin | ||
14 | INSTALL_INC= $(INSTALL_TOP)/include | ||
15 | INSTALL_LIB= $(INSTALL_TOP)/lib | ||
16 | INSTALL_MAN= $(INSTALL_TOP)/man/man1 | ||
17 | # | ||
18 | # You probably want to make INSTALL_LMOD and INSTALL_CMOD consistent with | ||
19 | # LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h (and also with etc/luajit.pc). | ||
20 | INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V | ||
21 | INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V | ||
22 | |||
23 | # How to install. If your install program does not support "-p", then you | ||
24 | # may have to run ranlib on the installed liblua.a (do "make ranlib"). | ||
25 | INSTALL= install -p | ||
26 | INSTALL_EXEC= $(INSTALL) -m 0755 | ||
27 | INSTALL_DATA= $(INSTALL) -m 0644 | ||
28 | # | ||
29 | # If you don't have install you can use cp instead. | ||
30 | # INSTALL= cp -p | ||
31 | # INSTALL_EXEC= $(INSTALL) | ||
32 | # INSTALL_DATA= $(INSTALL) | ||
33 | |||
34 | # Utilities. | ||
35 | MKDIR= mkdir -p | ||
36 | RANLIB= ranlib | ||
37 | |||
38 | # == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= | ||
39 | |||
40 | # Convenience platforms targets. | ||
41 | PLATS= linux bsd macosx solaris mingw cygwin posix generic linux_rl bsd_rl macosx_rl | ||
42 | |||
43 | # What to install. | ||
44 | TO_BIN= luajit | ||
45 | ###TO_INC= lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp | ||
46 | ###TO_LIB= liblua.a | ||
47 | ###TO_MAN= lua.1 luac.1 | ||
48 | |||
49 | # Lua version and release. | ||
50 | V= 5.1 | ||
51 | R= 5.1.4 | ||
52 | # LuaJIT version. | ||
53 | JV= 1.1.7 | ||
54 | |||
55 | all: $(PLAT) | ||
56 | |||
57 | $(PLATS) clean: | ||
58 | cd src && $(MAKE) $@ | ||
59 | |||
60 | test: dummy | ||
61 | src/luajit -O -e 'io.write("Hello world, from ", jit.version, "!\n")' | ||
62 | |||
63 | install: dummy | ||
64 | cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD) $(INSTALL_LMOD)/jit | ||
65 | cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN) | ||
66 | ###cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC) | ||
67 | ###cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB) | ||
68 | ###cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN) | ||
69 | cd jit && $(INSTALL_DATA) *.lua $(INSTALL_LMOD)/jit | ||
70 | |||
71 | ranlib: | ||
72 | cd src && cd $(INSTALL_LIB) && $(RANLIB) $(TO_LIB) | ||
73 | |||
74 | none: | ||
75 | @echo "Please do" | ||
76 | @echo " make PLATFORM" | ||
77 | @echo "where PLATFORM is one of these:" | ||
78 | @echo " $(PLATS)" | ||
79 | @echo "See jitdoc/luajit_install.html for complete instructions." | ||
80 | |||
81 | # make may get confused with test/ and INSTALL in a case-insensitive OS | ||
82 | dummy: | ||
83 | |||
84 | # echo config parameters | ||
85 | echo: | ||
86 | @echo "" | ||
87 | @echo "These are the parameters currently set in src/Makefile to build LuaJIT $(JV):" | ||
88 | @echo "" | ||
89 | @cd src && $(MAKE) -s echo | ||
90 | @echo "" | ||
91 | @echo "These are the parameters currently set in Makefile to install LuaJIT $(JV):" | ||
92 | @echo "" | ||
93 | @echo "PLAT = $(PLAT)" | ||
94 | @echo "INSTALL_TOP = $(INSTALL_TOP)" | ||
95 | @echo "INSTALL_BIN = $(INSTALL_BIN)" | ||
96 | @echo "INSTALL_INC = $(INSTALL_INC)" | ||
97 | @echo "INSTALL_LIB = $(INSTALL_LIB)" | ||
98 | @echo "INSTALL_MAN = $(INSTALL_MAN)" | ||
99 | @echo "INSTALL_LMOD = $(INSTALL_LMOD)" | ||
100 | @echo "INSTALL_CMOD = $(INSTALL_CMOD)" | ||
101 | @echo "INSTALL_EXEC = $(INSTALL_EXEC)" | ||
102 | @echo "INSTALL_DATA = $(INSTALL_DATA)" | ||
103 | @echo "" | ||
104 | @echo "See also src/luaconf.h ." | ||
105 | @echo "" | ||
106 | |||
107 | # echo private config parameters | ||
108 | pecho: | ||
109 | @echo "V = $(V)" | ||
110 | @echo "R = $(R)" | ||
111 | @echo "JV = $(JV)" | ||
112 | @echo "TO_BIN = $(TO_BIN)" | ||
113 | @echo "TO_INC = $(TO_INC)" | ||
114 | @echo "TO_LIB = $(TO_LIB)" | ||
115 | @echo "TO_MAN = $(TO_MAN)" | ||
116 | |||
117 | # echo config parameters as Lua code | ||
118 | # uncomment the last sed expression if you want nil instead of empty strings | ||
119 | lecho: | ||
120 | @echo "-- installation parameters for Lua $(R), LuaJIT $(JV)" | ||
121 | @echo "VERSION = '$(V)'" | ||
122 | @echo "RELEASE = '$(R)'" | ||
123 | @echo "LUAJIT_VERSION = '$(JV)'" | ||
124 | @$(MAKE) echo | grep = | sed -e 's/= /= "/' -e 's/$$/"/' #-e 's/""/nil/' | ||
125 | @echo "-- EOF" | ||
126 | |||
127 | # list targets that do not create files (but not all makes understand .PHONY) | ||
128 | .PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho | ||
129 | |||
130 | # (end of Makefile) | ||
diff --git a/libraries/LuaJIT-1.1.7/README b/libraries/LuaJIT-1.1.7/README new file mode 100644 index 0000000..3af04b8 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/README | |||
@@ -0,0 +1,46 @@ | |||
1 | README for LuaJIT 1.1.7 | ||
2 | ----------------------- | ||
3 | |||
4 | ************************************************************ | ||
5 | * This is only a bugfix release for the LuaJIT 1.1 branch. * | ||
6 | * LuaJIT 2.0 is available with much improved performance! * | ||
7 | ************************************************************ | ||
8 | |||
9 | LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language. | ||
10 | |||
11 | Lua is a powerful, light-weight programming language designed | ||
12 | for extending applications. Lua is also frequently used as a | ||
13 | general-purpose, stand-alone language. More information about | ||
14 | Lua can be found in the docs (see below) or at: http://www.lua.org/ | ||
15 | |||
16 | LuaJIT 1.x is based on the Lua 5.1.x virtual machine and bytecode | ||
17 | interpreter from lua.org. It compiles bytecode to native x86 (i386+) | ||
18 | machine code to speed up the execution of Lua programs. | ||
19 | |||
20 | Homepage: http://luajit.org/ | ||
21 | |||
22 | LuaJIT is Copyright (C) 2005-2011 Mike Pall. LuaJIT is free | ||
23 | software, released under the MIT/X license. | ||
24 | |||
25 | ----------------------- | ||
26 | |||
27 | Full documentation for LuaJIT is available in HTML format. | ||
28 | Please point your favourite browser to: | ||
29 | |||
30 | jitdoc/luajit.html | ||
31 | |||
32 | Detailed installation instructions are here: | ||
33 | |||
34 | jitdoc/luajit_install.html | ||
35 | |||
36 | The original documentation for Lua has been included for convenience: | ||
37 | |||
38 | doc/readme.html | ||
39 | |||
40 | ----------------------- | ||
41 | |||
42 | LuaJIT 1.1.7 is a heavily modified version of Lua 5.1.4. | ||
43 | The unmodified Lua distribution is available at: | ||
44 | |||
45 | http://www.lua.org/ftp/lua-5.1.4.tar.gz | ||
46 | |||
diff --git a/libraries/LuaJIT-1.1.7/doc/amazon.gif b/libraries/LuaJIT-1.1.7/doc/amazon.gif new file mode 100644 index 0000000..f2586d5 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/doc/amazon.gif | |||
Binary files differ | |||
diff --git a/libraries/LuaJIT-1.1.7/doc/contents.html b/libraries/LuaJIT-1.1.7/doc/contents.html new file mode 100644 index 0000000..8e58e18 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/doc/contents.html | |||
@@ -0,0 +1,499 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||
2 | <HTML> | ||
3 | <HEAD> | ||
4 | <TITLE>Lua 5.1 Reference Manual - contents</TITLE> | ||
5 | <LINK REL="stylesheet" TYPE="text/css" HREF="lua.css"> | ||
6 | <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1"> | ||
7 | <STYLE TYPE="text/css"> | ||
8 | ul { | ||
9 | list-style-type: none ; | ||
10 | list-style-position: outside ; | ||
11 | } | ||
12 | </STYLE> | ||
13 | </HEAD> | ||
14 | |||
15 | <BODY> | ||
16 | |||
17 | <HR> | ||
18 | <H1> | ||
19 | <A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="" BORDER=0></A> | ||
20 | Lua 5.1 Reference Manual | ||
21 | </H1> | ||
22 | |||
23 | This is an online version of | ||
24 | <BLOCKQUOTE> | ||
25 | <A HREF="http://www.amazon.com/exec/obidos/ASIN/8590379833/lua-indexmanual-20"> | ||
26 | <IMG SRC="cover.png" ALT="" TITLE="buy from Amazon" BORDER=1 ALIGN="left" HSPACE=12> | ||
27 | </A> | ||
28 | <B>Lua 5.1 Reference Manual</B> | ||
29 | <BR>by R. Ierusalimschy, L. H. de Figueiredo, W. Celes | ||
30 | <BR>Lua.org, August 2006 | ||
31 | <BR>ISBN 85-903798-3-3 | ||
32 | <BR><A HREF="http://www.amazon.com/exec/obidos/ASIN/8590379833/lua-indexmanual-20"> | ||
33 | <IMG SRC="amazon.gif" ALT="[Buy from Amazon]" BORDER=0></A> | ||
34 | <BR CLEAR="all"> | ||
35 | </BLOCKQUOTE> | ||
36 | <P> | ||
37 | |||
38 | Buy a copy of this book and | ||
39 | <A HREF="http://www.lua.org/donations.html">help to support</A> | ||
40 | the Lua project. | ||
41 | <P> | ||
42 | |||
43 | The reference manual is the official definition of the Lua language. | ||
44 | For a complete introduction to Lua programming, see the book | ||
45 | <A HREF="http://www.lua.org/docs.html#books">Programming in Lua</A>. | ||
46 | <P> | ||
47 | |||
48 | <A HREF="manual.html">start</A> | ||
49 | · | ||
50 | <A HREF="#contents">contents</A> | ||
51 | · | ||
52 | <A HREF="#index">index</A> | ||
53 | · | ||
54 | <A HREF="http://www.lua.org/manual/5.1/pt/">português</A> | ||
55 | · | ||
56 | <A HREF="http://www.lua.org/manual/5.1/es/">español</A> | ||
57 | <HR> | ||
58 | <SMALL> | ||
59 | Copyright © 2006-2008 Lua.org, PUC-Rio. | ||
60 | Freely available under the terms of the | ||
61 | <a href="http://www.lua.org/license.html#5">Lua license</a>. | ||
62 | </SMALL> | ||
63 | <P> | ||
64 | |||
65 | <H2><A NAME="contents">Contents</A></H2> | ||
66 | <UL style="padding: 0"> | ||
67 | <LI><A HREF="manual.html">1 - Introduction</A> | ||
68 | <P> | ||
69 | <LI><A HREF="manual.html#2">2 - The Language</A> | ||
70 | <UL> | ||
71 | <LI><A HREF="manual.html#2.1">2.1 - Lexical Conventions</A> | ||
72 | <LI><A HREF="manual.html#2.2">2.2 - Values and Types</A> | ||
73 | <UL> | ||
74 | <LI><A HREF="manual.html#2.2.1">2.2.1 - Coercion</A> | ||
75 | </UL> | ||
76 | <LI><A HREF="manual.html#2.3">2.3 - Variables</A> | ||
77 | <LI><A HREF="manual.html#2.4">2.4 - Statements</A> | ||
78 | <UL> | ||
79 | <LI><A HREF="manual.html#2.4.1">2.4.1 - Chunks</A> | ||
80 | <LI><A HREF="manual.html#2.4.2">2.4.2 - Blocks</A> | ||
81 | <LI><A HREF="manual.html#2.4.3">2.4.3 - Assignment</A> | ||
82 | <LI><A HREF="manual.html#2.4.4">2.4.4 - Control Structures</A> | ||
83 | <LI><A HREF="manual.html#2.4.5">2.4.5 - For Statement</A> | ||
84 | <LI><A HREF="manual.html#2.4.6">2.4.6 - Function Calls as Statements</A> | ||
85 | <LI><A HREF="manual.html#2.4.7">2.4.7 - Local Declarations</A> | ||
86 | </UL> | ||
87 | <LI><A HREF="manual.html#2.5">2.5 - Expressions</A> | ||
88 | <UL> | ||
89 | <LI><A HREF="manual.html#2.5.1">2.5.1 - Arithmetic Operators</A> | ||
90 | <LI><A HREF="manual.html#2.5.2">2.5.2 - Relational Operators</A> | ||
91 | <LI><A HREF="manual.html#2.5.3">2.5.3 - Logical Operators</A> | ||
92 | <LI><A HREF="manual.html#2.5.4">2.5.4 - Concatenation</A> | ||
93 | <LI><A HREF="manual.html#2.5.5">2.5.5 - The Length Operator</A> | ||
94 | <LI><A HREF="manual.html#2.5.6">2.5.6 - Precedence</A> | ||
95 | <LI><A HREF="manual.html#2.5.7">2.5.7 - Table Constructors</A> | ||
96 | <LI><A HREF="manual.html#2.5.8">2.5.8 - Function Calls</A> | ||
97 | <LI><A HREF="manual.html#2.5.9">2.5.9 - Function Definitions</A> | ||
98 | </UL> | ||
99 | <LI><A HREF="manual.html#2.6">2.6 - Visibility Rules</A> | ||
100 | <LI><A HREF="manual.html#2.7">2.7 - Error Handling</A> | ||
101 | <LI><A HREF="manual.html#2.8">2.8 - Metatables</A> | ||
102 | <LI><A HREF="manual.html#2.9">2.9 - Environments</A> | ||
103 | <LI><A HREF="manual.html#2.10">2.10 - Garbage Collection</A> | ||
104 | <UL> | ||
105 | <LI><A HREF="manual.html#2.10.1">2.10.1 - Garbage-Collection Metamethods</A> | ||
106 | <LI><A HREF="manual.html#2.10.2">2.10.2 - Weak Tables</A> | ||
107 | </UL> | ||
108 | <LI><A HREF="manual.html#2.11">2.11 - Coroutines</A> | ||
109 | </UL> | ||
110 | <P> | ||
111 | <LI><A HREF="manual.html#3">3 - The Application Program Interface</A> | ||
112 | <UL> | ||
113 | <LI><A HREF="manual.html#3.1">3.1 - The Stack</A> | ||
114 | <LI><A HREF="manual.html#3.2">3.2 - Stack Size</A> | ||
115 | <LI><A HREF="manual.html#3.3">3.3 - Pseudo-Indices</A> | ||
116 | <LI><A HREF="manual.html#3.4">3.4 - C Closures</A> | ||
117 | <LI><A HREF="manual.html#3.5">3.5 - Registry</A> | ||
118 | <LI><A HREF="manual.html#3.6">3.6 - Error Handling in C</A> | ||
119 | <LI><A HREF="manual.html#3.7">3.7 - Functions and Types</A> | ||
120 | <LI><A HREF="manual.html#3.8">3.8 - The Debug Interface</A> | ||
121 | </UL> | ||
122 | <P> | ||
123 | <LI><A HREF="manual.html#4">4 - The Auxiliary Library</A> | ||
124 | <UL> | ||
125 | <LI><A HREF="manual.html#4.1">4.1 - Functions and Types</A> | ||
126 | </UL> | ||
127 | <P> | ||
128 | <LI><A HREF="manual.html#5">5 - Standard Libraries</A> | ||
129 | <UL> | ||
130 | <LI><A HREF="manual.html#5.1">5.1 - Basic Functions</A> | ||
131 | <LI><A HREF="manual.html#5.2">5.2 - Coroutine Manipulation</A> | ||
132 | <LI><A HREF="manual.html#5.3">5.3 - Modules</A> | ||
133 | <LI><A HREF="manual.html#5.4">5.4 - String Manipulation</A> | ||
134 | <UL> | ||
135 | <LI><A HREF="manual.html#5.4.1">5.4.1 - Patterns</A> | ||
136 | </UL> | ||
137 | <LI><A HREF="manual.html#5.5">5.5 - Table Manipulation</A> | ||
138 | <LI><A HREF="manual.html#5.6">5.6 - Mathematical Functions</A> | ||
139 | <LI><A HREF="manual.html#5.7">5.7 - Input and Output Facilities</A> | ||
140 | <LI><A HREF="manual.html#5.8">5.8 - Operating System Facilities</A> | ||
141 | <LI><A HREF="manual.html#5.9">5.9 - The Debug Library</A> | ||
142 | </UL> | ||
143 | <P> | ||
144 | <LI><A HREF="manual.html#6">6 - Lua Stand-alone</A> | ||
145 | <P> | ||
146 | <LI><A HREF="manual.html#7">7 - Incompatibilities with the Previous Version</A> | ||
147 | <UL> | ||
148 | <LI><A HREF="manual.html#7.1">7.1 - Changes in the Language</A> | ||
149 | <LI><A HREF="manual.html#7.2">7.2 - Changes in the Libraries</A> | ||
150 | <LI><A HREF="manual.html#7.3">7.3 - Changes in the API</A> | ||
151 | </UL> | ||
152 | <P> | ||
153 | <LI><A HREF="manual.html#8">8 - The Complete Syntax of Lua</A> | ||
154 | </UL> | ||
155 | |||
156 | <H2><A NAME="index">Index</A></H2> | ||
157 | <TABLE WIDTH="100%"> | ||
158 | <TR VALIGN="top"> | ||
159 | <TD> | ||
160 | <H3><A NAME="functions">Lua functions</A></H3> | ||
161 | <A HREF="manual.html#pdf-_G">_G</A><BR> | ||
162 | <A HREF="manual.html#pdf-_VERSION">_VERSION</A><BR> | ||
163 | <A HREF="manual.html#pdf-assert">assert</A><BR> | ||
164 | <A HREF="manual.html#pdf-collectgarbage">collectgarbage</A><BR> | ||
165 | <A HREF="manual.html#pdf-dofile">dofile</A><BR> | ||
166 | <A HREF="manual.html#pdf-error">error</A><BR> | ||
167 | <A HREF="manual.html#pdf-getfenv">getfenv</A><BR> | ||
168 | <A HREF="manual.html#pdf-getmetatable">getmetatable</A><BR> | ||
169 | <A HREF="manual.html#pdf-ipairs">ipairs</A><BR> | ||
170 | <A HREF="manual.html#pdf-load">load</A><BR> | ||
171 | <A HREF="manual.html#pdf-loadfile">loadfile</A><BR> | ||
172 | <A HREF="manual.html#pdf-loadstring">loadstring</A><BR> | ||
173 | <A HREF="manual.html#pdf-module">module</A><BR> | ||
174 | <A HREF="manual.html#pdf-next">next</A><BR> | ||
175 | <A HREF="manual.html#pdf-pairs">pairs</A><BR> | ||
176 | <A HREF="manual.html#pdf-pcall">pcall</A><BR> | ||
177 | <A HREF="manual.html#pdf-print">print</A><BR> | ||
178 | <A HREF="manual.html#pdf-rawequal">rawequal</A><BR> | ||
179 | <A HREF="manual.html#pdf-rawget">rawget</A><BR> | ||
180 | <A HREF="manual.html#pdf-rawset">rawset</A><BR> | ||
181 | <A HREF="manual.html#pdf-require">require</A><BR> | ||
182 | <A HREF="manual.html#pdf-select">select</A><BR> | ||
183 | <A HREF="manual.html#pdf-setfenv">setfenv</A><BR> | ||
184 | <A HREF="manual.html#pdf-setmetatable">setmetatable</A><BR> | ||
185 | <A HREF="manual.html#pdf-tonumber">tonumber</A><BR> | ||
186 | <A HREF="manual.html#pdf-tostring">tostring</A><BR> | ||
187 | <A HREF="manual.html#pdf-type">type</A><BR> | ||
188 | <A HREF="manual.html#pdf-unpack">unpack</A><BR> | ||
189 | <A HREF="manual.html#pdf-xpcall">xpcall</A><BR> | ||
190 | <P> | ||
191 | |||
192 | <A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR> | ||
193 | <A HREF="manual.html#pdf-coroutine.resume">coroutine.resume</A><BR> | ||
194 | <A HREF="manual.html#pdf-coroutine.running">coroutine.running</A><BR> | ||
195 | <A HREF="manual.html#pdf-coroutine.status">coroutine.status</A><BR> | ||
196 | <A HREF="manual.html#pdf-coroutine.wrap">coroutine.wrap</A><BR> | ||
197 | <A HREF="manual.html#pdf-coroutine.yield">coroutine.yield</A><BR> | ||
198 | <P> | ||
199 | |||
200 | <A HREF="manual.html#pdf-debug.debug">debug.debug</A><BR> | ||
201 | <A HREF="manual.html#pdf-debug.getfenv">debug.getfenv</A><BR> | ||
202 | <A HREF="manual.html#pdf-debug.gethook">debug.gethook</A><BR> | ||
203 | <A HREF="manual.html#pdf-debug.getinfo">debug.getinfo</A><BR> | ||
204 | <A HREF="manual.html#pdf-debug.getlocal">debug.getlocal</A><BR> | ||
205 | <A HREF="manual.html#pdf-debug.getmetatable">debug.getmetatable</A><BR> | ||
206 | <A HREF="manual.html#pdf-debug.getregistry">debug.getregistry</A><BR> | ||
207 | <A HREF="manual.html#pdf-debug.getupvalue">debug.getupvalue</A><BR> | ||
208 | <A HREF="manual.html#pdf-debug.setfenv">debug.setfenv</A><BR> | ||
209 | <A HREF="manual.html#pdf-debug.sethook">debug.sethook</A><BR> | ||
210 | <A HREF="manual.html#pdf-debug.setlocal">debug.setlocal</A><BR> | ||
211 | <A HREF="manual.html#pdf-debug.setmetatable">debug.setmetatable</A><BR> | ||
212 | <A HREF="manual.html#pdf-debug.setupvalue">debug.setupvalue</A><BR> | ||
213 | <A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR> | ||
214 | |||
215 | </TD> | ||
216 | <TD> | ||
217 | <H3> </H3> | ||
218 | <A HREF="manual.html#pdf-file:close">file:close</A><BR> | ||
219 | <A HREF="manual.html#pdf-file:flush">file:flush</A><BR> | ||
220 | <A HREF="manual.html#pdf-file:lines">file:lines</A><BR> | ||
221 | <A HREF="manual.html#pdf-file:read">file:read</A><BR> | ||
222 | <A HREF="manual.html#pdf-file:seek">file:seek</A><BR> | ||
223 | <A HREF="manual.html#pdf-file:setvbuf">file:setvbuf</A><BR> | ||
224 | <A HREF="manual.html#pdf-file:write">file:write</A><BR> | ||
225 | <P> | ||
226 | |||
227 | <A HREF="manual.html#pdf-io.close">io.close</A><BR> | ||
228 | <A HREF="manual.html#pdf-io.flush">io.flush</A><BR> | ||
229 | <A HREF="manual.html#pdf-io.input">io.input</A><BR> | ||
230 | <A HREF="manual.html#pdf-io.lines">io.lines</A><BR> | ||
231 | <A HREF="manual.html#pdf-io.open">io.open</A><BR> | ||
232 | <A HREF="manual.html#pdf-io.output">io.output</A><BR> | ||
233 | <A HREF="manual.html#pdf-io.popen">io.popen</A><BR> | ||
234 | <A HREF="manual.html#pdf-io.read">io.read</A><BR> | ||
235 | <A HREF="manual.html#pdf-io.stderr">io.stderr</A><BR> | ||
236 | <A HREF="manual.html#pdf-io.stdin">io.stdin</A><BR> | ||
237 | <A HREF="manual.html#pdf-io.stdout">io.stdout</A><BR> | ||
238 | <A HREF="manual.html#pdf-io.tmpfile">io.tmpfile</A><BR> | ||
239 | <A HREF="manual.html#pdf-io.type">io.type</A><BR> | ||
240 | <A HREF="manual.html#pdf-io.write">io.write</A><BR> | ||
241 | <P> | ||
242 | |||
243 | <A HREF="manual.html#pdf-math.abs">math.abs</A><BR> | ||
244 | <A HREF="manual.html#pdf-math.acos">math.acos</A><BR> | ||
245 | <A HREF="manual.html#pdf-math.asin">math.asin</A><BR> | ||
246 | <A HREF="manual.html#pdf-math.atan">math.atan</A><BR> | ||
247 | <A HREF="manual.html#pdf-math.atan2">math.atan2</A><BR> | ||
248 | <A HREF="manual.html#pdf-math.ceil">math.ceil</A><BR> | ||
249 | <A HREF="manual.html#pdf-math.cos">math.cos</A><BR> | ||
250 | <A HREF="manual.html#pdf-math.cosh">math.cosh</A><BR> | ||
251 | <A HREF="manual.html#pdf-math.deg">math.deg</A><BR> | ||
252 | <A HREF="manual.html#pdf-math.exp">math.exp</A><BR> | ||
253 | <A HREF="manual.html#pdf-math.floor">math.floor</A><BR> | ||
254 | <A HREF="manual.html#pdf-math.fmod">math.fmod</A><BR> | ||
255 | <A HREF="manual.html#pdf-math.frexp">math.frexp</A><BR> | ||
256 | <A HREF="manual.html#pdf-math.huge">math.huge</A><BR> | ||
257 | <A HREF="manual.html#pdf-math.ldexp">math.ldexp</A><BR> | ||
258 | <A HREF="manual.html#pdf-math.log">math.log</A><BR> | ||
259 | <A HREF="manual.html#pdf-math.log10">math.log10</A><BR> | ||
260 | <A HREF="manual.html#pdf-math.max">math.max</A><BR> | ||
261 | <A HREF="manual.html#pdf-math.min">math.min</A><BR> | ||
262 | <A HREF="manual.html#pdf-math.modf">math.modf</A><BR> | ||
263 | <A HREF="manual.html#pdf-math.pi">math.pi</A><BR> | ||
264 | <A HREF="manual.html#pdf-math.pow">math.pow</A><BR> | ||
265 | <A HREF="manual.html#pdf-math.rad">math.rad</A><BR> | ||
266 | <A HREF="manual.html#pdf-math.random">math.random</A><BR> | ||
267 | <A HREF="manual.html#pdf-math.randomseed">math.randomseed</A><BR> | ||
268 | <A HREF="manual.html#pdf-math.sin">math.sin</A><BR> | ||
269 | <A HREF="manual.html#pdf-math.sinh">math.sinh</A><BR> | ||
270 | <A HREF="manual.html#pdf-math.sqrt">math.sqrt</A><BR> | ||
271 | <A HREF="manual.html#pdf-math.tan">math.tan</A><BR> | ||
272 | <A HREF="manual.html#pdf-math.tanh">math.tanh</A><BR> | ||
273 | <P> | ||
274 | |||
275 | <A HREF="manual.html#pdf-os.clock">os.clock</A><BR> | ||
276 | <A HREF="manual.html#pdf-os.date">os.date</A><BR> | ||
277 | <A HREF="manual.html#pdf-os.difftime">os.difftime</A><BR> | ||
278 | <A HREF="manual.html#pdf-os.execute">os.execute</A><BR> | ||
279 | <A HREF="manual.html#pdf-os.exit">os.exit</A><BR> | ||
280 | <A HREF="manual.html#pdf-os.getenv">os.getenv</A><BR> | ||
281 | <A HREF="manual.html#pdf-os.remove">os.remove</A><BR> | ||
282 | <A HREF="manual.html#pdf-os.rename">os.rename</A><BR> | ||
283 | <A HREF="manual.html#pdf-os.setlocale">os.setlocale</A><BR> | ||
284 | <A HREF="manual.html#pdf-os.time">os.time</A><BR> | ||
285 | <A HREF="manual.html#pdf-os.tmpname">os.tmpname</A><BR> | ||
286 | <P> | ||
287 | |||
288 | <A HREF="manual.html#pdf-package.cpath">package.cpath</A><BR> | ||
289 | <A HREF="manual.html#pdf-package.loaded">package.loaded</A><BR> | ||
290 | <A HREF="manual.html#pdf-package.loaders">package.loaders</A><BR> | ||
291 | <A HREF="manual.html#pdf-package.loadlib">package.loadlib</A><BR> | ||
292 | <A HREF="manual.html#pdf-package.path">package.path</A><BR> | ||
293 | <A HREF="manual.html#pdf-package.preload">package.preload</A><BR> | ||
294 | <A HREF="manual.html#pdf-package.seeall">package.seeall</A><BR> | ||
295 | <P> | ||
296 | |||
297 | <A HREF="manual.html#pdf-string.byte">string.byte</A><BR> | ||
298 | <A HREF="manual.html#pdf-string.char">string.char</A><BR> | ||
299 | <A HREF="manual.html#pdf-string.dump">string.dump</A><BR> | ||
300 | <A HREF="manual.html#pdf-string.find">string.find</A><BR> | ||
301 | <A HREF="manual.html#pdf-string.format">string.format</A><BR> | ||
302 | <A HREF="manual.html#pdf-string.gmatch">string.gmatch</A><BR> | ||
303 | <A HREF="manual.html#pdf-string.gsub">string.gsub</A><BR> | ||
304 | <A HREF="manual.html#pdf-string.len">string.len</A><BR> | ||
305 | <A HREF="manual.html#pdf-string.lower">string.lower</A><BR> | ||
306 | <A HREF="manual.html#pdf-string.match">string.match</A><BR> | ||
307 | <A HREF="manual.html#pdf-string.rep">string.rep</A><BR> | ||
308 | <A HREF="manual.html#pdf-string.reverse">string.reverse</A><BR> | ||
309 | <A HREF="manual.html#pdf-string.sub">string.sub</A><BR> | ||
310 | <A HREF="manual.html#pdf-string.upper">string.upper</A><BR> | ||
311 | <P> | ||
312 | |||
313 | <A HREF="manual.html#pdf-table.concat">table.concat</A><BR> | ||
314 | <A HREF="manual.html#pdf-table.insert">table.insert</A><BR> | ||
315 | <A HREF="manual.html#pdf-table.maxn">table.maxn</A><BR> | ||
316 | <A HREF="manual.html#pdf-table.remove">table.remove</A><BR> | ||
317 | <A HREF="manual.html#pdf-table.sort">table.sort</A><BR> | ||
318 | |||
319 | </TD> | ||
320 | <TD> | ||
321 | <H3>C API</H3> | ||
322 | <A HREF="manual.html#lua_Alloc">lua_Alloc</A><BR> | ||
323 | <A HREF="manual.html#lua_CFunction">lua_CFunction</A><BR> | ||
324 | <A HREF="manual.html#lua_Debug">lua_Debug</A><BR> | ||
325 | <A HREF="manual.html#lua_Hook">lua_Hook</A><BR> | ||
326 | <A HREF="manual.html#lua_Integer">lua_Integer</A><BR> | ||
327 | <A HREF="manual.html#lua_Number">lua_Number</A><BR> | ||
328 | <A HREF="manual.html#lua_Reader">lua_Reader</A><BR> | ||
329 | <A HREF="manual.html#lua_State">lua_State</A><BR> | ||
330 | <A HREF="manual.html#lua_Writer">lua_Writer</A><BR> | ||
331 | <P> | ||
332 | |||
333 | <A HREF="manual.html#lua_atpanic">lua_atpanic</A><BR> | ||
334 | <A HREF="manual.html#lua_call">lua_call</A><BR> | ||
335 | <A HREF="manual.html#lua_checkstack">lua_checkstack</A><BR> | ||
336 | <A HREF="manual.html#lua_close">lua_close</A><BR> | ||
337 | <A HREF="manual.html#lua_concat">lua_concat</A><BR> | ||
338 | <A HREF="manual.html#lua_cpcall">lua_cpcall</A><BR> | ||
339 | <A HREF="manual.html#lua_createtable">lua_createtable</A><BR> | ||
340 | <A HREF="manual.html#lua_dump">lua_dump</A><BR> | ||
341 | <A HREF="manual.html#lua_equal">lua_equal</A><BR> | ||
342 | <A HREF="manual.html#lua_error">lua_error</A><BR> | ||
343 | <A HREF="manual.html#lua_gc">lua_gc</A><BR> | ||
344 | <A HREF="manual.html#lua_getallocf">lua_getallocf</A><BR> | ||
345 | <A HREF="manual.html#lua_getfenv">lua_getfenv</A><BR> | ||
346 | <A HREF="manual.html#lua_getfield">lua_getfield</A><BR> | ||
347 | <A HREF="manual.html#lua_getglobal">lua_getglobal</A><BR> | ||
348 | <A HREF="manual.html#lua_gethook">lua_gethook</A><BR> | ||
349 | <A HREF="manual.html#lua_gethookcount">lua_gethookcount</A><BR> | ||
350 | <A HREF="manual.html#lua_gethookmask">lua_gethookmask</A><BR> | ||
351 | <A HREF="manual.html#lua_getinfo">lua_getinfo</A><BR> | ||
352 | <A HREF="manual.html#lua_getlocal">lua_getlocal</A><BR> | ||
353 | <A HREF="manual.html#lua_getmetatable">lua_getmetatable</A><BR> | ||
354 | <A HREF="manual.html#lua_getstack">lua_getstack</A><BR> | ||
355 | <A HREF="manual.html#lua_gettable">lua_gettable</A><BR> | ||
356 | <A HREF="manual.html#lua_gettop">lua_gettop</A><BR> | ||
357 | <A HREF="manual.html#lua_getupvalue">lua_getupvalue</A><BR> | ||
358 | <A HREF="manual.html#lua_insert">lua_insert</A><BR> | ||
359 | <A HREF="manual.html#lua_isboolean">lua_isboolean</A><BR> | ||
360 | <A HREF="manual.html#lua_iscfunction">lua_iscfunction</A><BR> | ||
361 | <A HREF="manual.html#lua_isfunction">lua_isfunction</A><BR> | ||
362 | <A HREF="manual.html#lua_islightuserdata">lua_islightuserdata</A><BR> | ||
363 | <A HREF="manual.html#lua_isnil">lua_isnil</A><BR> | ||
364 | <A HREF="manual.html#lua_isnone">lua_isnone</A><BR> | ||
365 | <A HREF="manual.html#lua_isnoneornil">lua_isnoneornil</A><BR> | ||
366 | <A HREF="manual.html#lua_isnumber">lua_isnumber</A><BR> | ||
367 | <A HREF="manual.html#lua_isstring">lua_isstring</A><BR> | ||
368 | <A HREF="manual.html#lua_istable">lua_istable</A><BR> | ||
369 | <A HREF="manual.html#lua_isthread">lua_isthread</A><BR> | ||
370 | <A HREF="manual.html#lua_isuserdata">lua_isuserdata</A><BR> | ||
371 | <A HREF="manual.html#lua_lessthan">lua_lessthan</A><BR> | ||
372 | <A HREF="manual.html#lua_load">lua_load</A><BR> | ||
373 | <A HREF="manual.html#lua_newstate">lua_newstate</A><BR> | ||
374 | <A HREF="manual.html#lua_newtable">lua_newtable</A><BR> | ||
375 | <A HREF="manual.html#lua_newthread">lua_newthread</A><BR> | ||
376 | <A HREF="manual.html#lua_newuserdata">lua_newuserdata</A><BR> | ||
377 | <A HREF="manual.html#lua_next">lua_next</A><BR> | ||
378 | <A HREF="manual.html#lua_objlen">lua_objlen</A><BR> | ||
379 | <A HREF="manual.html#lua_pcall">lua_pcall</A><BR> | ||
380 | <A HREF="manual.html#lua_pop">lua_pop</A><BR> | ||
381 | <A HREF="manual.html#lua_pushboolean">lua_pushboolean</A><BR> | ||
382 | <A HREF="manual.html#lua_pushcclosure">lua_pushcclosure</A><BR> | ||
383 | <A HREF="manual.html#lua_pushcfunction">lua_pushcfunction</A><BR> | ||
384 | <A HREF="manual.html#lua_pushfstring">lua_pushfstring</A><BR> | ||
385 | <A HREF="manual.html#lua_pushinteger">lua_pushinteger</A><BR> | ||
386 | <A HREF="manual.html#lua_pushlightuserdata">lua_pushlightuserdata</A><BR> | ||
387 | <A HREF="manual.html#lua_pushliteral">lua_pushliteral</A><BR> | ||
388 | <A HREF="manual.html#lua_pushlstring">lua_pushlstring</A><BR> | ||
389 | <A HREF="manual.html#lua_pushnil">lua_pushnil</A><BR> | ||
390 | <A HREF="manual.html#lua_pushnumber">lua_pushnumber</A><BR> | ||
391 | <A HREF="manual.html#lua_pushstring">lua_pushstring</A><BR> | ||
392 | <A HREF="manual.html#lua_pushthread">lua_pushthread</A><BR> | ||
393 | <A HREF="manual.html#lua_pushvalue">lua_pushvalue</A><BR> | ||
394 | <A HREF="manual.html#lua_pushvfstring">lua_pushvfstring</A><BR> | ||
395 | <A HREF="manual.html#lua_rawequal">lua_rawequal</A><BR> | ||
396 | <A HREF="manual.html#lua_rawget">lua_rawget</A><BR> | ||
397 | <A HREF="manual.html#lua_rawgeti">lua_rawgeti</A><BR> | ||
398 | <A HREF="manual.html#lua_rawset">lua_rawset</A><BR> | ||
399 | <A HREF="manual.html#lua_rawseti">lua_rawseti</A><BR> | ||
400 | <A HREF="manual.html#lua_register">lua_register</A><BR> | ||
401 | <A HREF="manual.html#lua_remove">lua_remove</A><BR> | ||
402 | <A HREF="manual.html#lua_replace">lua_replace</A><BR> | ||
403 | <A HREF="manual.html#lua_resume">lua_resume</A><BR> | ||
404 | <A HREF="manual.html#lua_setallocf">lua_setallocf</A><BR> | ||
405 | <A HREF="manual.html#lua_setfenv">lua_setfenv</A><BR> | ||
406 | <A HREF="manual.html#lua_setfield">lua_setfield</A><BR> | ||
407 | <A HREF="manual.html#lua_setglobal">lua_setglobal</A><BR> | ||
408 | <A HREF="manual.html#lua_sethook">lua_sethook</A><BR> | ||
409 | <A HREF="manual.html#lua_setlocal">lua_setlocal</A><BR> | ||
410 | <A HREF="manual.html#lua_setmetatable">lua_setmetatable</A><BR> | ||
411 | <A HREF="manual.html#lua_settable">lua_settable</A><BR> | ||
412 | <A HREF="manual.html#lua_settop">lua_settop</A><BR> | ||
413 | <A HREF="manual.html#lua_setupvalue">lua_setupvalue</A><BR> | ||
414 | <A HREF="manual.html#lua_status">lua_status</A><BR> | ||
415 | <A HREF="manual.html#lua_toboolean">lua_toboolean</A><BR> | ||
416 | <A HREF="manual.html#lua_tocfunction">lua_tocfunction</A><BR> | ||
417 | <A HREF="manual.html#lua_tointeger">lua_tointeger</A><BR> | ||
418 | <A HREF="manual.html#lua_tolstring">lua_tolstring</A><BR> | ||
419 | <A HREF="manual.html#lua_tonumber">lua_tonumber</A><BR> | ||
420 | <A HREF="manual.html#lua_topointer">lua_topointer</A><BR> | ||
421 | <A HREF="manual.html#lua_tostring">lua_tostring</A><BR> | ||
422 | <A HREF="manual.html#lua_tothread">lua_tothread</A><BR> | ||
423 | <A HREF="manual.html#lua_touserdata">lua_touserdata</A><BR> | ||
424 | <A HREF="manual.html#lua_type">lua_type</A><BR> | ||
425 | <A HREF="manual.html#lua_typename">lua_typename</A><BR> | ||
426 | <A HREF="manual.html#lua_upvalueindex">lua_upvalueindex</A><BR> | ||
427 | <A HREF="manual.html#lua_xmove">lua_xmove</A><BR> | ||
428 | <A HREF="manual.html#lua_yield">lua_yield</A><BR> | ||
429 | |||
430 | </TD> | ||
431 | <TD> | ||
432 | <H3>auxiliary library</H3> | ||
433 | <A HREF="manual.html#luaL_Buffer">luaL_Buffer</A><BR> | ||
434 | <A HREF="manual.html#luaL_Reg">luaL_Reg</A><BR> | ||
435 | <P> | ||
436 | |||
437 | <A HREF="manual.html#luaL_addchar">luaL_addchar</A><BR> | ||
438 | <A HREF="manual.html#luaL_addlstring">luaL_addlstring</A><BR> | ||
439 | <A HREF="manual.html#luaL_addsize">luaL_addsize</A><BR> | ||
440 | <A HREF="manual.html#luaL_addstring">luaL_addstring</A><BR> | ||
441 | <A HREF="manual.html#luaL_addvalue">luaL_addvalue</A><BR> | ||
442 | <A HREF="manual.html#luaL_argcheck">luaL_argcheck</A><BR> | ||
443 | <A HREF="manual.html#luaL_argerror">luaL_argerror</A><BR> | ||
444 | <A HREF="manual.html#luaL_buffinit">luaL_buffinit</A><BR> | ||
445 | <A HREF="manual.html#luaL_callmeta">luaL_callmeta</A><BR> | ||
446 | <A HREF="manual.html#luaL_checkany">luaL_checkany</A><BR> | ||
447 | <A HREF="manual.html#luaL_checkint">luaL_checkint</A><BR> | ||
448 | <A HREF="manual.html#luaL_checkinteger">luaL_checkinteger</A><BR> | ||
449 | <A HREF="manual.html#luaL_checklong">luaL_checklong</A><BR> | ||
450 | <A HREF="manual.html#luaL_checklstring">luaL_checklstring</A><BR> | ||
451 | <A HREF="manual.html#luaL_checknumber">luaL_checknumber</A><BR> | ||
452 | <A HREF="manual.html#luaL_checkoption">luaL_checkoption</A><BR> | ||
453 | <A HREF="manual.html#luaL_checkstack">luaL_checkstack</A><BR> | ||
454 | <A HREF="manual.html#luaL_checkstring">luaL_checkstring</A><BR> | ||
455 | <A HREF="manual.html#luaL_checktype">luaL_checktype</A><BR> | ||
456 | <A HREF="manual.html#luaL_checkudata">luaL_checkudata</A><BR> | ||
457 | <A HREF="manual.html#luaL_dofile">luaL_dofile</A><BR> | ||
458 | <A HREF="manual.html#luaL_dostring">luaL_dostring</A><BR> | ||
459 | <A HREF="manual.html#luaL_error">luaL_error</A><BR> | ||
460 | <A HREF="manual.html#luaL_getmetafield">luaL_getmetafield</A><BR> | ||
461 | <A HREF="manual.html#luaL_getmetatable">luaL_getmetatable</A><BR> | ||
462 | <A HREF="manual.html#luaL_gsub">luaL_gsub</A><BR> | ||
463 | <A HREF="manual.html#luaL_loadbuffer">luaL_loadbuffer</A><BR> | ||
464 | <A HREF="manual.html#luaL_loadfile">luaL_loadfile</A><BR> | ||
465 | <A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR> | ||
466 | <A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR> | ||
467 | <A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR> | ||
468 | <A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR> | ||
469 | <A HREF="manual.html#luaL_optint">luaL_optint</A><BR> | ||
470 | <A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR> | ||
471 | <A HREF="manual.html#luaL_optlong">luaL_optlong</A><BR> | ||
472 | <A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR> | ||
473 | <A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR> | ||
474 | <A HREF="manual.html#luaL_optstring">luaL_optstring</A><BR> | ||
475 | <A HREF="manual.html#luaL_prepbuffer">luaL_prepbuffer</A><BR> | ||
476 | <A HREF="manual.html#luaL_pushresult">luaL_pushresult</A><BR> | ||
477 | <A HREF="manual.html#luaL_ref">luaL_ref</A><BR> | ||
478 | <A HREF="manual.html#luaL_register">luaL_register</A><BR> | ||
479 | <A HREF="manual.html#luaL_typename">luaL_typename</A><BR> | ||
480 | <A HREF="manual.html#luaL_typerror">luaL_typerror</A><BR> | ||
481 | <A HREF="manual.html#luaL_unref">luaL_unref</A><BR> | ||
482 | <A HREF="manual.html#luaL_where">luaL_where</A><BR> | ||
483 | |||
484 | </TD> | ||
485 | </TR> | ||
486 | </TABLE> | ||
487 | <P> | ||
488 | |||
489 | <HR> | ||
490 | <SMALL> | ||
491 | Last update: | ||
492 | Sat Jan 19 13:24:29 BRST 2008 | ||
493 | </SMALL> | ||
494 | <!-- | ||
495 | Last change: revised for Lua 5.1.3 | ||
496 | --> | ||
497 | |||
498 | </BODY> | ||
499 | </HTML> | ||
diff --git a/libraries/LuaJIT-1.1.7/doc/cover.png b/libraries/LuaJIT-1.1.7/doc/cover.png new file mode 100644 index 0000000..2dbb198 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/doc/cover.png | |||
Binary files differ | |||
diff --git a/libraries/LuaJIT-1.1.7/doc/logo.gif b/libraries/LuaJIT-1.1.7/doc/logo.gif new file mode 100644 index 0000000..2f5e4ac --- /dev/null +++ b/libraries/LuaJIT-1.1.7/doc/logo.gif | |||
Binary files differ | |||
diff --git a/libraries/LuaJIT-1.1.7/doc/lua.1 b/libraries/LuaJIT-1.1.7/doc/lua.1 new file mode 100644 index 0000000..24809cc --- /dev/null +++ b/libraries/LuaJIT-1.1.7/doc/lua.1 | |||
@@ -0,0 +1,163 @@ | |||
1 | .\" $Id: lua.man,v 1.11 2006/01/06 16:03:34 lhf Exp $ | ||
2 | .TH LUA 1 "$Date: 2006/01/06 16:03:34 $" | ||
3 | .SH NAME | ||
4 | lua \- Lua interpreter | ||
5 | .SH SYNOPSIS | ||
6 | .B lua | ||
7 | [ | ||
8 | .I options | ||
9 | ] | ||
10 | [ | ||
11 | .I script | ||
12 | [ | ||
13 | .I args | ||
14 | ] | ||
15 | ] | ||
16 | .SH DESCRIPTION | ||
17 | .B lua | ||
18 | is the stand-alone Lua interpreter. | ||
19 | It loads and executes Lua programs, | ||
20 | either in textual source form or | ||
21 | in precompiled binary form. | ||
22 | (Precompiled binaries are output by | ||
23 | .BR luac , | ||
24 | the Lua compiler.) | ||
25 | .B lua | ||
26 | can be used as a batch interpreter and also interactively. | ||
27 | .LP | ||
28 | The given | ||
29 | .I options | ||
30 | (see below) | ||
31 | are executed and then | ||
32 | the Lua program in file | ||
33 | .I script | ||
34 | is loaded and executed. | ||
35 | The given | ||
36 | .I args | ||
37 | are available to | ||
38 | .I script | ||
39 | as strings in a global table named | ||
40 | .BR arg . | ||
41 | If these arguments contain spaces or other characters special to the shell, | ||
42 | then they should be quoted | ||
43 | (but note that the quotes will be removed by the shell). | ||
44 | The arguments in | ||
45 | .B arg | ||
46 | start at 0, | ||
47 | which contains the string | ||
48 | .RI ' script '. | ||
49 | The index of the last argument is stored in | ||
50 | .BR arg.n . | ||
51 | The arguments given in the command line before | ||
52 | .IR script , | ||
53 | including the name of the interpreter, | ||
54 | are available in negative indices in | ||
55 | .BR arg . | ||
56 | .LP | ||
57 | At the very start, | ||
58 | before even handling the command line, | ||
59 | .B lua | ||
60 | executes the contents of the environment variable | ||
61 | .BR LUA_INIT , | ||
62 | if it is defined. | ||
63 | If the value of | ||
64 | .B LUA_INIT | ||
65 | is of the form | ||
66 | .RI '@ filename ', | ||
67 | then | ||
68 | .I filename | ||
69 | is executed. | ||
70 | Otherwise, the string is assumed to be a Lua statement and is executed. | ||
71 | .LP | ||
72 | Options start with | ||
73 | .B '\-' | ||
74 | and are described below. | ||
75 | You can use | ||
76 | .B "'\--'" | ||
77 | to signal the end of options. | ||
78 | .LP | ||
79 | If no arguments are given, | ||
80 | then | ||
81 | .B "\-v \-i" | ||
82 | is assumed when the standard input is a terminal; | ||
83 | otherwise, | ||
84 | .B "\-" | ||
85 | is assumed. | ||
86 | .LP | ||
87 | In interactive mode, | ||
88 | .B lua | ||
89 | prompts the user, | ||
90 | reads lines from the standard input, | ||
91 | and executes them as they are read. | ||
92 | If a line does not contain a complete statement, | ||
93 | then a secondary prompt is displayed and | ||
94 | lines are read until a complete statement is formed or | ||
95 | a syntax error is found. | ||
96 | So, one way to interrupt the reading of an incomplete statement is | ||
97 | to force a syntax error: | ||
98 | adding a | ||
99 | .B ';' | ||
100 | in the middle of a statement is a sure way of forcing a syntax error | ||
101 | (except inside multiline strings and comments; these must be closed explicitly). | ||
102 | If a line starts with | ||
103 | .BR '=' , | ||
104 | then | ||
105 | .B lua | ||
106 | displays the values of all the expressions in the remainder of the | ||
107 | line. The expressions must be separated by commas. | ||
108 | The primary prompt is the value of the global variable | ||
109 | .BR _PROMPT , | ||
110 | if this value is a string; | ||
111 | otherwise, the default prompt is used. | ||
112 | Similarly, the secondary prompt is the value of the global variable | ||
113 | .BR _PROMPT2 . | ||
114 | So, | ||
115 | to change the prompts, | ||
116 | set the corresponding variable to a string of your choice. | ||
117 | You can do that after calling the interpreter | ||
118 | or on the command line | ||
119 | (but in this case you have to be careful with quotes | ||
120 | if the prompt string contains a space; otherwise you may confuse the shell.) | ||
121 | The default prompts are "> " and ">> ". | ||
122 | .SH OPTIONS | ||
123 | .TP | ||
124 | .B \- | ||
125 | load and execute the standard input as a file, | ||
126 | that is, | ||
127 | not interactively, | ||
128 | even when the standard input is a terminal. | ||
129 | .TP | ||
130 | .BI \-e " stat" | ||
131 | execute statement | ||
132 | .IR stat . | ||
133 | You need to quote | ||
134 | .I stat | ||
135 | if it contains spaces, quotes, | ||
136 | or other characters special to the shell. | ||
137 | .TP | ||
138 | .B \-i | ||
139 | enter interactive mode after | ||
140 | .I script | ||
141 | is executed. | ||
142 | .TP | ||
143 | .BI \-l " name" | ||
144 | call | ||
145 | .BI require(' name ') | ||
146 | before executing | ||
147 | .IR script . | ||
148 | Typically used to load libraries. | ||
149 | .TP | ||
150 | .B \-v | ||
151 | show version information. | ||
152 | .SH "SEE ALSO" | ||
153 | .BR luac (1) | ||
154 | .br | ||
155 | http://www.lua.org/ | ||
156 | .SH DIAGNOSTICS | ||
157 | Error messages should be self explanatory. | ||
158 | .SH AUTHORS | ||
159 | R. Ierusalimschy, | ||
160 | L. H. de Figueiredo, | ||
161 | and | ||
162 | W. Celes | ||
163 | .\" EOF | ||
diff --git a/libraries/LuaJIT-1.1.7/doc/lua.css b/libraries/LuaJIT-1.1.7/doc/lua.css new file mode 100644 index 0000000..039cf11 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/doc/lua.css | |||
@@ -0,0 +1,41 @@ | |||
1 | body { | ||
2 | color: #000000 ; | ||
3 | background-color: #FFFFFF ; | ||
4 | font-family: sans-serif ; | ||
5 | text-align: justify ; | ||
6 | margin-right: 20px ; | ||
7 | margin-left: 20px ; | ||
8 | } | ||
9 | |||
10 | h1, h2, h3, h4 { | ||
11 | font-weight: normal ; | ||
12 | font-style: italic ; | ||
13 | } | ||
14 | |||
15 | a:link { | ||
16 | color: #000080 ; | ||
17 | background-color: inherit ; | ||
18 | text-decoration: none ; | ||
19 | } | ||
20 | |||
21 | a:visited { | ||
22 | background-color: inherit ; | ||
23 | text-decoration: none ; | ||
24 | } | ||
25 | |||
26 | a:link:hover, a:visited:hover { | ||
27 | color: #000080 ; | ||
28 | background-color: #E0E0FF ; | ||
29 | } | ||
30 | |||
31 | a:link:active, a:visited:active { | ||
32 | color: #FF0000 ; | ||
33 | } | ||
34 | |||
35 | hr { | ||
36 | border: 0 ; | ||
37 | height: 1px ; | ||
38 | color: #a0a0a0 ; | ||
39 | background-color: #a0a0a0 ; | ||
40 | } | ||
41 | |||
diff --git a/libraries/LuaJIT-1.1.7/doc/lua.html b/libraries/LuaJIT-1.1.7/doc/lua.html new file mode 100644 index 0000000..1d435ab --- /dev/null +++ b/libraries/LuaJIT-1.1.7/doc/lua.html | |||
@@ -0,0 +1,172 @@ | |||
1 | <!-- $Id: lua.man,v 1.11 2006/01/06 16:03:34 lhf Exp $ --> | ||
2 | <HTML> | ||
3 | <HEAD> | ||
4 | <TITLE>LUA man page</TITLE> | ||
5 | <LINK REL="stylesheet" TYPE="text/css" HREF="lua.css"> | ||
6 | </HEAD> | ||
7 | |||
8 | <BODY BGCOLOR="#FFFFFF"> | ||
9 | |||
10 | <H2>NAME</H2> | ||
11 | lua - Lua interpreter | ||
12 | <H2>SYNOPSIS</H2> | ||
13 | <B>lua</B> | ||
14 | [ | ||
15 | <I>options</I> | ||
16 | ] | ||
17 | [ | ||
18 | <I>script</I> | ||
19 | [ | ||
20 | <I>args</I> | ||
21 | ] | ||
22 | ] | ||
23 | <H2>DESCRIPTION</H2> | ||
24 | <B>lua</B> | ||
25 | is the stand-alone Lua interpreter. | ||
26 | It loads and executes Lua programs, | ||
27 | either in textual source form or | ||
28 | in precompiled binary form. | ||
29 | (Precompiled binaries are output by | ||
30 | <B>luac</B>, | ||
31 | the Lua compiler.) | ||
32 | <B>lua</B> | ||
33 | can be used as a batch interpreter and also interactively. | ||
34 | <P> | ||
35 | The given | ||
36 | <I>options</I> | ||
37 | (see below) | ||
38 | are executed and then | ||
39 | the Lua program in file | ||
40 | <I>script</I> | ||
41 | is loaded and executed. | ||
42 | The given | ||
43 | <I>args</I> | ||
44 | are available to | ||
45 | <I>script</I> | ||
46 | as strings in a global table named | ||
47 | <B>arg</B>. | ||
48 | If these arguments contain spaces or other characters special to the shell, | ||
49 | then they should be quoted | ||
50 | (but note that the quotes will be removed by the shell). | ||
51 | The arguments in | ||
52 | <B>arg</B> | ||
53 | start at 0, | ||
54 | which contains the string | ||
55 | '<I>script</I>'. | ||
56 | The index of the last argument is stored in | ||
57 | <B>arg.n</B>. | ||
58 | The arguments given in the command line before | ||
59 | <I>script</I>, | ||
60 | including the name of the interpreter, | ||
61 | are available in negative indices in | ||
62 | <B>arg</B>. | ||
63 | <P> | ||
64 | At the very start, | ||
65 | before even handling the command line, | ||
66 | <B>lua</B> | ||
67 | executes the contents of the environment variable | ||
68 | <B>LUA_INIT</B>, | ||
69 | if it is defined. | ||
70 | If the value of | ||
71 | <B>LUA_INIT</B> | ||
72 | is of the form | ||
73 | '@<I>filename</I>', | ||
74 | then | ||
75 | <I>filename</I> | ||
76 | is executed. | ||
77 | Otherwise, the string is assumed to be a Lua statement and is executed. | ||
78 | <P> | ||
79 | Options start with | ||
80 | <B>'-'</B> | ||
81 | and are described below. | ||
82 | You can use | ||
83 | <B>'--'</B> | ||
84 | to signal the end of options. | ||
85 | <P> | ||
86 | If no arguments are given, | ||
87 | then | ||
88 | <B>"-v -i"</B> | ||
89 | is assumed when the standard input is a terminal; | ||
90 | otherwise, | ||
91 | <B>"-"</B> | ||
92 | is assumed. | ||
93 | <P> | ||
94 | In interactive mode, | ||
95 | <B>lua</B> | ||
96 | prompts the user, | ||
97 | reads lines from the standard input, | ||
98 | and executes them as they are read. | ||
99 | If a line does not contain a complete statement, | ||
100 | then a secondary prompt is displayed and | ||
101 | lines are read until a complete statement is formed or | ||
102 | a syntax error is found. | ||
103 | So, one way to interrupt the reading of an incomplete statement is | ||
104 | to force a syntax error: | ||
105 | adding a | ||
106 | <B>';'</B> | ||
107 | in the middle of a statement is a sure way of forcing a syntax error | ||
108 | (except inside multiline strings and comments; these must be closed explicitly). | ||
109 | If a line starts with | ||
110 | <B>'='</B>, | ||
111 | then | ||
112 | <B>lua</B> | ||
113 | displays the values of all the expressions in the remainder of the | ||
114 | line. The expressions must be separated by commas. | ||
115 | The primary prompt is the value of the global variable | ||
116 | <B>_PROMPT</B>, | ||
117 | if this value is a string; | ||
118 | otherwise, the default prompt is used. | ||
119 | Similarly, the secondary prompt is the value of the global variable | ||
120 | <B>_PROMPT2</B>. | ||
121 | So, | ||
122 | to change the prompts, | ||
123 | set the corresponding variable to a string of your choice. | ||
124 | You can do that after calling the interpreter | ||
125 | or on the command line | ||
126 | (but in this case you have to be careful with quotes | ||
127 | if the prompt string contains a space; otherwise you may confuse the shell.) | ||
128 | The default prompts are "> " and ">> ". | ||
129 | <H2>OPTIONS</H2> | ||
130 | <P> | ||
131 | <B>-</B> | ||
132 | load and execute the standard input as a file, | ||
133 | that is, | ||
134 | not interactively, | ||
135 | even when the standard input is a terminal. | ||
136 | <P> | ||
137 | <B>-e </B><I>stat</I> | ||
138 | execute statement | ||
139 | <I>stat</I>. | ||
140 | You need to quote | ||
141 | <I>stat </I> | ||
142 | if it contains spaces, quotes, | ||
143 | or other characters special to the shell. | ||
144 | <P> | ||
145 | <B>-i</B> | ||
146 | enter interactive mode after | ||
147 | <I>script</I> | ||
148 | is executed. | ||
149 | <P> | ||
150 | <B>-l </B><I>name</I> | ||
151 | call | ||
152 | <B>require</B>('<I>name</I>') | ||
153 | before executing | ||
154 | <I>script</I>. | ||
155 | Typically used to load libraries. | ||
156 | <P> | ||
157 | <B>-v</B> | ||
158 | show version information. | ||
159 | <H2>SEE ALSO</H2> | ||
160 | <B>luac</B>(1) | ||
161 | <BR> | ||
162 | <A HREF="http://www.lua.org/">http://www.lua.org/</A> | ||
163 | <H2>DIAGNOSTICS</H2> | ||
164 | Error messages should be self explanatory. | ||
165 | <H2>AUTHORS</H2> | ||
166 | R. Ierusalimschy, | ||
167 | L. H. de Figueiredo, | ||
168 | and | ||
169 | W. Celes | ||
170 | <!-- EOF --> | ||
171 | </BODY> | ||
172 | </HTML> | ||
diff --git a/libraries/LuaJIT-1.1.7/doc/luac.1 b/libraries/LuaJIT-1.1.7/doc/luac.1 new file mode 100644 index 0000000..d814678 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/doc/luac.1 | |||
@@ -0,0 +1,136 @@ | |||
1 | .\" $Id: luac.man,v 1.28 2006/01/06 16:03:34 lhf Exp $ | ||
2 | .TH LUAC 1 "$Date: 2006/01/06 16:03:34 $" | ||
3 | .SH NAME | ||
4 | luac \- Lua compiler | ||
5 | .SH SYNOPSIS | ||
6 | .B luac | ||
7 | [ | ||
8 | .I options | ||
9 | ] [ | ||
10 | .I filenames | ||
11 | ] | ||
12 | .SH DESCRIPTION | ||
13 | .B luac | ||
14 | is the Lua compiler. | ||
15 | It translates programs written in the Lua programming language | ||
16 | into binary files that can be later loaded and executed. | ||
17 | .LP | ||
18 | The main advantages of precompiling chunks are: | ||
19 | faster loading, | ||
20 | protecting source code from accidental user changes, | ||
21 | and | ||
22 | off-line syntax checking. | ||
23 | .LP | ||
24 | Pre-compiling does not imply faster execution | ||
25 | because in Lua chunks are always compiled into bytecodes before being executed. | ||
26 | .B luac | ||
27 | simply allows those bytecodes to be saved in a file for later execution. | ||
28 | .LP | ||
29 | Pre-compiled chunks are not necessarily smaller than the corresponding source. | ||
30 | The main goal in pre-compiling is faster loading. | ||
31 | .LP | ||
32 | The binary files created by | ||
33 | .B luac | ||
34 | are portable only among architectures with the same word size and byte order. | ||
35 | .LP | ||
36 | .B luac | ||
37 | produces a single output file containing the bytecodes | ||
38 | for all source files given. | ||
39 | By default, | ||
40 | the output file is named | ||
41 | .BR luac.out , | ||
42 | but you can change this with the | ||
43 | .B \-o | ||
44 | option. | ||
45 | .LP | ||
46 | In the command line, | ||
47 | you can mix | ||
48 | text files containing Lua source and | ||
49 | binary files containing precompiled chunks. | ||
50 | This is useful to combine several precompiled chunks, | ||
51 | even from different (but compatible) platforms, | ||
52 | into a single precompiled chunk. | ||
53 | .LP | ||
54 | You can use | ||
55 | .B "'\-'" | ||
56 | to indicate the standard input as a source file | ||
57 | and | ||
58 | .B "'\--'" | ||
59 | to signal the end of options | ||
60 | (that is, | ||
61 | all remaining arguments will be treated as files even if they start with | ||
62 | .BR "'\-'" ). | ||
63 | .LP | ||
64 | The internal format of the binary files produced by | ||
65 | .B luac | ||
66 | is likely to change when a new version of Lua is released. | ||
67 | So, | ||
68 | save the source files of all Lua programs that you precompile. | ||
69 | .LP | ||
70 | .SH OPTIONS | ||
71 | Options must be separate. | ||
72 | .TP | ||
73 | .B \-l | ||
74 | produce a listing of the compiled bytecode for Lua's virtual machine. | ||
75 | Listing bytecodes is useful to learn about Lua's virtual machine. | ||
76 | If no files are given, then | ||
77 | .B luac | ||
78 | loads | ||
79 | .B luac.out | ||
80 | and lists its contents. | ||
81 | .TP | ||
82 | .BI \-o " file" | ||
83 | output to | ||
84 | .IR file , | ||
85 | instead of the default | ||
86 | .BR luac.out . | ||
87 | (You can use | ||
88 | .B "'\-'" | ||
89 | for standard output, | ||
90 | but not on platforms that open standard output in text mode.) | ||
91 | The output file may be a source file because | ||
92 | all files are loaded before the output file is written. | ||
93 | Be careful not to overwrite precious files. | ||
94 | .TP | ||
95 | .B \-p | ||
96 | load files but do not generate any output file. | ||
97 | Used mainly for syntax checking and for testing precompiled chunks: | ||
98 | corrupted files will probably generate errors when loaded. | ||
99 | Lua always performs a thorough integrity test on precompiled chunks. | ||
100 | Bytecode that passes this test is completely safe, | ||
101 | in the sense that it will not break the interpreter. | ||
102 | However, | ||
103 | there is no guarantee that such code does anything sensible. | ||
104 | (None can be given, because the halting problem is unsolvable.) | ||
105 | If no files are given, then | ||
106 | .B luac | ||
107 | loads | ||
108 | .B luac.out | ||
109 | and tests its contents. | ||
110 | No messages are displayed if the file passes the integrity test. | ||
111 | .TP | ||
112 | .B \-s | ||
113 | strip debug information before writing the output file. | ||
114 | This saves some space in very large chunks, | ||
115 | but if errors occur when running a stripped chunk, | ||
116 | then the error messages may not contain the full information they usually do. | ||
117 | For instance, | ||
118 | line numbers and names of local variables are lost. | ||
119 | .TP | ||
120 | .B \-v | ||
121 | show version information. | ||
122 | .SH FILES | ||
123 | .TP 15 | ||
124 | .B luac.out | ||
125 | default output file | ||
126 | .SH "SEE ALSO" | ||
127 | .BR lua (1) | ||
128 | .br | ||
129 | http://www.lua.org/ | ||
130 | .SH DIAGNOSTICS | ||
131 | Error messages should be self explanatory. | ||
132 | .SH AUTHORS | ||
133 | L. H. de Figueiredo, | ||
134 | R. Ierusalimschy and | ||
135 | W. Celes | ||
136 | .\" EOF | ||
diff --git a/libraries/LuaJIT-1.1.7/doc/luac.html b/libraries/LuaJIT-1.1.7/doc/luac.html new file mode 100644 index 0000000..179ffe8 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/doc/luac.html | |||
@@ -0,0 +1,145 @@ | |||
1 | <!-- $Id: luac.man,v 1.28 2006/01/06 16:03:34 lhf Exp $ --> | ||
2 | <HTML> | ||
3 | <HEAD> | ||
4 | <TITLE>LUAC man page</TITLE> | ||
5 | <LINK REL="stylesheet" TYPE="text/css" HREF="lua.css"> | ||
6 | </HEAD> | ||
7 | |||
8 | <BODY BGCOLOR="#FFFFFF"> | ||
9 | |||
10 | <H2>NAME</H2> | ||
11 | luac - Lua compiler | ||
12 | <H2>SYNOPSIS</H2> | ||
13 | <B>luac</B> | ||
14 | [ | ||
15 | <I>options</I> | ||
16 | ] [ | ||
17 | <I>filenames</I> | ||
18 | ] | ||
19 | <H2>DESCRIPTION</H2> | ||
20 | <B>luac</B> | ||
21 | is the Lua compiler. | ||
22 | It translates programs written in the Lua programming language | ||
23 | into binary files that can be later loaded and executed. | ||
24 | <P> | ||
25 | The main advantages of precompiling chunks are: | ||
26 | faster loading, | ||
27 | protecting source code from accidental user changes, | ||
28 | and | ||
29 | off-line syntax checking. | ||
30 | <P> | ||
31 | Precompiling does not imply faster execution | ||
32 | because in Lua chunks are always compiled into bytecodes before being executed. | ||
33 | <B>luac</B> | ||
34 | simply allows those bytecodes to be saved in a file for later execution. | ||
35 | <P> | ||
36 | Precompiled chunks are not necessarily smaller than the corresponding source. | ||
37 | The main goal in precompiling is faster loading. | ||
38 | <P> | ||
39 | The binary files created by | ||
40 | <B>luac</B> | ||
41 | are portable only among architectures with the same word size and byte order. | ||
42 | <P> | ||
43 | <B>luac</B> | ||
44 | produces a single output file containing the bytecodes | ||
45 | for all source files given. | ||
46 | By default, | ||
47 | the output file is named | ||
48 | <B>luac.out</B>, | ||
49 | but you can change this with the | ||
50 | <B>-o</B> | ||
51 | option. | ||
52 | <P> | ||
53 | In the command line, | ||
54 | you can mix | ||
55 | text files containing Lua source and | ||
56 | binary files containing precompiled chunks. | ||
57 | This is useful because several precompiled chunks, | ||
58 | even from different (but compatible) platforms, | ||
59 | can be combined into a single precompiled chunk. | ||
60 | <P> | ||
61 | You can use | ||
62 | <B>'-'</B> | ||
63 | to indicate the standard input as a source file | ||
64 | and | ||
65 | <B>'--'</B> | ||
66 | to signal the end of options | ||
67 | (that is, | ||
68 | all remaining arguments will be treated as files even if they start with | ||
69 | <B>'-'</B>). | ||
70 | <P> | ||
71 | The internal format of the binary files produced by | ||
72 | <B>luac</B> | ||
73 | is likely to change when a new version of Lua is released. | ||
74 | So, | ||
75 | save the source files of all Lua programs that you precompile. | ||
76 | <P> | ||
77 | <H2>OPTIONS</H2> | ||
78 | Options must be separate. | ||
79 | <P> | ||
80 | <B>-l</B> | ||
81 | produce a listing of the compiled bytecode for Lua's virtual machine. | ||
82 | Listing bytecodes is useful to learn about Lua's virtual machine. | ||
83 | If no files are given, then | ||
84 | <B>luac</B> | ||
85 | loads | ||
86 | <B>luac.out</B> | ||
87 | and lists its contents. | ||
88 | <P> | ||
89 | <B>-o </B><I>file</I> | ||
90 | output to | ||
91 | <I>file</I>, | ||
92 | instead of the default | ||
93 | <B>luac.out</B>. | ||
94 | (You can use | ||
95 | <B>'-'</B> | ||
96 | for standard output, | ||
97 | but not on platforms that open standard output in text mode.) | ||
98 | The output file may be a source file because | ||
99 | all files are loaded before the output file is written. | ||
100 | Be careful not to overwrite precious files. | ||
101 | <P> | ||
102 | <B>-p</B> | ||
103 | load files but do not generate any output file. | ||
104 | Used mainly for syntax checking and for testing precompiled chunks: | ||
105 | corrupted files will probably generate errors when loaded. | ||
106 | Lua always performs a thorough integrity test on precompiled chunks. | ||
107 | Bytecode that passes this test is completely safe, | ||
108 | in the sense that it will not break the interpreter. | ||
109 | However, | ||
110 | there is no guarantee that such code does anything sensible. | ||
111 | (None can be given, because the halting problem is unsolvable.) | ||
112 | If no files are given, then | ||
113 | <B>luac</B> | ||
114 | loads | ||
115 | <B>luac.out</B> | ||
116 | and tests its contents. | ||
117 | No messages are displayed if the file passes the integrity test. | ||
118 | <P> | ||
119 | <B>-s</B> | ||
120 | strip debug information before writing the output file. | ||
121 | This saves some space in very large chunks, | ||
122 | but if errors occur when running a stripped chunk, | ||
123 | then the error messages may not contain the full information they usually do. | ||
124 | For instance, | ||
125 | line numbers and names of local variables are lost. | ||
126 | <P> | ||
127 | <B>-v</B> | ||
128 | show version information. | ||
129 | <H2>FILES</H2> | ||
130 | <P> | ||
131 | <B>luac.out</B> | ||
132 | default output file | ||
133 | <H2>SEE ALSO</H2> | ||
134 | <B>lua</B>(1) | ||
135 | <BR> | ||
136 | <A HREF="http://www.lua.org/">http://www.lua.org/</A> | ||
137 | <H2>DIAGNOSTICS</H2> | ||
138 | Error messages should be self explanatory. | ||
139 | <H2>AUTHORS</H2> | ||
140 | L. H. de Figueiredo, | ||
141 | R. Ierusalimschy and | ||
142 | W. Celes | ||
143 | <!-- EOF --> | ||
144 | </BODY> | ||
145 | </HTML> | ||
diff --git a/libraries/LuaJIT-1.1.7/doc/manual.css b/libraries/LuaJIT-1.1.7/doc/manual.css new file mode 100644 index 0000000..eed5afd --- /dev/null +++ b/libraries/LuaJIT-1.1.7/doc/manual.css | |||
@@ -0,0 +1,13 @@ | |||
1 | h3 code { | ||
2 | font-family: inherit ; | ||
3 | } | ||
4 | |||
5 | pre { | ||
6 | font-size: 105% ; | ||
7 | } | ||
8 | |||
9 | span.apii { | ||
10 | float: right ; | ||
11 | font-family: inherit ; | ||
12 | } | ||
13 | |||
diff --git a/libraries/LuaJIT-1.1.7/doc/manual.html b/libraries/LuaJIT-1.1.7/doc/manual.html new file mode 100644 index 0000000..f46f17c --- /dev/null +++ b/libraries/LuaJIT-1.1.7/doc/manual.html | |||
@@ -0,0 +1,8801 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||
2 | <html> | ||
3 | |||
4 | <head> | ||
5 | <title>Lua 5.1 Reference Manual</title> | ||
6 | <link rel="stylesheet" type="text/css" href="lua.css"> | ||
7 | <link rel="stylesheet" type="text/css" href="manual.css"> | ||
8 | <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1"> | ||
9 | </head> | ||
10 | |||
11 | <body> | ||
12 | |||
13 | <hr> | ||
14 | <h1> | ||
15 | <a href="http://www.lua.org/"><img src="logo.gif" alt="" border="0"></a> | ||
16 | Lua 5.1 Reference Manual | ||
17 | </h1> | ||
18 | |||
19 | by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes | ||
20 | <p> | ||
21 | <small> | ||
22 | Copyright © 2006-2008 Lua.org, PUC-Rio. | ||
23 | Freely available under the terms of the | ||
24 | <a href="http://www.lua.org/license.html#5">Lua license</a>. | ||
25 | </small> | ||
26 | <hr> | ||
27 | <p> | ||
28 | |||
29 | <a href="contents.html#contents">contents</A> | ||
30 | · | ||
31 | <a href="contents.html#index">index</A> | ||
32 | |||
33 | <!-- ====================================================================== --> | ||
34 | <p> | ||
35 | |||
36 | <!-- $Id: manual.of,v 1.48 2008/08/18 15:24:20 roberto Exp $ --> | ||
37 | |||
38 | |||
39 | |||
40 | |||
41 | <h1>1 - <a name="1">Introduction</a></h1> | ||
42 | |||
43 | <p> | ||
44 | Lua is an extension programming language designed to support | ||
45 | general procedural programming with data description | ||
46 | facilities. | ||
47 | It also offers good support for object-oriented programming, | ||
48 | functional programming, and data-driven programming. | ||
49 | Lua is intended to be used as a powerful, light-weight | ||
50 | scripting language for any program that needs one. | ||
51 | Lua is implemented as a library, written in <em>clean</em> C | ||
52 | (that is, in the common subset of ANSI C and C++). | ||
53 | |||
54 | |||
55 | <p> | ||
56 | Being an extension language, Lua has no notion of a "main" program: | ||
57 | it only works <em>embedded</em> in a host client, | ||
58 | called the <em>embedding program</em> or simply the <em>host</em>. | ||
59 | This host program can invoke functions to execute a piece of Lua code, | ||
60 | can write and read Lua variables, | ||
61 | and can register C functions to be called by Lua code. | ||
62 | Through the use of C functions, Lua can be augmented to cope with | ||
63 | a wide range of different domains, | ||
64 | thus creating customized programming languages sharing a syntactical framework. | ||
65 | The Lua distribution includes a sample host program called <code>lua</code>, | ||
66 | which uses the Lua library to offer a complete, stand-alone Lua interpreter. | ||
67 | |||
68 | |||
69 | <p> | ||
70 | Lua is free software, | ||
71 | and is provided as usual with no guarantees, | ||
72 | as stated in its license. | ||
73 | The implementation described in this manual is available | ||
74 | at Lua's official web site, <code>www.lua.org</code>. | ||
75 | |||
76 | |||
77 | <p> | ||
78 | Like any other reference manual, | ||
79 | this document is dry in places. | ||
80 | For a discussion of the decisions behind the design of Lua, | ||
81 | see the technical papers available at Lua's web site. | ||
82 | For a detailed introduction to programming in Lua, | ||
83 | see Roberto's book, <em>Programming in Lua (Second Edition)</em>. | ||
84 | |||
85 | |||
86 | |||
87 | <h1>2 - <a name="2">The Language</a></h1> | ||
88 | |||
89 | <p> | ||
90 | This section describes the lexis, the syntax, and the semantics of Lua. | ||
91 | In other words, | ||
92 | this section describes | ||
93 | which tokens are valid, | ||
94 | how they can be combined, | ||
95 | and what their combinations mean. | ||
96 | |||
97 | |||
98 | <p> | ||
99 | The language constructs will be explained using the usual extended BNF notation, | ||
100 | in which | ||
101 | {<em>a</em>} means 0 or more <em>a</em>'s, and | ||
102 | [<em>a</em>] means an optional <em>a</em>. | ||
103 | Non-terminals are shown like non-terminal, | ||
104 | keywords are shown like <b>kword</b>, | ||
105 | and other terminal symbols are shown like `<b>=</b>´. | ||
106 | The complete syntax of Lua can be found in <a href="#8">§8</a> | ||
107 | at the end of this manual. | ||
108 | |||
109 | |||
110 | |||
111 | <h2>2.1 - <a name="2.1">Lexical Conventions</a></h2> | ||
112 | |||
113 | <p> | ||
114 | <em>Names</em> | ||
115 | (also called <em>identifiers</em>) | ||
116 | in Lua can be any string of letters, | ||
117 | digits, and underscores, | ||
118 | not beginning with a digit. | ||
119 | This coincides with the definition of names in most languages. | ||
120 | (The definition of letter depends on the current locale: | ||
121 | any character considered alphabetic by the current locale | ||
122 | can be used in an identifier.) | ||
123 | Identifiers are used to name variables and table fields. | ||
124 | |||
125 | |||
126 | <p> | ||
127 | The following <em>keywords</em> are reserved | ||
128 | and cannot be used as names: | ||
129 | |||
130 | |||
131 | <pre> | ||
132 | and break do else elseif | ||
133 | end false for function if | ||
134 | in local nil not or | ||
135 | repeat return then true until while | ||
136 | </pre> | ||
137 | |||
138 | <p> | ||
139 | Lua is a case-sensitive language: | ||
140 | <code>and</code> is a reserved word, but <code>And</code> and <code>AND</code> | ||
141 | are two different, valid names. | ||
142 | As a convention, names starting with an underscore followed by | ||
143 | uppercase letters (such as <a href="#pdf-_VERSION"><code>_VERSION</code></a>) | ||
144 | are reserved for internal global variables used by Lua. | ||
145 | |||
146 | |||
147 | <p> | ||
148 | The following strings denote other tokens: | ||
149 | |||
150 | <pre> | ||
151 | + - * / % ^ # | ||
152 | == ~= <= >= < > = | ||
153 | ( ) { } [ ] | ||
154 | ; : , . .. ... | ||
155 | </pre> | ||
156 | |||
157 | <p> | ||
158 | <em>Literal strings</em> | ||
159 | can be delimited by matching single or double quotes, | ||
160 | and can contain the following C-like escape sequences: | ||
161 | '<code>\a</code>' (bell), | ||
162 | '<code>\b</code>' (backspace), | ||
163 | '<code>\f</code>' (form feed), | ||
164 | '<code>\n</code>' (newline), | ||
165 | '<code>\r</code>' (carriage return), | ||
166 | '<code>\t</code>' (horizontal tab), | ||
167 | '<code>\v</code>' (vertical tab), | ||
168 | '<code>\\</code>' (backslash), | ||
169 | '<code>\"</code>' (quotation mark [double quote]), | ||
170 | and '<code>\'</code>' (apostrophe [single quote]). | ||
171 | Moreover, a backslash followed by a real newline | ||
172 | results in a newline in the string. | ||
173 | A character in a string can also be specified by its numerical value | ||
174 | using the escape sequence <code>\<em>ddd</em></code>, | ||
175 | where <em>ddd</em> is a sequence of up to three decimal digits. | ||
176 | (Note that if a numerical escape is to be followed by a digit, | ||
177 | it must be expressed using exactly three digits.) | ||
178 | Strings in Lua can contain any 8-bit value, including embedded zeros, | ||
179 | which can be specified as '<code>\0</code>'. | ||
180 | |||
181 | |||
182 | <p> | ||
183 | Literal strings can also be defined using a long format | ||
184 | enclosed by <em>long brackets</em>. | ||
185 | We define an <em>opening long bracket of level <em>n</em></em> as an opening | ||
186 | square bracket followed by <em>n</em> equal signs followed by another | ||
187 | opening square bracket. | ||
188 | So, an opening long bracket of level 0 is written as <code>[[</code>, | ||
189 | an opening long bracket of level 1 is written as <code>[=[</code>, | ||
190 | and so on. | ||
191 | A <em>closing long bracket</em> is defined similarly; | ||
192 | for instance, a closing long bracket of level 4 is written as <code>]====]</code>. | ||
193 | A long string starts with an opening long bracket of any level and | ||
194 | ends at the first closing long bracket of the same level. | ||
195 | Literals in this bracketed form can run for several lines, | ||
196 | do not interpret any escape sequences, | ||
197 | and ignore long brackets of any other level. | ||
198 | They can contain anything except a closing bracket of the proper level. | ||
199 | |||
200 | |||
201 | <p> | ||
202 | For convenience, | ||
203 | when the opening long bracket is immediately followed by a newline, | ||
204 | the newline is not included in the string. | ||
205 | As an example, in a system using ASCII | ||
206 | (in which '<code>a</code>' is coded as 97, | ||
207 | newline is coded as 10, and '<code>1</code>' is coded as 49), | ||
208 | the five literal strings below denote the same string: | ||
209 | |||
210 | <pre> | ||
211 | a = 'alo\n123"' | ||
212 | a = "alo\n123\"" | ||
213 | a = '\97lo\10\04923"' | ||
214 | a = [[alo | ||
215 | 123"]] | ||
216 | a = [==[ | ||
217 | alo | ||
218 | 123"]==] | ||
219 | </pre> | ||
220 | |||
221 | <p> | ||
222 | A <em>numerical constant</em> can be written with an optional decimal part | ||
223 | and an optional decimal exponent. | ||
224 | Lua also accepts integer hexadecimal constants, | ||
225 | by prefixing them with <code>0x</code>. | ||
226 | Examples of valid numerical constants are | ||
227 | |||
228 | <pre> | ||
229 | 3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56 | ||
230 | </pre> | ||
231 | |||
232 | <p> | ||
233 | A <em>comment</em> starts with a double hyphen (<code>--</code>) | ||
234 | anywhere outside a string. | ||
235 | If the text immediately after <code>--</code> is not an opening long bracket, | ||
236 | the comment is a <em>short comment</em>, | ||
237 | which runs until the end of the line. | ||
238 | Otherwise, it is a <em>long comment</em>, | ||
239 | which runs until the corresponding closing long bracket. | ||
240 | Long comments are frequently used to disable code temporarily. | ||
241 | |||
242 | |||
243 | |||
244 | |||
245 | |||
246 | <h2>2.2 - <a name="2.2">Values and Types</a></h2> | ||
247 | |||
248 | <p> | ||
249 | Lua is a <em>dynamically typed language</em>. | ||
250 | This means that | ||
251 | variables do not have types; only values do. | ||
252 | There are no type definitions in the language. | ||
253 | All values carry their own type. | ||
254 | |||
255 | |||
256 | <p> | ||
257 | All values in Lua are <em>first-class values</em>. | ||
258 | This means that all values can be stored in variables, | ||
259 | passed as arguments to other functions, and returned as results. | ||
260 | |||
261 | |||
262 | <p> | ||
263 | There are eight basic types in Lua: | ||
264 | <em>nil</em>, <em>boolean</em>, <em>number</em>, | ||
265 | <em>string</em>, <em>function</em>, <em>userdata</em>, | ||
266 | <em>thread</em>, and <em>table</em>. | ||
267 | <em>Nil</em> is the type of the value <b>nil</b>, | ||
268 | whose main property is to be different from any other value; | ||
269 | it usually represents the absence of a useful value. | ||
270 | <em>Boolean</em> is the type of the values <b>false</b> and <b>true</b>. | ||
271 | Both <b>nil</b> and <b>false</b> make a condition false; | ||
272 | any other value makes it true. | ||
273 | <em>Number</em> represents real (double-precision floating-point) numbers. | ||
274 | (It is easy to build Lua interpreters that use other | ||
275 | internal representations for numbers, | ||
276 | such as single-precision float or long integers; | ||
277 | see file <code>luaconf.h</code>.) | ||
278 | <em>String</em> represents arrays of characters. | ||
279 | |||
280 | Lua is 8-bit clean: | ||
281 | strings can contain any 8-bit character, | ||
282 | including embedded zeros ('<code>\0</code>') (see <a href="#2.1">§2.1</a>). | ||
283 | |||
284 | |||
285 | <p> | ||
286 | Lua can call (and manipulate) functions written in Lua and | ||
287 | functions written in C | ||
288 | (see <a href="#2.5.8">§2.5.8</a>). | ||
289 | |||
290 | |||
291 | <p> | ||
292 | The type <em>userdata</em> is provided to allow arbitrary C data to | ||
293 | be stored in Lua variables. | ||
294 | This type corresponds to a block of raw memory | ||
295 | and has no pre-defined operations in Lua, | ||
296 | except assignment and identity test. | ||
297 | However, by using <em>metatables</em>, | ||
298 | the programmer can define operations for userdata values | ||
299 | (see <a href="#2.8">§2.8</a>). | ||
300 | Userdata values cannot be created or modified in Lua, | ||
301 | only through the C API. | ||
302 | This guarantees the integrity of data owned by the host program. | ||
303 | |||
304 | |||
305 | <p> | ||
306 | The type <em>thread</em> represents independent threads of execution | ||
307 | and it is used to implement coroutines (see <a href="#2.11">§2.11</a>). | ||
308 | Do not confuse Lua threads with operating-system threads. | ||
309 | Lua supports coroutines on all systems, | ||
310 | even those that do not support threads. | ||
311 | |||
312 | |||
313 | <p> | ||
314 | The type <em>table</em> implements associative arrays, | ||
315 | that is, arrays that can be indexed not only with numbers, | ||
316 | but with any value (except <b>nil</b>). | ||
317 | Tables can be <em>heterogeneous</em>; | ||
318 | that is, they can contain values of all types (except <b>nil</b>). | ||
319 | Tables are the sole data structuring mechanism in Lua; | ||
320 | they can be used to represent ordinary arrays, | ||
321 | symbol tables, sets, records, graphs, trees, etc. | ||
322 | To represent records, Lua uses the field name as an index. | ||
323 | The language supports this representation by | ||
324 | providing <code>a.name</code> as syntactic sugar for <code>a["name"]</code>. | ||
325 | There are several convenient ways to create tables in Lua | ||
326 | (see <a href="#2.5.7">§2.5.7</a>). | ||
327 | |||
328 | |||
329 | <p> | ||
330 | Like indices, | ||
331 | the value of a table field can be of any type (except <b>nil</b>). | ||
332 | In particular, | ||
333 | because functions are first-class values, | ||
334 | table fields can contain functions. | ||
335 | Thus tables can also carry <em>methods</em> (see <a href="#2.5.9">§2.5.9</a>). | ||
336 | |||
337 | |||
338 | <p> | ||
339 | Tables, functions, threads, and (full) userdata values are <em>objects</em>: | ||
340 | variables do not actually <em>contain</em> these values, | ||
341 | only <em>references</em> to them. | ||
342 | Assignment, parameter passing, and function returns | ||
343 | always manipulate references to such values; | ||
344 | these operations do not imply any kind of copy. | ||
345 | |||
346 | |||
347 | <p> | ||
348 | The library function <a href="#pdf-type"><code>type</code></a> returns a string describing the type | ||
349 | of a given value. | ||
350 | |||
351 | |||
352 | |||
353 | <h3>2.2.1 - <a name="2.2.1">Coercion</a></h3> | ||
354 | |||
355 | <p> | ||
356 | Lua provides automatic conversion between | ||
357 | string and number values at run time. | ||
358 | Any arithmetic operation applied to a string tries to convert | ||
359 | this string to a number, following the usual conversion rules. | ||
360 | Conversely, whenever a number is used where a string is expected, | ||
361 | the number is converted to a string, in a reasonable format. | ||
362 | For complete control over how numbers are converted to strings, | ||
363 | use the <code>format</code> function from the string library | ||
364 | (see <a href="#pdf-string.format"><code>string.format</code></a>). | ||
365 | |||
366 | |||
367 | |||
368 | |||
369 | |||
370 | |||
371 | |||
372 | <h2>2.3 - <a name="2.3">Variables</a></h2> | ||
373 | |||
374 | <p> | ||
375 | Variables are places that store values. | ||
376 | |||
377 | There are three kinds of variables in Lua: | ||
378 | global variables, local variables, and table fields. | ||
379 | |||
380 | |||
381 | <p> | ||
382 | A single name can denote a global variable or a local variable | ||
383 | (or a function's formal parameter, | ||
384 | which is a particular kind of local variable): | ||
385 | |||
386 | <pre> | ||
387 | var ::= Name | ||
388 | </pre><p> | ||
389 | Name denotes identifiers, as defined in <a href="#2.1">§2.1</a>. | ||
390 | |||
391 | |||
392 | <p> | ||
393 | Any variable is assumed to be global unless explicitly declared | ||
394 | as a local (see <a href="#2.4.7">§2.4.7</a>). | ||
395 | Local variables are <em>lexically scoped</em>: | ||
396 | local variables can be freely accessed by functions | ||
397 | defined inside their scope (see <a href="#2.6">§2.6</a>). | ||
398 | |||
399 | |||
400 | <p> | ||
401 | Before the first assignment to a variable, its value is <b>nil</b>. | ||
402 | |||
403 | |||
404 | <p> | ||
405 | Square brackets are used to index a table: | ||
406 | |||
407 | <pre> | ||
408 | var ::= prefixexp `<b>[</b>´ exp `<b>]</b>´ | ||
409 | </pre><p> | ||
410 | The meaning of accesses to global variables | ||
411 | and table fields can be changed via metatables. | ||
412 | An access to an indexed variable <code>t[i]</code> is equivalent to | ||
413 | a call <code>gettable_event(t,i)</code>. | ||
414 | (See <a href="#2.8">§2.8</a> for a complete description of the | ||
415 | <code>gettable_event</code> function. | ||
416 | This function is not defined or callable in Lua. | ||
417 | We use it here only for explanatory purposes.) | ||
418 | |||
419 | |||
420 | <p> | ||
421 | The syntax <code>var.Name</code> is just syntactic sugar for | ||
422 | <code>var["Name"]</code>: | ||
423 | |||
424 | <pre> | ||
425 | var ::= prefixexp `<b>.</b>´ Name | ||
426 | </pre> | ||
427 | |||
428 | <p> | ||
429 | All global variables live as fields in ordinary Lua tables, | ||
430 | called <em>environment tables</em> or simply | ||
431 | <em>environments</em> (see <a href="#2.9">§2.9</a>). | ||
432 | Each function has its own reference to an environment, | ||
433 | so that all global variables in this function | ||
434 | will refer to this environment table. | ||
435 | When a function is created, | ||
436 | it inherits the environment from the function that created it. | ||
437 | To get the environment table of a Lua function, | ||
438 | you call <a href="#pdf-getfenv"><code>getfenv</code></a>. | ||
439 | To replace it, | ||
440 | you call <a href="#pdf-setfenv"><code>setfenv</code></a>. | ||
441 | (You can only manipulate the environment of C functions | ||
442 | through the debug library; (see <a href="#5.9">§5.9</a>).) | ||
443 | |||
444 | |||
445 | <p> | ||
446 | An access to a global variable <code>x</code> | ||
447 | is equivalent to <code>_env.x</code>, | ||
448 | which in turn is equivalent to | ||
449 | |||
450 | <pre> | ||
451 | gettable_event(_env, "x") | ||
452 | </pre><p> | ||
453 | where <code>_env</code> is the environment of the running function. | ||
454 | (See <a href="#2.8">§2.8</a> for a complete description of the | ||
455 | <code>gettable_event</code> function. | ||
456 | This function is not defined or callable in Lua. | ||
457 | Similarly, the <code>_env</code> variable is not defined in Lua. | ||
458 | We use them here only for explanatory purposes.) | ||
459 | |||
460 | |||
461 | |||
462 | |||
463 | |||
464 | <h2>2.4 - <a name="2.4">Statements</a></h2> | ||
465 | |||
466 | <p> | ||
467 | Lua supports an almost conventional set of statements, | ||
468 | similar to those in Pascal or C. | ||
469 | This set includes | ||
470 | assignments, control structures, function calls, | ||
471 | and variable declarations. | ||
472 | |||
473 | |||
474 | |||
475 | <h3>2.4.1 - <a name="2.4.1">Chunks</a></h3> | ||
476 | |||
477 | <p> | ||
478 | The unit of execution of Lua is called a <em>chunk</em>. | ||
479 | A chunk is simply a sequence of statements, | ||
480 | which are executed sequentially. | ||
481 | Each statement can be optionally followed by a semicolon: | ||
482 | |||
483 | <pre> | ||
484 | chunk ::= {stat [`<b>;</b>´]} | ||
485 | </pre><p> | ||
486 | There are no empty statements and thus '<code>;;</code>' is not legal. | ||
487 | |||
488 | |||
489 | <p> | ||
490 | Lua handles a chunk as the body of an anonymous function | ||
491 | with a variable number of arguments | ||
492 | (see <a href="#2.5.9">§2.5.9</a>). | ||
493 | As such, chunks can define local variables, | ||
494 | receive arguments, and return values. | ||
495 | |||
496 | |||
497 | <p> | ||
498 | A chunk can be stored in a file or in a string inside the host program. | ||
499 | To execute a chunk, | ||
500 | Lua first pre-compiles the chunk into instructions for a virtual machine, | ||
501 | and then it executes the compiled code | ||
502 | with an interpreter for the virtual machine. | ||
503 | |||
504 | |||
505 | <p> | ||
506 | Chunks can also be pre-compiled into binary form; | ||
507 | see program <code>luac</code> for details. | ||
508 | Programs in source and compiled forms are interchangeable; | ||
509 | Lua automatically detects the file type and acts accordingly. | ||
510 | |||
511 | |||
512 | |||
513 | |||
514 | |||
515 | |||
516 | <h3>2.4.2 - <a name="2.4.2">Blocks</a></h3><p> | ||
517 | A block is a list of statements; | ||
518 | syntactically, a block is the same as a chunk: | ||
519 | |||
520 | <pre> | ||
521 | block ::= chunk | ||
522 | </pre> | ||
523 | |||
524 | <p> | ||
525 | A block can be explicitly delimited to produce a single statement: | ||
526 | |||
527 | <pre> | ||
528 | stat ::= <b>do</b> block <b>end</b> | ||
529 | </pre><p> | ||
530 | Explicit blocks are useful | ||
531 | to control the scope of variable declarations. | ||
532 | Explicit blocks are also sometimes used to | ||
533 | add a <b>return</b> or <b>break</b> statement in the middle | ||
534 | of another block (see <a href="#2.4.4">§2.4.4</a>). | ||
535 | |||
536 | |||
537 | |||
538 | |||
539 | |||
540 | <h3>2.4.3 - <a name="2.4.3">Assignment</a></h3> | ||
541 | |||
542 | <p> | ||
543 | Lua allows multiple assignments. | ||
544 | Therefore, the syntax for assignment | ||
545 | defines a list of variables on the left side | ||
546 | and a list of expressions on the right side. | ||
547 | The elements in both lists are separated by commas: | ||
548 | |||
549 | <pre> | ||
550 | stat ::= varlist `<b>=</b>´ explist | ||
551 | varlist ::= var {`<b>,</b>´ var} | ||
552 | explist ::= exp {`<b>,</b>´ exp} | ||
553 | </pre><p> | ||
554 | Expressions are discussed in <a href="#2.5">§2.5</a>. | ||
555 | |||
556 | |||
557 | <p> | ||
558 | Before the assignment, | ||
559 | the list of values is <em>adjusted</em> to the length of | ||
560 | the list of variables. | ||
561 | If there are more values than needed, | ||
562 | the excess values are thrown away. | ||
563 | If there are fewer values than needed, | ||
564 | the list is extended with as many <b>nil</b>'s as needed. | ||
565 | If the list of expressions ends with a function call, | ||
566 | then all values returned by that call enter the list of values, | ||
567 | before the adjustment | ||
568 | (except when the call is enclosed in parentheses; see <a href="#2.5">§2.5</a>). | ||
569 | |||
570 | |||
571 | <p> | ||
572 | The assignment statement first evaluates all its expressions | ||
573 | and only then are the assignments performed. | ||
574 | Thus the code | ||
575 | |||
576 | <pre> | ||
577 | i = 3 | ||
578 | i, a[i] = i+1, 20 | ||
579 | </pre><p> | ||
580 | sets <code>a[3]</code> to 20, without affecting <code>a[4]</code> | ||
581 | because the <code>i</code> in <code>a[i]</code> is evaluated (to 3) | ||
582 | before it is assigned 4. | ||
583 | Similarly, the line | ||
584 | |||
585 | <pre> | ||
586 | x, y = y, x | ||
587 | </pre><p> | ||
588 | exchanges the values of <code>x</code> and <code>y</code>, | ||
589 | and | ||
590 | |||
591 | <pre> | ||
592 | x, y, z = y, z, x | ||
593 | </pre><p> | ||
594 | cyclically permutes the values of <code>x</code>, <code>y</code>, and <code>z</code>. | ||
595 | |||
596 | |||
597 | <p> | ||
598 | The meaning of assignments to global variables | ||
599 | and table fields can be changed via metatables. | ||
600 | An assignment to an indexed variable <code>t[i] = val</code> is equivalent to | ||
601 | <code>settable_event(t,i,val)</code>. | ||
602 | (See <a href="#2.8">§2.8</a> for a complete description of the | ||
603 | <code>settable_event</code> function. | ||
604 | This function is not defined or callable in Lua. | ||
605 | We use it here only for explanatory purposes.) | ||
606 | |||
607 | |||
608 | <p> | ||
609 | An assignment to a global variable <code>x = val</code> | ||
610 | is equivalent to the assignment | ||
611 | <code>_env.x = val</code>, | ||
612 | which in turn is equivalent to | ||
613 | |||
614 | <pre> | ||
615 | settable_event(_env, "x", val) | ||
616 | </pre><p> | ||
617 | where <code>_env</code> is the environment of the running function. | ||
618 | (The <code>_env</code> variable is not defined in Lua. | ||
619 | We use it here only for explanatory purposes.) | ||
620 | |||
621 | |||
622 | |||
623 | |||
624 | |||
625 | <h3>2.4.4 - <a name="2.4.4">Control Structures</a></h3><p> | ||
626 | The control structures | ||
627 | <b>if</b>, <b>while</b>, and <b>repeat</b> have the usual meaning and | ||
628 | familiar syntax: | ||
629 | |||
630 | |||
631 | |||
632 | |||
633 | <pre> | ||
634 | stat ::= <b>while</b> exp <b>do</b> block <b>end</b> | ||
635 | stat ::= <b>repeat</b> block <b>until</b> exp | ||
636 | stat ::= <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b> | ||
637 | </pre><p> | ||
638 | Lua also has a <b>for</b> statement, in two flavors (see <a href="#2.4.5">§2.4.5</a>). | ||
639 | |||
640 | |||
641 | <p> | ||
642 | The condition expression of a | ||
643 | control structure can return any value. | ||
644 | Both <b>false</b> and <b>nil</b> are considered false. | ||
645 | All values different from <b>nil</b> and <b>false</b> are considered true | ||
646 | (in particular, the number 0 and the empty string are also true). | ||
647 | |||
648 | |||
649 | <p> | ||
650 | In the <b>repeat</b>–<b>until</b> loop, | ||
651 | the inner block does not end at the <b>until</b> keyword, | ||
652 | but only after the condition. | ||
653 | So, the condition can refer to local variables | ||
654 | declared inside the loop block. | ||
655 | |||
656 | |||
657 | <p> | ||
658 | The <b>return</b> statement is used to return values | ||
659 | from a function or a chunk (which is just a function). | ||
660 | |||
661 | Functions and chunks can return more than one value, | ||
662 | and so the syntax for the <b>return</b> statement is | ||
663 | |||
664 | <pre> | ||
665 | stat ::= <b>return</b> [explist] | ||
666 | </pre> | ||
667 | |||
668 | <p> | ||
669 | The <b>break</b> statement is used to terminate the execution of a | ||
670 | <b>while</b>, <b>repeat</b>, or <b>for</b> loop, | ||
671 | skipping to the next statement after the loop: | ||
672 | |||
673 | |||
674 | <pre> | ||
675 | stat ::= <b>break</b> | ||
676 | </pre><p> | ||
677 | A <b>break</b> ends the innermost enclosing loop. | ||
678 | |||
679 | |||
680 | <p> | ||
681 | The <b>return</b> and <b>break</b> | ||
682 | statements can only be written as the <em>last</em> statement of a block. | ||
683 | If it is really necessary to <b>return</b> or <b>break</b> in the | ||
684 | middle of a block, | ||
685 | then an explicit inner block can be used, | ||
686 | as in the idioms | ||
687 | <code>do return end</code> and <code>do break end</code>, | ||
688 | because now <b>return</b> and <b>break</b> are the last statements in | ||
689 | their (inner) blocks. | ||
690 | |||
691 | |||
692 | |||
693 | |||
694 | |||
695 | <h3>2.4.5 - <a name="2.4.5">For Statement</a></h3> | ||
696 | |||
697 | <p> | ||
698 | |||
699 | The <b>for</b> statement has two forms: | ||
700 | one numeric and one generic. | ||
701 | |||
702 | |||
703 | <p> | ||
704 | The numeric <b>for</b> loop repeats a block of code while a | ||
705 | control variable runs through an arithmetic progression. | ||
706 | It has the following syntax: | ||
707 | |||
708 | <pre> | ||
709 | stat ::= <b>for</b> Name `<b>=</b>´ exp `<b>,</b>´ exp [`<b>,</b>´ exp] <b>do</b> block <b>end</b> | ||
710 | </pre><p> | ||
711 | The <em>block</em> is repeated for <em>name</em> starting at the value of | ||
712 | the first <em>exp</em>, until it passes the second <em>exp</em> by steps of the | ||
713 | third <em>exp</em>. | ||
714 | More precisely, a <b>for</b> statement like | ||
715 | |||
716 | <pre> | ||
717 | for v = <em>e1</em>, <em>e2</em>, <em>e3</em> do <em>block</em> end | ||
718 | </pre><p> | ||
719 | is equivalent to the code: | ||
720 | |||
721 | <pre> | ||
722 | do | ||
723 | local <em>var</em>, <em>limit</em>, <em>step</em> = tonumber(<em>e1</em>), tonumber(<em>e2</em>), tonumber(<em>e3</em>) | ||
724 | if not (<em>var</em> and <em>limit</em> and <em>step</em>) then error() end | ||
725 | while (<em>step</em> > 0 and <em>var</em> <= <em>limit</em>) or (<em>step</em> <= 0 and <em>var</em> >= <em>limit</em>) do | ||
726 | local v = <em>var</em> | ||
727 | <em>block</em> | ||
728 | <em>var</em> = <em>var</em> + <em>step</em> | ||
729 | end | ||
730 | end | ||
731 | </pre><p> | ||
732 | Note the following: | ||
733 | |||
734 | <ul> | ||
735 | |||
736 | <li> | ||
737 | All three control expressions are evaluated only once, | ||
738 | before the loop starts. | ||
739 | They must all result in numbers. | ||
740 | </li> | ||
741 | |||
742 | <li> | ||
743 | <code><em>var</em></code>, <code><em>limit</em></code>, and <code><em>step</em></code> are invisible variables. | ||
744 | The names shown here are for explanatory purposes only. | ||
745 | </li> | ||
746 | |||
747 | <li> | ||
748 | If the third expression (the step) is absent, | ||
749 | then a step of 1 is used. | ||
750 | </li> | ||
751 | |||
752 | <li> | ||
753 | You can use <b>break</b> to exit a <b>for</b> loop. | ||
754 | </li> | ||
755 | |||
756 | <li> | ||
757 | The loop variable <code>v</code> is local to the loop; | ||
758 | you cannot use its value after the <b>for</b> ends or is broken. | ||
759 | If you need this value, | ||
760 | assign it to another variable before breaking or exiting the loop. | ||
761 | </li> | ||
762 | |||
763 | </ul> | ||
764 | |||
765 | <p> | ||
766 | The generic <b>for</b> statement works over functions, | ||
767 | called <em>iterators</em>. | ||
768 | On each iteration, the iterator function is called to produce a new value, | ||
769 | stopping when this new value is <b>nil</b>. | ||
770 | The generic <b>for</b> loop has the following syntax: | ||
771 | |||
772 | <pre> | ||
773 | stat ::= <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b> | ||
774 | namelist ::= Name {`<b>,</b>´ Name} | ||
775 | </pre><p> | ||
776 | A <b>for</b> statement like | ||
777 | |||
778 | <pre> | ||
779 | for <em>var_1</em>, ···, <em>var_n</em> in <em>explist</em> do <em>block</em> end | ||
780 | </pre><p> | ||
781 | is equivalent to the code: | ||
782 | |||
783 | <pre> | ||
784 | do | ||
785 | local <em>f</em>, <em>s</em>, <em>var</em> = <em>explist</em> | ||
786 | while true do | ||
787 | local <em>var_1</em>, ···, <em>var_n</em> = <em>f</em>(<em>s</em>, <em>var</em>) | ||
788 | <em>var</em> = <em>var_1</em> | ||
789 | if <em>var</em> == nil then break end | ||
790 | <em>block</em> | ||
791 | end | ||
792 | end | ||
793 | </pre><p> | ||
794 | Note the following: | ||
795 | |||
796 | <ul> | ||
797 | |||
798 | <li> | ||
799 | <code><em>explist</em></code> is evaluated only once. | ||
800 | Its results are an <em>iterator</em> function, | ||
801 | a <em>state</em>, | ||
802 | and an initial value for the first <em>iterator variable</em>. | ||
803 | </li> | ||
804 | |||
805 | <li> | ||
806 | <code><em>f</em></code>, <code><em>s</em></code>, and <code><em>var</em></code> are invisible variables. | ||
807 | The names are here for explanatory purposes only. | ||
808 | </li> | ||
809 | |||
810 | <li> | ||
811 | You can use <b>break</b> to exit a <b>for</b> loop. | ||
812 | </li> | ||
813 | |||
814 | <li> | ||
815 | The loop variables <code><em>var_i</em></code> are local to the loop; | ||
816 | you cannot use their values after the <b>for</b> ends. | ||
817 | If you need these values, | ||
818 | then assign them to other variables before breaking or exiting the loop. | ||
819 | </li> | ||
820 | |||
821 | </ul> | ||
822 | |||
823 | |||
824 | |||
825 | |||
826 | <h3>2.4.6 - <a name="2.4.6">Function Calls as Statements</a></h3><p> | ||
827 | To allow possible side-effects, | ||
828 | function calls can be executed as statements: | ||
829 | |||
830 | <pre> | ||
831 | stat ::= functioncall | ||
832 | </pre><p> | ||
833 | In this case, all returned values are thrown away. | ||
834 | Function calls are explained in <a href="#2.5.8">§2.5.8</a>. | ||
835 | |||
836 | |||
837 | |||
838 | |||
839 | |||
840 | <h3>2.4.7 - <a name="2.4.7">Local Declarations</a></h3><p> | ||
841 | Local variables can be declared anywhere inside a block. | ||
842 | The declaration can include an initial assignment: | ||
843 | |||
844 | <pre> | ||
845 | stat ::= <b>local</b> namelist [`<b>=</b>´ explist] | ||
846 | </pre><p> | ||
847 | If present, an initial assignment has the same semantics | ||
848 | of a multiple assignment (see <a href="#2.4.3">§2.4.3</a>). | ||
849 | Otherwise, all variables are initialized with <b>nil</b>. | ||
850 | |||
851 | |||
852 | <p> | ||
853 | A chunk is also a block (see <a href="#2.4.1">§2.4.1</a>), | ||
854 | and so local variables can be declared in a chunk outside any explicit block. | ||
855 | The scope of such local variables extends until the end of the chunk. | ||
856 | |||
857 | |||
858 | <p> | ||
859 | The visibility rules for local variables are explained in <a href="#2.6">§2.6</a>. | ||
860 | |||
861 | |||
862 | |||
863 | |||
864 | |||
865 | |||
866 | |||
867 | <h2>2.5 - <a name="2.5">Expressions</a></h2> | ||
868 | |||
869 | <p> | ||
870 | The basic expressions in Lua are the following: | ||
871 | |||
872 | <pre> | ||
873 | exp ::= prefixexp | ||
874 | exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | ||
875 | exp ::= Number | ||
876 | exp ::= String | ||
877 | exp ::= function | ||
878 | exp ::= tableconstructor | ||
879 | exp ::= `<b>...</b>´ | ||
880 | exp ::= exp binop exp | ||
881 | exp ::= unop exp | ||
882 | prefixexp ::= var | functioncall | `<b>(</b>´ exp `<b>)</b>´ | ||
883 | </pre> | ||
884 | |||
885 | <p> | ||
886 | Numbers and literal strings are explained in <a href="#2.1">§2.1</a>; | ||
887 | variables are explained in <a href="#2.3">§2.3</a>; | ||
888 | function definitions are explained in <a href="#2.5.9">§2.5.9</a>; | ||
889 | function calls are explained in <a href="#2.5.8">§2.5.8</a>; | ||
890 | table constructors are explained in <a href="#2.5.7">§2.5.7</a>. | ||
891 | Vararg expressions, | ||
892 | denoted by three dots ('<code>...</code>'), can only be used when | ||
893 | directly inside a vararg function; | ||
894 | they are explained in <a href="#2.5.9">§2.5.9</a>. | ||
895 | |||
896 | |||
897 | <p> | ||
898 | Binary operators comprise arithmetic operators (see <a href="#2.5.1">§2.5.1</a>), | ||
899 | relational operators (see <a href="#2.5.2">§2.5.2</a>), logical operators (see <a href="#2.5.3">§2.5.3</a>), | ||
900 | and the concatenation operator (see <a href="#2.5.4">§2.5.4</a>). | ||
901 | Unary operators comprise the unary minus (see <a href="#2.5.1">§2.5.1</a>), | ||
902 | the unary <b>not</b> (see <a href="#2.5.3">§2.5.3</a>), | ||
903 | and the unary <em>length operator</em> (see <a href="#2.5.5">§2.5.5</a>). | ||
904 | |||
905 | |||
906 | <p> | ||
907 | Both function calls and vararg expressions can result in multiple values. | ||
908 | If an expression is used as a statement | ||
909 | (only possible for function calls (see <a href="#2.4.6">§2.4.6</a>)), | ||
910 | then its return list is adjusted to zero elements, | ||
911 | thus discarding all returned values. | ||
912 | If an expression is used as the last (or the only) element | ||
913 | of a list of expressions, | ||
914 | then no adjustment is made | ||
915 | (unless the call is enclosed in parentheses). | ||
916 | In all other contexts, | ||
917 | Lua adjusts the result list to one element, | ||
918 | discarding all values except the first one. | ||
919 | |||
920 | |||
921 | <p> | ||
922 | Here are some examples: | ||
923 | |||
924 | <pre> | ||
925 | f() -- adjusted to 0 results | ||
926 | g(f(), x) -- f() is adjusted to 1 result | ||
927 | g(x, f()) -- g gets x plus all results from f() | ||
928 | a,b,c = f(), x -- f() is adjusted to 1 result (c gets nil) | ||
929 | a,b = ... -- a gets the first vararg parameter, b gets | ||
930 | -- the second (both a and b can get nil if there | ||
931 | -- is no corresponding vararg parameter) | ||
932 | |||
933 | a,b,c = x, f() -- f() is adjusted to 2 results | ||
934 | a,b,c = f() -- f() is adjusted to 3 results | ||
935 | return f() -- returns all results from f() | ||
936 | return ... -- returns all received vararg parameters | ||
937 | return x,y,f() -- returns x, y, and all results from f() | ||
938 | {f()} -- creates a list with all results from f() | ||
939 | {...} -- creates a list with all vararg parameters | ||
940 | {f(), nil} -- f() is adjusted to 1 result | ||
941 | </pre> | ||
942 | |||
943 | <p> | ||
944 | Any expression enclosed in parentheses always results in only one value. | ||
945 | Thus, | ||
946 | <code>(f(x,y,z))</code> is always a single value, | ||
947 | even if <code>f</code> returns several values. | ||
948 | (The value of <code>(f(x,y,z))</code> is the first value returned by <code>f</code> | ||
949 | or <b>nil</b> if <code>f</code> does not return any values.) | ||
950 | |||
951 | |||
952 | |||
953 | <h3>2.5.1 - <a name="2.5.1">Arithmetic Operators</a></h3><p> | ||
954 | Lua supports the usual arithmetic operators: | ||
955 | the binary <code>+</code> (addition), | ||
956 | <code>-</code> (subtraction), <code>*</code> (multiplication), | ||
957 | <code>/</code> (division), <code>%</code> (modulo), and <code>^</code> (exponentiation); | ||
958 | and unary <code>-</code> (negation). | ||
959 | If the operands are numbers, or strings that can be converted to | ||
960 | numbers (see <a href="#2.2.1">§2.2.1</a>), | ||
961 | then all operations have the usual meaning. | ||
962 | Exponentiation works for any exponent. | ||
963 | For instance, <code>x^(-0.5)</code> computes the inverse of the square root of <code>x</code>. | ||
964 | Modulo is defined as | ||
965 | |||
966 | <pre> | ||
967 | a % b == a - math.floor(a/b)*b | ||
968 | </pre><p> | ||
969 | That is, it is the remainder of a division that rounds | ||
970 | the quotient towards minus infinity. | ||
971 | |||
972 | |||
973 | |||
974 | |||
975 | |||
976 | <h3>2.5.2 - <a name="2.5.2">Relational Operators</a></h3><p> | ||
977 | The relational operators in Lua are | ||
978 | |||
979 | <pre> | ||
980 | == ~= < > <= >= | ||
981 | </pre><p> | ||
982 | These operators always result in <b>false</b> or <b>true</b>. | ||
983 | |||
984 | |||
985 | <p> | ||
986 | Equality (<code>==</code>) first compares the type of its operands. | ||
987 | If the types are different, then the result is <b>false</b>. | ||
988 | Otherwise, the values of the operands are compared. | ||
989 | Numbers and strings are compared in the usual way. | ||
990 | Objects (tables, userdata, threads, and functions) | ||
991 | are compared by <em>reference</em>: | ||
992 | two objects are considered equal only if they are the <em>same</em> object. | ||
993 | Every time you create a new object | ||
994 | (a table, userdata, thread, or function), | ||
995 | this new object is different from any previously existing object. | ||
996 | |||
997 | |||
998 | <p> | ||
999 | You can change the way that Lua compares tables and userdata | ||
1000 | by using the "eq" metamethod (see <a href="#2.8">§2.8</a>). | ||
1001 | |||
1002 | |||
1003 | <p> | ||
1004 | The conversion rules of <a href="#2.2.1">§2.2.1</a> | ||
1005 | <em>do not</em> apply to equality comparisons. | ||
1006 | Thus, <code>"0"==0</code> evaluates to <b>false</b>, | ||
1007 | and <code>t[0]</code> and <code>t["0"]</code> denote different | ||
1008 | entries in a table. | ||
1009 | |||
1010 | |||
1011 | <p> | ||
1012 | The operator <code>~=</code> is exactly the negation of equality (<code>==</code>). | ||
1013 | |||
1014 | |||
1015 | <p> | ||
1016 | The order operators work as follows. | ||
1017 | If both arguments are numbers, then they are compared as such. | ||
1018 | Otherwise, if both arguments are strings, | ||
1019 | then their values are compared according to the current locale. | ||
1020 | Otherwise, Lua tries to call the "lt" or the "le" | ||
1021 | metamethod (see <a href="#2.8">§2.8</a>). | ||
1022 | A comparison <code>a > b</code> is translated to <code>b < a</code> | ||
1023 | and <code>a >= b</code> is translated to <code>b <= a</code>. | ||
1024 | |||
1025 | |||
1026 | |||
1027 | |||
1028 | |||
1029 | <h3>2.5.3 - <a name="2.5.3">Logical Operators</a></h3><p> | ||
1030 | The logical operators in Lua are | ||
1031 | <b>and</b>, <b>or</b>, and <b>not</b>. | ||
1032 | Like the control structures (see <a href="#2.4.4">§2.4.4</a>), | ||
1033 | all logical operators consider both <b>false</b> and <b>nil</b> as false | ||
1034 | and anything else as true. | ||
1035 | |||
1036 | |||
1037 | <p> | ||
1038 | The negation operator <b>not</b> always returns <b>false</b> or <b>true</b>. | ||
1039 | The conjunction operator <b>and</b> returns its first argument | ||
1040 | if this value is <b>false</b> or <b>nil</b>; | ||
1041 | otherwise, <b>and</b> returns its second argument. | ||
1042 | The disjunction operator <b>or</b> returns its first argument | ||
1043 | if this value is different from <b>nil</b> and <b>false</b>; | ||
1044 | otherwise, <b>or</b> returns its second argument. | ||
1045 | Both <b>and</b> and <b>or</b> use short-cut evaluation; | ||
1046 | that is, | ||
1047 | the second operand is evaluated only if necessary. | ||
1048 | Here are some examples: | ||
1049 | |||
1050 | <pre> | ||
1051 | 10 or 20 --> 10 | ||
1052 | 10 or error() --> 10 | ||
1053 | nil or "a" --> "a" | ||
1054 | nil and 10 --> nil | ||
1055 | false and error() --> false | ||
1056 | false and nil --> false | ||
1057 | false or nil --> nil | ||
1058 | 10 and 20 --> 20 | ||
1059 | </pre><p> | ||
1060 | (In this manual, | ||
1061 | <code>--></code> indicates the result of the preceding expression.) | ||
1062 | |||
1063 | |||
1064 | |||
1065 | |||
1066 | |||
1067 | <h3>2.5.4 - <a name="2.5.4">Concatenation</a></h3><p> | ||
1068 | The string concatenation operator in Lua is | ||
1069 | denoted by two dots ('<code>..</code>'). | ||
1070 | If both operands are strings or numbers, then they are converted to | ||
1071 | strings according to the rules mentioned in <a href="#2.2.1">§2.2.1</a>. | ||
1072 | Otherwise, the "concat" metamethod is called (see <a href="#2.8">§2.8</a>). | ||
1073 | |||
1074 | |||
1075 | |||
1076 | |||
1077 | |||
1078 | <h3>2.5.5 - <a name="2.5.5">The Length Operator</a></h3> | ||
1079 | |||
1080 | <p> | ||
1081 | The length operator is denoted by the unary operator <code>#</code>. | ||
1082 | The length of a string is its number of bytes | ||
1083 | (that is, the usual meaning of string length when each | ||
1084 | character is one byte). | ||
1085 | |||
1086 | |||
1087 | <p> | ||
1088 | The length of a table <code>t</code> is defined to be any | ||
1089 | integer index <code>n</code> | ||
1090 | such that <code>t[n]</code> is not <b>nil</b> and <code>t[n+1]</code> is <b>nil</b>; | ||
1091 | moreover, if <code>t[1]</code> is <b>nil</b>, <code>n</code> can be zero. | ||
1092 | For a regular array, with non-nil values from 1 to a given <code>n</code>, | ||
1093 | its length is exactly that <code>n</code>, | ||
1094 | the index of its last value. | ||
1095 | If the array has "holes" | ||
1096 | (that is, <b>nil</b> values between other non-nil values), | ||
1097 | then <code>#t</code> can be any of the indices that | ||
1098 | directly precedes a <b>nil</b> value | ||
1099 | (that is, it may consider any such <b>nil</b> value as the end of | ||
1100 | the array). | ||
1101 | |||
1102 | |||
1103 | |||
1104 | |||
1105 | |||
1106 | <h3>2.5.6 - <a name="2.5.6">Precedence</a></h3><p> | ||
1107 | Operator precedence in Lua follows the table below, | ||
1108 | from lower to higher priority: | ||
1109 | |||
1110 | <pre> | ||
1111 | or | ||
1112 | and | ||
1113 | < > <= >= ~= == | ||
1114 | .. | ||
1115 | + - | ||
1116 | * / % | ||
1117 | not # - (unary) | ||
1118 | ^ | ||
1119 | </pre><p> | ||
1120 | As usual, | ||
1121 | you can use parentheses to change the precedences of an expression. | ||
1122 | The concatenation ('<code>..</code>') and exponentiation ('<code>^</code>') | ||
1123 | operators are right associative. | ||
1124 | All other binary operators are left associative. | ||
1125 | |||
1126 | |||
1127 | |||
1128 | |||
1129 | |||
1130 | <h3>2.5.7 - <a name="2.5.7">Table Constructors</a></h3><p> | ||
1131 | Table constructors are expressions that create tables. | ||
1132 | Every time a constructor is evaluated, a new table is created. | ||
1133 | A constructor can be used to create an empty table | ||
1134 | or to create a table and initialize some of its fields. | ||
1135 | The general syntax for constructors is | ||
1136 | |||
1137 | <pre> | ||
1138 | tableconstructor ::= `<b>{</b>´ [fieldlist] `<b>}</b>´ | ||
1139 | fieldlist ::= field {fieldsep field} [fieldsep] | ||
1140 | field ::= `<b>[</b>´ exp `<b>]</b>´ `<b>=</b>´ exp | Name `<b>=</b>´ exp | exp | ||
1141 | fieldsep ::= `<b>,</b>´ | `<b>;</b>´ | ||
1142 | </pre> | ||
1143 | |||
1144 | <p> | ||
1145 | Each field of the form <code>[exp1] = exp2</code> adds to the new table an entry | ||
1146 | with key <code>exp1</code> and value <code>exp2</code>. | ||
1147 | A field of the form <code>name = exp</code> is equivalent to | ||
1148 | <code>["name"] = exp</code>. | ||
1149 | Finally, fields of the form <code>exp</code> are equivalent to | ||
1150 | <code>[i] = exp</code>, where <code>i</code> are consecutive numerical integers, | ||
1151 | starting with 1. | ||
1152 | Fields in the other formats do not affect this counting. | ||
1153 | For example, | ||
1154 | |||
1155 | <pre> | ||
1156 | a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 } | ||
1157 | </pre><p> | ||
1158 | is equivalent to | ||
1159 | |||
1160 | <pre> | ||
1161 | do | ||
1162 | local t = {} | ||
1163 | t[f(1)] = g | ||
1164 | t[1] = "x" -- 1st exp | ||
1165 | t[2] = "y" -- 2nd exp | ||
1166 | t.x = 1 -- t["x"] = 1 | ||
1167 | t[3] = f(x) -- 3rd exp | ||
1168 | t[30] = 23 | ||
1169 | t[4] = 45 -- 4th exp | ||
1170 | a = t | ||
1171 | end | ||
1172 | </pre> | ||
1173 | |||
1174 | <p> | ||
1175 | If the last field in the list has the form <code>exp</code> | ||
1176 | and the expression is a function call or a vararg expression, | ||
1177 | then all values returned by this expression enter the list consecutively | ||
1178 | (see <a href="#2.5.8">§2.5.8</a>). | ||
1179 | To avoid this, | ||
1180 | enclose the function call or the vararg expression | ||
1181 | in parentheses (see <a href="#2.5">§2.5</a>). | ||
1182 | |||
1183 | |||
1184 | <p> | ||
1185 | The field list can have an optional trailing separator, | ||
1186 | as a convenience for machine-generated code. | ||
1187 | |||
1188 | |||
1189 | |||
1190 | |||
1191 | |||
1192 | <h3>2.5.8 - <a name="2.5.8">Function Calls</a></h3><p> | ||
1193 | A function call in Lua has the following syntax: | ||
1194 | |||
1195 | <pre> | ||
1196 | functioncall ::= prefixexp args | ||
1197 | </pre><p> | ||
1198 | In a function call, | ||
1199 | first prefixexp and args are evaluated. | ||
1200 | If the value of prefixexp has type <em>function</em>, | ||
1201 | then this function is called | ||
1202 | with the given arguments. | ||
1203 | Otherwise, the prefixexp "call" metamethod is called, | ||
1204 | having as first parameter the value of prefixexp, | ||
1205 | followed by the original call arguments | ||
1206 | (see <a href="#2.8">§2.8</a>). | ||
1207 | |||
1208 | |||
1209 | <p> | ||
1210 | The form | ||
1211 | |||
1212 | <pre> | ||
1213 | functioncall ::= prefixexp `<b>:</b>´ Name args | ||
1214 | </pre><p> | ||
1215 | can be used to call "methods". | ||
1216 | A call <code>v:name(<em>args</em>)</code> | ||
1217 | is syntactic sugar for <code>v.name(v,<em>args</em>)</code>, | ||
1218 | except that <code>v</code> is evaluated only once. | ||
1219 | |||
1220 | |||
1221 | <p> | ||
1222 | Arguments have the following syntax: | ||
1223 | |||
1224 | <pre> | ||
1225 | args ::= `<b>(</b>´ [explist] `<b>)</b>´ | ||
1226 | args ::= tableconstructor | ||
1227 | args ::= String | ||
1228 | </pre><p> | ||
1229 | All argument expressions are evaluated before the call. | ||
1230 | A call of the form <code>f{<em>fields</em>}</code> is | ||
1231 | syntactic sugar for <code>f({<em>fields</em>})</code>; | ||
1232 | that is, the argument list is a single new table. | ||
1233 | A call of the form <code>f'<em>string</em>'</code> | ||
1234 | (or <code>f"<em>string</em>"</code> or <code>f[[<em>string</em>]]</code>) | ||
1235 | is syntactic sugar for <code>f('<em>string</em>')</code>; | ||
1236 | that is, the argument list is a single literal string. | ||
1237 | |||
1238 | |||
1239 | <p> | ||
1240 | As an exception to the free-format syntax of Lua, | ||
1241 | you cannot put a line break before the '<code>(</code>' in a function call. | ||
1242 | This restriction avoids some ambiguities in the language. | ||
1243 | If you write | ||
1244 | |||
1245 | <pre> | ||
1246 | a = f | ||
1247 | (g).x(a) | ||
1248 | </pre><p> | ||
1249 | Lua would see that as a single statement, <code>a = f(g).x(a)</code>. | ||
1250 | So, if you want two statements, you must add a semi-colon between them. | ||
1251 | If you actually want to call <code>f</code>, | ||
1252 | you must remove the line break before <code>(g)</code>. | ||
1253 | |||
1254 | |||
1255 | <p> | ||
1256 | A call of the form <code>return</code> <em>functioncall</em> is called | ||
1257 | a <em>tail call</em>. | ||
1258 | Lua implements <em>proper tail calls</em> | ||
1259 | (or <em>proper tail recursion</em>): | ||
1260 | in a tail call, | ||
1261 | the called function reuses the stack entry of the calling function. | ||
1262 | Therefore, there is no limit on the number of nested tail calls that | ||
1263 | a program can execute. | ||
1264 | However, a tail call erases any debug information about the | ||
1265 | calling function. | ||
1266 | Note that a tail call only happens with a particular syntax, | ||
1267 | where the <b>return</b> has one single function call as argument; | ||
1268 | this syntax makes the calling function return exactly | ||
1269 | the returns of the called function. | ||
1270 | So, none of the following examples are tail calls: | ||
1271 | |||
1272 | <pre> | ||
1273 | return (f(x)) -- results adjusted to 1 | ||
1274 | return 2 * f(x) | ||
1275 | return x, f(x) -- additional results | ||
1276 | f(x); return -- results discarded | ||
1277 | return x or f(x) -- results adjusted to 1 | ||
1278 | </pre> | ||
1279 | |||
1280 | |||
1281 | |||
1282 | |||
1283 | <h3>2.5.9 - <a name="2.5.9">Function Definitions</a></h3> | ||
1284 | |||
1285 | <p> | ||
1286 | The syntax for function definition is | ||
1287 | |||
1288 | <pre> | ||
1289 | function ::= <b>function</b> funcbody | ||
1290 | funcbody ::= `<b>(</b>´ [parlist] `<b>)</b>´ block <b>end</b> | ||
1291 | </pre> | ||
1292 | |||
1293 | <p> | ||
1294 | The following syntactic sugar simplifies function definitions: | ||
1295 | |||
1296 | <pre> | ||
1297 | stat ::= <b>function</b> funcname funcbody | ||
1298 | stat ::= <b>local</b> <b>function</b> Name funcbody | ||
1299 | funcname ::= Name {`<b>.</b>´ Name} [`<b>:</b>´ Name] | ||
1300 | </pre><p> | ||
1301 | The statement | ||
1302 | |||
1303 | <pre> | ||
1304 | function f () <em>body</em> end | ||
1305 | </pre><p> | ||
1306 | translates to | ||
1307 | |||
1308 | <pre> | ||
1309 | f = function () <em>body</em> end | ||
1310 | </pre><p> | ||
1311 | The statement | ||
1312 | |||
1313 | <pre> | ||
1314 | function t.a.b.c.f () <em>body</em> end | ||
1315 | </pre><p> | ||
1316 | translates to | ||
1317 | |||
1318 | <pre> | ||
1319 | t.a.b.c.f = function () <em>body</em> end | ||
1320 | </pre><p> | ||
1321 | The statement | ||
1322 | |||
1323 | <pre> | ||
1324 | local function f () <em>body</em> end | ||
1325 | </pre><p> | ||
1326 | translates to | ||
1327 | |||
1328 | <pre> | ||
1329 | local f; f = function () <em>body</em> end | ||
1330 | </pre><p> | ||
1331 | <em>not</em> to | ||
1332 | |||
1333 | <pre> | ||
1334 | local f = function () <em>body</em> end | ||
1335 | </pre><p> | ||
1336 | (This only makes a difference when the body of the function | ||
1337 | contains references to <code>f</code>.) | ||
1338 | |||
1339 | |||
1340 | <p> | ||
1341 | A function definition is an executable expression, | ||
1342 | whose value has type <em>function</em>. | ||
1343 | When Lua pre-compiles a chunk, | ||
1344 | all its function bodies are pre-compiled too. | ||
1345 | Then, whenever Lua executes the function definition, | ||
1346 | the function is <em>instantiated</em> (or <em>closed</em>). | ||
1347 | This function instance (or <em>closure</em>) | ||
1348 | is the final value of the expression. | ||
1349 | Different instances of the same function | ||
1350 | can refer to different external local variables | ||
1351 | and can have different environment tables. | ||
1352 | |||
1353 | |||
1354 | <p> | ||
1355 | Parameters act as local variables that are | ||
1356 | initialized with the argument values: | ||
1357 | |||
1358 | <pre> | ||
1359 | parlist ::= namelist [`<b>,</b>´ `<b>...</b>´] | `<b>...</b>´ | ||
1360 | </pre><p> | ||
1361 | When a function is called, | ||
1362 | the list of arguments is adjusted to | ||
1363 | the length of the list of parameters, | ||
1364 | unless the function is a variadic or <em>vararg function</em>, | ||
1365 | which is | ||
1366 | indicated by three dots ('<code>...</code>') at the end of its parameter list. | ||
1367 | A vararg function does not adjust its argument list; | ||
1368 | instead, it collects all extra arguments and supplies them | ||
1369 | to the function through a <em>vararg expression</em>, | ||
1370 | which is also written as three dots. | ||
1371 | The value of this expression is a list of all actual extra arguments, | ||
1372 | similar to a function with multiple results. | ||
1373 | If a vararg expression is used inside another expression | ||
1374 | or in the middle of a list of expressions, | ||
1375 | then its return list is adjusted to one element. | ||
1376 | If the expression is used as the last element of a list of expressions, | ||
1377 | then no adjustment is made | ||
1378 | (unless that last expression is enclosed in parentheses). | ||
1379 | |||
1380 | |||
1381 | <p> | ||
1382 | As an example, consider the following definitions: | ||
1383 | |||
1384 | <pre> | ||
1385 | function f(a, b) end | ||
1386 | function g(a, b, ...) end | ||
1387 | function r() return 1,2,3 end | ||
1388 | </pre><p> | ||
1389 | Then, we have the following mapping from arguments to parameters and | ||
1390 | to the vararg expression: | ||
1391 | |||
1392 | <pre> | ||
1393 | CALL PARAMETERS | ||
1394 | |||
1395 | f(3) a=3, b=nil | ||
1396 | f(3, 4) a=3, b=4 | ||
1397 | f(3, 4, 5) a=3, b=4 | ||
1398 | f(r(), 10) a=1, b=10 | ||
1399 | f(r()) a=1, b=2 | ||
1400 | |||
1401 | g(3) a=3, b=nil, ... --> (nothing) | ||
1402 | g(3, 4) a=3, b=4, ... --> (nothing) | ||
1403 | g(3, 4, 5, 8) a=3, b=4, ... --> 5 8 | ||
1404 | g(5, r()) a=5, b=1, ... --> 2 3 | ||
1405 | </pre> | ||
1406 | |||
1407 | <p> | ||
1408 | Results are returned using the <b>return</b> statement (see <a href="#2.4.4">§2.4.4</a>). | ||
1409 | If control reaches the end of a function | ||
1410 | without encountering a <b>return</b> statement, | ||
1411 | then the function returns with no results. | ||
1412 | |||
1413 | |||
1414 | <p> | ||
1415 | The <em>colon</em> syntax | ||
1416 | is used for defining <em>methods</em>, | ||
1417 | that is, functions that have an implicit extra parameter <code>self</code>. | ||
1418 | Thus, the statement | ||
1419 | |||
1420 | <pre> | ||
1421 | function t.a.b.c:f (<em>params</em>) <em>body</em> end | ||
1422 | </pre><p> | ||
1423 | is syntactic sugar for | ||
1424 | |||
1425 | <pre> | ||
1426 | t.a.b.c.f = function (self, <em>params</em>) <em>body</em> end | ||
1427 | </pre> | ||
1428 | |||
1429 | |||
1430 | |||
1431 | |||
1432 | |||
1433 | |||
1434 | <h2>2.6 - <a name="2.6">Visibility Rules</a></h2> | ||
1435 | |||
1436 | <p> | ||
1437 | |||
1438 | Lua is a lexically scoped language. | ||
1439 | The scope of variables begins at the first statement <em>after</em> | ||
1440 | their declaration and lasts until the end of the innermost block that | ||
1441 | includes the declaration. | ||
1442 | Consider the following example: | ||
1443 | |||
1444 | <pre> | ||
1445 | x = 10 -- global variable | ||
1446 | do -- new block | ||
1447 | local x = x -- new 'x', with value 10 | ||
1448 | print(x) --> 10 | ||
1449 | x = x+1 | ||
1450 | do -- another block | ||
1451 | local x = x+1 -- another 'x' | ||
1452 | print(x) --> 12 | ||
1453 | end | ||
1454 | print(x) --> 11 | ||
1455 | end | ||
1456 | print(x) --> 10 (the global one) | ||
1457 | </pre> | ||
1458 | |||
1459 | <p> | ||
1460 | Notice that, in a declaration like <code>local x = x</code>, | ||
1461 | the new <code>x</code> being declared is not in scope yet, | ||
1462 | and so the second <code>x</code> refers to the outside variable. | ||
1463 | |||
1464 | |||
1465 | <p> | ||
1466 | Because of the lexical scoping rules, | ||
1467 | local variables can be freely accessed by functions | ||
1468 | defined inside their scope. | ||
1469 | A local variable used by an inner function is called | ||
1470 | an <em>upvalue</em>, or <em>external local variable</em>, | ||
1471 | inside the inner function. | ||
1472 | |||
1473 | |||
1474 | <p> | ||
1475 | Notice that each execution of a <b>local</b> statement | ||
1476 | defines new local variables. | ||
1477 | Consider the following example: | ||
1478 | |||
1479 | <pre> | ||
1480 | a = {} | ||
1481 | local x = 20 | ||
1482 | for i=1,10 do | ||
1483 | local y = 0 | ||
1484 | a[i] = function () y=y+1; return x+y end | ||
1485 | end | ||
1486 | </pre><p> | ||
1487 | The loop creates ten closures | ||
1488 | (that is, ten instances of the anonymous function). | ||
1489 | Each of these closures uses a different <code>y</code> variable, | ||
1490 | while all of them share the same <code>x</code>. | ||
1491 | |||
1492 | |||
1493 | |||
1494 | |||
1495 | |||
1496 | <h2>2.7 - <a name="2.7">Error Handling</a></h2> | ||
1497 | |||
1498 | <p> | ||
1499 | Because Lua is an embedded extension language, | ||
1500 | all Lua actions start from C code in the host program | ||
1501 | calling a function from the Lua library (see <a href="#lua_pcall"><code>lua_pcall</code></a>). | ||
1502 | Whenever an error occurs during Lua compilation or execution, | ||
1503 | control returns to C, | ||
1504 | which can take appropriate measures | ||
1505 | (such as printing an error message). | ||
1506 | |||
1507 | |||
1508 | <p> | ||
1509 | Lua code can explicitly generate an error by calling the | ||
1510 | <a href="#pdf-error"><code>error</code></a> function. | ||
1511 | If you need to catch errors in Lua, | ||
1512 | you can use the <a href="#pdf-pcall"><code>pcall</code></a> function. | ||
1513 | |||
1514 | |||
1515 | |||
1516 | |||
1517 | |||
1518 | <h2>2.8 - <a name="2.8">Metatables</a></h2> | ||
1519 | |||
1520 | <p> | ||
1521 | Every value in Lua can have a <em>metatable</em>. | ||
1522 | This <em>metatable</em> is an ordinary Lua table | ||
1523 | that defines the behavior of the original value | ||
1524 | under certain special operations. | ||
1525 | You can change several aspects of the behavior | ||
1526 | of operations over a value by setting specific fields in its metatable. | ||
1527 | For instance, when a non-numeric value is the operand of an addition, | ||
1528 | Lua checks for a function in the field <code>"__add"</code> in its metatable. | ||
1529 | If it finds one, | ||
1530 | Lua calls this function to perform the addition. | ||
1531 | |||
1532 | |||
1533 | <p> | ||
1534 | We call the keys in a metatable <em>events</em> | ||
1535 | and the values <em>metamethods</em>. | ||
1536 | In the previous example, the event is <code>"add"</code> | ||
1537 | and the metamethod is the function that performs the addition. | ||
1538 | |||
1539 | |||
1540 | <p> | ||
1541 | You can query the metatable of any value | ||
1542 | through the <a href="#pdf-getmetatable"><code>getmetatable</code></a> function. | ||
1543 | |||
1544 | |||
1545 | <p> | ||
1546 | You can replace the metatable of tables | ||
1547 | through the <a href="#pdf-setmetatable"><code>setmetatable</code></a> | ||
1548 | function. | ||
1549 | You cannot change the metatable of other types from Lua | ||
1550 | (except by using the debug library); | ||
1551 | you must use the C API for that. | ||
1552 | |||
1553 | |||
1554 | <p> | ||
1555 | Tables and full userdata have individual metatables | ||
1556 | (although multiple tables and userdata can share their metatables). | ||
1557 | Values of all other types share one single metatable per type; | ||
1558 | that is, there is one single metatable for all numbers, | ||
1559 | one for all strings, etc. | ||
1560 | |||
1561 | |||
1562 | <p> | ||
1563 | A metatable controls how an object behaves in arithmetic operations, | ||
1564 | order comparisons, concatenation, length operation, and indexing. | ||
1565 | A metatable also can define a function to be called when a userdata | ||
1566 | is garbage collected. | ||
1567 | For each of these operations Lua associates a specific key | ||
1568 | called an <em>event</em>. | ||
1569 | When Lua performs one of these operations over a value, | ||
1570 | it checks whether this value has a metatable with the corresponding event. | ||
1571 | If so, the value associated with that key (the metamethod) | ||
1572 | controls how Lua will perform the operation. | ||
1573 | |||
1574 | |||
1575 | <p> | ||
1576 | Metatables control the operations listed next. | ||
1577 | Each operation is identified by its corresponding name. | ||
1578 | The key for each operation is a string with its name prefixed by | ||
1579 | two underscores, '<code>__</code>'; | ||
1580 | for instance, the key for operation "add" is the | ||
1581 | string <code>"__add"</code>. | ||
1582 | The semantics of these operations is better explained by a Lua function | ||
1583 | describing how the interpreter executes the operation. | ||
1584 | |||
1585 | |||
1586 | <p> | ||
1587 | The code shown here in Lua is only illustrative; | ||
1588 | the real behavior is hard coded in the interpreter | ||
1589 | and it is much more efficient than this simulation. | ||
1590 | All functions used in these descriptions | ||
1591 | (<a href="#pdf-rawget"><code>rawget</code></a>, <a href="#pdf-tonumber"><code>tonumber</code></a>, etc.) | ||
1592 | are described in <a href="#5.1">§5.1</a>. | ||
1593 | In particular, to retrieve the metamethod of a given object, | ||
1594 | we use the expression | ||
1595 | |||
1596 | <pre> | ||
1597 | metatable(obj)[event] | ||
1598 | </pre><p> | ||
1599 | This should be read as | ||
1600 | |||
1601 | <pre> | ||
1602 | rawget(getmetatable(obj) or {}, event) | ||
1603 | </pre><p> | ||
1604 | |||
1605 | That is, the access to a metamethod does not invoke other metamethods, | ||
1606 | and the access to objects with no metatables does not fail | ||
1607 | (it simply results in <b>nil</b>). | ||
1608 | |||
1609 | |||
1610 | |||
1611 | <ul> | ||
1612 | |||
1613 | <li><b>"add":</b> | ||
1614 | the <code>+</code> operation. | ||
1615 | |||
1616 | |||
1617 | |||
1618 | <p> | ||
1619 | The function <code>getbinhandler</code> below defines how Lua chooses a handler | ||
1620 | for a binary operation. | ||
1621 | First, Lua tries the first operand. | ||
1622 | If its type does not define a handler for the operation, | ||
1623 | then Lua tries the second operand. | ||
1624 | |||
1625 | <pre> | ||
1626 | function getbinhandler (op1, op2, event) | ||
1627 | return metatable(op1)[event] or metatable(op2)[event] | ||
1628 | end | ||
1629 | </pre><p> | ||
1630 | By using this function, | ||
1631 | the behavior of the <code>op1 + op2</code> is | ||
1632 | |||
1633 | <pre> | ||
1634 | function add_event (op1, op2) | ||
1635 | local o1, o2 = tonumber(op1), tonumber(op2) | ||
1636 | if o1 and o2 then -- both operands are numeric? | ||
1637 | return o1 + o2 -- '+' here is the primitive 'add' | ||
1638 | else -- at least one of the operands is not numeric | ||
1639 | local h = getbinhandler(op1, op2, "__add") | ||
1640 | if h then | ||
1641 | -- call the handler with both operands | ||
1642 | return (h(op1, op2)) | ||
1643 | else -- no handler available: default behavior | ||
1644 | error(···) | ||
1645 | end | ||
1646 | end | ||
1647 | end | ||
1648 | </pre><p> | ||
1649 | </li> | ||
1650 | |||
1651 | <li><b>"sub":</b> | ||
1652 | the <code>-</code> operation. | ||
1653 | |||
1654 | Behavior similar to the "add" operation. | ||
1655 | </li> | ||
1656 | |||
1657 | <li><b>"mul":</b> | ||
1658 | the <code>*</code> operation. | ||
1659 | |||
1660 | Behavior similar to the "add" operation. | ||
1661 | </li> | ||
1662 | |||
1663 | <li><b>"div":</b> | ||
1664 | the <code>/</code> operation. | ||
1665 | |||
1666 | Behavior similar to the "add" operation. | ||
1667 | </li> | ||
1668 | |||
1669 | <li><b>"mod":</b> | ||
1670 | the <code>%</code> operation. | ||
1671 | |||
1672 | Behavior similar to the "add" operation, | ||
1673 | with the operation | ||
1674 | <code>o1 - floor(o1/o2)*o2</code> as the primitive operation. | ||
1675 | </li> | ||
1676 | |||
1677 | <li><b>"pow":</b> | ||
1678 | the <code>^</code> (exponentiation) operation. | ||
1679 | |||
1680 | Behavior similar to the "add" operation, | ||
1681 | with the function <code>pow</code> (from the C math library) | ||
1682 | as the primitive operation. | ||
1683 | </li> | ||
1684 | |||
1685 | <li><b>"unm":</b> | ||
1686 | the unary <code>-</code> operation. | ||
1687 | |||
1688 | |||
1689 | <pre> | ||
1690 | function unm_event (op) | ||
1691 | local o = tonumber(op) | ||
1692 | if o then -- operand is numeric? | ||
1693 | return -o -- '-' here is the primitive 'unm' | ||
1694 | else -- the operand is not numeric. | ||
1695 | -- Try to get a handler from the operand | ||
1696 | local h = metatable(op).__unm | ||
1697 | if h then | ||
1698 | -- call the handler with the operand | ||
1699 | return (h(op)) | ||
1700 | else -- no handler available: default behavior | ||
1701 | error(···) | ||
1702 | end | ||
1703 | end | ||
1704 | end | ||
1705 | </pre><p> | ||
1706 | </li> | ||
1707 | |||
1708 | <li><b>"concat":</b> | ||
1709 | the <code>..</code> (concatenation) operation. | ||
1710 | |||
1711 | |||
1712 | <pre> | ||
1713 | function concat_event (op1, op2) | ||
1714 | if (type(op1) == "string" or type(op1) == "number") and | ||
1715 | (type(op2) == "string" or type(op2) == "number") then | ||
1716 | return op1 .. op2 -- primitive string concatenation | ||
1717 | else | ||
1718 | local h = getbinhandler(op1, op2, "__concat") | ||
1719 | if h then | ||
1720 | return (h(op1, op2)) | ||
1721 | else | ||
1722 | error(···) | ||
1723 | end | ||
1724 | end | ||
1725 | end | ||
1726 | </pre><p> | ||
1727 | </li> | ||
1728 | |||
1729 | <li><b>"len":</b> | ||
1730 | the <code>#</code> operation. | ||
1731 | |||
1732 | |||
1733 | <pre> | ||
1734 | function len_event (op) | ||
1735 | if type(op) == "string" then | ||
1736 | return strlen(op) -- primitive string length | ||
1737 | elseif type(op) == "table" then | ||
1738 | return #op -- primitive table length | ||
1739 | else | ||
1740 | local h = metatable(op).__len | ||
1741 | if h then | ||
1742 | -- call the handler with the operand | ||
1743 | return (h(op)) | ||
1744 | else -- no handler available: default behavior | ||
1745 | error(···) | ||
1746 | end | ||
1747 | end | ||
1748 | end | ||
1749 | </pre><p> | ||
1750 | See <a href="#2.5.5">§2.5.5</a> for a description of the length of a table. | ||
1751 | </li> | ||
1752 | |||
1753 | <li><b>"eq":</b> | ||
1754 | the <code>==</code> operation. | ||
1755 | |||
1756 | The function <code>getcomphandler</code> defines how Lua chooses a metamethod | ||
1757 | for comparison operators. | ||
1758 | A metamethod only is selected when both objects | ||
1759 | being compared have the same type | ||
1760 | and the same metamethod for the selected operation. | ||
1761 | |||
1762 | <pre> | ||
1763 | function getcomphandler (op1, op2, event) | ||
1764 | if type(op1) ~= type(op2) then return nil end | ||
1765 | local mm1 = metatable(op1)[event] | ||
1766 | local mm2 = metatable(op2)[event] | ||
1767 | if mm1 == mm2 then return mm1 else return nil end | ||
1768 | end | ||
1769 | </pre><p> | ||
1770 | The "eq" event is defined as follows: | ||
1771 | |||
1772 | <pre> | ||
1773 | function eq_event (op1, op2) | ||
1774 | if type(op1) ~= type(op2) then -- different types? | ||
1775 | return false -- different objects | ||
1776 | end | ||
1777 | if op1 == op2 then -- primitive equal? | ||
1778 | return true -- objects are equal | ||
1779 | end | ||
1780 | -- try metamethod | ||
1781 | local h = getcomphandler(op1, op2, "__eq") | ||
1782 | if h then | ||
1783 | return (h(op1, op2)) | ||
1784 | else | ||
1785 | return false | ||
1786 | end | ||
1787 | end | ||
1788 | </pre><p> | ||
1789 | <code>a ~= b</code> is equivalent to <code>not (a == b)</code>. | ||
1790 | </li> | ||
1791 | |||
1792 | <li><b>"lt":</b> | ||
1793 | the <code><</code> operation. | ||
1794 | |||
1795 | |||
1796 | <pre> | ||
1797 | function lt_event (op1, op2) | ||
1798 | if type(op1) == "number" and type(op2) == "number" then | ||
1799 | return op1 < op2 -- numeric comparison | ||
1800 | elseif type(op1) == "string" and type(op2) == "string" then | ||
1801 | return op1 < op2 -- lexicographic comparison | ||
1802 | else | ||
1803 | local h = getcomphandler(op1, op2, "__lt") | ||
1804 | if h then | ||
1805 | return (h(op1, op2)) | ||
1806 | else | ||
1807 | error(···) | ||
1808 | end | ||
1809 | end | ||
1810 | end | ||
1811 | </pre><p> | ||
1812 | <code>a > b</code> is equivalent to <code>b < a</code>. | ||
1813 | </li> | ||
1814 | |||
1815 | <li><b>"le":</b> | ||
1816 | the <code><=</code> operation. | ||
1817 | |||
1818 | |||
1819 | <pre> | ||
1820 | function le_event (op1, op2) | ||
1821 | if type(op1) == "number" and type(op2) == "number" then | ||
1822 | return op1 <= op2 -- numeric comparison | ||
1823 | elseif type(op1) == "string" and type(op2) == "string" then | ||
1824 | return op1 <= op2 -- lexicographic comparison | ||
1825 | else | ||
1826 | local h = getcomphandler(op1, op2, "__le") | ||
1827 | if h then | ||
1828 | return (h(op1, op2)) | ||
1829 | else | ||
1830 | h = getcomphandler(op1, op2, "__lt") | ||
1831 | if h then | ||
1832 | return not h(op2, op1) | ||
1833 | else | ||
1834 | error(···) | ||
1835 | end | ||
1836 | end | ||
1837 | end | ||
1838 | end | ||
1839 | </pre><p> | ||
1840 | <code>a >= b</code> is equivalent to <code>b <= a</code>. | ||
1841 | Note that, in the absence of a "le" metamethod, | ||
1842 | Lua tries the "lt", assuming that <code>a <= b</code> is | ||
1843 | equivalent to <code>not (b < a)</code>. | ||
1844 | </li> | ||
1845 | |||
1846 | <li><b>"index":</b> | ||
1847 | The indexing access <code>table[key]</code>. | ||
1848 | |||
1849 | |||
1850 | <pre> | ||
1851 | function gettable_event (table, key) | ||
1852 | local h | ||
1853 | if type(table) == "table" then | ||
1854 | local v = rawget(table, key) | ||
1855 | if v ~= nil then return v end | ||
1856 | h = metatable(table).__index | ||
1857 | if h == nil then return nil end | ||
1858 | else | ||
1859 | h = metatable(table).__index | ||
1860 | if h == nil then | ||
1861 | error(···) | ||
1862 | end | ||
1863 | end | ||
1864 | if type(h) == "function" then | ||
1865 | return (h(table, key)) -- call the handler | ||
1866 | else return h[key] -- or repeat operation on it | ||
1867 | end | ||
1868 | end | ||
1869 | </pre><p> | ||
1870 | </li> | ||
1871 | |||
1872 | <li><b>"newindex":</b> | ||
1873 | The indexing assignment <code>table[key] = value</code>. | ||
1874 | |||
1875 | |||
1876 | <pre> | ||
1877 | function settable_event (table, key, value) | ||
1878 | local h | ||
1879 | if type(table) == "table" then | ||
1880 | local v = rawget(table, key) | ||
1881 | if v ~= nil then rawset(table, key, value); return end | ||
1882 | h = metatable(table).__newindex | ||
1883 | if h == nil then rawset(table, key, value); return end | ||
1884 | else | ||
1885 | h = metatable(table).__newindex | ||
1886 | if h == nil then | ||
1887 | error(···) | ||
1888 | end | ||
1889 | end | ||
1890 | if type(h) == "function" then | ||
1891 | h(table, key,value) -- call the handler | ||
1892 | else h[key] = value -- or repeat operation on it | ||
1893 | end | ||
1894 | end | ||
1895 | </pre><p> | ||
1896 | </li> | ||
1897 | |||
1898 | <li><b>"call":</b> | ||
1899 | called when Lua calls a value. | ||
1900 | |||
1901 | |||
1902 | <pre> | ||
1903 | function function_event (func, ...) | ||
1904 | if type(func) == "function" then | ||
1905 | return func(...) -- primitive call | ||
1906 | else | ||
1907 | local h = metatable(func).__call | ||
1908 | if h then | ||
1909 | return h(func, ...) | ||
1910 | else | ||
1911 | error(···) | ||
1912 | end | ||
1913 | end | ||
1914 | end | ||
1915 | </pre><p> | ||
1916 | </li> | ||
1917 | |||
1918 | </ul> | ||
1919 | |||
1920 | |||
1921 | |||
1922 | |||
1923 | <h2>2.9 - <a name="2.9">Environments</a></h2> | ||
1924 | |||
1925 | <p> | ||
1926 | Besides metatables, | ||
1927 | objects of types thread, function, and userdata | ||
1928 | have another table associated with them, | ||
1929 | called their <em>environment</em>. | ||
1930 | Like metatables, environments are regular tables and | ||
1931 | multiple objects can share the same environment. | ||
1932 | |||
1933 | |||
1934 | <p> | ||
1935 | Threads are created sharing the environment of the creating thread. | ||
1936 | Userdata and C functions are created sharing the environment | ||
1937 | of the creating C function. | ||
1938 | Non-nested Lua functions | ||
1939 | (created by <a href="#pdf-loadfile"><code>loadfile</code></a>, <a href="#pdf-loadstring"><code>loadstring</code></a> or <a href="#pdf-load"><code>load</code></a>) | ||
1940 | are created sharing the environment of the creating thread. | ||
1941 | Nested Lua functions are created sharing the environment of | ||
1942 | the creating Lua function. | ||
1943 | |||
1944 | |||
1945 | <p> | ||
1946 | Environments associated with userdata have no meaning for Lua. | ||
1947 | It is only a convenience feature for programmers to associate a table to | ||
1948 | a userdata. | ||
1949 | |||
1950 | |||
1951 | <p> | ||
1952 | Environments associated with threads are called | ||
1953 | <em>global environments</em>. | ||
1954 | They are used as the default environment for threads and | ||
1955 | non-nested Lua functions created by the thread | ||
1956 | and can be directly accessed by C code (see <a href="#3.3">§3.3</a>). | ||
1957 | |||
1958 | |||
1959 | <p> | ||
1960 | The environment associated with a C function can be directly | ||
1961 | accessed by C code (see <a href="#3.3">§3.3</a>). | ||
1962 | It is used as the default environment for other C functions | ||
1963 | and userdata created by the function. | ||
1964 | |||
1965 | |||
1966 | <p> | ||
1967 | Environments associated with Lua functions are used to resolve | ||
1968 | all accesses to global variables within the function (see <a href="#2.3">§2.3</a>). | ||
1969 | They are used as the default environment for nested Lua functions | ||
1970 | created by the function. | ||
1971 | |||
1972 | |||
1973 | <p> | ||
1974 | You can change the environment of a Lua function or the | ||
1975 | running thread by calling <a href="#pdf-setfenv"><code>setfenv</code></a>. | ||
1976 | You can get the environment of a Lua function or the running thread | ||
1977 | by calling <a href="#pdf-getfenv"><code>getfenv</code></a>. | ||
1978 | To manipulate the environment of other objects | ||
1979 | (userdata, C functions, other threads) you must | ||
1980 | use the C API. | ||
1981 | |||
1982 | |||
1983 | |||
1984 | |||
1985 | |||
1986 | <h2>2.10 - <a name="2.10">Garbage Collection</a></h2> | ||
1987 | |||
1988 | <p> | ||
1989 | Lua performs automatic memory management. | ||
1990 | This means that | ||
1991 | you have to worry neither about allocating memory for new objects | ||
1992 | nor about freeing it when the objects are no longer needed. | ||
1993 | Lua manages memory automatically by running | ||
1994 | a <em>garbage collector</em> from time to time | ||
1995 | to collect all <em>dead objects</em> | ||
1996 | (that is, objects that are no longer accessible from Lua). | ||
1997 | All memory used by Lua is subject to automatic management: | ||
1998 | tables, userdata, functions, threads, strings, etc. | ||
1999 | |||
2000 | |||
2001 | <p> | ||
2002 | Lua implements an incremental mark-and-sweep collector. | ||
2003 | It uses two numbers to control its garbage-collection cycles: | ||
2004 | the <em>garbage-collector pause</em> and | ||
2005 | the <em>garbage-collector step multiplier</em>. | ||
2006 | Both use percentage points as units | ||
2007 | (so that a value of 100 means an internal value of 1). | ||
2008 | |||
2009 | |||
2010 | <p> | ||
2011 | The garbage-collector pause | ||
2012 | controls how long the collector waits before starting a new cycle. | ||
2013 | Larger values make the collector less aggressive. | ||
2014 | Values smaller than 100 mean the collector will not wait to | ||
2015 | start a new cycle. | ||
2016 | A value of 200 means that the collector waits for the total memory in use | ||
2017 | to double before starting a new cycle. | ||
2018 | |||
2019 | |||
2020 | <p> | ||
2021 | The step multiplier | ||
2022 | controls the relative speed of the collector relative to | ||
2023 | memory allocation. | ||
2024 | Larger values make the collector more aggressive but also increase | ||
2025 | the size of each incremental step. | ||
2026 | Values smaller than 100 make the collector too slow and | ||
2027 | can result in the collector never finishing a cycle. | ||
2028 | The default, 200, means that the collector runs at "twice" | ||
2029 | the speed of memory allocation. | ||
2030 | |||
2031 | |||
2032 | <p> | ||
2033 | You can change these numbers by calling <a href="#lua_gc"><code>lua_gc</code></a> in C | ||
2034 | or <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> in Lua. | ||
2035 | With these functions you can also control | ||
2036 | the collector directly (e.g., stop and restart it). | ||
2037 | |||
2038 | |||
2039 | |||
2040 | <h3>2.10.1 - <a name="2.10.1">Garbage-Collection Metamethods</a></h3> | ||
2041 | |||
2042 | <p> | ||
2043 | Using the C API, | ||
2044 | you can set garbage-collector metamethods for userdata (see <a href="#2.8">§2.8</a>). | ||
2045 | These metamethods are also called <em>finalizers</em>. | ||
2046 | Finalizers allow you to coordinate Lua's garbage collection | ||
2047 | with external resource management | ||
2048 | (such as closing files, network or database connections, | ||
2049 | or freeing your own memory). | ||
2050 | |||
2051 | |||
2052 | <p> | ||
2053 | Garbage userdata with a field <code>__gc</code> in their metatables are not | ||
2054 | collected immediately by the garbage collector. | ||
2055 | Instead, Lua puts them in a list. | ||
2056 | After the collection, | ||
2057 | Lua does the equivalent of the following function | ||
2058 | for each userdata in that list: | ||
2059 | |||
2060 | <pre> | ||
2061 | function gc_event (udata) | ||
2062 | local h = metatable(udata).__gc | ||
2063 | if h then | ||
2064 | h(udata) | ||
2065 | end | ||
2066 | end | ||
2067 | </pre> | ||
2068 | |||
2069 | <p> | ||
2070 | At the end of each garbage-collection cycle, | ||
2071 | the finalizers for userdata are called in <em>reverse</em> | ||
2072 | order of their creation, | ||
2073 | among those collected in that cycle. | ||
2074 | That is, the first finalizer to be called is the one associated | ||
2075 | with the userdata created last in the program. | ||
2076 | The userdata itself is freed only in the next garbage-collection cycle. | ||
2077 | |||
2078 | |||
2079 | |||
2080 | |||
2081 | |||
2082 | <h3>2.10.2 - <a name="2.10.2">Weak Tables</a></h3> | ||
2083 | |||
2084 | <p> | ||
2085 | A <em>weak table</em> is a table whose elements are | ||
2086 | <em>weak references</em>. | ||
2087 | A weak reference is ignored by the garbage collector. | ||
2088 | In other words, | ||
2089 | if the only references to an object are weak references, | ||
2090 | then the garbage collector will collect this object. | ||
2091 | |||
2092 | |||
2093 | <p> | ||
2094 | A weak table can have weak keys, weak values, or both. | ||
2095 | A table with weak keys allows the collection of its keys, | ||
2096 | but prevents the collection of its values. | ||
2097 | A table with both weak keys and weak values allows the collection of | ||
2098 | both keys and values. | ||
2099 | In any case, if either the key or the value is collected, | ||
2100 | the whole pair is removed from the table. | ||
2101 | The weakness of a table is controlled by the | ||
2102 | <code>__mode</code> field of its metatable. | ||
2103 | If the <code>__mode</code> field is a string containing the character '<code>k</code>', | ||
2104 | the keys in the table are weak. | ||
2105 | If <code>__mode</code> contains '<code>v</code>', | ||
2106 | the values in the table are weak. | ||
2107 | |||
2108 | |||
2109 | <p> | ||
2110 | After you use a table as a metatable, | ||
2111 | you should not change the value of its <code>__mode</code> field. | ||
2112 | Otherwise, the weak behavior of the tables controlled by this | ||
2113 | metatable is undefined. | ||
2114 | |||
2115 | |||
2116 | |||
2117 | |||
2118 | |||
2119 | |||
2120 | |||
2121 | <h2>2.11 - <a name="2.11">Coroutines</a></h2> | ||
2122 | |||
2123 | <p> | ||
2124 | Lua supports coroutines, | ||
2125 | also called <em>collaborative multithreading</em>. | ||
2126 | A coroutine in Lua represents an independent thread of execution. | ||
2127 | Unlike threads in multithread systems, however, | ||
2128 | a coroutine only suspends its execution by explicitly calling | ||
2129 | a yield function. | ||
2130 | |||
2131 | |||
2132 | <p> | ||
2133 | You create a coroutine with a call to <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>. | ||
2134 | Its sole argument is a function | ||
2135 | that is the main function of the coroutine. | ||
2136 | The <code>create</code> function only creates a new coroutine and | ||
2137 | returns a handle to it (an object of type <em>thread</em>); | ||
2138 | it does not start the coroutine execution. | ||
2139 | |||
2140 | |||
2141 | <p> | ||
2142 | When you first call <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>, | ||
2143 | passing as its first argument | ||
2144 | a thread returned by <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>, | ||
2145 | the coroutine starts its execution, | ||
2146 | at the first line of its main function. | ||
2147 | Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed on | ||
2148 | to the coroutine main function. | ||
2149 | After the coroutine starts running, | ||
2150 | it runs until it terminates or <em>yields</em>. | ||
2151 | |||
2152 | |||
2153 | <p> | ||
2154 | A coroutine can terminate its execution in two ways: | ||
2155 | normally, when its main function returns | ||
2156 | (explicitly or implicitly, after the last instruction); | ||
2157 | and abnormally, if there is an unprotected error. | ||
2158 | In the first case, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>, | ||
2159 | plus any values returned by the coroutine main function. | ||
2160 | In case of errors, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>false</b> | ||
2161 | plus an error message. | ||
2162 | |||
2163 | |||
2164 | <p> | ||
2165 | A coroutine yields by calling <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>. | ||
2166 | When a coroutine yields, | ||
2167 | the corresponding <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns immediately, | ||
2168 | even if the yield happens inside nested function calls | ||
2169 | (that is, not in the main function, | ||
2170 | but in a function directly or indirectly called by the main function). | ||
2171 | In the case of a yield, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> also returns <b>true</b>, | ||
2172 | plus any values passed to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>. | ||
2173 | The next time you resume the same coroutine, | ||
2174 | it continues its execution from the point where it yielded, | ||
2175 | with the call to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a> returning any extra | ||
2176 | arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>. | ||
2177 | |||
2178 | |||
2179 | <p> | ||
2180 | Like <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>, | ||
2181 | the <a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> function also creates a coroutine, | ||
2182 | but instead of returning the coroutine itself, | ||
2183 | it returns a function that, when called, resumes the coroutine. | ||
2184 | Any arguments passed to this function | ||
2185 | go as extra arguments to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>. | ||
2186 | <a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> returns all the values returned by <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>, | ||
2187 | except the first one (the boolean error code). | ||
2188 | Unlike <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>, | ||
2189 | <a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> does not catch errors; | ||
2190 | any error is propagated to the caller. | ||
2191 | |||
2192 | |||
2193 | <p> | ||
2194 | As an example, | ||
2195 | consider the following code: | ||
2196 | |||
2197 | <pre> | ||
2198 | function foo (a) | ||
2199 | print("foo", a) | ||
2200 | return coroutine.yield(2*a) | ||
2201 | end | ||
2202 | |||
2203 | co = coroutine.create(function (a,b) | ||
2204 | print("co-body", a, b) | ||
2205 | local r = foo(a+1) | ||
2206 | print("co-body", r) | ||
2207 | local r, s = coroutine.yield(a+b, a-b) | ||
2208 | print("co-body", r, s) | ||
2209 | return b, "end" | ||
2210 | end) | ||
2211 | |||
2212 | print("main", coroutine.resume(co, 1, 10)) | ||
2213 | print("main", coroutine.resume(co, "r")) | ||
2214 | print("main", coroutine.resume(co, "x", "y")) | ||
2215 | print("main", coroutine.resume(co, "x", "y")) | ||
2216 | </pre><p> | ||
2217 | When you run it, it produces the following output: | ||
2218 | |||
2219 | <pre> | ||
2220 | co-body 1 10 | ||
2221 | foo 2 | ||
2222 | |||
2223 | main true 4 | ||
2224 | co-body r | ||
2225 | main true 11 -9 | ||
2226 | co-body x y | ||
2227 | main true 10 end | ||
2228 | main false cannot resume dead coroutine | ||
2229 | </pre> | ||
2230 | |||
2231 | |||
2232 | |||
2233 | |||
2234 | <h1>3 - <a name="3">The Application Program Interface</a></h1> | ||
2235 | |||
2236 | <p> | ||
2237 | |||
2238 | This section describes the C API for Lua, that is, | ||
2239 | the set of C functions available to the host program to communicate | ||
2240 | with Lua. | ||
2241 | All API functions and related types and constants | ||
2242 | are declared in the header file <a name="pdf-lua.h"><code>lua.h</code></a>. | ||
2243 | |||
2244 | |||
2245 | <p> | ||
2246 | Even when we use the term "function", | ||
2247 | any facility in the API may be provided as a macro instead. | ||
2248 | All such macros use each of their arguments exactly once | ||
2249 | (except for the first argument, which is always a Lua state), | ||
2250 | and so do not generate any hidden side-effects. | ||
2251 | |||
2252 | |||
2253 | <p> | ||
2254 | As in most C libraries, | ||
2255 | the Lua API functions do not check their arguments for validity or consistency. | ||
2256 | However, you can change this behavior by compiling Lua | ||
2257 | with a proper definition for the macro <a name="pdf-luai_apicheck"><code>luai_apicheck</code></a>, | ||
2258 | in file <code>luaconf.h</code>. | ||
2259 | |||
2260 | |||
2261 | |||
2262 | <h2>3.1 - <a name="3.1">The Stack</a></h2> | ||
2263 | |||
2264 | <p> | ||
2265 | Lua uses a <em>virtual stack</em> to pass values to and from C. | ||
2266 | Each element in this stack represents a Lua value | ||
2267 | (<b>nil</b>, number, string, etc.). | ||
2268 | |||
2269 | |||
2270 | <p> | ||
2271 | Whenever Lua calls C, the called function gets a new stack, | ||
2272 | which is independent of previous stacks and of stacks of | ||
2273 | C functions that are still active. | ||
2274 | This stack initially contains any arguments to the C function | ||
2275 | and it is where the C function pushes its results | ||
2276 | to be returned to the caller (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>). | ||
2277 | |||
2278 | |||
2279 | <p> | ||
2280 | For convenience, | ||
2281 | most query operations in the API do not follow a strict stack discipline. | ||
2282 | Instead, they can refer to any element in the stack | ||
2283 | by using an <em>index</em>: | ||
2284 | A positive index represents an <em>absolute</em> stack position | ||
2285 | (starting at 1); | ||
2286 | a negative index represents an <em>offset</em> relative to the top of the stack. | ||
2287 | More specifically, if the stack has <em>n</em> elements, | ||
2288 | then index 1 represents the first element | ||
2289 | (that is, the element that was pushed onto the stack first) | ||
2290 | and | ||
2291 | index <em>n</em> represents the last element; | ||
2292 | index -1 also represents the last element | ||
2293 | (that is, the element at the top) | ||
2294 | and index <em>-n</em> represents the first element. | ||
2295 | We say that an index is <em>valid</em> | ||
2296 | if it lies between 1 and the stack top | ||
2297 | (that is, if <code>1 ≤ abs(index) ≤ top</code>). | ||
2298 | |||
2299 | |||
2300 | |||
2301 | |||
2302 | |||
2303 | |||
2304 | <h2>3.2 - <a name="3.2">Stack Size</a></h2> | ||
2305 | |||
2306 | <p> | ||
2307 | When you interact with Lua API, | ||
2308 | you are responsible for ensuring consistency. | ||
2309 | In particular, | ||
2310 | <em>you are responsible for controlling stack overflow</em>. | ||
2311 | You can use the function <a href="#lua_checkstack"><code>lua_checkstack</code></a> | ||
2312 | to grow the stack size. | ||
2313 | |||
2314 | |||
2315 | <p> | ||
2316 | Whenever Lua calls C, | ||
2317 | it ensures that at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> stack positions are available. | ||
2318 | <code>LUA_MINSTACK</code> is defined as 20, | ||
2319 | so that usually you do not have to worry about stack space | ||
2320 | unless your code has loops pushing elements onto the stack. | ||
2321 | |||
2322 | |||
2323 | <p> | ||
2324 | Most query functions accept as indices any value inside the | ||
2325 | available stack space, that is, indices up to the maximum stack size | ||
2326 | you have set through <a href="#lua_checkstack"><code>lua_checkstack</code></a>. | ||
2327 | Such indices are called <em>acceptable indices</em>. | ||
2328 | More formally, we define an <em>acceptable index</em> | ||
2329 | as follows: | ||
2330 | |||
2331 | <pre> | ||
2332 | (index < 0 && abs(index) <= top) || | ||
2333 | (index > 0 && index <= stackspace) | ||
2334 | </pre><p> | ||
2335 | Note that 0 is never an acceptable index. | ||
2336 | |||
2337 | |||
2338 | |||
2339 | |||
2340 | |||
2341 | <h2>3.3 - <a name="3.3">Pseudo-Indices</a></h2> | ||
2342 | |||
2343 | <p> | ||
2344 | Unless otherwise noted, | ||
2345 | any function that accepts valid indices can also be called with | ||
2346 | <em>pseudo-indices</em>, | ||
2347 | which represent some Lua values that are accessible to C code | ||
2348 | but which are not in the stack. | ||
2349 | Pseudo-indices are used to access the thread environment, | ||
2350 | the function environment, | ||
2351 | the registry, | ||
2352 | and the upvalues of a C function (see <a href="#3.4">§3.4</a>). | ||
2353 | |||
2354 | |||
2355 | <p> | ||
2356 | The thread environment (where global variables live) is | ||
2357 | always at pseudo-index <a name="pdf-LUA_GLOBALSINDEX"><code>LUA_GLOBALSINDEX</code></a>. | ||
2358 | The environment of the running C function is always | ||
2359 | at pseudo-index <a name="pdf-LUA_ENVIRONINDEX"><code>LUA_ENVIRONINDEX</code></a>. | ||
2360 | |||
2361 | |||
2362 | <p> | ||
2363 | To access and change the value of global variables, | ||
2364 | you can use regular table operations over an environment table. | ||
2365 | For instance, to access the value of a global variable, do | ||
2366 | |||
2367 | <pre> | ||
2368 | lua_getfield(L, LUA_GLOBALSINDEX, varname); | ||
2369 | </pre> | ||
2370 | |||
2371 | |||
2372 | |||
2373 | |||
2374 | <h2>3.4 - <a name="3.4">C Closures</a></h2> | ||
2375 | |||
2376 | <p> | ||
2377 | When a C function is created, | ||
2378 | it is possible to associate some values with it, | ||
2379 | thus creating a <em>C closure</em>; | ||
2380 | these values are called <em>upvalues</em> and are | ||
2381 | accessible to the function whenever it is called | ||
2382 | (see <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a>). | ||
2383 | |||
2384 | |||
2385 | <p> | ||
2386 | Whenever a C function is called, | ||
2387 | its upvalues are located at specific pseudo-indices. | ||
2388 | These pseudo-indices are produced by the macro | ||
2389 | <a name="lua_upvalueindex"><code>lua_upvalueindex</code></a>. | ||
2390 | The first value associated with a function is at position | ||
2391 | <code>lua_upvalueindex(1)</code>, and so on. | ||
2392 | Any access to <code>lua_upvalueindex(<em>n</em>)</code>, | ||
2393 | where <em>n</em> is greater than the number of upvalues of the | ||
2394 | current function (but not greater than 256), | ||
2395 | produces an acceptable (but invalid) index. | ||
2396 | |||
2397 | |||
2398 | |||
2399 | |||
2400 | |||
2401 | <h2>3.5 - <a name="3.5">Registry</a></h2> | ||
2402 | |||
2403 | <p> | ||
2404 | Lua provides a <em>registry</em>, | ||
2405 | a pre-defined table that can be used by any C code to | ||
2406 | store whatever Lua value it needs to store. | ||
2407 | This table is always located at pseudo-index | ||
2408 | <a name="pdf-LUA_REGISTRYINDEX"><code>LUA_REGISTRYINDEX</code></a>. | ||
2409 | Any C library can store data into this table, | ||
2410 | but it should take care to choose keys different from those used | ||
2411 | by other libraries, to avoid collisions. | ||
2412 | Typically, you should use as key a string containing your library name | ||
2413 | or a light userdata with the address of a C object in your code. | ||
2414 | |||
2415 | |||
2416 | <p> | ||
2417 | The integer keys in the registry are used by the reference mechanism, | ||
2418 | implemented by the auxiliary library, | ||
2419 | and therefore should not be used for other purposes. | ||
2420 | |||
2421 | |||
2422 | |||
2423 | |||
2424 | |||
2425 | <h2>3.6 - <a name="3.6">Error Handling in C</a></h2> | ||
2426 | |||
2427 | <p> | ||
2428 | Internally, Lua uses the C <code>longjmp</code> facility to handle errors. | ||
2429 | (You can also choose to use exceptions if you use C++; | ||
2430 | see file <code>luaconf.h</code>.) | ||
2431 | When Lua faces any error | ||
2432 | (such as memory allocation errors, type errors, syntax errors, | ||
2433 | and runtime errors) | ||
2434 | it <em>raises</em> an error; | ||
2435 | that is, it does a long jump. | ||
2436 | A <em>protected environment</em> uses <code>setjmp</code> | ||
2437 | to set a recover point; | ||
2438 | any error jumps to the most recent active recover point. | ||
2439 | |||
2440 | |||
2441 | <p> | ||
2442 | Most functions in the API can throw an error, | ||
2443 | for instance due to a memory allocation error. | ||
2444 | The documentation for each function indicates whether | ||
2445 | it can throw errors. | ||
2446 | |||
2447 | |||
2448 | <p> | ||
2449 | Inside a C function you can throw an error by calling <a href="#lua_error"><code>lua_error</code></a>. | ||
2450 | |||
2451 | |||
2452 | |||
2453 | |||
2454 | |||
2455 | <h2>3.7 - <a name="3.7">Functions and Types</a></h2> | ||
2456 | |||
2457 | <p> | ||
2458 | Here we list all functions and types from the C API in | ||
2459 | alphabetical order. | ||
2460 | Each function has an indicator like this: | ||
2461 | <span class="apii">[-o, +p, <em>x</em>]</span> | ||
2462 | |||
2463 | |||
2464 | <p> | ||
2465 | The first field, <code>o</code>, | ||
2466 | is how many elements the function pops from the stack. | ||
2467 | The second field, <code>p</code>, | ||
2468 | is how many elements the function pushes onto the stack. | ||
2469 | (Any function always pushes its results after popping its arguments.) | ||
2470 | A field in the form <code>x|y</code> means the function can push (or pop) | ||
2471 | <code>x</code> or <code>y</code> elements, | ||
2472 | depending on the situation; | ||
2473 | an interrogation mark '<code>?</code>' means that | ||
2474 | we cannot know how many elements the function pops/pushes | ||
2475 | by looking only at its arguments | ||
2476 | (e.g., they may depend on what is on the stack). | ||
2477 | The third field, <code>x</code>, | ||
2478 | tells whether the function may throw errors: | ||
2479 | '<code>-</code>' means the function never throws any error; | ||
2480 | '<code>m</code>' means the function may throw an error | ||
2481 | only due to not enough memory; | ||
2482 | '<code>e</code>' means the function may throw other kinds of errors; | ||
2483 | '<code>v</code>' means the function may throw an error on purpose. | ||
2484 | |||
2485 | |||
2486 | |||
2487 | <hr><h3><a name="lua_Alloc"><code>lua_Alloc</code></a></h3> | ||
2488 | <pre>typedef void * (*lua_Alloc) (void *ud, | ||
2489 | void *ptr, | ||
2490 | size_t osize, | ||
2491 | size_t nsize);</pre> | ||
2492 | |||
2493 | <p> | ||
2494 | The type of the memory-allocation function used by Lua states. | ||
2495 | The allocator function must provide a | ||
2496 | functionality similar to <code>realloc</code>, | ||
2497 | but not exactly the same. | ||
2498 | Its arguments are | ||
2499 | <code>ud</code>, an opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>; | ||
2500 | <code>ptr</code>, a pointer to the block being allocated/reallocated/freed; | ||
2501 | <code>osize</code>, the original size of the block; | ||
2502 | <code>nsize</code>, the new size of the block. | ||
2503 | <code>ptr</code> is <code>NULL</code> if and only if <code>osize</code> is zero. | ||
2504 | When <code>nsize</code> is zero, the allocator must return <code>NULL</code>; | ||
2505 | if <code>osize</code> is not zero, | ||
2506 | it should free the block pointed to by <code>ptr</code>. | ||
2507 | When <code>nsize</code> is not zero, the allocator returns <code>NULL</code> | ||
2508 | if and only if it cannot fill the request. | ||
2509 | When <code>nsize</code> is not zero and <code>osize</code> is zero, | ||
2510 | the allocator should behave like <code>malloc</code>. | ||
2511 | When <code>nsize</code> and <code>osize</code> are not zero, | ||
2512 | the allocator behaves like <code>realloc</code>. | ||
2513 | Lua assumes that the allocator never fails when | ||
2514 | <code>osize >= nsize</code>. | ||
2515 | |||
2516 | |||
2517 | <p> | ||
2518 | Here is a simple implementation for the allocator function. | ||
2519 | It is used in the auxiliary library by <a href="#luaL_newstate"><code>luaL_newstate</code></a>. | ||
2520 | |||
2521 | <pre> | ||
2522 | static void *l_alloc (void *ud, void *ptr, size_t osize, | ||
2523 | size_t nsize) { | ||
2524 | (void)ud; (void)osize; /* not used */ | ||
2525 | if (nsize == 0) { | ||
2526 | free(ptr); | ||
2527 | return NULL; | ||
2528 | } | ||
2529 | else | ||
2530 | return realloc(ptr, nsize); | ||
2531 | } | ||
2532 | </pre><p> | ||
2533 | This code assumes | ||
2534 | that <code>free(NULL)</code> has no effect and that | ||
2535 | <code>realloc(NULL, size)</code> is equivalent to <code>malloc(size)</code>. | ||
2536 | ANSI C ensures both behaviors. | ||
2537 | |||
2538 | |||
2539 | |||
2540 | |||
2541 | |||
2542 | <hr><h3><a name="lua_atpanic"><code>lua_atpanic</code></a></h3><p> | ||
2543 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
2544 | <pre>lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);</pre> | ||
2545 | |||
2546 | <p> | ||
2547 | Sets a new panic function and returns the old one. | ||
2548 | |||
2549 | |||
2550 | <p> | ||
2551 | If an error happens outside any protected environment, | ||
2552 | Lua calls a <em>panic function</em> | ||
2553 | and then calls <code>exit(EXIT_FAILURE)</code>, | ||
2554 | thus exiting the host application. | ||
2555 | Your panic function can avoid this exit by | ||
2556 | never returning (e.g., doing a long jump). | ||
2557 | |||
2558 | |||
2559 | <p> | ||
2560 | The panic function can access the error message at the top of the stack. | ||
2561 | |||
2562 | |||
2563 | |||
2564 | |||
2565 | |||
2566 | <hr><h3><a name="lua_call"><code>lua_call</code></a></h3><p> | ||
2567 | <span class="apii">[-(nargs + 1), +nresults, <em>e</em>]</span> | ||
2568 | <pre>void lua_call (lua_State *L, int nargs, int nresults);</pre> | ||
2569 | |||
2570 | <p> | ||
2571 | Calls a function. | ||
2572 | |||
2573 | |||
2574 | <p> | ||
2575 | To call a function you must use the following protocol: | ||
2576 | first, the function to be called is pushed onto the stack; | ||
2577 | then, the arguments to the function are pushed | ||
2578 | in direct order; | ||
2579 | that is, the first argument is pushed first. | ||
2580 | Finally you call <a href="#lua_call"><code>lua_call</code></a>; | ||
2581 | <code>nargs</code> is the number of arguments that you pushed onto the stack. | ||
2582 | All arguments and the function value are popped from the stack | ||
2583 | when the function is called. | ||
2584 | The function results are pushed onto the stack when the function returns. | ||
2585 | The number of results is adjusted to <code>nresults</code>, | ||
2586 | unless <code>nresults</code> is <a name="pdf-LUA_MULTRET"><code>LUA_MULTRET</code></a>. | ||
2587 | In this case, <em>all</em> results from the function are pushed. | ||
2588 | Lua takes care that the returned values fit into the stack space. | ||
2589 | The function results are pushed onto the stack in direct order | ||
2590 | (the first result is pushed first), | ||
2591 | so that after the call the last result is on the top of the stack. | ||
2592 | |||
2593 | |||
2594 | <p> | ||
2595 | Any error inside the called function is propagated upwards | ||
2596 | (with a <code>longjmp</code>). | ||
2597 | |||
2598 | |||
2599 | <p> | ||
2600 | The following example shows how the host program can do the | ||
2601 | equivalent to this Lua code: | ||
2602 | |||
2603 | <pre> | ||
2604 | a = f("how", t.x, 14) | ||
2605 | </pre><p> | ||
2606 | Here it is in C: | ||
2607 | |||
2608 | <pre> | ||
2609 | lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* function to be called */ | ||
2610 | lua_pushstring(L, "how"); /* 1st argument */ | ||
2611 | lua_getfield(L, LUA_GLOBALSINDEX, "t"); /* table to be indexed */ | ||
2612 | lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */ | ||
2613 | lua_remove(L, -2); /* remove 't' from the stack */ | ||
2614 | lua_pushinteger(L, 14); /* 3rd argument */ | ||
2615 | lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */ | ||
2616 | lua_setfield(L, LUA_GLOBALSINDEX, "a"); /* set global 'a' */ | ||
2617 | </pre><p> | ||
2618 | Note that the code above is "balanced": | ||
2619 | at its end, the stack is back to its original configuration. | ||
2620 | This is considered good programming practice. | ||
2621 | |||
2622 | |||
2623 | |||
2624 | |||
2625 | |||
2626 | <hr><h3><a name="lua_CFunction"><code>lua_CFunction</code></a></h3> | ||
2627 | <pre>typedef int (*lua_CFunction) (lua_State *L);</pre> | ||
2628 | |||
2629 | <p> | ||
2630 | Type for C functions. | ||
2631 | |||
2632 | |||
2633 | <p> | ||
2634 | In order to communicate properly with Lua, | ||
2635 | a C function must use the following protocol, | ||
2636 | which defines the way parameters and results are passed: | ||
2637 | a C function receives its arguments from Lua in its stack | ||
2638 | in direct order (the first argument is pushed first). | ||
2639 | So, when the function starts, | ||
2640 | <code>lua_gettop(L)</code> returns the number of arguments received by the function. | ||
2641 | The first argument (if any) is at index 1 | ||
2642 | and its last argument is at index <code>lua_gettop(L)</code>. | ||
2643 | To return values to Lua, a C function just pushes them onto the stack, | ||
2644 | in direct order (the first result is pushed first), | ||
2645 | and returns the number of results. | ||
2646 | Any other value in the stack below the results will be properly | ||
2647 | discarded by Lua. | ||
2648 | Like a Lua function, a C function called by Lua can also return | ||
2649 | many results. | ||
2650 | |||
2651 | |||
2652 | <p> | ||
2653 | As an example, the following function receives a variable number | ||
2654 | of numerical arguments and returns their average and sum: | ||
2655 | |||
2656 | <pre> | ||
2657 | static int foo (lua_State *L) { | ||
2658 | int n = lua_gettop(L); /* number of arguments */ | ||
2659 | lua_Number sum = 0; | ||
2660 | int i; | ||
2661 | for (i = 1; i <= n; i++) { | ||
2662 | if (!lua_isnumber(L, i)) { | ||
2663 | lua_pushstring(L, "incorrect argument"); | ||
2664 | lua_error(L); | ||
2665 | } | ||
2666 | sum += lua_tonumber(L, i); | ||
2667 | } | ||
2668 | lua_pushnumber(L, sum/n); /* first result */ | ||
2669 | lua_pushnumber(L, sum); /* second result */ | ||
2670 | return 2; /* number of results */ | ||
2671 | } | ||
2672 | </pre> | ||
2673 | |||
2674 | |||
2675 | |||
2676 | |||
2677 | <hr><h3><a name="lua_checkstack"><code>lua_checkstack</code></a></h3><p> | ||
2678 | <span class="apii">[-0, +0, <em>m</em>]</span> | ||
2679 | <pre>int lua_checkstack (lua_State *L, int extra);</pre> | ||
2680 | |||
2681 | <p> | ||
2682 | Ensures that there are at least <code>extra</code> free stack slots in the stack. | ||
2683 | It returns false if it cannot grow the stack to that size. | ||
2684 | This function never shrinks the stack; | ||
2685 | if the stack is already larger than the new size, | ||
2686 | it is left unchanged. | ||
2687 | |||
2688 | |||
2689 | |||
2690 | |||
2691 | |||
2692 | <hr><h3><a name="lua_close"><code>lua_close</code></a></h3><p> | ||
2693 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
2694 | <pre>void lua_close (lua_State *L);</pre> | ||
2695 | |||
2696 | <p> | ||
2697 | Destroys all objects in the given Lua state | ||
2698 | (calling the corresponding garbage-collection metamethods, if any) | ||
2699 | and frees all dynamic memory used by this state. | ||
2700 | On several platforms, you may not need to call this function, | ||
2701 | because all resources are naturally released when the host program ends. | ||
2702 | On the other hand, long-running programs, | ||
2703 | such as a daemon or a web server, | ||
2704 | might need to release states as soon as they are not needed, | ||
2705 | to avoid growing too large. | ||
2706 | |||
2707 | |||
2708 | |||
2709 | |||
2710 | |||
2711 | <hr><h3><a name="lua_concat"><code>lua_concat</code></a></h3><p> | ||
2712 | <span class="apii">[-n, +1, <em>e</em>]</span> | ||
2713 | <pre>void lua_concat (lua_State *L, int n);</pre> | ||
2714 | |||
2715 | <p> | ||
2716 | Concatenates the <code>n</code> values at the top of the stack, | ||
2717 | pops them, and leaves the result at the top. | ||
2718 | If <code>n</code> is 1, the result is the single value on the stack | ||
2719 | (that is, the function does nothing); | ||
2720 | if <code>n</code> is 0, the result is the empty string. | ||
2721 | Concatenation is performed following the usual semantics of Lua | ||
2722 | (see <a href="#2.5.4">§2.5.4</a>). | ||
2723 | |||
2724 | |||
2725 | |||
2726 | |||
2727 | |||
2728 | <hr><h3><a name="lua_cpcall"><code>lua_cpcall</code></a></h3><p> | ||
2729 | <span class="apii">[-0, +(0|1), <em>-</em>]</span> | ||
2730 | <pre>int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);</pre> | ||
2731 | |||
2732 | <p> | ||
2733 | Calls the C function <code>func</code> in protected mode. | ||
2734 | <code>func</code> starts with only one element in its stack, | ||
2735 | a light userdata containing <code>ud</code>. | ||
2736 | In case of errors, | ||
2737 | <a href="#lua_cpcall"><code>lua_cpcall</code></a> returns the same error codes as <a href="#lua_pcall"><code>lua_pcall</code></a>, | ||
2738 | plus the error object on the top of the stack; | ||
2739 | otherwise, it returns zero, and does not change the stack. | ||
2740 | All values returned by <code>func</code> are discarded. | ||
2741 | |||
2742 | |||
2743 | |||
2744 | |||
2745 | |||
2746 | <hr><h3><a name="lua_createtable"><code>lua_createtable</code></a></h3><p> | ||
2747 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
2748 | <pre>void lua_createtable (lua_State *L, int narr, int nrec);</pre> | ||
2749 | |||
2750 | <p> | ||
2751 | Creates a new empty table and pushes it onto the stack. | ||
2752 | The new table has space pre-allocated | ||
2753 | for <code>narr</code> array elements and <code>nrec</code> non-array elements. | ||
2754 | This pre-allocation is useful when you know exactly how many elements | ||
2755 | the table will have. | ||
2756 | Otherwise you can use the function <a href="#lua_newtable"><code>lua_newtable</code></a>. | ||
2757 | |||
2758 | |||
2759 | |||
2760 | |||
2761 | |||
2762 | <hr><h3><a name="lua_dump"><code>lua_dump</code></a></h3><p> | ||
2763 | <span class="apii">[-0, +0, <em>m</em>]</span> | ||
2764 | <pre>int lua_dump (lua_State *L, lua_Writer writer, void *data);</pre> | ||
2765 | |||
2766 | <p> | ||
2767 | Dumps a function as a binary chunk. | ||
2768 | Receives a Lua function on the top of the stack | ||
2769 | and produces a binary chunk that, | ||
2770 | if loaded again, | ||
2771 | results in a function equivalent to the one dumped. | ||
2772 | As it produces parts of the chunk, | ||
2773 | <a href="#lua_dump"><code>lua_dump</code></a> calls function <code>writer</code> (see <a href="#lua_Writer"><code>lua_Writer</code></a>) | ||
2774 | with the given <code>data</code> | ||
2775 | to write them. | ||
2776 | |||
2777 | |||
2778 | <p> | ||
2779 | The value returned is the error code returned by the last | ||
2780 | call to the writer; | ||
2781 | 0 means no errors. | ||
2782 | |||
2783 | |||
2784 | <p> | ||
2785 | This function does not pop the Lua function from the stack. | ||
2786 | |||
2787 | |||
2788 | |||
2789 | |||
2790 | |||
2791 | <hr><h3><a name="lua_equal"><code>lua_equal</code></a></h3><p> | ||
2792 | <span class="apii">[-0, +0, <em>e</em>]</span> | ||
2793 | <pre>int lua_equal (lua_State *L, int index1, int index2);</pre> | ||
2794 | |||
2795 | <p> | ||
2796 | Returns 1 if the two values in acceptable indices <code>index1</code> and | ||
2797 | <code>index2</code> are equal, | ||
2798 | following the semantics of the Lua <code>==</code> operator | ||
2799 | (that is, may call metamethods). | ||
2800 | Otherwise returns 0. | ||
2801 | Also returns 0 if any of the indices is non valid. | ||
2802 | |||
2803 | |||
2804 | |||
2805 | |||
2806 | |||
2807 | <hr><h3><a name="lua_error"><code>lua_error</code></a></h3><p> | ||
2808 | <span class="apii">[-1, +0, <em>v</em>]</span> | ||
2809 | <pre>int lua_error (lua_State *L);</pre> | ||
2810 | |||
2811 | <p> | ||
2812 | Generates a Lua error. | ||
2813 | The error message (which can actually be a Lua value of any type) | ||
2814 | must be on the stack top. | ||
2815 | This function does a long jump, | ||
2816 | and therefore never returns. | ||
2817 | (see <a href="#luaL_error"><code>luaL_error</code></a>). | ||
2818 | |||
2819 | |||
2820 | |||
2821 | |||
2822 | |||
2823 | <hr><h3><a name="lua_gc"><code>lua_gc</code></a></h3><p> | ||
2824 | <span class="apii">[-0, +0, <em>e</em>]</span> | ||
2825 | <pre>int lua_gc (lua_State *L, int what, int data);</pre> | ||
2826 | |||
2827 | <p> | ||
2828 | Controls the garbage collector. | ||
2829 | |||
2830 | |||
2831 | <p> | ||
2832 | This function performs several tasks, | ||
2833 | according to the value of the parameter <code>what</code>: | ||
2834 | |||
2835 | <ul> | ||
2836 | |||
2837 | <li><b><code>LUA_GCSTOP</code>:</b> | ||
2838 | stops the garbage collector. | ||
2839 | </li> | ||
2840 | |||
2841 | <li><b><code>LUA_GCRESTART</code>:</b> | ||
2842 | restarts the garbage collector. | ||
2843 | </li> | ||
2844 | |||
2845 | <li><b><code>LUA_GCCOLLECT</code>:</b> | ||
2846 | performs a full garbage-collection cycle. | ||
2847 | </li> | ||
2848 | |||
2849 | <li><b><code>LUA_GCCOUNT</code>:</b> | ||
2850 | returns the current amount of memory (in Kbytes) in use by Lua. | ||
2851 | </li> | ||
2852 | |||
2853 | <li><b><code>LUA_GCCOUNTB</code>:</b> | ||
2854 | returns the remainder of dividing the current amount of bytes of | ||
2855 | memory in use by Lua by 1024. | ||
2856 | </li> | ||
2857 | |||
2858 | <li><b><code>LUA_GCSTEP</code>:</b> | ||
2859 | performs an incremental step of garbage collection. | ||
2860 | The step "size" is controlled by <code>data</code> | ||
2861 | (larger values mean more steps) in a non-specified way. | ||
2862 | If you want to control the step size | ||
2863 | you must experimentally tune the value of <code>data</code>. | ||
2864 | The function returns 1 if the step finished a | ||
2865 | garbage-collection cycle. | ||
2866 | </li> | ||
2867 | |||
2868 | <li><b><code>LUA_GCSETPAUSE</code>:</b> | ||
2869 | sets <code>data</code> as the new value | ||
2870 | for the <em>pause</em> of the collector (see <a href="#2.10">§2.10</a>). | ||
2871 | The function returns the previous value of the pause. | ||
2872 | </li> | ||
2873 | |||
2874 | <li><b><code>LUA_GCSETSTEPMUL</code>:</b> | ||
2875 | sets <code>data</code> as the new value for the <em>step multiplier</em> of | ||
2876 | the collector (see <a href="#2.10">§2.10</a>). | ||
2877 | The function returns the previous value of the step multiplier. | ||
2878 | </li> | ||
2879 | |||
2880 | </ul> | ||
2881 | |||
2882 | |||
2883 | |||
2884 | |||
2885 | <hr><h3><a name="lua_getallocf"><code>lua_getallocf</code></a></h3><p> | ||
2886 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
2887 | <pre>lua_Alloc lua_getallocf (lua_State *L, void **ud);</pre> | ||
2888 | |||
2889 | <p> | ||
2890 | Returns the memory-allocation function of a given state. | ||
2891 | If <code>ud</code> is not <code>NULL</code>, Lua stores in <code>*ud</code> the | ||
2892 | opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>. | ||
2893 | |||
2894 | |||
2895 | |||
2896 | |||
2897 | |||
2898 | <hr><h3><a name="lua_getfenv"><code>lua_getfenv</code></a></h3><p> | ||
2899 | <span class="apii">[-0, +1, <em>-</em>]</span> | ||
2900 | <pre>void lua_getfenv (lua_State *L, int index);</pre> | ||
2901 | |||
2902 | <p> | ||
2903 | Pushes onto the stack the environment table of | ||
2904 | the value at the given index. | ||
2905 | |||
2906 | |||
2907 | |||
2908 | |||
2909 | |||
2910 | <hr><h3><a name="lua_getfield"><code>lua_getfield</code></a></h3><p> | ||
2911 | <span class="apii">[-0, +1, <em>e</em>]</span> | ||
2912 | <pre>void lua_getfield (lua_State *L, int index, const char *k);</pre> | ||
2913 | |||
2914 | <p> | ||
2915 | Pushes onto the stack the value <code>t[k]</code>, | ||
2916 | where <code>t</code> is the value at the given valid index. | ||
2917 | As in Lua, this function may trigger a metamethod | ||
2918 | for the "index" event (see <a href="#2.8">§2.8</a>). | ||
2919 | |||
2920 | |||
2921 | |||
2922 | |||
2923 | |||
2924 | <hr><h3><a name="lua_getglobal"><code>lua_getglobal</code></a></h3><p> | ||
2925 | <span class="apii">[-0, +1, <em>e</em>]</span> | ||
2926 | <pre>void lua_getglobal (lua_State *L, const char *name);</pre> | ||
2927 | |||
2928 | <p> | ||
2929 | Pushes onto the stack the value of the global <code>name</code>. | ||
2930 | It is defined as a macro: | ||
2931 | |||
2932 | <pre> | ||
2933 | #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s) | ||
2934 | </pre> | ||
2935 | |||
2936 | |||
2937 | |||
2938 | |||
2939 | <hr><h3><a name="lua_getmetatable"><code>lua_getmetatable</code></a></h3><p> | ||
2940 | <span class="apii">[-0, +(0|1), <em>-</em>]</span> | ||
2941 | <pre>int lua_getmetatable (lua_State *L, int index);</pre> | ||
2942 | |||
2943 | <p> | ||
2944 | Pushes onto the stack the metatable of the value at the given | ||
2945 | acceptable index. | ||
2946 | If the index is not valid, | ||
2947 | or if the value does not have a metatable, | ||
2948 | the function returns 0 and pushes nothing on the stack. | ||
2949 | |||
2950 | |||
2951 | |||
2952 | |||
2953 | |||
2954 | <hr><h3><a name="lua_gettable"><code>lua_gettable</code></a></h3><p> | ||
2955 | <span class="apii">[-1, +1, <em>e</em>]</span> | ||
2956 | <pre>void lua_gettable (lua_State *L, int index);</pre> | ||
2957 | |||
2958 | <p> | ||
2959 | Pushes onto the stack the value <code>t[k]</code>, | ||
2960 | where <code>t</code> is the value at the given valid index | ||
2961 | and <code>k</code> is the value at the top of the stack. | ||
2962 | |||
2963 | |||
2964 | <p> | ||
2965 | This function pops the key from the stack | ||
2966 | (putting the resulting value in its place). | ||
2967 | As in Lua, this function may trigger a metamethod | ||
2968 | for the "index" event (see <a href="#2.8">§2.8</a>). | ||
2969 | |||
2970 | |||
2971 | |||
2972 | |||
2973 | |||
2974 | <hr><h3><a name="lua_gettop"><code>lua_gettop</code></a></h3><p> | ||
2975 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
2976 | <pre>int lua_gettop (lua_State *L);</pre> | ||
2977 | |||
2978 | <p> | ||
2979 | Returns the index of the top element in the stack. | ||
2980 | Because indices start at 1, | ||
2981 | this result is equal to the number of elements in the stack | ||
2982 | (and so 0 means an empty stack). | ||
2983 | |||
2984 | |||
2985 | |||
2986 | |||
2987 | |||
2988 | <hr><h3><a name="lua_insert"><code>lua_insert</code></a></h3><p> | ||
2989 | <span class="apii">[-1, +1, <em>-</em>]</span> | ||
2990 | <pre>void lua_insert (lua_State *L, int index);</pre> | ||
2991 | |||
2992 | <p> | ||
2993 | Moves the top element into the given valid index, | ||
2994 | shifting up the elements above this index to open space. | ||
2995 | Cannot be called with a pseudo-index, | ||
2996 | because a pseudo-index is not an actual stack position. | ||
2997 | |||
2998 | |||
2999 | |||
3000 | |||
3001 | |||
3002 | <hr><h3><a name="lua_Integer"><code>lua_Integer</code></a></h3> | ||
3003 | <pre>typedef ptrdiff_t lua_Integer;</pre> | ||
3004 | |||
3005 | <p> | ||
3006 | The type used by the Lua API to represent integral values. | ||
3007 | |||
3008 | |||
3009 | <p> | ||
3010 | By default it is a <code>ptrdiff_t</code>, | ||
3011 | which is usually the largest signed integral type the machine handles | ||
3012 | "comfortably". | ||
3013 | |||
3014 | |||
3015 | |||
3016 | |||
3017 | |||
3018 | <hr><h3><a name="lua_isboolean"><code>lua_isboolean</code></a></h3><p> | ||
3019 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3020 | <pre>int lua_isboolean (lua_State *L, int index);</pre> | ||
3021 | |||
3022 | <p> | ||
3023 | Returns 1 if the value at the given acceptable index has type boolean, | ||
3024 | and 0 otherwise. | ||
3025 | |||
3026 | |||
3027 | |||
3028 | |||
3029 | |||
3030 | <hr><h3><a name="lua_iscfunction"><code>lua_iscfunction</code></a></h3><p> | ||
3031 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3032 | <pre>int lua_iscfunction (lua_State *L, int index);</pre> | ||
3033 | |||
3034 | <p> | ||
3035 | Returns 1 if the value at the given acceptable index is a C function, | ||
3036 | and 0 otherwise. | ||
3037 | |||
3038 | |||
3039 | |||
3040 | |||
3041 | |||
3042 | <hr><h3><a name="lua_isfunction"><code>lua_isfunction</code></a></h3><p> | ||
3043 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3044 | <pre>int lua_isfunction (lua_State *L, int index);</pre> | ||
3045 | |||
3046 | <p> | ||
3047 | Returns 1 if the value at the given acceptable index is a function | ||
3048 | (either C or Lua), and 0 otherwise. | ||
3049 | |||
3050 | |||
3051 | |||
3052 | |||
3053 | |||
3054 | <hr><h3><a name="lua_islightuserdata"><code>lua_islightuserdata</code></a></h3><p> | ||
3055 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3056 | <pre>int lua_islightuserdata (lua_State *L, int index);</pre> | ||
3057 | |||
3058 | <p> | ||
3059 | Returns 1 if the value at the given acceptable index is a light userdata, | ||
3060 | and 0 otherwise. | ||
3061 | |||
3062 | |||
3063 | |||
3064 | |||
3065 | |||
3066 | <hr><h3><a name="lua_isnil"><code>lua_isnil</code></a></h3><p> | ||
3067 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3068 | <pre>int lua_isnil (lua_State *L, int index);</pre> | ||
3069 | |||
3070 | <p> | ||
3071 | Returns 1 if the value at the given acceptable index is <b>nil</b>, | ||
3072 | and 0 otherwise. | ||
3073 | |||
3074 | |||
3075 | |||
3076 | |||
3077 | |||
3078 | <hr><h3><a name="lua_isnone"><code>lua_isnone</code></a></h3><p> | ||
3079 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3080 | <pre>int lua_isnone (lua_State *L, int index);</pre> | ||
3081 | |||
3082 | <p> | ||
3083 | Returns 1 if the given acceptable index is not valid | ||
3084 | (that is, it refers to an element outside the current stack), | ||
3085 | and 0 otherwise. | ||
3086 | |||
3087 | |||
3088 | |||
3089 | |||
3090 | |||
3091 | <hr><h3><a name="lua_isnoneornil"><code>lua_isnoneornil</code></a></h3><p> | ||
3092 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3093 | <pre>int lua_isnoneornil (lua_State *L, int index);</pre> | ||
3094 | |||
3095 | <p> | ||
3096 | Returns 1 if the given acceptable index is not valid | ||
3097 | (that is, it refers to an element outside the current stack) | ||
3098 | or if the value at this index is <b>nil</b>, | ||
3099 | and 0 otherwise. | ||
3100 | |||
3101 | |||
3102 | |||
3103 | |||
3104 | |||
3105 | <hr><h3><a name="lua_isnumber"><code>lua_isnumber</code></a></h3><p> | ||
3106 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3107 | <pre>int lua_isnumber (lua_State *L, int index);</pre> | ||
3108 | |||
3109 | <p> | ||
3110 | Returns 1 if the value at the given acceptable index is a number | ||
3111 | or a string convertible to a number, | ||
3112 | and 0 otherwise. | ||
3113 | |||
3114 | |||
3115 | |||
3116 | |||
3117 | |||
3118 | <hr><h3><a name="lua_isstring"><code>lua_isstring</code></a></h3><p> | ||
3119 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3120 | <pre>int lua_isstring (lua_State *L, int index);</pre> | ||
3121 | |||
3122 | <p> | ||
3123 | Returns 1 if the value at the given acceptable index is a string | ||
3124 | or a number (which is always convertible to a string), | ||
3125 | and 0 otherwise. | ||
3126 | |||
3127 | |||
3128 | |||
3129 | |||
3130 | |||
3131 | <hr><h3><a name="lua_istable"><code>lua_istable</code></a></h3><p> | ||
3132 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3133 | <pre>int lua_istable (lua_State *L, int index);</pre> | ||
3134 | |||
3135 | <p> | ||
3136 | Returns 1 if the value at the given acceptable index is a table, | ||
3137 | and 0 otherwise. | ||
3138 | |||
3139 | |||
3140 | |||
3141 | |||
3142 | |||
3143 | <hr><h3><a name="lua_isthread"><code>lua_isthread</code></a></h3><p> | ||
3144 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3145 | <pre>int lua_isthread (lua_State *L, int index);</pre> | ||
3146 | |||
3147 | <p> | ||
3148 | Returns 1 if the value at the given acceptable index is a thread, | ||
3149 | and 0 otherwise. | ||
3150 | |||
3151 | |||
3152 | |||
3153 | |||
3154 | |||
3155 | <hr><h3><a name="lua_isuserdata"><code>lua_isuserdata</code></a></h3><p> | ||
3156 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3157 | <pre>int lua_isuserdata (lua_State *L, int index);</pre> | ||
3158 | |||
3159 | <p> | ||
3160 | Returns 1 if the value at the given acceptable index is a userdata | ||
3161 | (either full or light), and 0 otherwise. | ||
3162 | |||
3163 | |||
3164 | |||
3165 | |||
3166 | |||
3167 | <hr><h3><a name="lua_lessthan"><code>lua_lessthan</code></a></h3><p> | ||
3168 | <span class="apii">[-0, +0, <em>e</em>]</span> | ||
3169 | <pre>int lua_lessthan (lua_State *L, int index1, int index2);</pre> | ||
3170 | |||
3171 | <p> | ||
3172 | Returns 1 if the value at acceptable index <code>index1</code> is smaller | ||
3173 | than the value at acceptable index <code>index2</code>, | ||
3174 | following the semantics of the Lua <code><</code> operator | ||
3175 | (that is, may call metamethods). | ||
3176 | Otherwise returns 0. | ||
3177 | Also returns 0 if any of the indices is non valid. | ||
3178 | |||
3179 | |||
3180 | |||
3181 | |||
3182 | |||
3183 | <hr><h3><a name="lua_load"><code>lua_load</code></a></h3><p> | ||
3184 | <span class="apii">[-0, +1, <em>-</em>]</span> | ||
3185 | <pre>int lua_load (lua_State *L, | ||
3186 | lua_Reader reader, | ||
3187 | void *data, | ||
3188 | const char *chunkname);</pre> | ||
3189 | |||
3190 | <p> | ||
3191 | Loads a Lua chunk. | ||
3192 | If there are no errors, | ||
3193 | <a href="#lua_load"><code>lua_load</code></a> pushes the compiled chunk as a Lua | ||
3194 | function on top of the stack. | ||
3195 | Otherwise, it pushes an error message. | ||
3196 | The return values of <a href="#lua_load"><code>lua_load</code></a> are: | ||
3197 | |||
3198 | <ul> | ||
3199 | |||
3200 | <li><b>0:</b> no errors;</li> | ||
3201 | |||
3202 | <li><b><a name="pdf-LUA_ERRSYNTAX"><code>LUA_ERRSYNTAX</code></a>:</b> | ||
3203 | syntax error during pre-compilation;</li> | ||
3204 | |||
3205 | <li><b><a href="#pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>:</b> | ||
3206 | memory allocation error.</li> | ||
3207 | |||
3208 | </ul> | ||
3209 | |||
3210 | <p> | ||
3211 | This function only loads a chunk; | ||
3212 | it does not run it. | ||
3213 | |||
3214 | |||
3215 | <p> | ||
3216 | <a href="#lua_load"><code>lua_load</code></a> automatically detects whether the chunk is text or binary, | ||
3217 | and loads it accordingly (see program <code>luac</code>). | ||
3218 | |||
3219 | |||
3220 | <p> | ||
3221 | The <a href="#lua_load"><code>lua_load</code></a> function uses a user-supplied <code>reader</code> function | ||
3222 | to read the chunk (see <a href="#lua_Reader"><code>lua_Reader</code></a>). | ||
3223 | The <code>data</code> argument is an opaque value passed to the reader function. | ||
3224 | |||
3225 | |||
3226 | <p> | ||
3227 | The <code>chunkname</code> argument gives a name to the chunk, | ||
3228 | which is used for error messages and in debug information (see <a href="#3.8">§3.8</a>). | ||
3229 | |||
3230 | |||
3231 | |||
3232 | |||
3233 | |||
3234 | <hr><h3><a name="lua_newstate"><code>lua_newstate</code></a></h3><p> | ||
3235 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3236 | <pre>lua_State *lua_newstate (lua_Alloc f, void *ud);</pre> | ||
3237 | |||
3238 | <p> | ||
3239 | Creates a new, independent state. | ||
3240 | Returns <code>NULL</code> if cannot create the state | ||
3241 | (due to lack of memory). | ||
3242 | The argument <code>f</code> is the allocator function; | ||
3243 | Lua does all memory allocation for this state through this function. | ||
3244 | The second argument, <code>ud</code>, is an opaque pointer that Lua | ||
3245 | simply passes to the allocator in every call. | ||
3246 | |||
3247 | |||
3248 | |||
3249 | |||
3250 | |||
3251 | <hr><h3><a name="lua_newtable"><code>lua_newtable</code></a></h3><p> | ||
3252 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
3253 | <pre>void lua_newtable (lua_State *L);</pre> | ||
3254 | |||
3255 | <p> | ||
3256 | Creates a new empty table and pushes it onto the stack. | ||
3257 | It is equivalent to <code>lua_createtable(L, 0, 0)</code>. | ||
3258 | |||
3259 | |||
3260 | |||
3261 | |||
3262 | |||
3263 | <hr><h3><a name="lua_newthread"><code>lua_newthread</code></a></h3><p> | ||
3264 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
3265 | <pre>lua_State *lua_newthread (lua_State *L);</pre> | ||
3266 | |||
3267 | <p> | ||
3268 | Creates a new thread, pushes it on the stack, | ||
3269 | and returns a pointer to a <a href="#lua_State"><code>lua_State</code></a> that represents this new thread. | ||
3270 | The new state returned by this function shares with the original state | ||
3271 | all global objects (such as tables), | ||
3272 | but has an independent execution stack. | ||
3273 | |||
3274 | |||
3275 | <p> | ||
3276 | There is no explicit function to close or to destroy a thread. | ||
3277 | Threads are subject to garbage collection, | ||
3278 | like any Lua object. | ||
3279 | |||
3280 | |||
3281 | |||
3282 | |||
3283 | |||
3284 | <hr><h3><a name="lua_newuserdata"><code>lua_newuserdata</code></a></h3><p> | ||
3285 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
3286 | <pre>void *lua_newuserdata (lua_State *L, size_t size);</pre> | ||
3287 | |||
3288 | <p> | ||
3289 | This function allocates a new block of memory with the given size, | ||
3290 | pushes onto the stack a new full userdata with the block address, | ||
3291 | and returns this address. | ||
3292 | |||
3293 | |||
3294 | <p> | ||
3295 | Userdata represent C values in Lua. | ||
3296 | A <em>full userdata</em> represents a block of memory. | ||
3297 | It is an object (like a table): | ||
3298 | you must create it, it can have its own metatable, | ||
3299 | and you can detect when it is being collected. | ||
3300 | A full userdata is only equal to itself (under raw equality). | ||
3301 | |||
3302 | |||
3303 | <p> | ||
3304 | When Lua collects a full userdata with a <code>gc</code> metamethod, | ||
3305 | Lua calls the metamethod and marks the userdata as finalized. | ||
3306 | When this userdata is collected again then | ||
3307 | Lua frees its corresponding memory. | ||
3308 | |||
3309 | |||
3310 | |||
3311 | |||
3312 | |||
3313 | <hr><h3><a name="lua_next"><code>lua_next</code></a></h3><p> | ||
3314 | <span class="apii">[-1, +(2|0), <em>e</em>]</span> | ||
3315 | <pre>int lua_next (lua_State *L, int index);</pre> | ||
3316 | |||
3317 | <p> | ||
3318 | Pops a key from the stack, | ||
3319 | and pushes a key-value pair from the table at the given index | ||
3320 | (the "next" pair after the given key). | ||
3321 | If there are no more elements in the table, | ||
3322 | then <a href="#lua_next"><code>lua_next</code></a> returns 0 (and pushes nothing). | ||
3323 | |||
3324 | |||
3325 | <p> | ||
3326 | A typical traversal looks like this: | ||
3327 | |||
3328 | <pre> | ||
3329 | /* table is in the stack at index 't' */ | ||
3330 | lua_pushnil(L); /* first key */ | ||
3331 | while (lua_next(L, t) != 0) { | ||
3332 | /* uses 'key' (at index -2) and 'value' (at index -1) */ | ||
3333 | printf("%s - %s\n", | ||
3334 | lua_typename(L, lua_type(L, -2)), | ||
3335 | lua_typename(L, lua_type(L, -1))); | ||
3336 | /* removes 'value'; keeps 'key' for next iteration */ | ||
3337 | lua_pop(L, 1); | ||
3338 | } | ||
3339 | </pre> | ||
3340 | |||
3341 | <p> | ||
3342 | While traversing a table, | ||
3343 | do not call <a href="#lua_tolstring"><code>lua_tolstring</code></a> directly on a key, | ||
3344 | unless you know that the key is actually a string. | ||
3345 | Recall that <a href="#lua_tolstring"><code>lua_tolstring</code></a> <em>changes</em> | ||
3346 | the value at the given index; | ||
3347 | this confuses the next call to <a href="#lua_next"><code>lua_next</code></a>. | ||
3348 | |||
3349 | |||
3350 | |||
3351 | |||
3352 | |||
3353 | <hr><h3><a name="lua_Number"><code>lua_Number</code></a></h3> | ||
3354 | <pre>typedef double lua_Number;</pre> | ||
3355 | |||
3356 | <p> | ||
3357 | The type of numbers in Lua. | ||
3358 | By default, it is double, but that can be changed in <code>luaconf.h</code>. | ||
3359 | |||
3360 | |||
3361 | <p> | ||
3362 | Through the configuration file you can change | ||
3363 | Lua to operate with another type for numbers (e.g., float or long). | ||
3364 | |||
3365 | |||
3366 | |||
3367 | |||
3368 | |||
3369 | <hr><h3><a name="lua_objlen"><code>lua_objlen</code></a></h3><p> | ||
3370 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3371 | <pre>size_t lua_objlen (lua_State *L, int index);</pre> | ||
3372 | |||
3373 | <p> | ||
3374 | Returns the "length" of the value at the given acceptable index: | ||
3375 | for strings, this is the string length; | ||
3376 | for tables, this is the result of the length operator ('<code>#</code>'); | ||
3377 | for userdata, this is the size of the block of memory allocated | ||
3378 | for the userdata; | ||
3379 | for other values, it is 0. | ||
3380 | |||
3381 | |||
3382 | |||
3383 | |||
3384 | |||
3385 | <hr><h3><a name="lua_pcall"><code>lua_pcall</code></a></h3><p> | ||
3386 | <span class="apii">[-(nargs + 1), +(nresults|1), <em>-</em>]</span> | ||
3387 | <pre>int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);</pre> | ||
3388 | |||
3389 | <p> | ||
3390 | Calls a function in protected mode. | ||
3391 | |||
3392 | |||
3393 | <p> | ||
3394 | Both <code>nargs</code> and <code>nresults</code> have the same meaning as | ||
3395 | in <a href="#lua_call"><code>lua_call</code></a>. | ||
3396 | If there are no errors during the call, | ||
3397 | <a href="#lua_pcall"><code>lua_pcall</code></a> behaves exactly like <a href="#lua_call"><code>lua_call</code></a>. | ||
3398 | However, if there is any error, | ||
3399 | <a href="#lua_pcall"><code>lua_pcall</code></a> catches it, | ||
3400 | pushes a single value on the stack (the error message), | ||
3401 | and returns an error code. | ||
3402 | Like <a href="#lua_call"><code>lua_call</code></a>, | ||
3403 | <a href="#lua_pcall"><code>lua_pcall</code></a> always removes the function | ||
3404 | and its arguments from the stack. | ||
3405 | |||
3406 | |||
3407 | <p> | ||
3408 | If <code>errfunc</code> is 0, | ||
3409 | then the error message returned on the stack | ||
3410 | is exactly the original error message. | ||
3411 | Otherwise, <code>errfunc</code> is the stack index of an | ||
3412 | <em>error handler function</em>. | ||
3413 | (In the current implementation, this index cannot be a pseudo-index.) | ||
3414 | In case of runtime errors, | ||
3415 | this function will be called with the error message | ||
3416 | and its return value will be the message returned on the stack by <a href="#lua_pcall"><code>lua_pcall</code></a>. | ||
3417 | |||
3418 | |||
3419 | <p> | ||
3420 | Typically, the error handler function is used to add more debug | ||
3421 | information to the error message, such as a stack traceback. | ||
3422 | Such information cannot be gathered after the return of <a href="#lua_pcall"><code>lua_pcall</code></a>, | ||
3423 | since by then the stack has unwound. | ||
3424 | |||
3425 | |||
3426 | <p> | ||
3427 | The <a href="#lua_pcall"><code>lua_pcall</code></a> function returns 0 in case of success | ||
3428 | or one of the following error codes | ||
3429 | (defined in <code>lua.h</code>): | ||
3430 | |||
3431 | <ul> | ||
3432 | |||
3433 | <li><b><a name="pdf-LUA_ERRRUN"><code>LUA_ERRRUN</code></a>:</b> | ||
3434 | a runtime error. | ||
3435 | </li> | ||
3436 | |||
3437 | <li><b><a name="pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>:</b> | ||
3438 | memory allocation error. | ||
3439 | For such errors, Lua does not call the error handler function. | ||
3440 | </li> | ||
3441 | |||
3442 | <li><b><a name="pdf-LUA_ERRERR"><code>LUA_ERRERR</code></a>:</b> | ||
3443 | error while running the error handler function. | ||
3444 | </li> | ||
3445 | |||
3446 | </ul> | ||
3447 | |||
3448 | |||
3449 | |||
3450 | |||
3451 | <hr><h3><a name="lua_pop"><code>lua_pop</code></a></h3><p> | ||
3452 | <span class="apii">[-n, +0, <em>-</em>]</span> | ||
3453 | <pre>void lua_pop (lua_State *L, int n);</pre> | ||
3454 | |||
3455 | <p> | ||
3456 | Pops <code>n</code> elements from the stack. | ||
3457 | |||
3458 | |||
3459 | |||
3460 | |||
3461 | |||
3462 | <hr><h3><a name="lua_pushboolean"><code>lua_pushboolean</code></a></h3><p> | ||
3463 | <span class="apii">[-0, +1, <em>-</em>]</span> | ||
3464 | <pre>void lua_pushboolean (lua_State *L, int b);</pre> | ||
3465 | |||
3466 | <p> | ||
3467 | Pushes a boolean value with value <code>b</code> onto the stack. | ||
3468 | |||
3469 | |||
3470 | |||
3471 | |||
3472 | |||
3473 | <hr><h3><a name="lua_pushcclosure"><code>lua_pushcclosure</code></a></h3><p> | ||
3474 | <span class="apii">[-n, +1, <em>m</em>]</span> | ||
3475 | <pre>void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);</pre> | ||
3476 | |||
3477 | <p> | ||
3478 | Pushes a new C closure onto the stack. | ||
3479 | |||
3480 | |||
3481 | <p> | ||
3482 | When a C function is created, | ||
3483 | it is possible to associate some values with it, | ||
3484 | thus creating a C closure (see <a href="#3.4">§3.4</a>); | ||
3485 | these values are then accessible to the function whenever it is called. | ||
3486 | To associate values with a C function, | ||
3487 | first these values should be pushed onto the stack | ||
3488 | (when there are multiple values, the first value is pushed first). | ||
3489 | Then <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a> | ||
3490 | is called to create and push the C function onto the stack, | ||
3491 | with the argument <code>n</code> telling how many values should be | ||
3492 | associated with the function. | ||
3493 | <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a> also pops these values from the stack. | ||
3494 | |||
3495 | |||
3496 | <p> | ||
3497 | The maximum value for <code>n</code> is 255. | ||
3498 | |||
3499 | |||
3500 | |||
3501 | |||
3502 | |||
3503 | <hr><h3><a name="lua_pushcfunction"><code>lua_pushcfunction</code></a></h3><p> | ||
3504 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
3505 | <pre>void lua_pushcfunction (lua_State *L, lua_CFunction f);</pre> | ||
3506 | |||
3507 | <p> | ||
3508 | Pushes a C function onto the stack. | ||
3509 | This function receives a pointer to a C function | ||
3510 | and pushes onto the stack a Lua value of type <code>function</code> that, | ||
3511 | when called, invokes the corresponding C function. | ||
3512 | |||
3513 | |||
3514 | <p> | ||
3515 | Any function to be registered in Lua must | ||
3516 | follow the correct protocol to receive its parameters | ||
3517 | and return its results (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>). | ||
3518 | |||
3519 | |||
3520 | <p> | ||
3521 | <code>lua_pushcfunction</code> is defined as a macro: | ||
3522 | |||
3523 | <pre> | ||
3524 | #define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0) | ||
3525 | </pre> | ||
3526 | |||
3527 | |||
3528 | |||
3529 | |||
3530 | <hr><h3><a name="lua_pushfstring"><code>lua_pushfstring</code></a></h3><p> | ||
3531 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
3532 | <pre>const char *lua_pushfstring (lua_State *L, const char *fmt, ...);</pre> | ||
3533 | |||
3534 | <p> | ||
3535 | Pushes onto the stack a formatted string | ||
3536 | and returns a pointer to this string. | ||
3537 | It is similar to the C function <code>sprintf</code>, | ||
3538 | but has some important differences: | ||
3539 | |||
3540 | <ul> | ||
3541 | |||
3542 | <li> | ||
3543 | You do not have to allocate space for the result: | ||
3544 | the result is a Lua string and Lua takes care of memory allocation | ||
3545 | (and deallocation, through garbage collection). | ||
3546 | </li> | ||
3547 | |||
3548 | <li> | ||
3549 | The conversion specifiers are quite restricted. | ||
3550 | There are no flags, widths, or precisions. | ||
3551 | The conversion specifiers can only be | ||
3552 | '<code>%%</code>' (inserts a '<code>%</code>' in the string), | ||
3553 | '<code>%s</code>' (inserts a zero-terminated string, with no size restrictions), | ||
3554 | '<code>%f</code>' (inserts a <a href="#lua_Number"><code>lua_Number</code></a>), | ||
3555 | '<code>%p</code>' (inserts a pointer as a hexadecimal numeral), | ||
3556 | '<code>%d</code>' (inserts an <code>int</code>), and | ||
3557 | '<code>%c</code>' (inserts an <code>int</code> as a character). | ||
3558 | </li> | ||
3559 | |||
3560 | </ul> | ||
3561 | |||
3562 | |||
3563 | |||
3564 | |||
3565 | <hr><h3><a name="lua_pushinteger"><code>lua_pushinteger</code></a></h3><p> | ||
3566 | <span class="apii">[-0, +1, <em>-</em>]</span> | ||
3567 | <pre>void lua_pushinteger (lua_State *L, lua_Integer n);</pre> | ||
3568 | |||
3569 | <p> | ||
3570 | Pushes a number with value <code>n</code> onto the stack. | ||
3571 | |||
3572 | |||
3573 | |||
3574 | |||
3575 | |||
3576 | <hr><h3><a name="lua_pushlightuserdata"><code>lua_pushlightuserdata</code></a></h3><p> | ||
3577 | <span class="apii">[-0, +1, <em>-</em>]</span> | ||
3578 | <pre>void lua_pushlightuserdata (lua_State *L, void *p);</pre> | ||
3579 | |||
3580 | <p> | ||
3581 | Pushes a light userdata onto the stack. | ||
3582 | |||
3583 | |||
3584 | <p> | ||
3585 | Userdata represent C values in Lua. | ||
3586 | A <em>light userdata</em> represents a pointer. | ||
3587 | It is a value (like a number): | ||
3588 | you do not create it, it has no individual metatable, | ||
3589 | and it is not collected (as it was never created). | ||
3590 | A light userdata is equal to "any" | ||
3591 | light userdata with the same C address. | ||
3592 | |||
3593 | |||
3594 | |||
3595 | |||
3596 | |||
3597 | <hr><h3><a name="lua_pushliteral"><code>lua_pushliteral</code></a></h3><p> | ||
3598 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
3599 | <pre>void lua_pushliteral (lua_State *L, const char *s);</pre> | ||
3600 | |||
3601 | <p> | ||
3602 | This macro is equivalent to <a href="#lua_pushlstring"><code>lua_pushlstring</code></a>, | ||
3603 | but can be used only when <code>s</code> is a literal string. | ||
3604 | In these cases, it automatically provides the string length. | ||
3605 | |||
3606 | |||
3607 | |||
3608 | |||
3609 | |||
3610 | <hr><h3><a name="lua_pushlstring"><code>lua_pushlstring</code></a></h3><p> | ||
3611 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
3612 | <pre>void lua_pushlstring (lua_State *L, const char *s, size_t len);</pre> | ||
3613 | |||
3614 | <p> | ||
3615 | Pushes the string pointed to by <code>s</code> with size <code>len</code> | ||
3616 | onto the stack. | ||
3617 | Lua makes (or reuses) an internal copy of the given string, | ||
3618 | so the memory at <code>s</code> can be freed or reused immediately after | ||
3619 | the function returns. | ||
3620 | The string can contain embedded zeros. | ||
3621 | |||
3622 | |||
3623 | |||
3624 | |||
3625 | |||
3626 | <hr><h3><a name="lua_pushnil"><code>lua_pushnil</code></a></h3><p> | ||
3627 | <span class="apii">[-0, +1, <em>-</em>]</span> | ||
3628 | <pre>void lua_pushnil (lua_State *L);</pre> | ||
3629 | |||
3630 | <p> | ||
3631 | Pushes a nil value onto the stack. | ||
3632 | |||
3633 | |||
3634 | |||
3635 | |||
3636 | |||
3637 | <hr><h3><a name="lua_pushnumber"><code>lua_pushnumber</code></a></h3><p> | ||
3638 | <span class="apii">[-0, +1, <em>-</em>]</span> | ||
3639 | <pre>void lua_pushnumber (lua_State *L, lua_Number n);</pre> | ||
3640 | |||
3641 | <p> | ||
3642 | Pushes a number with value <code>n</code> onto the stack. | ||
3643 | |||
3644 | |||
3645 | |||
3646 | |||
3647 | |||
3648 | <hr><h3><a name="lua_pushstring"><code>lua_pushstring</code></a></h3><p> | ||
3649 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
3650 | <pre>void lua_pushstring (lua_State *L, const char *s);</pre> | ||
3651 | |||
3652 | <p> | ||
3653 | Pushes the zero-terminated string pointed to by <code>s</code> | ||
3654 | onto the stack. | ||
3655 | Lua makes (or reuses) an internal copy of the given string, | ||
3656 | so the memory at <code>s</code> can be freed or reused immediately after | ||
3657 | the function returns. | ||
3658 | The string cannot contain embedded zeros; | ||
3659 | it is assumed to end at the first zero. | ||
3660 | |||
3661 | |||
3662 | |||
3663 | |||
3664 | |||
3665 | <hr><h3><a name="lua_pushthread"><code>lua_pushthread</code></a></h3><p> | ||
3666 | <span class="apii">[-0, +1, <em>-</em>]</span> | ||
3667 | <pre>int lua_pushthread (lua_State *L);</pre> | ||
3668 | |||
3669 | <p> | ||
3670 | Pushes the thread represented by <code>L</code> onto the stack. | ||
3671 | Returns 1 if this thread is the main thread of its state. | ||
3672 | |||
3673 | |||
3674 | |||
3675 | |||
3676 | |||
3677 | <hr><h3><a name="lua_pushvalue"><code>lua_pushvalue</code></a></h3><p> | ||
3678 | <span class="apii">[-0, +1, <em>-</em>]</span> | ||
3679 | <pre>void lua_pushvalue (lua_State *L, int index);</pre> | ||
3680 | |||
3681 | <p> | ||
3682 | Pushes a copy of the element at the given valid index | ||
3683 | onto the stack. | ||
3684 | |||
3685 | |||
3686 | |||
3687 | |||
3688 | |||
3689 | <hr><h3><a name="lua_pushvfstring"><code>lua_pushvfstring</code></a></h3><p> | ||
3690 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
3691 | <pre>const char *lua_pushvfstring (lua_State *L, | ||
3692 | const char *fmt, | ||
3693 | va_list argp);</pre> | ||
3694 | |||
3695 | <p> | ||
3696 | Equivalent to <a href="#lua_pushfstring"><code>lua_pushfstring</code></a>, except that it receives a <code>va_list</code> | ||
3697 | instead of a variable number of arguments. | ||
3698 | |||
3699 | |||
3700 | |||
3701 | |||
3702 | |||
3703 | <hr><h3><a name="lua_rawequal"><code>lua_rawequal</code></a></h3><p> | ||
3704 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3705 | <pre>int lua_rawequal (lua_State *L, int index1, int index2);</pre> | ||
3706 | |||
3707 | <p> | ||
3708 | Returns 1 if the two values in acceptable indices <code>index1</code> and | ||
3709 | <code>index2</code> are primitively equal | ||
3710 | (that is, without calling metamethods). | ||
3711 | Otherwise returns 0. | ||
3712 | Also returns 0 if any of the indices are non valid. | ||
3713 | |||
3714 | |||
3715 | |||
3716 | |||
3717 | |||
3718 | <hr><h3><a name="lua_rawget"><code>lua_rawget</code></a></h3><p> | ||
3719 | <span class="apii">[-1, +1, <em>-</em>]</span> | ||
3720 | <pre>void lua_rawget (lua_State *L, int index);</pre> | ||
3721 | |||
3722 | <p> | ||
3723 | Similar to <a href="#lua_gettable"><code>lua_gettable</code></a>, but does a raw access | ||
3724 | (i.e., without metamethods). | ||
3725 | |||
3726 | |||
3727 | |||
3728 | |||
3729 | |||
3730 | <hr><h3><a name="lua_rawgeti"><code>lua_rawgeti</code></a></h3><p> | ||
3731 | <span class="apii">[-0, +1, <em>-</em>]</span> | ||
3732 | <pre>void lua_rawgeti (lua_State *L, int index, int n);</pre> | ||
3733 | |||
3734 | <p> | ||
3735 | Pushes onto the stack the value <code>t[n]</code>, | ||
3736 | where <code>t</code> is the value at the given valid index. | ||
3737 | The access is raw; | ||
3738 | that is, it does not invoke metamethods. | ||
3739 | |||
3740 | |||
3741 | |||
3742 | |||
3743 | |||
3744 | <hr><h3><a name="lua_rawset"><code>lua_rawset</code></a></h3><p> | ||
3745 | <span class="apii">[-2, +0, <em>m</em>]</span> | ||
3746 | <pre>void lua_rawset (lua_State *L, int index);</pre> | ||
3747 | |||
3748 | <p> | ||
3749 | Similar to <a href="#lua_settable"><code>lua_settable</code></a>, but does a raw assignment | ||
3750 | (i.e., without metamethods). | ||
3751 | |||
3752 | |||
3753 | |||
3754 | |||
3755 | |||
3756 | <hr><h3><a name="lua_rawseti"><code>lua_rawseti</code></a></h3><p> | ||
3757 | <span class="apii">[-1, +0, <em>m</em>]</span> | ||
3758 | <pre>void lua_rawseti (lua_State *L, int index, int n);</pre> | ||
3759 | |||
3760 | <p> | ||
3761 | Does the equivalent of <code>t[n] = v</code>, | ||
3762 | where <code>t</code> is the value at the given valid index | ||
3763 | and <code>v</code> is the value at the top of the stack. | ||
3764 | |||
3765 | |||
3766 | <p> | ||
3767 | This function pops the value from the stack. | ||
3768 | The assignment is raw; | ||
3769 | that is, it does not invoke metamethods. | ||
3770 | |||
3771 | |||
3772 | |||
3773 | |||
3774 | |||
3775 | <hr><h3><a name="lua_Reader"><code>lua_Reader</code></a></h3> | ||
3776 | <pre>typedef const char * (*lua_Reader) (lua_State *L, | ||
3777 | void *data, | ||
3778 | size_t *size);</pre> | ||
3779 | |||
3780 | <p> | ||
3781 | The reader function used by <a href="#lua_load"><code>lua_load</code></a>. | ||
3782 | Every time it needs another piece of the chunk, | ||
3783 | <a href="#lua_load"><code>lua_load</code></a> calls the reader, | ||
3784 | passing along its <code>data</code> parameter. | ||
3785 | The reader must return a pointer to a block of memory | ||
3786 | with a new piece of the chunk | ||
3787 | and set <code>size</code> to the block size. | ||
3788 | The block must exist until the reader function is called again. | ||
3789 | To signal the end of the chunk, | ||
3790 | the reader must return <code>NULL</code> or set <code>size</code> to zero. | ||
3791 | The reader function may return pieces of any size greater than zero. | ||
3792 | |||
3793 | |||
3794 | |||
3795 | |||
3796 | |||
3797 | <hr><h3><a name="lua_register"><code>lua_register</code></a></h3><p> | ||
3798 | <span class="apii">[-0, +0, <em>e</em>]</span> | ||
3799 | <pre>void lua_register (lua_State *L, | ||
3800 | const char *name, | ||
3801 | lua_CFunction f);</pre> | ||
3802 | |||
3803 | <p> | ||
3804 | Sets the C function <code>f</code> as the new value of global <code>name</code>. | ||
3805 | It is defined as a macro: | ||
3806 | |||
3807 | <pre> | ||
3808 | #define lua_register(L,n,f) \ | ||
3809 | (lua_pushcfunction(L, f), lua_setglobal(L, n)) | ||
3810 | </pre> | ||
3811 | |||
3812 | |||
3813 | |||
3814 | |||
3815 | <hr><h3><a name="lua_remove"><code>lua_remove</code></a></h3><p> | ||
3816 | <span class="apii">[-1, +0, <em>-</em>]</span> | ||
3817 | <pre>void lua_remove (lua_State *L, int index);</pre> | ||
3818 | |||
3819 | <p> | ||
3820 | Removes the element at the given valid index, | ||
3821 | shifting down the elements above this index to fill the gap. | ||
3822 | Cannot be called with a pseudo-index, | ||
3823 | because a pseudo-index is not an actual stack position. | ||
3824 | |||
3825 | |||
3826 | |||
3827 | |||
3828 | |||
3829 | <hr><h3><a name="lua_replace"><code>lua_replace</code></a></h3><p> | ||
3830 | <span class="apii">[-1, +0, <em>-</em>]</span> | ||
3831 | <pre>void lua_replace (lua_State *L, int index);</pre> | ||
3832 | |||
3833 | <p> | ||
3834 | Moves the top element into the given position (and pops it), | ||
3835 | without shifting any element | ||
3836 | (therefore replacing the value at the given position). | ||
3837 | |||
3838 | |||
3839 | |||
3840 | |||
3841 | |||
3842 | <hr><h3><a name="lua_resume"><code>lua_resume</code></a></h3><p> | ||
3843 | <span class="apii">[-?, +?, <em>-</em>]</span> | ||
3844 | <pre>int lua_resume (lua_State *L, int narg);</pre> | ||
3845 | |||
3846 | <p> | ||
3847 | Starts and resumes a coroutine in a given thread. | ||
3848 | |||
3849 | |||
3850 | <p> | ||
3851 | To start a coroutine, you first create a new thread | ||
3852 | (see <a href="#lua_newthread"><code>lua_newthread</code></a>); | ||
3853 | then you push onto its stack the main function plus any arguments; | ||
3854 | then you call <a href="#lua_resume"><code>lua_resume</code></a>, | ||
3855 | with <code>narg</code> being the number of arguments. | ||
3856 | This call returns when the coroutine suspends or finishes its execution. | ||
3857 | When it returns, the stack contains all values passed to <a href="#lua_yield"><code>lua_yield</code></a>, | ||
3858 | or all values returned by the body function. | ||
3859 | <a href="#lua_resume"><code>lua_resume</code></a> returns | ||
3860 | <a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> if the coroutine yields, | ||
3861 | 0 if the coroutine finishes its execution | ||
3862 | without errors, | ||
3863 | or an error code in case of errors (see <a href="#lua_pcall"><code>lua_pcall</code></a>). | ||
3864 | In case of errors, | ||
3865 | the stack is not unwound, | ||
3866 | so you can use the debug API over it. | ||
3867 | The error message is on the top of the stack. | ||
3868 | To restart a coroutine, you put on its stack only the values to | ||
3869 | be passed as results from <code>yield</code>, | ||
3870 | and then call <a href="#lua_resume"><code>lua_resume</code></a>. | ||
3871 | |||
3872 | |||
3873 | |||
3874 | |||
3875 | |||
3876 | <hr><h3><a name="lua_setallocf"><code>lua_setallocf</code></a></h3><p> | ||
3877 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
3878 | <pre>void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);</pre> | ||
3879 | |||
3880 | <p> | ||
3881 | Changes the allocator function of a given state to <code>f</code> | ||
3882 | with user data <code>ud</code>. | ||
3883 | |||
3884 | |||
3885 | |||
3886 | |||
3887 | |||
3888 | <hr><h3><a name="lua_setfenv"><code>lua_setfenv</code></a></h3><p> | ||
3889 | <span class="apii">[-1, +0, <em>-</em>]</span> | ||
3890 | <pre>int lua_setfenv (lua_State *L, int index);</pre> | ||
3891 | |||
3892 | <p> | ||
3893 | Pops a table from the stack and sets it as | ||
3894 | the new environment for the value at the given index. | ||
3895 | If the value at the given index is | ||
3896 | neither a function nor a thread nor a userdata, | ||
3897 | <a href="#lua_setfenv"><code>lua_setfenv</code></a> returns 0. | ||
3898 | Otherwise it returns 1. | ||
3899 | |||
3900 | |||
3901 | |||
3902 | |||
3903 | |||
3904 | <hr><h3><a name="lua_setfield"><code>lua_setfield</code></a></h3><p> | ||
3905 | <span class="apii">[-1, +0, <em>e</em>]</span> | ||
3906 | <pre>void lua_setfield (lua_State *L, int index, const char *k);</pre> | ||
3907 | |||
3908 | <p> | ||
3909 | Does the equivalent to <code>t[k] = v</code>, | ||
3910 | where <code>t</code> is the value at the given valid index | ||
3911 | and <code>v</code> is the value at the top of the stack. | ||
3912 | |||
3913 | |||
3914 | <p> | ||
3915 | This function pops the value from the stack. | ||
3916 | As in Lua, this function may trigger a metamethod | ||
3917 | for the "newindex" event (see <a href="#2.8">§2.8</a>). | ||
3918 | |||
3919 | |||
3920 | |||
3921 | |||
3922 | |||
3923 | <hr><h3><a name="lua_setglobal"><code>lua_setglobal</code></a></h3><p> | ||
3924 | <span class="apii">[-1, +0, <em>e</em>]</span> | ||
3925 | <pre>void lua_setglobal (lua_State *L, const char *name);</pre> | ||
3926 | |||
3927 | <p> | ||
3928 | Pops a value from the stack and | ||
3929 | sets it as the new value of global <code>name</code>. | ||
3930 | It is defined as a macro: | ||
3931 | |||
3932 | <pre> | ||
3933 | #define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, s) | ||
3934 | </pre> | ||
3935 | |||
3936 | |||
3937 | |||
3938 | |||
3939 | <hr><h3><a name="lua_setmetatable"><code>lua_setmetatable</code></a></h3><p> | ||
3940 | <span class="apii">[-1, +0, <em>-</em>]</span> | ||
3941 | <pre>int lua_setmetatable (lua_State *L, int index);</pre> | ||
3942 | |||
3943 | <p> | ||
3944 | Pops a table from the stack and | ||
3945 | sets it as the new metatable for the value at the given | ||
3946 | acceptable index. | ||
3947 | |||
3948 | |||
3949 | |||
3950 | |||
3951 | |||
3952 | <hr><h3><a name="lua_settable"><code>lua_settable</code></a></h3><p> | ||
3953 | <span class="apii">[-2, +0, <em>e</em>]</span> | ||
3954 | <pre>void lua_settable (lua_State *L, int index);</pre> | ||
3955 | |||
3956 | <p> | ||
3957 | Does the equivalent to <code>t[k] = v</code>, | ||
3958 | where <code>t</code> is the value at the given valid index, | ||
3959 | <code>v</code> is the value at the top of the stack, | ||
3960 | and <code>k</code> is the value just below the top. | ||
3961 | |||
3962 | |||
3963 | <p> | ||
3964 | This function pops both the key and the value from the stack. | ||
3965 | As in Lua, this function may trigger a metamethod | ||
3966 | for the "newindex" event (see <a href="#2.8">§2.8</a>). | ||
3967 | |||
3968 | |||
3969 | |||
3970 | |||
3971 | |||
3972 | <hr><h3><a name="lua_settop"><code>lua_settop</code></a></h3><p> | ||
3973 | <span class="apii">[-?, +?, <em>-</em>]</span> | ||
3974 | <pre>void lua_settop (lua_State *L, int index);</pre> | ||
3975 | |||
3976 | <p> | ||
3977 | Accepts any acceptable index, or 0, | ||
3978 | and sets the stack top to this index. | ||
3979 | If the new top is larger than the old one, | ||
3980 | then the new elements are filled with <b>nil</b>. | ||
3981 | If <code>index</code> is 0, then all stack elements are removed. | ||
3982 | |||
3983 | |||
3984 | |||
3985 | |||
3986 | |||
3987 | <hr><h3><a name="lua_State"><code>lua_State</code></a></h3> | ||
3988 | <pre>typedef struct lua_State lua_State;</pre> | ||
3989 | |||
3990 | <p> | ||
3991 | Opaque structure that keeps the whole state of a Lua interpreter. | ||
3992 | The Lua library is fully reentrant: | ||
3993 | it has no global variables. | ||
3994 | All information about a state is kept in this structure. | ||
3995 | |||
3996 | |||
3997 | <p> | ||
3998 | A pointer to this state must be passed as the first argument to | ||
3999 | every function in the library, except to <a href="#lua_newstate"><code>lua_newstate</code></a>, | ||
4000 | which creates a Lua state from scratch. | ||
4001 | |||
4002 | |||
4003 | |||
4004 | |||
4005 | |||
4006 | <hr><h3><a name="lua_status"><code>lua_status</code></a></h3><p> | ||
4007 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4008 | <pre>int lua_status (lua_State *L);</pre> | ||
4009 | |||
4010 | <p> | ||
4011 | Returns the status of the thread <code>L</code>. | ||
4012 | |||
4013 | |||
4014 | <p> | ||
4015 | The status can be 0 for a normal thread, | ||
4016 | an error code if the thread finished its execution with an error, | ||
4017 | or <a name="pdf-LUA_YIELD"><code>LUA_YIELD</code></a> if the thread is suspended. | ||
4018 | |||
4019 | |||
4020 | |||
4021 | |||
4022 | |||
4023 | <hr><h3><a name="lua_toboolean"><code>lua_toboolean</code></a></h3><p> | ||
4024 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4025 | <pre>int lua_toboolean (lua_State *L, int index);</pre> | ||
4026 | |||
4027 | <p> | ||
4028 | Converts the Lua value at the given acceptable index to a C boolean | ||
4029 | value (0 or 1). | ||
4030 | Like all tests in Lua, | ||
4031 | <a href="#lua_toboolean"><code>lua_toboolean</code></a> returns 1 for any Lua value | ||
4032 | different from <b>false</b> and <b>nil</b>; | ||
4033 | otherwise it returns 0. | ||
4034 | It also returns 0 when called with a non-valid index. | ||
4035 | (If you want to accept only actual boolean values, | ||
4036 | use <a href="#lua_isboolean"><code>lua_isboolean</code></a> to test the value's type.) | ||
4037 | |||
4038 | |||
4039 | |||
4040 | |||
4041 | |||
4042 | <hr><h3><a name="lua_tocfunction"><code>lua_tocfunction</code></a></h3><p> | ||
4043 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4044 | <pre>lua_CFunction lua_tocfunction (lua_State *L, int index);</pre> | ||
4045 | |||
4046 | <p> | ||
4047 | Converts a value at the given acceptable index to a C function. | ||
4048 | That value must be a C function; | ||
4049 | otherwise, returns <code>NULL</code>. | ||
4050 | |||
4051 | |||
4052 | |||
4053 | |||
4054 | |||
4055 | <hr><h3><a name="lua_tointeger"><code>lua_tointeger</code></a></h3><p> | ||
4056 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4057 | <pre>lua_Integer lua_tointeger (lua_State *L, int index);</pre> | ||
4058 | |||
4059 | <p> | ||
4060 | Converts the Lua value at the given acceptable index | ||
4061 | to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>. | ||
4062 | The Lua value must be a number or a string convertible to a number | ||
4063 | (see <a href="#2.2.1">§2.2.1</a>); | ||
4064 | otherwise, <a href="#lua_tointeger"><code>lua_tointeger</code></a> returns 0. | ||
4065 | |||
4066 | |||
4067 | <p> | ||
4068 | If the number is not an integer, | ||
4069 | it is truncated in some non-specified way. | ||
4070 | |||
4071 | |||
4072 | |||
4073 | |||
4074 | |||
4075 | <hr><h3><a name="lua_tolstring"><code>lua_tolstring</code></a></h3><p> | ||
4076 | <span class="apii">[-0, +0, <em>m</em>]</span> | ||
4077 | <pre>const char *lua_tolstring (lua_State *L, int index, size_t *len);</pre> | ||
4078 | |||
4079 | <p> | ||
4080 | Converts the Lua value at the given acceptable index to a C string. | ||
4081 | If <code>len</code> is not <code>NULL</code>, | ||
4082 | it also sets <code>*len</code> with the string length. | ||
4083 | The Lua value must be a string or a number; | ||
4084 | otherwise, the function returns <code>NULL</code>. | ||
4085 | If the value is a number, | ||
4086 | then <a href="#lua_tolstring"><code>lua_tolstring</code></a> also | ||
4087 | <em>changes the actual value in the stack to a string</em>. | ||
4088 | (This change confuses <a href="#lua_next"><code>lua_next</code></a> | ||
4089 | when <a href="#lua_tolstring"><code>lua_tolstring</code></a> is applied to keys during a table traversal.) | ||
4090 | |||
4091 | |||
4092 | <p> | ||
4093 | <a href="#lua_tolstring"><code>lua_tolstring</code></a> returns a fully aligned pointer | ||
4094 | to a string inside the Lua state. | ||
4095 | This string always has a zero ('<code>\0</code>') | ||
4096 | after its last character (as in C), | ||
4097 | but can contain other zeros in its body. | ||
4098 | Because Lua has garbage collection, | ||
4099 | there is no guarantee that the pointer returned by <a href="#lua_tolstring"><code>lua_tolstring</code></a> | ||
4100 | will be valid after the corresponding value is removed from the stack. | ||
4101 | |||
4102 | |||
4103 | |||
4104 | |||
4105 | |||
4106 | <hr><h3><a name="lua_tonumber"><code>lua_tonumber</code></a></h3><p> | ||
4107 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4108 | <pre>lua_Number lua_tonumber (lua_State *L, int index);</pre> | ||
4109 | |||
4110 | <p> | ||
4111 | Converts the Lua value at the given acceptable index | ||
4112 | to the C type <a href="#lua_Number"><code>lua_Number</code></a> (see <a href="#lua_Number"><code>lua_Number</code></a>). | ||
4113 | The Lua value must be a number or a string convertible to a number | ||
4114 | (see <a href="#2.2.1">§2.2.1</a>); | ||
4115 | otherwise, <a href="#lua_tonumber"><code>lua_tonumber</code></a> returns 0. | ||
4116 | |||
4117 | |||
4118 | |||
4119 | |||
4120 | |||
4121 | <hr><h3><a name="lua_topointer"><code>lua_topointer</code></a></h3><p> | ||
4122 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4123 | <pre>const void *lua_topointer (lua_State *L, int index);</pre> | ||
4124 | |||
4125 | <p> | ||
4126 | Converts the value at the given acceptable index to a generic | ||
4127 | C pointer (<code>void*</code>). | ||
4128 | The value can be a userdata, a table, a thread, or a function; | ||
4129 | otherwise, <a href="#lua_topointer"><code>lua_topointer</code></a> returns <code>NULL</code>. | ||
4130 | Different objects will give different pointers. | ||
4131 | There is no way to convert the pointer back to its original value. | ||
4132 | |||
4133 | |||
4134 | <p> | ||
4135 | Typically this function is used only for debug information. | ||
4136 | |||
4137 | |||
4138 | |||
4139 | |||
4140 | |||
4141 | <hr><h3><a name="lua_tostring"><code>lua_tostring</code></a></h3><p> | ||
4142 | <span class="apii">[-0, +0, <em>m</em>]</span> | ||
4143 | <pre>const char *lua_tostring (lua_State *L, int index);</pre> | ||
4144 | |||
4145 | <p> | ||
4146 | Equivalent to <a href="#lua_tolstring"><code>lua_tolstring</code></a> with <code>len</code> equal to <code>NULL</code>. | ||
4147 | |||
4148 | |||
4149 | |||
4150 | |||
4151 | |||
4152 | <hr><h3><a name="lua_tothread"><code>lua_tothread</code></a></h3><p> | ||
4153 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4154 | <pre>lua_State *lua_tothread (lua_State *L, int index);</pre> | ||
4155 | |||
4156 | <p> | ||
4157 | Converts the value at the given acceptable index to a Lua thread | ||
4158 | (represented as <code>lua_State*</code>). | ||
4159 | This value must be a thread; | ||
4160 | otherwise, the function returns <code>NULL</code>. | ||
4161 | |||
4162 | |||
4163 | |||
4164 | |||
4165 | |||
4166 | <hr><h3><a name="lua_touserdata"><code>lua_touserdata</code></a></h3><p> | ||
4167 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4168 | <pre>void *lua_touserdata (lua_State *L, int index);</pre> | ||
4169 | |||
4170 | <p> | ||
4171 | If the value at the given acceptable index is a full userdata, | ||
4172 | returns its block address. | ||
4173 | If the value is a light userdata, | ||
4174 | returns its pointer. | ||
4175 | Otherwise, returns <code>NULL</code>. | ||
4176 | |||
4177 | |||
4178 | |||
4179 | |||
4180 | |||
4181 | <hr><h3><a name="lua_type"><code>lua_type</code></a></h3><p> | ||
4182 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4183 | <pre>int lua_type (lua_State *L, int index);</pre> | ||
4184 | |||
4185 | <p> | ||
4186 | Returns the type of the value in the given acceptable index, | ||
4187 | or <code>LUA_TNONE</code> for a non-valid index | ||
4188 | (that is, an index to an "empty" stack position). | ||
4189 | The types returned by <a href="#lua_type"><code>lua_type</code></a> are coded by the following constants | ||
4190 | defined in <code>lua.h</code>: | ||
4191 | <code>LUA_TNIL</code>, | ||
4192 | <code>LUA_TNUMBER</code>, | ||
4193 | <code>LUA_TBOOLEAN</code>, | ||
4194 | <code>LUA_TSTRING</code>, | ||
4195 | <code>LUA_TTABLE</code>, | ||
4196 | <code>LUA_TFUNCTION</code>, | ||
4197 | <code>LUA_TUSERDATA</code>, | ||
4198 | <code>LUA_TTHREAD</code>, | ||
4199 | and | ||
4200 | <code>LUA_TLIGHTUSERDATA</code>. | ||
4201 | |||
4202 | |||
4203 | |||
4204 | |||
4205 | |||
4206 | <hr><h3><a name="lua_typename"><code>lua_typename</code></a></h3><p> | ||
4207 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4208 | <pre>const char *lua_typename (lua_State *L, int tp);</pre> | ||
4209 | |||
4210 | <p> | ||
4211 | Returns the name of the type encoded by the value <code>tp</code>, | ||
4212 | which must be one the values returned by <a href="#lua_type"><code>lua_type</code></a>. | ||
4213 | |||
4214 | |||
4215 | |||
4216 | |||
4217 | |||
4218 | <hr><h3><a name="lua_Writer"><code>lua_Writer</code></a></h3> | ||
4219 | <pre>typedef int (*lua_Writer) (lua_State *L, | ||
4220 | const void* p, | ||
4221 | size_t sz, | ||
4222 | void* ud);</pre> | ||
4223 | |||
4224 | <p> | ||
4225 | The type of the writer function used by <a href="#lua_dump"><code>lua_dump</code></a>. | ||
4226 | Every time it produces another piece of chunk, | ||
4227 | <a href="#lua_dump"><code>lua_dump</code></a> calls the writer, | ||
4228 | passing along the buffer to be written (<code>p</code>), | ||
4229 | its size (<code>sz</code>), | ||
4230 | and the <code>data</code> parameter supplied to <a href="#lua_dump"><code>lua_dump</code></a>. | ||
4231 | |||
4232 | |||
4233 | <p> | ||
4234 | The writer returns an error code: | ||
4235 | 0 means no errors; | ||
4236 | any other value means an error and stops <a href="#lua_dump"><code>lua_dump</code></a> from | ||
4237 | calling the writer again. | ||
4238 | |||
4239 | |||
4240 | |||
4241 | |||
4242 | |||
4243 | <hr><h3><a name="lua_xmove"><code>lua_xmove</code></a></h3><p> | ||
4244 | <span class="apii">[-?, +?, <em>-</em>]</span> | ||
4245 | <pre>void lua_xmove (lua_State *from, lua_State *to, int n);</pre> | ||
4246 | |||
4247 | <p> | ||
4248 | Exchange values between different threads of the <em>same</em> global state. | ||
4249 | |||
4250 | |||
4251 | <p> | ||
4252 | This function pops <code>n</code> values from the stack <code>from</code>, | ||
4253 | and pushes them onto the stack <code>to</code>. | ||
4254 | |||
4255 | |||
4256 | |||
4257 | |||
4258 | |||
4259 | <hr><h3><a name="lua_yield"><code>lua_yield</code></a></h3><p> | ||
4260 | <span class="apii">[-?, +?, <em>-</em>]</span> | ||
4261 | <pre>int lua_yield (lua_State *L, int nresults);</pre> | ||
4262 | |||
4263 | <p> | ||
4264 | Yields a coroutine. | ||
4265 | |||
4266 | |||
4267 | <p> | ||
4268 | This function should only be called as the | ||
4269 | return expression of a C function, as follows: | ||
4270 | |||
4271 | <pre> | ||
4272 | return lua_yield (L, nresults); | ||
4273 | </pre><p> | ||
4274 | When a C function calls <a href="#lua_yield"><code>lua_yield</code></a> in that way, | ||
4275 | the running coroutine suspends its execution, | ||
4276 | and the call to <a href="#lua_resume"><code>lua_resume</code></a> that started this coroutine returns. | ||
4277 | The parameter <code>nresults</code> is the number of values from the stack | ||
4278 | that are passed as results to <a href="#lua_resume"><code>lua_resume</code></a>. | ||
4279 | |||
4280 | |||
4281 | |||
4282 | |||
4283 | |||
4284 | |||
4285 | |||
4286 | <h2>3.8 - <a name="3.8">The Debug Interface</a></h2> | ||
4287 | |||
4288 | <p> | ||
4289 | Lua has no built-in debugging facilities. | ||
4290 | Instead, it offers a special interface | ||
4291 | by means of functions and <em>hooks</em>. | ||
4292 | This interface allows the construction of different | ||
4293 | kinds of debuggers, profilers, and other tools | ||
4294 | that need "inside information" from the interpreter. | ||
4295 | |||
4296 | |||
4297 | |||
4298 | <hr><h3><a name="lua_Debug"><code>lua_Debug</code></a></h3> | ||
4299 | <pre>typedef struct lua_Debug { | ||
4300 | int event; | ||
4301 | const char *name; /* (n) */ | ||
4302 | const char *namewhat; /* (n) */ | ||
4303 | const char *what; /* (S) */ | ||
4304 | const char *source; /* (S) */ | ||
4305 | int currentline; /* (l) */ | ||
4306 | int nups; /* (u) number of upvalues */ | ||
4307 | int linedefined; /* (S) */ | ||
4308 | int lastlinedefined; /* (S) */ | ||
4309 | char short_src[LUA_IDSIZE]; /* (S) */ | ||
4310 | /* private part */ | ||
4311 | <em>other fields</em> | ||
4312 | } lua_Debug;</pre> | ||
4313 | |||
4314 | <p> | ||
4315 | A structure used to carry different pieces of | ||
4316 | information about an active function. | ||
4317 | <a href="#lua_getstack"><code>lua_getstack</code></a> fills only the private part | ||
4318 | of this structure, for later use. | ||
4319 | To fill the other fields of <a href="#lua_Debug"><code>lua_Debug</code></a> with useful information, | ||
4320 | call <a href="#lua_getinfo"><code>lua_getinfo</code></a>. | ||
4321 | |||
4322 | |||
4323 | <p> | ||
4324 | The fields of <a href="#lua_Debug"><code>lua_Debug</code></a> have the following meaning: | ||
4325 | |||
4326 | <ul> | ||
4327 | |||
4328 | <li><b><code>source</code>:</b> | ||
4329 | If the function was defined in a string, | ||
4330 | then <code>source</code> is that string. | ||
4331 | If the function was defined in a file, | ||
4332 | then <code>source</code> starts with a '<code>@</code>' followed by the file name. | ||
4333 | </li> | ||
4334 | |||
4335 | <li><b><code>short_src</code>:</b> | ||
4336 | a "printable" version of <code>source</code>, to be used in error messages. | ||
4337 | </li> | ||
4338 | |||
4339 | <li><b><code>linedefined</code>:</b> | ||
4340 | the line number where the definition of the function starts. | ||
4341 | </li> | ||
4342 | |||
4343 | <li><b><code>lastlinedefined</code>:</b> | ||
4344 | the line number where the definition of the function ends. | ||
4345 | </li> | ||
4346 | |||
4347 | <li><b><code>what</code>:</b> | ||
4348 | the string <code>"Lua"</code> if the function is a Lua function, | ||
4349 | <code>"C"</code> if it is a C function, | ||
4350 | <code>"main"</code> if it is the main part of a chunk, | ||
4351 | and <code>"tail"</code> if it was a function that did a tail call. | ||
4352 | In the latter case, | ||
4353 | Lua has no other information about the function. | ||
4354 | </li> | ||
4355 | |||
4356 | <li><b><code>currentline</code>:</b> | ||
4357 | the current line where the given function is executing. | ||
4358 | When no line information is available, | ||
4359 | <code>currentline</code> is set to -1. | ||
4360 | </li> | ||
4361 | |||
4362 | <li><b><code>name</code>:</b> | ||
4363 | a reasonable name for the given function. | ||
4364 | Because functions in Lua are first-class values, | ||
4365 | they do not have a fixed name: | ||
4366 | some functions can be the value of multiple global variables, | ||
4367 | while others can be stored only in a table field. | ||
4368 | The <code>lua_getinfo</code> function checks how the function was | ||
4369 | called to find a suitable name. | ||
4370 | If it cannot find a name, | ||
4371 | then <code>name</code> is set to <code>NULL</code>. | ||
4372 | </li> | ||
4373 | |||
4374 | <li><b><code>namewhat</code>:</b> | ||
4375 | explains the <code>name</code> field. | ||
4376 | The value of <code>namewhat</code> can be | ||
4377 | <code>"global"</code>, <code>"local"</code>, <code>"method"</code>, | ||
4378 | <code>"field"</code>, <code>"upvalue"</code>, or <code>""</code> (the empty string), | ||
4379 | according to how the function was called. | ||
4380 | (Lua uses the empty string when no other option seems to apply.) | ||
4381 | </li> | ||
4382 | |||
4383 | <li><b><code>nups</code>:</b> | ||
4384 | the number of upvalues of the function. | ||
4385 | </li> | ||
4386 | |||
4387 | </ul> | ||
4388 | |||
4389 | |||
4390 | |||
4391 | |||
4392 | <hr><h3><a name="lua_gethook"><code>lua_gethook</code></a></h3><p> | ||
4393 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4394 | <pre>lua_Hook lua_gethook (lua_State *L);</pre> | ||
4395 | |||
4396 | <p> | ||
4397 | Returns the current hook function. | ||
4398 | |||
4399 | |||
4400 | |||
4401 | |||
4402 | |||
4403 | <hr><h3><a name="lua_gethookcount"><code>lua_gethookcount</code></a></h3><p> | ||
4404 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4405 | <pre>int lua_gethookcount (lua_State *L);</pre> | ||
4406 | |||
4407 | <p> | ||
4408 | Returns the current hook count. | ||
4409 | |||
4410 | |||
4411 | |||
4412 | |||
4413 | |||
4414 | <hr><h3><a name="lua_gethookmask"><code>lua_gethookmask</code></a></h3><p> | ||
4415 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4416 | <pre>int lua_gethookmask (lua_State *L);</pre> | ||
4417 | |||
4418 | <p> | ||
4419 | Returns the current hook mask. | ||
4420 | |||
4421 | |||
4422 | |||
4423 | |||
4424 | |||
4425 | <hr><h3><a name="lua_getinfo"><code>lua_getinfo</code></a></h3><p> | ||
4426 | <span class="apii">[-(0|1), +(0|1|2), <em>m</em>]</span> | ||
4427 | <pre>int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);</pre> | ||
4428 | |||
4429 | <p> | ||
4430 | Returns information about a specific function or function invocation. | ||
4431 | |||
4432 | |||
4433 | <p> | ||
4434 | To get information about a function invocation, | ||
4435 | the parameter <code>ar</code> must be a valid activation record that was | ||
4436 | filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or | ||
4437 | given as argument to a hook (see <a href="#lua_Hook"><code>lua_Hook</code></a>). | ||
4438 | |||
4439 | |||
4440 | <p> | ||
4441 | To get information about a function you push it onto the stack | ||
4442 | and start the <code>what</code> string with the character '<code>></code>'. | ||
4443 | (In that case, | ||
4444 | <code>lua_getinfo</code> pops the function in the top of the stack.) | ||
4445 | For instance, to know in which line a function <code>f</code> was defined, | ||
4446 | you can write the following code: | ||
4447 | |||
4448 | <pre> | ||
4449 | lua_Debug ar; | ||
4450 | lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* get global 'f' */ | ||
4451 | lua_getinfo(L, ">S", &ar); | ||
4452 | printf("%d\n", ar.linedefined); | ||
4453 | </pre> | ||
4454 | |||
4455 | <p> | ||
4456 | Each character in the string <code>what</code> | ||
4457 | selects some fields of the structure <code>ar</code> to be filled or | ||
4458 | a value to be pushed on the stack: | ||
4459 | |||
4460 | <ul> | ||
4461 | |||
4462 | <li><b>'<code>n</code>':</b> fills in the field <code>name</code> and <code>namewhat</code>; | ||
4463 | </li> | ||
4464 | |||
4465 | <li><b>'<code>S</code>':</b> | ||
4466 | fills in the fields <code>source</code>, <code>short_src</code>, | ||
4467 | <code>linedefined</code>, <code>lastlinedefined</code>, and <code>what</code>; | ||
4468 | </li> | ||
4469 | |||
4470 | <li><b>'<code>l</code>':</b> fills in the field <code>currentline</code>; | ||
4471 | </li> | ||
4472 | |||
4473 | <li><b>'<code>u</code>':</b> fills in the field <code>nups</code>; | ||
4474 | </li> | ||
4475 | |||
4476 | <li><b>'<code>f</code>':</b> | ||
4477 | pushes onto the stack the function that is | ||
4478 | running at the given level; | ||
4479 | </li> | ||
4480 | |||
4481 | <li><b>'<code>L</code>':</b> | ||
4482 | pushes onto the stack a table whose indices are the | ||
4483 | numbers of the lines that are valid on the function. | ||
4484 | (A <em>valid line</em> is a line with some associated code, | ||
4485 | that is, a line where you can put a break point. | ||
4486 | Non-valid lines include empty lines and comments.) | ||
4487 | </li> | ||
4488 | |||
4489 | </ul> | ||
4490 | |||
4491 | <p> | ||
4492 | This function returns 0 on error | ||
4493 | (for instance, an invalid option in <code>what</code>). | ||
4494 | |||
4495 | |||
4496 | |||
4497 | |||
4498 | |||
4499 | <hr><h3><a name="lua_getlocal"><code>lua_getlocal</code></a></h3><p> | ||
4500 | <span class="apii">[-0, +(0|1), <em>-</em>]</span> | ||
4501 | <pre>const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);</pre> | ||
4502 | |||
4503 | <p> | ||
4504 | Gets information about a local variable of a given activation record. | ||
4505 | The parameter <code>ar</code> must be a valid activation record that was | ||
4506 | filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or | ||
4507 | given as argument to a hook (see <a href="#lua_Hook"><code>lua_Hook</code></a>). | ||
4508 | The index <code>n</code> selects which local variable to inspect | ||
4509 | (1 is the first parameter or active local variable, and so on, | ||
4510 | until the last active local variable). | ||
4511 | <a href="#lua_getlocal"><code>lua_getlocal</code></a> pushes the variable's value onto the stack | ||
4512 | and returns its name. | ||
4513 | |||
4514 | |||
4515 | <p> | ||
4516 | Variable names starting with '<code>(</code>' (open parentheses) | ||
4517 | represent internal variables | ||
4518 | (loop control variables, temporaries, and C function locals). | ||
4519 | |||
4520 | |||
4521 | <p> | ||
4522 | Returns <code>NULL</code> (and pushes nothing) | ||
4523 | when the index is greater than | ||
4524 | the number of active local variables. | ||
4525 | |||
4526 | |||
4527 | |||
4528 | |||
4529 | |||
4530 | <hr><h3><a name="lua_getstack"><code>lua_getstack</code></a></h3><p> | ||
4531 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4532 | <pre>int lua_getstack (lua_State *L, int level, lua_Debug *ar);</pre> | ||
4533 | |||
4534 | <p> | ||
4535 | Get information about the interpreter runtime stack. | ||
4536 | |||
4537 | |||
4538 | <p> | ||
4539 | This function fills parts of a <a href="#lua_Debug"><code>lua_Debug</code></a> structure with | ||
4540 | an identification of the <em>activation record</em> | ||
4541 | of the function executing at a given level. | ||
4542 | Level 0 is the current running function, | ||
4543 | whereas level <em>n+1</em> is the function that has called level <em>n</em>. | ||
4544 | When there are no errors, <a href="#lua_getstack"><code>lua_getstack</code></a> returns 1; | ||
4545 | when called with a level greater than the stack depth, | ||
4546 | it returns 0. | ||
4547 | |||
4548 | |||
4549 | |||
4550 | |||
4551 | |||
4552 | <hr><h3><a name="lua_getupvalue"><code>lua_getupvalue</code></a></h3><p> | ||
4553 | <span class="apii">[-0, +(0|1), <em>-</em>]</span> | ||
4554 | <pre>const char *lua_getupvalue (lua_State *L, int funcindex, int n);</pre> | ||
4555 | |||
4556 | <p> | ||
4557 | Gets information about a closure's upvalue. | ||
4558 | (For Lua functions, | ||
4559 | upvalues are the external local variables that the function uses, | ||
4560 | and that are consequently included in its closure.) | ||
4561 | <a href="#lua_getupvalue"><code>lua_getupvalue</code></a> gets the index <code>n</code> of an upvalue, | ||
4562 | pushes the upvalue's value onto the stack, | ||
4563 | and returns its name. | ||
4564 | <code>funcindex</code> points to the closure in the stack. | ||
4565 | (Upvalues have no particular order, | ||
4566 | as they are active through the whole function. | ||
4567 | So, they are numbered in an arbitrary order.) | ||
4568 | |||
4569 | |||
4570 | <p> | ||
4571 | Returns <code>NULL</code> (and pushes nothing) | ||
4572 | when the index is greater than the number of upvalues. | ||
4573 | For C functions, this function uses the empty string <code>""</code> | ||
4574 | as a name for all upvalues. | ||
4575 | |||
4576 | |||
4577 | |||
4578 | |||
4579 | |||
4580 | <hr><h3><a name="lua_Hook"><code>lua_Hook</code></a></h3> | ||
4581 | <pre>typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);</pre> | ||
4582 | |||
4583 | <p> | ||
4584 | Type for debugging hook functions. | ||
4585 | |||
4586 | |||
4587 | <p> | ||
4588 | Whenever a hook is called, its <code>ar</code> argument has its field | ||
4589 | <code>event</code> set to the specific event that triggered the hook. | ||
4590 | Lua identifies these events with the following constants: | ||
4591 | <a name="pdf-LUA_HOOKCALL"><code>LUA_HOOKCALL</code></a>, <a name="pdf-LUA_HOOKRET"><code>LUA_HOOKRET</code></a>, | ||
4592 | <a name="pdf-LUA_HOOKTAILRET"><code>LUA_HOOKTAILRET</code></a>, <a name="pdf-LUA_HOOKLINE"><code>LUA_HOOKLINE</code></a>, | ||
4593 | and <a name="pdf-LUA_HOOKCOUNT"><code>LUA_HOOKCOUNT</code></a>. | ||
4594 | Moreover, for line events, the field <code>currentline</code> is also set. | ||
4595 | To get the value of any other field in <code>ar</code>, | ||
4596 | the hook must call <a href="#lua_getinfo"><code>lua_getinfo</code></a>. | ||
4597 | For return events, <code>event</code> can be <code>LUA_HOOKRET</code>, | ||
4598 | the normal value, or <code>LUA_HOOKTAILRET</code>. | ||
4599 | In the latter case, Lua is simulating a return from | ||
4600 | a function that did a tail call; | ||
4601 | in this case, it is useless to call <a href="#lua_getinfo"><code>lua_getinfo</code></a>. | ||
4602 | |||
4603 | |||
4604 | <p> | ||
4605 | While Lua is running a hook, it disables other calls to hooks. | ||
4606 | Therefore, if a hook calls back Lua to execute a function or a chunk, | ||
4607 | this execution occurs without any calls to hooks. | ||
4608 | |||
4609 | |||
4610 | |||
4611 | |||
4612 | |||
4613 | <hr><h3><a name="lua_sethook"><code>lua_sethook</code></a></h3><p> | ||
4614 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4615 | <pre>int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);</pre> | ||
4616 | |||
4617 | <p> | ||
4618 | Sets the debugging hook function. | ||
4619 | |||
4620 | |||
4621 | <p> | ||
4622 | Argument <code>f</code> is the hook function. | ||
4623 | <code>mask</code> specifies on which events the hook will be called: | ||
4624 | it is formed by a bitwise or of the constants | ||
4625 | <a name="pdf-LUA_MASKCALL"><code>LUA_MASKCALL</code></a>, | ||
4626 | <a name="pdf-LUA_MASKRET"><code>LUA_MASKRET</code></a>, | ||
4627 | <a name="pdf-LUA_MASKLINE"><code>LUA_MASKLINE</code></a>, | ||
4628 | and <a name="pdf-LUA_MASKCOUNT"><code>LUA_MASKCOUNT</code></a>. | ||
4629 | The <code>count</code> argument is only meaningful when the mask | ||
4630 | includes <code>LUA_MASKCOUNT</code>. | ||
4631 | For each event, the hook is called as explained below: | ||
4632 | |||
4633 | <ul> | ||
4634 | |||
4635 | <li><b>The call hook:</b> is called when the interpreter calls a function. | ||
4636 | The hook is called just after Lua enters the new function, | ||
4637 | before the function gets its arguments. | ||
4638 | </li> | ||
4639 | |||
4640 | <li><b>The return hook:</b> is called when the interpreter returns from a function. | ||
4641 | The hook is called just before Lua leaves the function. | ||
4642 | You have no access to the values to be returned by the function. | ||
4643 | </li> | ||
4644 | |||
4645 | <li><b>The line hook:</b> is called when the interpreter is about to | ||
4646 | start the execution of a new line of code, | ||
4647 | or when it jumps back in the code (even to the same line). | ||
4648 | (This event only happens while Lua is executing a Lua function.) | ||
4649 | </li> | ||
4650 | |||
4651 | <li><b>The count hook:</b> is called after the interpreter executes every | ||
4652 | <code>count</code> instructions. | ||
4653 | (This event only happens while Lua is executing a Lua function.) | ||
4654 | </li> | ||
4655 | |||
4656 | </ul> | ||
4657 | |||
4658 | <p> | ||
4659 | A hook is disabled by setting <code>mask</code> to zero. | ||
4660 | |||
4661 | |||
4662 | |||
4663 | |||
4664 | |||
4665 | <hr><h3><a name="lua_setlocal"><code>lua_setlocal</code></a></h3><p> | ||
4666 | <span class="apii">[-(0|1), +0, <em>-</em>]</span> | ||
4667 | <pre>const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);</pre> | ||
4668 | |||
4669 | <p> | ||
4670 | Sets the value of a local variable of a given activation record. | ||
4671 | Parameters <code>ar</code> and <code>n</code> are as in <a href="#lua_getlocal"><code>lua_getlocal</code></a> | ||
4672 | (see <a href="#lua_getlocal"><code>lua_getlocal</code></a>). | ||
4673 | <a href="#lua_setlocal"><code>lua_setlocal</code></a> assigns the value at the top of the stack | ||
4674 | to the variable and returns its name. | ||
4675 | It also pops the value from the stack. | ||
4676 | |||
4677 | |||
4678 | <p> | ||
4679 | Returns <code>NULL</code> (and pops nothing) | ||
4680 | when the index is greater than | ||
4681 | the number of active local variables. | ||
4682 | |||
4683 | |||
4684 | |||
4685 | |||
4686 | |||
4687 | <hr><h3><a name="lua_setupvalue"><code>lua_setupvalue</code></a></h3><p> | ||
4688 | <span class="apii">[-(0|1), +0, <em>-</em>]</span> | ||
4689 | <pre>const char *lua_setupvalue (lua_State *L, int funcindex, int n);</pre> | ||
4690 | |||
4691 | <p> | ||
4692 | Sets the value of a closure's upvalue. | ||
4693 | It assigns the value at the top of the stack | ||
4694 | to the upvalue and returns its name. | ||
4695 | It also pops the value from the stack. | ||
4696 | Parameters <code>funcindex</code> and <code>n</code> are as in the <a href="#lua_getupvalue"><code>lua_getupvalue</code></a> | ||
4697 | (see <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>). | ||
4698 | |||
4699 | |||
4700 | <p> | ||
4701 | Returns <code>NULL</code> (and pops nothing) | ||
4702 | when the index is greater than the number of upvalues. | ||
4703 | |||
4704 | |||
4705 | |||
4706 | |||
4707 | |||
4708 | |||
4709 | |||
4710 | <h1>4 - <a name="4">The Auxiliary Library</a></h1> | ||
4711 | |||
4712 | <p> | ||
4713 | |||
4714 | The <em>auxiliary library</em> provides several convenient functions | ||
4715 | to interface C with Lua. | ||
4716 | While the basic API provides the primitive functions for all | ||
4717 | interactions between C and Lua, | ||
4718 | the auxiliary library provides higher-level functions for some | ||
4719 | common tasks. | ||
4720 | |||
4721 | |||
4722 | <p> | ||
4723 | All functions from the auxiliary library | ||
4724 | are defined in header file <code>lauxlib.h</code> and | ||
4725 | have a prefix <code>luaL_</code>. | ||
4726 | |||
4727 | |||
4728 | <p> | ||
4729 | All functions in the auxiliary library are built on | ||
4730 | top of the basic API, | ||
4731 | and so they provide nothing that cannot be done with this API. | ||
4732 | |||
4733 | |||
4734 | <p> | ||
4735 | Several functions in the auxiliary library are used to | ||
4736 | check C function arguments. | ||
4737 | Their names are always <code>luaL_check*</code> or <code>luaL_opt*</code>. | ||
4738 | All of these functions throw an error if the check is not satisfied. | ||
4739 | Because the error message is formatted for arguments | ||
4740 | (e.g., "<code>bad argument #1</code>"), | ||
4741 | you should not use these functions for other stack values. | ||
4742 | |||
4743 | |||
4744 | |||
4745 | <h2>4.1 - <a name="4.1">Functions and Types</a></h2> | ||
4746 | |||
4747 | <p> | ||
4748 | Here we list all functions and types from the auxiliary library | ||
4749 | in alphabetical order. | ||
4750 | |||
4751 | |||
4752 | |||
4753 | <hr><h3><a name="luaL_addchar"><code>luaL_addchar</code></a></h3><p> | ||
4754 | <span class="apii">[-0, +0, <em>m</em>]</span> | ||
4755 | <pre>void luaL_addchar (luaL_Buffer *B, char c);</pre> | ||
4756 | |||
4757 | <p> | ||
4758 | Adds the character <code>c</code> to the buffer <code>B</code> | ||
4759 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). | ||
4760 | |||
4761 | |||
4762 | |||
4763 | |||
4764 | |||
4765 | <hr><h3><a name="luaL_addlstring"><code>luaL_addlstring</code></a></h3><p> | ||
4766 | <span class="apii">[-0, +0, <em>m</em>]</span> | ||
4767 | <pre>void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);</pre> | ||
4768 | |||
4769 | <p> | ||
4770 | Adds the string pointed to by <code>s</code> with length <code>l</code> to | ||
4771 | the buffer <code>B</code> | ||
4772 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). | ||
4773 | The string may contain embedded zeros. | ||
4774 | |||
4775 | |||
4776 | |||
4777 | |||
4778 | |||
4779 | <hr><h3><a name="luaL_addsize"><code>luaL_addsize</code></a></h3><p> | ||
4780 | <span class="apii">[-0, +0, <em>m</em>]</span> | ||
4781 | <pre>void luaL_addsize (luaL_Buffer *B, size_t n);</pre> | ||
4782 | |||
4783 | <p> | ||
4784 | Adds to the buffer <code>B</code> (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>) | ||
4785 | a string of length <code>n</code> previously copied to the | ||
4786 | buffer area (see <a href="#luaL_prepbuffer"><code>luaL_prepbuffer</code></a>). | ||
4787 | |||
4788 | |||
4789 | |||
4790 | |||
4791 | |||
4792 | <hr><h3><a name="luaL_addstring"><code>luaL_addstring</code></a></h3><p> | ||
4793 | <span class="apii">[-0, +0, <em>m</em>]</span> | ||
4794 | <pre>void luaL_addstring (luaL_Buffer *B, const char *s);</pre> | ||
4795 | |||
4796 | <p> | ||
4797 | Adds the zero-terminated string pointed to by <code>s</code> | ||
4798 | to the buffer <code>B</code> | ||
4799 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). | ||
4800 | The string may not contain embedded zeros. | ||
4801 | |||
4802 | |||
4803 | |||
4804 | |||
4805 | |||
4806 | <hr><h3><a name="luaL_addvalue"><code>luaL_addvalue</code></a></h3><p> | ||
4807 | <span class="apii">[-1, +0, <em>m</em>]</span> | ||
4808 | <pre>void luaL_addvalue (luaL_Buffer *B);</pre> | ||
4809 | |||
4810 | <p> | ||
4811 | Adds the value at the top of the stack | ||
4812 | to the buffer <code>B</code> | ||
4813 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). | ||
4814 | Pops the value. | ||
4815 | |||
4816 | |||
4817 | <p> | ||
4818 | This is the only function on string buffers that can (and must) | ||
4819 | be called with an extra element on the stack, | ||
4820 | which is the value to be added to the buffer. | ||
4821 | |||
4822 | |||
4823 | |||
4824 | |||
4825 | |||
4826 | <hr><h3><a name="luaL_argcheck"><code>luaL_argcheck</code></a></h3><p> | ||
4827 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
4828 | <pre>void luaL_argcheck (lua_State *L, | ||
4829 | int cond, | ||
4830 | int narg, | ||
4831 | const char *extramsg);</pre> | ||
4832 | |||
4833 | <p> | ||
4834 | Checks whether <code>cond</code> is true. | ||
4835 | If not, raises an error with the following message, | ||
4836 | where <code>func</code> is retrieved from the call stack: | ||
4837 | |||
4838 | <pre> | ||
4839 | bad argument #<narg> to <func> (<extramsg>) | ||
4840 | </pre> | ||
4841 | |||
4842 | |||
4843 | |||
4844 | |||
4845 | <hr><h3><a name="luaL_argerror"><code>luaL_argerror</code></a></h3><p> | ||
4846 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
4847 | <pre>int luaL_argerror (lua_State *L, int narg, const char *extramsg);</pre> | ||
4848 | |||
4849 | <p> | ||
4850 | Raises an error with the following message, | ||
4851 | where <code>func</code> is retrieved from the call stack: | ||
4852 | |||
4853 | <pre> | ||
4854 | bad argument #<narg> to <func> (<extramsg>) | ||
4855 | </pre> | ||
4856 | |||
4857 | <p> | ||
4858 | This function never returns, | ||
4859 | but it is an idiom to use it in C functions | ||
4860 | as <code>return luaL_argerror(<em>args</em>)</code>. | ||
4861 | |||
4862 | |||
4863 | |||
4864 | |||
4865 | |||
4866 | <hr><h3><a name="luaL_Buffer"><code>luaL_Buffer</code></a></h3> | ||
4867 | <pre>typedef struct luaL_Buffer luaL_Buffer;</pre> | ||
4868 | |||
4869 | <p> | ||
4870 | Type for a <em>string buffer</em>. | ||
4871 | |||
4872 | |||
4873 | <p> | ||
4874 | A string buffer allows C code to build Lua strings piecemeal. | ||
4875 | Its pattern of use is as follows: | ||
4876 | |||
4877 | <ul> | ||
4878 | |||
4879 | <li>First you declare a variable <code>b</code> of type <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>.</li> | ||
4880 | |||
4881 | <li>Then you initialize it with a call <code>luaL_buffinit(L, &b)</code>.</li> | ||
4882 | |||
4883 | <li> | ||
4884 | Then you add string pieces to the buffer calling any of | ||
4885 | the <code>luaL_add*</code> functions. | ||
4886 | </li> | ||
4887 | |||
4888 | <li> | ||
4889 | You finish by calling <code>luaL_pushresult(&b)</code>. | ||
4890 | This call leaves the final string on the top of the stack. | ||
4891 | </li> | ||
4892 | |||
4893 | </ul> | ||
4894 | |||
4895 | <p> | ||
4896 | During its normal operation, | ||
4897 | a string buffer uses a variable number of stack slots. | ||
4898 | So, while using a buffer, you cannot assume that you know where | ||
4899 | the top of the stack is. | ||
4900 | You can use the stack between successive calls to buffer operations | ||
4901 | as long as that use is balanced; | ||
4902 | that is, | ||
4903 | when you call a buffer operation, | ||
4904 | the stack is at the same level | ||
4905 | it was immediately after the previous buffer operation. | ||
4906 | (The only exception to this rule is <a href="#luaL_addvalue"><code>luaL_addvalue</code></a>.) | ||
4907 | After calling <a href="#luaL_pushresult"><code>luaL_pushresult</code></a> the stack is back to its | ||
4908 | level when the buffer was initialized, | ||
4909 | plus the final string on its top. | ||
4910 | |||
4911 | |||
4912 | |||
4913 | |||
4914 | |||
4915 | <hr><h3><a name="luaL_buffinit"><code>luaL_buffinit</code></a></h3><p> | ||
4916 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
4917 | <pre>void luaL_buffinit (lua_State *L, luaL_Buffer *B);</pre> | ||
4918 | |||
4919 | <p> | ||
4920 | Initializes a buffer <code>B</code>. | ||
4921 | This function does not allocate any space; | ||
4922 | the buffer must be declared as a variable | ||
4923 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). | ||
4924 | |||
4925 | |||
4926 | |||
4927 | |||
4928 | |||
4929 | <hr><h3><a name="luaL_callmeta"><code>luaL_callmeta</code></a></h3><p> | ||
4930 | <span class="apii">[-0, +(0|1), <em>e</em>]</span> | ||
4931 | <pre>int luaL_callmeta (lua_State *L, int obj, const char *e);</pre> | ||
4932 | |||
4933 | <p> | ||
4934 | Calls a metamethod. | ||
4935 | |||
4936 | |||
4937 | <p> | ||
4938 | If the object at index <code>obj</code> has a metatable and this | ||
4939 | metatable has a field <code>e</code>, | ||
4940 | this function calls this field and passes the object as its only argument. | ||
4941 | In this case this function returns 1 and pushes onto the | ||
4942 | stack the value returned by the call. | ||
4943 | If there is no metatable or no metamethod, | ||
4944 | this function returns 0 (without pushing any value on the stack). | ||
4945 | |||
4946 | |||
4947 | |||
4948 | |||
4949 | |||
4950 | <hr><h3><a name="luaL_checkany"><code>luaL_checkany</code></a></h3><p> | ||
4951 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
4952 | <pre>void luaL_checkany (lua_State *L, int narg);</pre> | ||
4953 | |||
4954 | <p> | ||
4955 | Checks whether the function has an argument | ||
4956 | of any type (including <b>nil</b>) at position <code>narg</code>. | ||
4957 | |||
4958 | |||
4959 | |||
4960 | |||
4961 | |||
4962 | <hr><h3><a name="luaL_checkint"><code>luaL_checkint</code></a></h3><p> | ||
4963 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
4964 | <pre>int luaL_checkint (lua_State *L, int narg);</pre> | ||
4965 | |||
4966 | <p> | ||
4967 | Checks whether the function argument <code>narg</code> is a number | ||
4968 | and returns this number cast to an <code>int</code>. | ||
4969 | |||
4970 | |||
4971 | |||
4972 | |||
4973 | |||
4974 | <hr><h3><a name="luaL_checkinteger"><code>luaL_checkinteger</code></a></h3><p> | ||
4975 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
4976 | <pre>lua_Integer luaL_checkinteger (lua_State *L, int narg);</pre> | ||
4977 | |||
4978 | <p> | ||
4979 | Checks whether the function argument <code>narg</code> is a number | ||
4980 | and returns this number cast to a <a href="#lua_Integer"><code>lua_Integer</code></a>. | ||
4981 | |||
4982 | |||
4983 | |||
4984 | |||
4985 | |||
4986 | <hr><h3><a name="luaL_checklong"><code>luaL_checklong</code></a></h3><p> | ||
4987 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
4988 | <pre>long luaL_checklong (lua_State *L, int narg);</pre> | ||
4989 | |||
4990 | <p> | ||
4991 | Checks whether the function argument <code>narg</code> is a number | ||
4992 | and returns this number cast to a <code>long</code>. | ||
4993 | |||
4994 | |||
4995 | |||
4996 | |||
4997 | |||
4998 | <hr><h3><a name="luaL_checklstring"><code>luaL_checklstring</code></a></h3><p> | ||
4999 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5000 | <pre>const char *luaL_checklstring (lua_State *L, int narg, size_t *l);</pre> | ||
5001 | |||
5002 | <p> | ||
5003 | Checks whether the function argument <code>narg</code> is a string | ||
5004 | and returns this string; | ||
5005 | if <code>l</code> is not <code>NULL</code> fills <code>*l</code> | ||
5006 | with the string's length. | ||
5007 | |||
5008 | |||
5009 | <p> | ||
5010 | This function uses <a href="#lua_tolstring"><code>lua_tolstring</code></a> to get its result, | ||
5011 | so all conversions and caveats of that function apply here. | ||
5012 | |||
5013 | |||
5014 | |||
5015 | |||
5016 | |||
5017 | <hr><h3><a name="luaL_checknumber"><code>luaL_checknumber</code></a></h3><p> | ||
5018 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5019 | <pre>lua_Number luaL_checknumber (lua_State *L, int narg);</pre> | ||
5020 | |||
5021 | <p> | ||
5022 | Checks whether the function argument <code>narg</code> is a number | ||
5023 | and returns this number. | ||
5024 | |||
5025 | |||
5026 | |||
5027 | |||
5028 | |||
5029 | <hr><h3><a name="luaL_checkoption"><code>luaL_checkoption</code></a></h3><p> | ||
5030 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5031 | <pre>int luaL_checkoption (lua_State *L, | ||
5032 | int narg, | ||
5033 | const char *def, | ||
5034 | const char *const lst[]);</pre> | ||
5035 | |||
5036 | <p> | ||
5037 | Checks whether the function argument <code>narg</code> is a string and | ||
5038 | searches for this string in the array <code>lst</code> | ||
5039 | (which must be NULL-terminated). | ||
5040 | Returns the index in the array where the string was found. | ||
5041 | Raises an error if the argument is not a string or | ||
5042 | if the string cannot be found. | ||
5043 | |||
5044 | |||
5045 | <p> | ||
5046 | If <code>def</code> is not <code>NULL</code>, | ||
5047 | the function uses <code>def</code> as a default value when | ||
5048 | there is no argument <code>narg</code> or if this argument is <b>nil</b>. | ||
5049 | |||
5050 | |||
5051 | <p> | ||
5052 | This is a useful function for mapping strings to C enums. | ||
5053 | (The usual convention in Lua libraries is | ||
5054 | to use strings instead of numbers to select options.) | ||
5055 | |||
5056 | |||
5057 | |||
5058 | |||
5059 | |||
5060 | <hr><h3><a name="luaL_checkstack"><code>luaL_checkstack</code></a></h3><p> | ||
5061 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5062 | <pre>void luaL_checkstack (lua_State *L, int sz, const char *msg);</pre> | ||
5063 | |||
5064 | <p> | ||
5065 | Grows the stack size to <code>top + sz</code> elements, | ||
5066 | raising an error if the stack cannot grow to that size. | ||
5067 | <code>msg</code> is an additional text to go into the error message. | ||
5068 | |||
5069 | |||
5070 | |||
5071 | |||
5072 | |||
5073 | <hr><h3><a name="luaL_checkstring"><code>luaL_checkstring</code></a></h3><p> | ||
5074 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5075 | <pre>const char *luaL_checkstring (lua_State *L, int narg);</pre> | ||
5076 | |||
5077 | <p> | ||
5078 | Checks whether the function argument <code>narg</code> is a string | ||
5079 | and returns this string. | ||
5080 | |||
5081 | |||
5082 | <p> | ||
5083 | This function uses <a href="#lua_tolstring"><code>lua_tolstring</code></a> to get its result, | ||
5084 | so all conversions and caveats of that function apply here. | ||
5085 | |||
5086 | |||
5087 | |||
5088 | |||
5089 | |||
5090 | <hr><h3><a name="luaL_checktype"><code>luaL_checktype</code></a></h3><p> | ||
5091 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5092 | <pre>void luaL_checktype (lua_State *L, int narg, int t);</pre> | ||
5093 | |||
5094 | <p> | ||
5095 | Checks whether the function argument <code>narg</code> has type <code>t</code>. | ||
5096 | See <a href="#lua_type"><code>lua_type</code></a> for the encoding of types for <code>t</code>. | ||
5097 | |||
5098 | |||
5099 | |||
5100 | |||
5101 | |||
5102 | <hr><h3><a name="luaL_checkudata"><code>luaL_checkudata</code></a></h3><p> | ||
5103 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5104 | <pre>void *luaL_checkudata (lua_State *L, int narg, const char *tname);</pre> | ||
5105 | |||
5106 | <p> | ||
5107 | Checks whether the function argument <code>narg</code> is a userdata | ||
5108 | of the type <code>tname</code> (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>). | ||
5109 | |||
5110 | |||
5111 | |||
5112 | |||
5113 | |||
5114 | <hr><h3><a name="luaL_dofile"><code>luaL_dofile</code></a></h3><p> | ||
5115 | <span class="apii">[-0, +?, <em>m</em>]</span> | ||
5116 | <pre>int luaL_dofile (lua_State *L, const char *filename);</pre> | ||
5117 | |||
5118 | <p> | ||
5119 | Loads and runs the given file. | ||
5120 | It is defined as the following macro: | ||
5121 | |||
5122 | <pre> | ||
5123 | (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0)) | ||
5124 | </pre><p> | ||
5125 | It returns 0 if there are no errors | ||
5126 | or 1 in case of errors. | ||
5127 | |||
5128 | |||
5129 | |||
5130 | |||
5131 | |||
5132 | <hr><h3><a name="luaL_dostring"><code>luaL_dostring</code></a></h3><p> | ||
5133 | <span class="apii">[-0, +?, <em>m</em>]</span> | ||
5134 | <pre>int luaL_dostring (lua_State *L, const char *str);</pre> | ||
5135 | |||
5136 | <p> | ||
5137 | Loads and runs the given string. | ||
5138 | It is defined as the following macro: | ||
5139 | |||
5140 | <pre> | ||
5141 | (luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0)) | ||
5142 | </pre><p> | ||
5143 | It returns 0 if there are no errors | ||
5144 | or 1 in case of errors. | ||
5145 | |||
5146 | |||
5147 | |||
5148 | |||
5149 | |||
5150 | <hr><h3><a name="luaL_error"><code>luaL_error</code></a></h3><p> | ||
5151 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5152 | <pre>int luaL_error (lua_State *L, const char *fmt, ...);</pre> | ||
5153 | |||
5154 | <p> | ||
5155 | Raises an error. | ||
5156 | The error message format is given by <code>fmt</code> | ||
5157 | plus any extra arguments, | ||
5158 | following the same rules of <a href="#lua_pushfstring"><code>lua_pushfstring</code></a>. | ||
5159 | It also adds at the beginning of the message the file name and | ||
5160 | the line number where the error occurred, | ||
5161 | if this information is available. | ||
5162 | |||
5163 | |||
5164 | <p> | ||
5165 | This function never returns, | ||
5166 | but it is an idiom to use it in C functions | ||
5167 | as <code>return luaL_error(<em>args</em>)</code>. | ||
5168 | |||
5169 | |||
5170 | |||
5171 | |||
5172 | |||
5173 | <hr><h3><a name="luaL_getmetafield"><code>luaL_getmetafield</code></a></h3><p> | ||
5174 | <span class="apii">[-0, +(0|1), <em>m</em>]</span> | ||
5175 | <pre>int luaL_getmetafield (lua_State *L, int obj, const char *e);</pre> | ||
5176 | |||
5177 | <p> | ||
5178 | Pushes onto the stack the field <code>e</code> from the metatable | ||
5179 | of the object at index <code>obj</code>. | ||
5180 | If the object does not have a metatable, | ||
5181 | or if the metatable does not have this field, | ||
5182 | returns 0 and pushes nothing. | ||
5183 | |||
5184 | |||
5185 | |||
5186 | |||
5187 | |||
5188 | <hr><h3><a name="luaL_getmetatable"><code>luaL_getmetatable</code></a></h3><p> | ||
5189 | <span class="apii">[-0, +1, <em>-</em>]</span> | ||
5190 | <pre>void luaL_getmetatable (lua_State *L, const char *tname);</pre> | ||
5191 | |||
5192 | <p> | ||
5193 | Pushes onto the stack the metatable associated with name <code>tname</code> | ||
5194 | in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>). | ||
5195 | |||
5196 | |||
5197 | |||
5198 | |||
5199 | |||
5200 | <hr><h3><a name="luaL_gsub"><code>luaL_gsub</code></a></h3><p> | ||
5201 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
5202 | <pre>const char *luaL_gsub (lua_State *L, | ||
5203 | const char *s, | ||
5204 | const char *p, | ||
5205 | const char *r);</pre> | ||
5206 | |||
5207 | <p> | ||
5208 | Creates a copy of string <code>s</code> by replacing | ||
5209 | any occurrence of the string <code>p</code> | ||
5210 | with the string <code>r</code>. | ||
5211 | Pushes the resulting string on the stack and returns it. | ||
5212 | |||
5213 | |||
5214 | |||
5215 | |||
5216 | |||
5217 | <hr><h3><a name="luaL_loadbuffer"><code>luaL_loadbuffer</code></a></h3><p> | ||
5218 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
5219 | <pre>int luaL_loadbuffer (lua_State *L, | ||
5220 | const char *buff, | ||
5221 | size_t sz, | ||
5222 | const char *name);</pre> | ||
5223 | |||
5224 | <p> | ||
5225 | Loads a buffer as a Lua chunk. | ||
5226 | This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in the | ||
5227 | buffer pointed to by <code>buff</code> with size <code>sz</code>. | ||
5228 | |||
5229 | |||
5230 | <p> | ||
5231 | This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>. | ||
5232 | <code>name</code> is the chunk name, | ||
5233 | used for debug information and error messages. | ||
5234 | |||
5235 | |||
5236 | |||
5237 | |||
5238 | |||
5239 | <hr><h3><a name="luaL_loadfile"><code>luaL_loadfile</code></a></h3><p> | ||
5240 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
5241 | <pre>int luaL_loadfile (lua_State *L, const char *filename);</pre> | ||
5242 | |||
5243 | <p> | ||
5244 | Loads a file as a Lua chunk. | ||
5245 | This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in the file | ||
5246 | named <code>filename</code>. | ||
5247 | If <code>filename</code> is <code>NULL</code>, | ||
5248 | then it loads from the standard input. | ||
5249 | The first line in the file is ignored if it starts with a <code>#</code>. | ||
5250 | |||
5251 | |||
5252 | <p> | ||
5253 | This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>, | ||
5254 | but it has an extra error code <a name="pdf-LUA_ERRFILE"><code>LUA_ERRFILE</code></a> | ||
5255 | if it cannot open/read the file. | ||
5256 | |||
5257 | |||
5258 | <p> | ||
5259 | As <a href="#lua_load"><code>lua_load</code></a>, this function only loads the chunk; | ||
5260 | it does not run it. | ||
5261 | |||
5262 | |||
5263 | |||
5264 | |||
5265 | |||
5266 | <hr><h3><a name="luaL_loadstring"><code>luaL_loadstring</code></a></h3><p> | ||
5267 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
5268 | <pre>int luaL_loadstring (lua_State *L, const char *s);</pre> | ||
5269 | |||
5270 | <p> | ||
5271 | Loads a string as a Lua chunk. | ||
5272 | This function uses <a href="#lua_load"><code>lua_load</code></a> to load the chunk in | ||
5273 | the zero-terminated string <code>s</code>. | ||
5274 | |||
5275 | |||
5276 | <p> | ||
5277 | This function returns the same results as <a href="#lua_load"><code>lua_load</code></a>. | ||
5278 | |||
5279 | |||
5280 | <p> | ||
5281 | Also as <a href="#lua_load"><code>lua_load</code></a>, this function only loads the chunk; | ||
5282 | it does not run it. | ||
5283 | |||
5284 | |||
5285 | |||
5286 | |||
5287 | |||
5288 | <hr><h3><a name="luaL_newmetatable"><code>luaL_newmetatable</code></a></h3><p> | ||
5289 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
5290 | <pre>int luaL_newmetatable (lua_State *L, const char *tname);</pre> | ||
5291 | |||
5292 | <p> | ||
5293 | If the registry already has the key <code>tname</code>, | ||
5294 | returns 0. | ||
5295 | Otherwise, | ||
5296 | creates a new table to be used as a metatable for userdata, | ||
5297 | adds it to the registry with key <code>tname</code>, | ||
5298 | and returns 1. | ||
5299 | |||
5300 | |||
5301 | <p> | ||
5302 | In both cases pushes onto the stack the final value associated | ||
5303 | with <code>tname</code> in the registry. | ||
5304 | |||
5305 | |||
5306 | |||
5307 | |||
5308 | |||
5309 | <hr><h3><a name="luaL_newstate"><code>luaL_newstate</code></a></h3><p> | ||
5310 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
5311 | <pre>lua_State *luaL_newstate (void);</pre> | ||
5312 | |||
5313 | <p> | ||
5314 | Creates a new Lua state. | ||
5315 | It calls <a href="#lua_newstate"><code>lua_newstate</code></a> with an | ||
5316 | allocator based on the standard C <code>realloc</code> function | ||
5317 | and then sets a panic function (see <a href="#lua_atpanic"><code>lua_atpanic</code></a>) that prints | ||
5318 | an error message to the standard error output in case of fatal | ||
5319 | errors. | ||
5320 | |||
5321 | |||
5322 | <p> | ||
5323 | Returns the new state, | ||
5324 | or <code>NULL</code> if there is a memory allocation error. | ||
5325 | |||
5326 | |||
5327 | |||
5328 | |||
5329 | |||
5330 | <hr><h3><a name="luaL_openlibs"><code>luaL_openlibs</code></a></h3><p> | ||
5331 | <span class="apii">[-0, +0, <em>m</em>]</span> | ||
5332 | <pre>void luaL_openlibs (lua_State *L);</pre> | ||
5333 | |||
5334 | <p> | ||
5335 | Opens all standard Lua libraries into the given state. | ||
5336 | |||
5337 | |||
5338 | |||
5339 | |||
5340 | |||
5341 | <hr><h3><a name="luaL_optint"><code>luaL_optint</code></a></h3><p> | ||
5342 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5343 | <pre>int luaL_optint (lua_State *L, int narg, int d);</pre> | ||
5344 | |||
5345 | <p> | ||
5346 | If the function argument <code>narg</code> is a number, | ||
5347 | returns this number cast to an <code>int</code>. | ||
5348 | If this argument is absent or is <b>nil</b>, | ||
5349 | returns <code>d</code>. | ||
5350 | Otherwise, raises an error. | ||
5351 | |||
5352 | |||
5353 | |||
5354 | |||
5355 | |||
5356 | <hr><h3><a name="luaL_optinteger"><code>luaL_optinteger</code></a></h3><p> | ||
5357 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5358 | <pre>lua_Integer luaL_optinteger (lua_State *L, | ||
5359 | int narg, | ||
5360 | lua_Integer d);</pre> | ||
5361 | |||
5362 | <p> | ||
5363 | If the function argument <code>narg</code> is a number, | ||
5364 | returns this number cast to a <a href="#lua_Integer"><code>lua_Integer</code></a>. | ||
5365 | If this argument is absent or is <b>nil</b>, | ||
5366 | returns <code>d</code>. | ||
5367 | Otherwise, raises an error. | ||
5368 | |||
5369 | |||
5370 | |||
5371 | |||
5372 | |||
5373 | <hr><h3><a name="luaL_optlong"><code>luaL_optlong</code></a></h3><p> | ||
5374 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5375 | <pre>long luaL_optlong (lua_State *L, int narg, long d);</pre> | ||
5376 | |||
5377 | <p> | ||
5378 | If the function argument <code>narg</code> is a number, | ||
5379 | returns this number cast to a <code>long</code>. | ||
5380 | If this argument is absent or is <b>nil</b>, | ||
5381 | returns <code>d</code>. | ||
5382 | Otherwise, raises an error. | ||
5383 | |||
5384 | |||
5385 | |||
5386 | |||
5387 | |||
5388 | <hr><h3><a name="luaL_optlstring"><code>luaL_optlstring</code></a></h3><p> | ||
5389 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5390 | <pre>const char *luaL_optlstring (lua_State *L, | ||
5391 | int narg, | ||
5392 | const char *d, | ||
5393 | size_t *l);</pre> | ||
5394 | |||
5395 | <p> | ||
5396 | If the function argument <code>narg</code> is a string, | ||
5397 | returns this string. | ||
5398 | If this argument is absent or is <b>nil</b>, | ||
5399 | returns <code>d</code>. | ||
5400 | Otherwise, raises an error. | ||
5401 | |||
5402 | |||
5403 | <p> | ||
5404 | If <code>l</code> is not <code>NULL</code>, | ||
5405 | fills the position <code>*l</code> with the results's length. | ||
5406 | |||
5407 | |||
5408 | |||
5409 | |||
5410 | |||
5411 | <hr><h3><a name="luaL_optnumber"><code>luaL_optnumber</code></a></h3><p> | ||
5412 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5413 | <pre>lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number d);</pre> | ||
5414 | |||
5415 | <p> | ||
5416 | If the function argument <code>narg</code> is a number, | ||
5417 | returns this number. | ||
5418 | If this argument is absent or is <b>nil</b>, | ||
5419 | returns <code>d</code>. | ||
5420 | Otherwise, raises an error. | ||
5421 | |||
5422 | |||
5423 | |||
5424 | |||
5425 | |||
5426 | <hr><h3><a name="luaL_optstring"><code>luaL_optstring</code></a></h3><p> | ||
5427 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5428 | <pre>const char *luaL_optstring (lua_State *L, | ||
5429 | int narg, | ||
5430 | const char *d);</pre> | ||
5431 | |||
5432 | <p> | ||
5433 | If the function argument <code>narg</code> is a string, | ||
5434 | returns this string. | ||
5435 | If this argument is absent or is <b>nil</b>, | ||
5436 | returns <code>d</code>. | ||
5437 | Otherwise, raises an error. | ||
5438 | |||
5439 | |||
5440 | |||
5441 | |||
5442 | |||
5443 | <hr><h3><a name="luaL_prepbuffer"><code>luaL_prepbuffer</code></a></h3><p> | ||
5444 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
5445 | <pre>char *luaL_prepbuffer (luaL_Buffer *B);</pre> | ||
5446 | |||
5447 | <p> | ||
5448 | Returns an address to a space of size <a name="pdf-LUAL_BUFFERSIZE"><code>LUAL_BUFFERSIZE</code></a> | ||
5449 | where you can copy a string to be added to buffer <code>B</code> | ||
5450 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). | ||
5451 | After copying the string into this space you must call | ||
5452 | <a href="#luaL_addsize"><code>luaL_addsize</code></a> with the size of the string to actually add | ||
5453 | it to the buffer. | ||
5454 | |||
5455 | |||
5456 | |||
5457 | |||
5458 | |||
5459 | <hr><h3><a name="luaL_pushresult"><code>luaL_pushresult</code></a></h3><p> | ||
5460 | <span class="apii">[-?, +1, <em>m</em>]</span> | ||
5461 | <pre>void luaL_pushresult (luaL_Buffer *B);</pre> | ||
5462 | |||
5463 | <p> | ||
5464 | Finishes the use of buffer <code>B</code> leaving the final string on | ||
5465 | the top of the stack. | ||
5466 | |||
5467 | |||
5468 | |||
5469 | |||
5470 | |||
5471 | <hr><h3><a name="luaL_ref"><code>luaL_ref</code></a></h3><p> | ||
5472 | <span class="apii">[-1, +0, <em>m</em>]</span> | ||
5473 | <pre>int luaL_ref (lua_State *L, int t);</pre> | ||
5474 | |||
5475 | <p> | ||
5476 | Creates and returns a <em>reference</em>, | ||
5477 | in the table at index <code>t</code>, | ||
5478 | for the object at the top of the stack (and pops the object). | ||
5479 | |||
5480 | |||
5481 | <p> | ||
5482 | A reference is a unique integer key. | ||
5483 | As long as you do not manually add integer keys into table <code>t</code>, | ||
5484 | <a href="#luaL_ref"><code>luaL_ref</code></a> ensures the uniqueness of the key it returns. | ||
5485 | You can retrieve an object referred by reference <code>r</code> | ||
5486 | by calling <code>lua_rawgeti(L, t, r)</code>. | ||
5487 | Function <a href="#luaL_unref"><code>luaL_unref</code></a> frees a reference and its associated object. | ||
5488 | |||
5489 | |||
5490 | <p> | ||
5491 | If the object at the top of the stack is <b>nil</b>, | ||
5492 | <a href="#luaL_ref"><code>luaL_ref</code></a> returns the constant <a name="pdf-LUA_REFNIL"><code>LUA_REFNIL</code></a>. | ||
5493 | The constant <a name="pdf-LUA_NOREF"><code>LUA_NOREF</code></a> is guaranteed to be different | ||
5494 | from any reference returned by <a href="#luaL_ref"><code>luaL_ref</code></a>. | ||
5495 | |||
5496 | |||
5497 | |||
5498 | |||
5499 | |||
5500 | <hr><h3><a name="luaL_Reg"><code>luaL_Reg</code></a></h3> | ||
5501 | <pre>typedef struct luaL_Reg { | ||
5502 | const char *name; | ||
5503 | lua_CFunction func; | ||
5504 | } luaL_Reg;</pre> | ||
5505 | |||
5506 | <p> | ||
5507 | Type for arrays of functions to be registered by | ||
5508 | <a href="#luaL_register"><code>luaL_register</code></a>. | ||
5509 | <code>name</code> is the function name and <code>func</code> is a pointer to | ||
5510 | the function. | ||
5511 | Any array of <a href="#luaL_Reg"><code>luaL_Reg</code></a> must end with an sentinel entry | ||
5512 | in which both <code>name</code> and <code>func</code> are <code>NULL</code>. | ||
5513 | |||
5514 | |||
5515 | |||
5516 | |||
5517 | |||
5518 | <hr><h3><a name="luaL_register"><code>luaL_register</code></a></h3><p> | ||
5519 | <span class="apii">[-(0|1), +1, <em>m</em>]</span> | ||
5520 | <pre>void luaL_register (lua_State *L, | ||
5521 | const char *libname, | ||
5522 | const luaL_Reg *l);</pre> | ||
5523 | |||
5524 | <p> | ||
5525 | Opens a library. | ||
5526 | |||
5527 | |||
5528 | <p> | ||
5529 | When called with <code>libname</code> equal to <code>NULL</code>, | ||
5530 | it simply registers all functions in the list <code>l</code> | ||
5531 | (see <a href="#luaL_Reg"><code>luaL_Reg</code></a>) into the table on the top of the stack. | ||
5532 | |||
5533 | |||
5534 | <p> | ||
5535 | When called with a non-null <code>libname</code>, | ||
5536 | <code>luaL_register</code> creates a new table <code>t</code>, | ||
5537 | sets it as the value of the global variable <code>libname</code>, | ||
5538 | sets it as the value of <code>package.loaded[libname]</code>, | ||
5539 | and registers on it all functions in the list <code>l</code>. | ||
5540 | If there is a table in <code>package.loaded[libname]</code> or in | ||
5541 | variable <code>libname</code>, | ||
5542 | reuses this table instead of creating a new one. | ||
5543 | |||
5544 | |||
5545 | <p> | ||
5546 | In any case the function leaves the table | ||
5547 | on the top of the stack. | ||
5548 | |||
5549 | |||
5550 | |||
5551 | |||
5552 | |||
5553 | <hr><h3><a name="luaL_typename"><code>luaL_typename</code></a></h3><p> | ||
5554 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
5555 | <pre>const char *luaL_typename (lua_State *L, int index);</pre> | ||
5556 | |||
5557 | <p> | ||
5558 | Returns the name of the type of the value at the given index. | ||
5559 | |||
5560 | |||
5561 | |||
5562 | |||
5563 | |||
5564 | <hr><h3><a name="luaL_typerror"><code>luaL_typerror</code></a></h3><p> | ||
5565 | <span class="apii">[-0, +0, <em>v</em>]</span> | ||
5566 | <pre>int luaL_typerror (lua_State *L, int narg, const char *tname);</pre> | ||
5567 | |||
5568 | <p> | ||
5569 | Generates an error with a message like the following: | ||
5570 | |||
5571 | <pre> | ||
5572 | <em>location</em>: bad argument <em>narg</em> to '<em>func</em>' (<em>tname</em> expected, got <em>rt</em>) | ||
5573 | </pre><p> | ||
5574 | where <code><em>location</em></code> is produced by <a href="#luaL_where"><code>luaL_where</code></a>, | ||
5575 | <code><em>func</em></code> is the name of the current function, | ||
5576 | and <code><em>rt</em></code> is the type name of the actual argument. | ||
5577 | |||
5578 | |||
5579 | |||
5580 | |||
5581 | |||
5582 | <hr><h3><a name="luaL_unref"><code>luaL_unref</code></a></h3><p> | ||
5583 | <span class="apii">[-0, +0, <em>-</em>]</span> | ||
5584 | <pre>void luaL_unref (lua_State *L, int t, int ref);</pre> | ||
5585 | |||
5586 | <p> | ||
5587 | Releases reference <code>ref</code> from the table at index <code>t</code> | ||
5588 | (see <a href="#luaL_ref"><code>luaL_ref</code></a>). | ||
5589 | The entry is removed from the table, | ||
5590 | so that the referred object can be collected. | ||
5591 | The reference <code>ref</code> is also freed to be used again. | ||
5592 | |||
5593 | |||
5594 | <p> | ||
5595 | If <code>ref</code> is <a href="#pdf-LUA_NOREF"><code>LUA_NOREF</code></a> or <a href="#pdf-LUA_REFNIL"><code>LUA_REFNIL</code></a>, | ||
5596 | <a href="#luaL_unref"><code>luaL_unref</code></a> does nothing. | ||
5597 | |||
5598 | |||
5599 | |||
5600 | |||
5601 | |||
5602 | <hr><h3><a name="luaL_where"><code>luaL_where</code></a></h3><p> | ||
5603 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
5604 | <pre>void luaL_where (lua_State *L, int lvl);</pre> | ||
5605 | |||
5606 | <p> | ||
5607 | Pushes onto the stack a string identifying the current position | ||
5608 | of the control at level <code>lvl</code> in the call stack. | ||
5609 | Typically this string has the following format: | ||
5610 | |||
5611 | <pre> | ||
5612 | <em>chunkname</em>:<em>currentline</em>: | ||
5613 | </pre><p> | ||
5614 | Level 0 is the running function, | ||
5615 | level 1 is the function that called the running function, | ||
5616 | etc. | ||
5617 | |||
5618 | |||
5619 | <p> | ||
5620 | This function is used to build a prefix for error messages. | ||
5621 | |||
5622 | |||
5623 | |||
5624 | |||
5625 | |||
5626 | |||
5627 | |||
5628 | <h1>5 - <a name="5">Standard Libraries</a></h1> | ||
5629 | |||
5630 | <p> | ||
5631 | The standard Lua libraries provide useful functions | ||
5632 | that are implemented directly through the C API. | ||
5633 | Some of these functions provide essential services to the language | ||
5634 | (e.g., <a href="#pdf-type"><code>type</code></a> and <a href="#pdf-getmetatable"><code>getmetatable</code></a>); | ||
5635 | others provide access to "outside" services (e.g., I/O); | ||
5636 | and others could be implemented in Lua itself, | ||
5637 | but are quite useful or have critical performance requirements that | ||
5638 | deserve an implementation in C (e.g., <a href="#pdf-table.sort"><code>table.sort</code></a>). | ||
5639 | |||
5640 | |||
5641 | <p> | ||
5642 | All libraries are implemented through the official C API | ||
5643 | and are provided as separate C modules. | ||
5644 | Currently, Lua has the following standard libraries: | ||
5645 | |||
5646 | <ul> | ||
5647 | |||
5648 | <li>basic library,</li> which includes the coroutine sub-library; | ||
5649 | |||
5650 | <li>package library;</li> | ||
5651 | |||
5652 | <li>string manipulation;</li> | ||
5653 | |||
5654 | <li>table manipulation;</li> | ||
5655 | |||
5656 | <li>mathematical functions (sin, log, etc.);</li> | ||
5657 | |||
5658 | <li>input and output;</li> | ||
5659 | |||
5660 | <li>operating system facilities;</li> | ||
5661 | |||
5662 | <li>debug facilities.</li> | ||
5663 | |||
5664 | </ul><p> | ||
5665 | Except for the basic and package libraries, | ||
5666 | each library provides all its functions as fields of a global table | ||
5667 | or as methods of its objects. | ||
5668 | |||
5669 | |||
5670 | <p> | ||
5671 | To have access to these libraries, | ||
5672 | the C host program should call the <a href="#luaL_openlibs"><code>luaL_openlibs</code></a> function, | ||
5673 | which opens all standard libraries. | ||
5674 | Alternatively, | ||
5675 | it can open them individually by calling | ||
5676 | <a name="pdf-luaopen_base"><code>luaopen_base</code></a> (for the basic library), | ||
5677 | <a name="pdf-luaopen_package"><code>luaopen_package</code></a> (for the package library), | ||
5678 | <a name="pdf-luaopen_string"><code>luaopen_string</code></a> (for the string library), | ||
5679 | <a name="pdf-luaopen_table"><code>luaopen_table</code></a> (for the table library), | ||
5680 | <a name="pdf-luaopen_math"><code>luaopen_math</code></a> (for the mathematical library), | ||
5681 | <a name="pdf-luaopen_io"><code>luaopen_io</code></a> (for the I/O library), | ||
5682 | <a name="pdf-luaopen_os"><code>luaopen_os</code></a> (for the Operating System library), | ||
5683 | and <a name="pdf-luaopen_debug"><code>luaopen_debug</code></a> (for the debug library). | ||
5684 | These functions are declared in <a name="pdf-lualib.h"><code>lualib.h</code></a> | ||
5685 | and should not be called directly: | ||
5686 | you must call them like any other Lua C function, | ||
5687 | e.g., by using <a href="#lua_call"><code>lua_call</code></a>. | ||
5688 | |||
5689 | |||
5690 | |||
5691 | <h2>5.1 - <a name="5.1">Basic Functions</a></h2> | ||
5692 | |||
5693 | <p> | ||
5694 | The basic library provides some core functions to Lua. | ||
5695 | If you do not include this library in your application, | ||
5696 | you should check carefully whether you need to provide | ||
5697 | implementations for some of its facilities. | ||
5698 | |||
5699 | |||
5700 | <p> | ||
5701 | <hr><h3><a name="pdf-assert"><code>assert (v [, message])</code></a></h3> | ||
5702 | Issues an error when | ||
5703 | the value of its argument <code>v</code> is false (i.e., <b>nil</b> or <b>false</b>); | ||
5704 | otherwise, returns all its arguments. | ||
5705 | <code>message</code> is an error message; | ||
5706 | when absent, it defaults to "assertion failed!" | ||
5707 | |||
5708 | |||
5709 | |||
5710 | |||
5711 | <p> | ||
5712 | <hr><h3><a name="pdf-collectgarbage"><code>collectgarbage (opt [, arg])</code></a></h3> | ||
5713 | |||
5714 | |||
5715 | <p> | ||
5716 | This function is a generic interface to the garbage collector. | ||
5717 | It performs different functions according to its first argument, <code>opt</code>: | ||
5718 | |||
5719 | <ul> | ||
5720 | |||
5721 | <li><b>"stop":</b> | ||
5722 | stops the garbage collector. | ||
5723 | </li> | ||
5724 | |||
5725 | <li><b>"restart":</b> | ||
5726 | restarts the garbage collector. | ||
5727 | </li> | ||
5728 | |||
5729 | <li><b>"collect":</b> | ||
5730 | performs a full garbage-collection cycle. | ||
5731 | </li> | ||
5732 | |||
5733 | <li><b>"count":</b> | ||
5734 | returns the total memory in use by Lua (in Kbytes). | ||
5735 | </li> | ||
5736 | |||
5737 | <li><b>"step":</b> | ||
5738 | performs a garbage-collection step. | ||
5739 | The step "size" is controlled by <code>arg</code> | ||
5740 | (larger values mean more steps) in a non-specified way. | ||
5741 | If you want to control the step size | ||
5742 | you must experimentally tune the value of <code>arg</code>. | ||
5743 | Returns <b>true</b> if the step finished a collection cycle. | ||
5744 | </li> | ||
5745 | |||
5746 | <li><b>"setpause":</b> | ||
5747 | sets <code>arg</code> as the new value for the <em>pause</em> of | ||
5748 | the collector (see <a href="#2.10">§2.10</a>). | ||
5749 | Returns the previous value for <em>pause</em>. | ||
5750 | </li> | ||
5751 | |||
5752 | <li><b>"setstepmul":</b> | ||
5753 | sets <code>arg</code> as the new value for the <em>step multiplier</em> of | ||
5754 | the collector (see <a href="#2.10">§2.10</a>). | ||
5755 | Returns the previous value for <em>step</em>. | ||
5756 | </li> | ||
5757 | |||
5758 | </ul> | ||
5759 | |||
5760 | |||
5761 | |||
5762 | <p> | ||
5763 | <hr><h3><a name="pdf-dofile"><code>dofile (filename)</code></a></h3> | ||
5764 | Opens the named file and executes its contents as a Lua chunk. | ||
5765 | When called without arguments, | ||
5766 | <code>dofile</code> executes the contents of the standard input (<code>stdin</code>). | ||
5767 | Returns all values returned by the chunk. | ||
5768 | In case of errors, <code>dofile</code> propagates the error | ||
5769 | to its caller (that is, <code>dofile</code> does not run in protected mode). | ||
5770 | |||
5771 | |||
5772 | |||
5773 | |||
5774 | <p> | ||
5775 | <hr><h3><a name="pdf-error"><code>error (message [, level])</code></a></h3> | ||
5776 | Terminates the last protected function called | ||
5777 | and returns <code>message</code> as the error message. | ||
5778 | Function <code>error</code> never returns. | ||
5779 | |||
5780 | |||
5781 | <p> | ||
5782 | Usually, <code>error</code> adds some information about the error position | ||
5783 | at the beginning of the message. | ||
5784 | The <code>level</code> argument specifies how to get the error position. | ||
5785 | With level 1 (the default), the error position is where the | ||
5786 | <code>error</code> function was called. | ||
5787 | Level 2 points the error to where the function | ||
5788 | that called <code>error</code> was called; and so on. | ||
5789 | Passing a level 0 avoids the addition of error position information | ||
5790 | to the message. | ||
5791 | |||
5792 | |||
5793 | |||
5794 | |||
5795 | <p> | ||
5796 | <hr><h3><a name="pdf-_G"><code>_G</code></a></h3> | ||
5797 | A global variable (not a function) that | ||
5798 | holds the global environment (that is, <code>_G._G = _G</code>). | ||
5799 | Lua itself does not use this variable; | ||
5800 | changing its value does not affect any environment, | ||
5801 | nor vice-versa. | ||
5802 | (Use <a href="#pdf-setfenv"><code>setfenv</code></a> to change environments.) | ||
5803 | |||
5804 | |||
5805 | |||
5806 | |||
5807 | <p> | ||
5808 | <hr><h3><a name="pdf-getfenv"><code>getfenv ([f])</code></a></h3> | ||
5809 | Returns the current environment in use by the function. | ||
5810 | <code>f</code> can be a Lua function or a number | ||
5811 | that specifies the function at that stack level: | ||
5812 | Level 1 is the function calling <code>getfenv</code>. | ||
5813 | If the given function is not a Lua function, | ||
5814 | or if <code>f</code> is 0, | ||
5815 | <code>getfenv</code> returns the global environment. | ||
5816 | The default for <code>f</code> is 1. | ||
5817 | |||
5818 | |||
5819 | |||
5820 | |||
5821 | <p> | ||
5822 | <hr><h3><a name="pdf-getmetatable"><code>getmetatable (object)</code></a></h3> | ||
5823 | |||
5824 | |||
5825 | <p> | ||
5826 | If <code>object</code> does not have a metatable, returns <b>nil</b>. | ||
5827 | Otherwise, | ||
5828 | if the object's metatable has a <code>"__metatable"</code> field, | ||
5829 | returns the associated value. | ||
5830 | Otherwise, returns the metatable of the given object. | ||
5831 | |||
5832 | |||
5833 | |||
5834 | |||
5835 | <p> | ||
5836 | <hr><h3><a name="pdf-ipairs"><code>ipairs (t)</code></a></h3> | ||
5837 | |||
5838 | |||
5839 | <p> | ||
5840 | Returns three values: an iterator function, the table <code>t</code>, and 0, | ||
5841 | so that the construction | ||
5842 | |||
5843 | <pre> | ||
5844 | for i,v in ipairs(t) do <em>body</em> end | ||
5845 | </pre><p> | ||
5846 | will iterate over the pairs (<code>1,t[1]</code>), (<code>2,t[2]</code>), ···, | ||
5847 | up to the first integer key absent from the table. | ||
5848 | |||
5849 | |||
5850 | |||
5851 | |||
5852 | <p> | ||
5853 | <hr><h3><a name="pdf-load"><code>load (func [, chunkname])</code></a></h3> | ||
5854 | |||
5855 | |||
5856 | <p> | ||
5857 | Loads a chunk using function <code>func</code> to get its pieces. | ||
5858 | Each call to <code>func</code> must return a string that concatenates | ||
5859 | with previous results. | ||
5860 | A return of an empty string, <b>nil</b>, or no value signals the end of the chunk. | ||
5861 | |||
5862 | |||
5863 | <p> | ||
5864 | If there are no errors, | ||
5865 | returns the compiled chunk as a function; | ||
5866 | otherwise, returns <b>nil</b> plus the error message. | ||
5867 | The environment of the returned function is the global environment. | ||
5868 | |||
5869 | |||
5870 | <p> | ||
5871 | <code>chunkname</code> is used as the chunk name for error messages | ||
5872 | and debug information. | ||
5873 | When absent, | ||
5874 | it defaults to "<code>=(load)</code>". | ||
5875 | |||
5876 | |||
5877 | |||
5878 | |||
5879 | <p> | ||
5880 | <hr><h3><a name="pdf-loadfile"><code>loadfile ([filename])</code></a></h3> | ||
5881 | |||
5882 | |||
5883 | <p> | ||
5884 | Similar to <a href="#pdf-load"><code>load</code></a>, | ||
5885 | but gets the chunk from file <code>filename</code> | ||
5886 | or from the standard input, | ||
5887 | if no file name is given. | ||
5888 | |||
5889 | |||
5890 | |||
5891 | |||
5892 | <p> | ||
5893 | <hr><h3><a name="pdf-loadstring"><code>loadstring (string [, chunkname])</code></a></h3> | ||
5894 | |||
5895 | |||
5896 | <p> | ||
5897 | Similar to <a href="#pdf-load"><code>load</code></a>, | ||
5898 | but gets the chunk from the given string. | ||
5899 | |||
5900 | |||
5901 | <p> | ||
5902 | To load and run a given string, use the idiom | ||
5903 | |||
5904 | <pre> | ||
5905 | assert(loadstring(s))() | ||
5906 | </pre> | ||
5907 | |||
5908 | <p> | ||
5909 | When absent, | ||
5910 | <code>chunkname</code> defaults to the given string. | ||
5911 | |||
5912 | |||
5913 | |||
5914 | |||
5915 | <p> | ||
5916 | <hr><h3><a name="pdf-next"><code>next (table [, index])</code></a></h3> | ||
5917 | |||
5918 | |||
5919 | <p> | ||
5920 | Allows a program to traverse all fields of a table. | ||
5921 | Its first argument is a table and its second argument | ||
5922 | is an index in this table. | ||
5923 | <code>next</code> returns the next index of the table | ||
5924 | and its associated value. | ||
5925 | When called with <b>nil</b> as its second argument, | ||
5926 | <code>next</code> returns an initial index | ||
5927 | and its associated value. | ||
5928 | When called with the last index, | ||
5929 | or with <b>nil</b> in an empty table, | ||
5930 | <code>next</code> returns <b>nil</b>. | ||
5931 | If the second argument is absent, then it is interpreted as <b>nil</b>. | ||
5932 | In particular, | ||
5933 | you can use <code>next(t)</code> to check whether a table is empty. | ||
5934 | |||
5935 | |||
5936 | <p> | ||
5937 | The order in which the indices are enumerated is not specified, | ||
5938 | <em>even for numeric indices</em>. | ||
5939 | (To traverse a table in numeric order, | ||
5940 | use a numerical <b>for</b> or the <a href="#pdf-ipairs"><code>ipairs</code></a> function.) | ||
5941 | |||
5942 | |||
5943 | <p> | ||
5944 | The behavior of <code>next</code> is <em>undefined</em> if, | ||
5945 | during the traversal, | ||
5946 | you assign any value to a non-existent field in the table. | ||
5947 | You may however modify existing fields. | ||
5948 | In particular, you may clear existing fields. | ||
5949 | |||
5950 | |||
5951 | |||
5952 | |||
5953 | <p> | ||
5954 | <hr><h3><a name="pdf-pairs"><code>pairs (t)</code></a></h3> | ||
5955 | |||
5956 | |||
5957 | <p> | ||
5958 | Returns three values: the <a href="#pdf-next"><code>next</code></a> function, the table <code>t</code>, and <b>nil</b>, | ||
5959 | so that the construction | ||
5960 | |||
5961 | <pre> | ||
5962 | for k,v in pairs(t) do <em>body</em> end | ||
5963 | </pre><p> | ||
5964 | will iterate over all key–value pairs of table <code>t</code>. | ||
5965 | |||
5966 | |||
5967 | <p> | ||
5968 | See function <a href="#pdf-next"><code>next</code></a> for the caveats of modifying | ||
5969 | the table during its traversal. | ||
5970 | |||
5971 | |||
5972 | |||
5973 | |||
5974 | <p> | ||
5975 | <hr><h3><a name="pdf-pcall"><code>pcall (f, arg1, ···)</code></a></h3> | ||
5976 | |||
5977 | |||
5978 | <p> | ||
5979 | Calls function <code>f</code> with | ||
5980 | the given arguments in <em>protected mode</em>. | ||
5981 | This means that any error inside <code>f</code> is not propagated; | ||
5982 | instead, <code>pcall</code> catches the error | ||
5983 | and returns a status code. | ||
5984 | Its first result is the status code (a boolean), | ||
5985 | which is true if the call succeeds without errors. | ||
5986 | In such case, <code>pcall</code> also returns all results from the call, | ||
5987 | after this first result. | ||
5988 | In case of any error, <code>pcall</code> returns <b>false</b> plus the error message. | ||
5989 | |||
5990 | |||
5991 | |||
5992 | |||
5993 | <p> | ||
5994 | <hr><h3><a name="pdf-print"><code>print (···)</code></a></h3> | ||
5995 | Receives any number of arguments, | ||
5996 | and prints their values to <code>stdout</code>, | ||
5997 | using the <a href="#pdf-tostring"><code>tostring</code></a> function to convert them to strings. | ||
5998 | <code>print</code> is not intended for formatted output, | ||
5999 | but only as a quick way to show a value, | ||
6000 | typically for debugging. | ||
6001 | For formatted output, use <a href="#pdf-string.format"><code>string.format</code></a>. | ||
6002 | |||
6003 | |||
6004 | |||
6005 | |||
6006 | <p> | ||
6007 | <hr><h3><a name="pdf-rawequal"><code>rawequal (v1, v2)</code></a></h3> | ||
6008 | Checks whether <code>v1</code> is equal to <code>v2</code>, | ||
6009 | without invoking any metamethod. | ||
6010 | Returns a boolean. | ||
6011 | |||
6012 | |||
6013 | |||
6014 | |||
6015 | <p> | ||
6016 | <hr><h3><a name="pdf-rawget"><code>rawget (table, index)</code></a></h3> | ||
6017 | Gets the real value of <code>table[index]</code>, | ||
6018 | without invoking any metamethod. | ||
6019 | <code>table</code> must be a table; | ||
6020 | <code>index</code> may be any value. | ||
6021 | |||
6022 | |||
6023 | |||
6024 | |||
6025 | <p> | ||
6026 | <hr><h3><a name="pdf-rawset"><code>rawset (table, index, value)</code></a></h3> | ||
6027 | Sets the real value of <code>table[index]</code> to <code>value</code>, | ||
6028 | without invoking any metamethod. | ||
6029 | <code>table</code> must be a table, | ||
6030 | <code>index</code> any value different from <b>nil</b>, | ||
6031 | and <code>value</code> any Lua value. | ||
6032 | |||
6033 | |||
6034 | <p> | ||
6035 | This function returns <code>table</code>. | ||
6036 | |||
6037 | |||
6038 | |||
6039 | |||
6040 | <p> | ||
6041 | <hr><h3><a name="pdf-select"><code>select (index, ···)</code></a></h3> | ||
6042 | |||
6043 | |||
6044 | <p> | ||
6045 | If <code>index</code> is a number, | ||
6046 | returns all arguments after argument number <code>index</code>. | ||
6047 | Otherwise, <code>index</code> must be the string <code>"#"</code>, | ||
6048 | and <code>select</code> returns the total number of extra arguments it received. | ||
6049 | |||
6050 | |||
6051 | |||
6052 | |||
6053 | <p> | ||
6054 | <hr><h3><a name="pdf-setfenv"><code>setfenv (f, table)</code></a></h3> | ||
6055 | |||
6056 | |||
6057 | <p> | ||
6058 | Sets the environment to be used by the given function. | ||
6059 | <code>f</code> can be a Lua function or a number | ||
6060 | that specifies the function at that stack level: | ||
6061 | Level 1 is the function calling <code>setfenv</code>. | ||
6062 | <code>setfenv</code> returns the given function. | ||
6063 | |||
6064 | |||
6065 | <p> | ||
6066 | As a special case, when <code>f</code> is 0 <code>setfenv</code> changes | ||
6067 | the environment of the running thread. | ||
6068 | In this case, <code>setfenv</code> returns no values. | ||
6069 | |||
6070 | |||
6071 | |||
6072 | |||
6073 | <p> | ||
6074 | <hr><h3><a name="pdf-setmetatable"><code>setmetatable (table, metatable)</code></a></h3> | ||
6075 | |||
6076 | |||
6077 | <p> | ||
6078 | Sets the metatable for the given table. | ||
6079 | (You cannot change the metatable of other types from Lua, only from C.) | ||
6080 | If <code>metatable</code> is <b>nil</b>, | ||
6081 | removes the metatable of the given table. | ||
6082 | If the original metatable has a <code>"__metatable"</code> field, | ||
6083 | raises an error. | ||
6084 | |||
6085 | |||
6086 | <p> | ||
6087 | This function returns <code>table</code>. | ||
6088 | |||
6089 | |||
6090 | |||
6091 | |||
6092 | <p> | ||
6093 | <hr><h3><a name="pdf-tonumber"><code>tonumber (e [, base])</code></a></h3> | ||
6094 | Tries to convert its argument to a number. | ||
6095 | If the argument is already a number or a string convertible | ||
6096 | to a number, then <code>tonumber</code> returns this number; | ||
6097 | otherwise, it returns <b>nil</b>. | ||
6098 | |||
6099 | |||
6100 | <p> | ||
6101 | An optional argument specifies the base to interpret the numeral. | ||
6102 | The base may be any integer between 2 and 36, inclusive. | ||
6103 | In bases above 10, the letter '<code>A</code>' (in either upper or lower case) | ||
6104 | represents 10, '<code>B</code>' represents 11, and so forth, | ||
6105 | with '<code>Z</code>' representing 35. | ||
6106 | In base 10 (the default), the number can have a decimal part, | ||
6107 | as well as an optional exponent part (see <a href="#2.1">§2.1</a>). | ||
6108 | In other bases, only unsigned integers are accepted. | ||
6109 | |||
6110 | |||
6111 | |||
6112 | |||
6113 | <p> | ||
6114 | <hr><h3><a name="pdf-tostring"><code>tostring (e)</code></a></h3> | ||
6115 | Receives an argument of any type and | ||
6116 | converts it to a string in a reasonable format. | ||
6117 | For complete control of how numbers are converted, | ||
6118 | use <a href="#pdf-string.format"><code>string.format</code></a>. | ||
6119 | |||
6120 | |||
6121 | <p> | ||
6122 | If the metatable of <code>e</code> has a <code>"__tostring"</code> field, | ||
6123 | then <code>tostring</code> calls the corresponding value | ||
6124 | with <code>e</code> as argument, | ||
6125 | and uses the result of the call as its result. | ||
6126 | |||
6127 | |||
6128 | |||
6129 | |||
6130 | <p> | ||
6131 | <hr><h3><a name="pdf-type"><code>type (v)</code></a></h3> | ||
6132 | Returns the type of its only argument, coded as a string. | ||
6133 | The possible results of this function are | ||
6134 | "<code>nil</code>" (a string, not the value <b>nil</b>), | ||
6135 | "<code>number</code>", | ||
6136 | "<code>string</code>", | ||
6137 | "<code>boolean</code>", | ||
6138 | "<code>table</code>", | ||
6139 | "<code>function</code>", | ||
6140 | "<code>thread</code>", | ||
6141 | and "<code>userdata</code>". | ||
6142 | |||
6143 | |||
6144 | |||
6145 | |||
6146 | <p> | ||
6147 | <hr><h3><a name="pdf-unpack"><code>unpack (list [, i [, j]])</code></a></h3> | ||
6148 | Returns the elements from the given table. | ||
6149 | This function is equivalent to | ||
6150 | |||
6151 | <pre> | ||
6152 | return list[i], list[i+1], ···, list[j] | ||
6153 | </pre><p> | ||
6154 | except that the above code can be written only for a fixed number | ||
6155 | of elements. | ||
6156 | By default, <code>i</code> is 1 and <code>j</code> is the length of the list, | ||
6157 | as defined by the length operator (see <a href="#2.5.5">§2.5.5</a>). | ||
6158 | |||
6159 | |||
6160 | |||
6161 | |||
6162 | <p> | ||
6163 | <hr><h3><a name="pdf-_VERSION"><code>_VERSION</code></a></h3> | ||
6164 | A global variable (not a function) that | ||
6165 | holds a string containing the current interpreter version. | ||
6166 | The current contents of this variable is "<code>Lua 5.1</code>". | ||
6167 | |||
6168 | |||
6169 | |||
6170 | |||
6171 | <p> | ||
6172 | <hr><h3><a name="pdf-xpcall"><code>xpcall (f, err)</code></a></h3> | ||
6173 | |||
6174 | |||
6175 | <p> | ||
6176 | This function is similar to <a href="#pdf-pcall"><code>pcall</code></a>, | ||
6177 | except that you can set a new error handler. | ||
6178 | |||
6179 | |||
6180 | <p> | ||
6181 | <code>xpcall</code> calls function <code>f</code> in protected mode, | ||
6182 | using <code>err</code> as the error handler. | ||
6183 | Any error inside <code>f</code> is not propagated; | ||
6184 | instead, <code>xpcall</code> catches the error, | ||
6185 | calls the <code>err</code> function with the original error object, | ||
6186 | and returns a status code. | ||
6187 | Its first result is the status code (a boolean), | ||
6188 | which is true if the call succeeds without errors. | ||
6189 | In this case, <code>xpcall</code> also returns all results from the call, | ||
6190 | after this first result. | ||
6191 | In case of any error, | ||
6192 | <code>xpcall</code> returns <b>false</b> plus the result from <code>err</code>. | ||
6193 | |||
6194 | |||
6195 | |||
6196 | |||
6197 | |||
6198 | |||
6199 | |||
6200 | <h2>5.2 - <a name="5.2">Coroutine Manipulation</a></h2> | ||
6201 | |||
6202 | <p> | ||
6203 | The operations related to coroutines comprise a sub-library of | ||
6204 | the basic library and come inside the table <a name="pdf-coroutine"><code>coroutine</code></a>. | ||
6205 | See <a href="#2.11">§2.11</a> for a general description of coroutines. | ||
6206 | |||
6207 | |||
6208 | <p> | ||
6209 | <hr><h3><a name="pdf-coroutine.create"><code>coroutine.create (f)</code></a></h3> | ||
6210 | |||
6211 | |||
6212 | <p> | ||
6213 | Creates a new coroutine, with body <code>f</code>. | ||
6214 | <code>f</code> must be a Lua function. | ||
6215 | Returns this new coroutine, | ||
6216 | an object with type <code>"thread"</code>. | ||
6217 | |||
6218 | |||
6219 | |||
6220 | |||
6221 | <p> | ||
6222 | <hr><h3><a name="pdf-coroutine.resume"><code>coroutine.resume (co [, val1, ···])</code></a></h3> | ||
6223 | |||
6224 | |||
6225 | <p> | ||
6226 | Starts or continues the execution of coroutine <code>co</code>. | ||
6227 | The first time you resume a coroutine, | ||
6228 | it starts running its body. | ||
6229 | The values <code>val1</code>, ··· are passed | ||
6230 | as the arguments to the body function. | ||
6231 | If the coroutine has yielded, | ||
6232 | <code>resume</code> restarts it; | ||
6233 | the values <code>val1</code>, ··· are passed | ||
6234 | as the results from the yield. | ||
6235 | |||
6236 | |||
6237 | <p> | ||
6238 | If the coroutine runs without any errors, | ||
6239 | <code>resume</code> returns <b>true</b> plus any values passed to <code>yield</code> | ||
6240 | (if the coroutine yields) or any values returned by the body function | ||
6241 | (if the coroutine terminates). | ||
6242 | If there is any error, | ||
6243 | <code>resume</code> returns <b>false</b> plus the error message. | ||
6244 | |||
6245 | |||
6246 | |||
6247 | |||
6248 | <p> | ||
6249 | <hr><h3><a name="pdf-coroutine.running"><code>coroutine.running ()</code></a></h3> | ||
6250 | |||
6251 | |||
6252 | <p> | ||
6253 | Returns the running coroutine, | ||
6254 | or <b>nil</b> when called by the main thread. | ||
6255 | |||
6256 | |||
6257 | |||
6258 | |||
6259 | <p> | ||
6260 | <hr><h3><a name="pdf-coroutine.status"><code>coroutine.status (co)</code></a></h3> | ||
6261 | |||
6262 | |||
6263 | <p> | ||
6264 | Returns the status of coroutine <code>co</code>, as a string: | ||
6265 | <code>"running"</code>, | ||
6266 | if the coroutine is running (that is, it called <code>status</code>); | ||
6267 | <code>"suspended"</code>, if the coroutine is suspended in a call to <code>yield</code>, | ||
6268 | or if it has not started running yet; | ||
6269 | <code>"normal"</code> if the coroutine is active but not running | ||
6270 | (that is, it has resumed another coroutine); | ||
6271 | and <code>"dead"</code> if the coroutine has finished its body function, | ||
6272 | or if it has stopped with an error. | ||
6273 | |||
6274 | |||
6275 | |||
6276 | |||
6277 | <p> | ||
6278 | <hr><h3><a name="pdf-coroutine.wrap"><code>coroutine.wrap (f)</code></a></h3> | ||
6279 | |||
6280 | |||
6281 | <p> | ||
6282 | Creates a new coroutine, with body <code>f</code>. | ||
6283 | <code>f</code> must be a Lua function. | ||
6284 | Returns a function that resumes the coroutine each time it is called. | ||
6285 | Any arguments passed to the function behave as the | ||
6286 | extra arguments to <code>resume</code>. | ||
6287 | Returns the same values returned by <code>resume</code>, | ||
6288 | except the first boolean. | ||
6289 | In case of error, propagates the error. | ||
6290 | |||
6291 | |||
6292 | |||
6293 | |||
6294 | <p> | ||
6295 | <hr><h3><a name="pdf-coroutine.yield"><code>coroutine.yield (···)</code></a></h3> | ||
6296 | |||
6297 | |||
6298 | <p> | ||
6299 | Suspends the execution of the calling coroutine. | ||
6300 | The coroutine cannot be running a C function, | ||
6301 | a metamethod, or an iterator. | ||
6302 | Any arguments to <code>yield</code> are passed as extra results to <code>resume</code>. | ||
6303 | |||
6304 | |||
6305 | |||
6306 | |||
6307 | |||
6308 | |||
6309 | |||
6310 | <h2>5.3 - <a name="5.3">Modules</a></h2> | ||
6311 | |||
6312 | <p> | ||
6313 | The package library provides basic | ||
6314 | facilities for loading and building modules in Lua. | ||
6315 | It exports two of its functions directly in the global environment: | ||
6316 | <a href="#pdf-require"><code>require</code></a> and <a href="#pdf-module"><code>module</code></a>. | ||
6317 | Everything else is exported in a table <a name="pdf-package"><code>package</code></a>. | ||
6318 | |||
6319 | |||
6320 | <p> | ||
6321 | <hr><h3><a name="pdf-module"><code>module (name [, ···])</code></a></h3> | ||
6322 | |||
6323 | |||
6324 | <p> | ||
6325 | Creates a module. | ||
6326 | If there is a table in <code>package.loaded[name]</code>, | ||
6327 | this table is the module. | ||
6328 | Otherwise, if there is a global table <code>t</code> with the given name, | ||
6329 | this table is the module. | ||
6330 | Otherwise creates a new table <code>t</code> and | ||
6331 | sets it as the value of the global <code>name</code> and | ||
6332 | the value of <code>package.loaded[name]</code>. | ||
6333 | This function also initializes <code>t._NAME</code> with the given name, | ||
6334 | <code>t._M</code> with the module (<code>t</code> itself), | ||
6335 | and <code>t._PACKAGE</code> with the package name | ||
6336 | (the full module name minus last component; see below). | ||
6337 | Finally, <code>module</code> sets <code>t</code> as the new environment | ||
6338 | of the current function and the new value of <code>package.loaded[name]</code>, | ||
6339 | so that <a href="#pdf-require"><code>require</code></a> returns <code>t</code>. | ||
6340 | |||
6341 | |||
6342 | <p> | ||
6343 | If <code>name</code> is a compound name | ||
6344 | (that is, one with components separated by dots), | ||
6345 | <code>module</code> creates (or reuses, if they already exist) | ||
6346 | tables for each component. | ||
6347 | For instance, if <code>name</code> is <code>a.b.c</code>, | ||
6348 | then <code>module</code> stores the module table in field <code>c</code> of | ||
6349 | field <code>b</code> of global <code>a</code>. | ||
6350 | |||
6351 | |||
6352 | <p> | ||
6353 | This function can receive optional <em>options</em> after | ||
6354 | the module name, | ||
6355 | where each option is a function to be applied over the module. | ||
6356 | |||
6357 | |||
6358 | |||
6359 | |||
6360 | <p> | ||
6361 | <hr><h3><a name="pdf-require"><code>require (modname)</code></a></h3> | ||
6362 | |||
6363 | |||
6364 | <p> | ||
6365 | Loads the given module. | ||
6366 | The function starts by looking into the <a href="#pdf-package.loaded"><code>package.loaded</code></a> table | ||
6367 | to determine whether <code>modname</code> is already loaded. | ||
6368 | If it is, then <code>require</code> returns the value stored | ||
6369 | at <code>package.loaded[modname]</code>. | ||
6370 | Otherwise, it tries to find a <em>loader</em> for the module. | ||
6371 | |||
6372 | |||
6373 | <p> | ||
6374 | To find a loader, | ||
6375 | <code>require</code> is guided by the <a href="#pdf-package.loaders"><code>package.loaders</code></a> array. | ||
6376 | By changing this array, | ||
6377 | we can change how <code>require</code> looks for a module. | ||
6378 | The following explanation is based on the default configuration | ||
6379 | for <a href="#pdf-package.loaders"><code>package.loaders</code></a>. | ||
6380 | |||
6381 | |||
6382 | <p> | ||
6383 | First <code>require</code> queries <code>package.preload[modname]</code>. | ||
6384 | If it has a value, | ||
6385 | this value (which should be a function) is the loader. | ||
6386 | Otherwise <code>require</code> searches for a Lua loader using the | ||
6387 | path stored in <a href="#pdf-package.path"><code>package.path</code></a>. | ||
6388 | If that also fails, it searches for a C loader using the | ||
6389 | path stored in <a href="#pdf-package.cpath"><code>package.cpath</code></a>. | ||
6390 | If that also fails, | ||
6391 | it tries an <em>all-in-one</em> loader (see <a href="#pdf-package.loaders"><code>package.loaders</code></a>). | ||
6392 | |||
6393 | |||
6394 | <p> | ||
6395 | Once a loader is found, | ||
6396 | <code>require</code> calls the loader with a single argument, <code>modname</code>. | ||
6397 | If the loader returns any value, | ||
6398 | <code>require</code> assigns the returned value to <code>package.loaded[modname]</code>. | ||
6399 | If the loader returns no value and | ||
6400 | has not assigned any value to <code>package.loaded[modname]</code>, | ||
6401 | then <code>require</code> assigns <b>true</b> to this entry. | ||
6402 | In any case, <code>require</code> returns the | ||
6403 | final value of <code>package.loaded[modname]</code>. | ||
6404 | |||
6405 | |||
6406 | <p> | ||
6407 | If there is any error loading or running the module, | ||
6408 | or if it cannot find any loader for the module, | ||
6409 | then <code>require</code> signals an error. | ||
6410 | |||
6411 | |||
6412 | |||
6413 | |||
6414 | <p> | ||
6415 | <hr><h3><a name="pdf-package.cpath"><code>package.cpath</code></a></h3> | ||
6416 | |||
6417 | |||
6418 | <p> | ||
6419 | The path used by <a href="#pdf-require"><code>require</code></a> to search for a C loader. | ||
6420 | |||
6421 | |||
6422 | <p> | ||
6423 | Lua initializes the C path <a href="#pdf-package.cpath"><code>package.cpath</code></a> in the same way | ||
6424 | it initializes the Lua path <a href="#pdf-package.path"><code>package.path</code></a>, | ||
6425 | using the environment variable <a name="pdf-LUA_CPATH"><code>LUA_CPATH</code></a> | ||
6426 | or a default path defined in <code>luaconf.h</code>. | ||
6427 | |||
6428 | |||
6429 | |||
6430 | |||
6431 | <p> | ||
6432 | |||
6433 | <hr><h3><a name="pdf-package.loaded"><code>package.loaded</code></a></h3> | ||
6434 | |||
6435 | |||
6436 | <p> | ||
6437 | A table used by <a href="#pdf-require"><code>require</code></a> to control which | ||
6438 | modules are already loaded. | ||
6439 | When you require a module <code>modname</code> and | ||
6440 | <code>package.loaded[modname]</code> is not false, | ||
6441 | <a href="#pdf-require"><code>require</code></a> simply returns the value stored there. | ||
6442 | |||
6443 | |||
6444 | |||
6445 | |||
6446 | <p> | ||
6447 | <hr><h3><a name="pdf-package.loaders"><code>package.loaders</code></a></h3> | ||
6448 | |||
6449 | |||
6450 | <p> | ||
6451 | A table used by <a href="#pdf-require"><code>require</code></a> to control how to load modules. | ||
6452 | |||
6453 | |||
6454 | <p> | ||
6455 | Each entry in this table is a <em>searcher function</em>. | ||
6456 | When looking for a module, | ||
6457 | <a href="#pdf-require"><code>require</code></a> calls each of these searchers in ascending order, | ||
6458 | with the module name (the argument given to <a href="#pdf-require"><code>require</code></a>) as its | ||
6459 | sole parameter. | ||
6460 | The function can return another function (the module <em>loader</em>) | ||
6461 | or a string explaining why it did not find that module | ||
6462 | (or <b>nil</b> if it has nothing to say). | ||
6463 | Lua initializes this table with four functions. | ||
6464 | |||
6465 | |||
6466 | <p> | ||
6467 | The first searcher simply looks for a loader in the | ||
6468 | <a href="#pdf-package.preload"><code>package.preload</code></a> table. | ||
6469 | |||
6470 | |||
6471 | <p> | ||
6472 | The second searcher looks for a loader as a Lua library, | ||
6473 | using the path stored at <a href="#pdf-package.path"><code>package.path</code></a>. | ||
6474 | A path is a sequence of <em>templates</em> separated by semicolons. | ||
6475 | For each template, | ||
6476 | the searcher will change each interrogation | ||
6477 | mark in the template by <code>filename</code>, | ||
6478 | which is the module name with each dot replaced by a | ||
6479 | "directory separator" (such as "<code>/</code>" in Unix); | ||
6480 | then it will try to open the resulting file name. | ||
6481 | So, for instance, if the Lua path is the string | ||
6482 | |||
6483 | <pre> | ||
6484 | "./?.lua;./?.lc;/usr/local/?/init.lua" | ||
6485 | </pre><p> | ||
6486 | the search for a Lua file for module <code>foo</code> | ||
6487 | will try to open the files | ||
6488 | <code>./foo.lua</code>, <code>./foo.lc</code>, and | ||
6489 | <code>/usr/local/foo/init.lua</code>, in that order. | ||
6490 | |||
6491 | |||
6492 | <p> | ||
6493 | The third searcher looks for a loader as a C library, | ||
6494 | using the path given by the variable <a href="#pdf-package.cpath"><code>package.cpath</code></a>. | ||
6495 | For instance, | ||
6496 | if the C path is the string | ||
6497 | |||
6498 | <pre> | ||
6499 | "./?.so;./?.dll;/usr/local/?/init.so" | ||
6500 | </pre><p> | ||
6501 | the searcher for module <code>foo</code> | ||
6502 | will try to open the files <code>./foo.so</code>, <code>./foo.dll</code>, | ||
6503 | and <code>/usr/local/foo/init.so</code>, in that order. | ||
6504 | Once it finds a C library, | ||
6505 | this searcher first uses a dynamic link facility to link the | ||
6506 | application with the library. | ||
6507 | Then it tries to find a C function inside the library to | ||
6508 | be used as the loader. | ||
6509 | The name of this C function is the string "<code>luaopen_</code>" | ||
6510 | concatenated with a copy of the module name where each dot | ||
6511 | is replaced by an underscore. | ||
6512 | Moreover, if the module name has a hyphen, | ||
6513 | its prefix up to (and including) the first hyphen is removed. | ||
6514 | For instance, if the module name is <code>a.v1-b.c</code>, | ||
6515 | the function name will be <code>luaopen_b_c</code>. | ||
6516 | |||
6517 | |||
6518 | <p> | ||
6519 | The fourth searcher tries an <em>all-in-one loader</em>. | ||
6520 | It searches the C path for a library for | ||
6521 | the root name of the given module. | ||
6522 | For instance, when requiring <code>a.b.c</code>, | ||
6523 | it will search for a C library for <code>a</code>. | ||
6524 | If found, it looks into it for an open function for | ||
6525 | the submodule; | ||
6526 | in our example, that would be <code>luaopen_a_b_c</code>. | ||
6527 | With this facility, a package can pack several C submodules | ||
6528 | into one single library, | ||
6529 | with each submodule keeping its original open function. | ||
6530 | |||
6531 | |||
6532 | |||
6533 | |||
6534 | <p> | ||
6535 | <hr><h3><a name="pdf-package.loadlib"><code>package.loadlib (libname, funcname)</code></a></h3> | ||
6536 | |||
6537 | |||
6538 | <p> | ||
6539 | Dynamically links the host program with the C library <code>libname</code>. | ||
6540 | Inside this library, looks for a function <code>funcname</code> | ||
6541 | and returns this function as a C function. | ||
6542 | (So, <code>funcname</code> must follow the protocol (see <a href="#lua_CFunction"><code>lua_CFunction</code></a>)). | ||
6543 | |||
6544 | |||
6545 | <p> | ||
6546 | This is a low-level function. | ||
6547 | It completely bypasses the package and module system. | ||
6548 | Unlike <a href="#pdf-require"><code>require</code></a>, | ||
6549 | it does not perform any path searching and | ||
6550 | does not automatically adds extensions. | ||
6551 | <code>libname</code> must be the complete file name of the C library, | ||
6552 | including if necessary a path and extension. | ||
6553 | <code>funcname</code> must be the exact name exported by the C library | ||
6554 | (which may depend on the C compiler and linker used). | ||
6555 | |||
6556 | |||
6557 | <p> | ||
6558 | This function is not supported by ANSI C. | ||
6559 | As such, it is only available on some platforms | ||
6560 | (Windows, Linux, Mac OS X, Solaris, BSD, | ||
6561 | plus other Unix systems that support the <code>dlfcn</code> standard). | ||
6562 | |||
6563 | |||
6564 | |||
6565 | |||
6566 | <p> | ||
6567 | <hr><h3><a name="pdf-package.path"><code>package.path</code></a></h3> | ||
6568 | |||
6569 | |||
6570 | <p> | ||
6571 | The path used by <a href="#pdf-require"><code>require</code></a> to search for a Lua loader. | ||
6572 | |||
6573 | |||
6574 | <p> | ||
6575 | At start-up, Lua initializes this variable with | ||
6576 | the value of the environment variable <a name="pdf-LUA_PATH"><code>LUA_PATH</code></a> or | ||
6577 | with a default path defined in <code>luaconf.h</code>, | ||
6578 | if the environment variable is not defined. | ||
6579 | Any "<code>;;</code>" in the value of the environment variable | ||
6580 | is replaced by the default path. | ||
6581 | |||
6582 | |||
6583 | |||
6584 | |||
6585 | <p> | ||
6586 | <hr><h3><a name="pdf-package.preload"><code>package.preload</code></a></h3> | ||
6587 | |||
6588 | |||
6589 | <p> | ||
6590 | A table to store loaders for specific modules | ||
6591 | (see <a href="#pdf-require"><code>require</code></a>). | ||
6592 | |||
6593 | |||
6594 | |||
6595 | |||
6596 | <p> | ||
6597 | <hr><h3><a name="pdf-package.seeall"><code>package.seeall (module)</code></a></h3> | ||
6598 | |||
6599 | |||
6600 | <p> | ||
6601 | Sets a metatable for <code>module</code> with | ||
6602 | its <code>__index</code> field referring to the global environment, | ||
6603 | so that this module inherits values | ||
6604 | from the global environment. | ||
6605 | To be used as an option to function <a href="#pdf-module"><code>module</code></a>. | ||
6606 | |||
6607 | |||
6608 | |||
6609 | |||
6610 | |||
6611 | |||
6612 | |||
6613 | <h2>5.4 - <a name="5.4">String Manipulation</a></h2> | ||
6614 | |||
6615 | <p> | ||
6616 | This library provides generic functions for string manipulation, | ||
6617 | such as finding and extracting substrings, and pattern matching. | ||
6618 | When indexing a string in Lua, the first character is at position 1 | ||
6619 | (not at 0, as in C). | ||
6620 | Indices are allowed to be negative and are interpreted as indexing backwards, | ||
6621 | from the end of the string. | ||
6622 | Thus, the last character is at position -1, and so on. | ||
6623 | |||
6624 | |||
6625 | <p> | ||
6626 | The string library provides all its functions inside the table | ||
6627 | <a name="pdf-string"><code>string</code></a>. | ||
6628 | It also sets a metatable for strings | ||
6629 | where the <code>__index</code> field points to the <code>string</code> table. | ||
6630 | Therefore, you can use the string functions in object-oriented style. | ||
6631 | For instance, <code>string.byte(s, i)</code> | ||
6632 | can be written as <code>s:byte(i)</code>. | ||
6633 | |||
6634 | |||
6635 | <p> | ||
6636 | The string library assumes one-byte character encodings. | ||
6637 | |||
6638 | |||
6639 | <p> | ||
6640 | <hr><h3><a name="pdf-string.byte"><code>string.byte (s [, i [, j]])</code></a></h3> | ||
6641 | Returns the internal numerical codes of the characters <code>s[i]</code>, | ||
6642 | <code>s[i+1]</code>, ···, <code>s[j]</code>. | ||
6643 | The default value for <code>i</code> is 1; | ||
6644 | the default value for <code>j</code> is <code>i</code>. | ||
6645 | |||
6646 | |||
6647 | <p> | ||
6648 | Note that numerical codes are not necessarily portable across platforms. | ||
6649 | |||
6650 | |||
6651 | |||
6652 | |||
6653 | <p> | ||
6654 | <hr><h3><a name="pdf-string.char"><code>string.char (···)</code></a></h3> | ||
6655 | Receives zero or more integers. | ||
6656 | Returns a string with length equal to the number of arguments, | ||
6657 | in which each character has the internal numerical code equal | ||
6658 | to its corresponding argument. | ||
6659 | |||
6660 | |||
6661 | <p> | ||
6662 | Note that numerical codes are not necessarily portable across platforms. | ||
6663 | |||
6664 | |||
6665 | |||
6666 | |||
6667 | <p> | ||
6668 | <hr><h3><a name="pdf-string.dump"><code>string.dump (function)</code></a></h3> | ||
6669 | |||
6670 | |||
6671 | <p> | ||
6672 | Returns a string containing a binary representation of the given function, | ||
6673 | so that a later <a href="#pdf-loadstring"><code>loadstring</code></a> on this string returns | ||
6674 | a copy of the function. | ||
6675 | <code>function</code> must be a Lua function without upvalues. | ||
6676 | |||
6677 | |||
6678 | |||
6679 | |||
6680 | <p> | ||
6681 | <hr><h3><a name="pdf-string.find"><code>string.find (s, pattern [, init [, plain]])</code></a></h3> | ||
6682 | Looks for the first match of | ||
6683 | <code>pattern</code> in the string <code>s</code>. | ||
6684 | If it finds a match, then <code>find</code> returns the indices of <code>s</code> | ||
6685 | where this occurrence starts and ends; | ||
6686 | otherwise, it returns <b>nil</b>. | ||
6687 | A third, optional numerical argument <code>init</code> specifies | ||
6688 | where to start the search; | ||
6689 | its default value is 1 and can be negative. | ||
6690 | A value of <b>true</b> as a fourth, optional argument <code>plain</code> | ||
6691 | turns off the pattern matching facilities, | ||
6692 | so the function does a plain "find substring" operation, | ||
6693 | with no characters in <code>pattern</code> being considered "magic". | ||
6694 | Note that if <code>plain</code> is given, then <code>init</code> must be given as well. | ||
6695 | |||
6696 | |||
6697 | <p> | ||
6698 | If the pattern has captures, | ||
6699 | then in a successful match | ||
6700 | the captured values are also returned, | ||
6701 | after the two indices. | ||
6702 | |||
6703 | |||
6704 | |||
6705 | |||
6706 | <p> | ||
6707 | <hr><h3><a name="pdf-string.format"><code>string.format (formatstring, ···)</code></a></h3> | ||
6708 | Returns a formatted version of its variable number of arguments | ||
6709 | following the description given in its first argument (which must be a string). | ||
6710 | The format string follows the same rules as the <code>printf</code> family of | ||
6711 | standard C functions. | ||
6712 | The only differences are that the options/modifiers | ||
6713 | <code>*</code>, <code>l</code>, <code>L</code>, <code>n</code>, <code>p</code>, | ||
6714 | and <code>h</code> are not supported | ||
6715 | and that there is an extra option, <code>q</code>. | ||
6716 | The <code>q</code> option formats a string in a form suitable to be safely read | ||
6717 | back by the Lua interpreter: | ||
6718 | the string is written between double quotes, | ||
6719 | and all double quotes, newlines, embedded zeros, | ||
6720 | and backslashes in the string | ||
6721 | are correctly escaped when written. | ||
6722 | For instance, the call | ||
6723 | |||
6724 | <pre> | ||
6725 | string.format('%q', 'a string with "quotes" and \n new line') | ||
6726 | </pre><p> | ||
6727 | will produce the string: | ||
6728 | |||
6729 | <pre> | ||
6730 | "a string with \"quotes\" and \ | ||
6731 | new line" | ||
6732 | </pre> | ||
6733 | |||
6734 | <p> | ||
6735 | The options <code>c</code>, <code>d</code>, <code>E</code>, <code>e</code>, <code>f</code>, | ||
6736 | <code>g</code>, <code>G</code>, <code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code> all | ||
6737 | expect a number as argument, | ||
6738 | whereas <code>q</code> and <code>s</code> expect a string. | ||
6739 | |||
6740 | |||
6741 | <p> | ||
6742 | This function does not accept string values | ||
6743 | containing embedded zeros, | ||
6744 | except as arguments to the <code>q</code> option. | ||
6745 | |||
6746 | |||
6747 | |||
6748 | |||
6749 | <p> | ||
6750 | <hr><h3><a name="pdf-string.gmatch"><code>string.gmatch (s, pattern)</code></a></h3> | ||
6751 | Returns an iterator function that, | ||
6752 | each time it is called, | ||
6753 | returns the next captures from <code>pattern</code> over string <code>s</code>. | ||
6754 | If <code>pattern</code> specifies no captures, | ||
6755 | then the whole match is produced in each call. | ||
6756 | |||
6757 | |||
6758 | <p> | ||
6759 | As an example, the following loop | ||
6760 | |||
6761 | <pre> | ||
6762 | s = "hello world from Lua" | ||
6763 | for w in string.gmatch(s, "%a+") do | ||
6764 | print(w) | ||
6765 | end | ||
6766 | </pre><p> | ||
6767 | will iterate over all the words from string <code>s</code>, | ||
6768 | printing one per line. | ||
6769 | The next example collects all pairs <code>key=value</code> from the | ||
6770 | given string into a table: | ||
6771 | |||
6772 | <pre> | ||
6773 | t = {} | ||
6774 | s = "from=world, to=Lua" | ||
6775 | for k, v in string.gmatch(s, "(%w+)=(%w+)") do | ||
6776 | t[k] = v | ||
6777 | end | ||
6778 | </pre> | ||
6779 | |||
6780 | <p> | ||
6781 | For this function, a '<code>^</code>' at the start of a pattern does not | ||
6782 | work as an anchor, as this would prevent the iteration. | ||
6783 | |||
6784 | |||
6785 | |||
6786 | |||
6787 | <p> | ||
6788 | <hr><h3><a name="pdf-string.gsub"><code>string.gsub (s, pattern, repl [, n])</code></a></h3> | ||
6789 | Returns a copy of <code>s</code> | ||
6790 | in which all (or the first <code>n</code>, if given) | ||
6791 | occurrences of the <code>pattern</code> have been | ||
6792 | replaced by a replacement string specified by <code>repl</code>, | ||
6793 | which can be a string, a table, or a function. | ||
6794 | <code>gsub</code> also returns, as its second value, | ||
6795 | the total number of matches that occurred. | ||
6796 | |||
6797 | |||
6798 | <p> | ||
6799 | If <code>repl</code> is a string, then its value is used for replacement. | ||
6800 | The character <code>%</code> works as an escape character: | ||
6801 | any sequence in <code>repl</code> of the form <code>%<em>n</em></code>, | ||
6802 | with <em>n</em> between 1 and 9, | ||
6803 | stands for the value of the <em>n</em>-th captured substring (see below). | ||
6804 | The sequence <code>%0</code> stands for the whole match. | ||
6805 | The sequence <code>%%</code> stands for a single <code>%</code>. | ||
6806 | |||
6807 | |||
6808 | <p> | ||
6809 | If <code>repl</code> is a table, then the table is queried for every match, | ||
6810 | using the first capture as the key; | ||
6811 | if the pattern specifies no captures, | ||
6812 | then the whole match is used as the key. | ||
6813 | |||
6814 | |||
6815 | <p> | ||
6816 | If <code>repl</code> is a function, then this function is called every time a | ||
6817 | match occurs, with all captured substrings passed as arguments, | ||
6818 | in order; | ||
6819 | if the pattern specifies no captures, | ||
6820 | then the whole match is passed as a sole argument. | ||
6821 | |||
6822 | |||
6823 | <p> | ||
6824 | If the value returned by the table query or by the function call | ||
6825 | is a string or a number, | ||
6826 | then it is used as the replacement string; | ||
6827 | otherwise, if it is <b>false</b> or <b>nil</b>, | ||
6828 | then there is no replacement | ||
6829 | (that is, the original match is kept in the string). | ||
6830 | |||
6831 | |||
6832 | <p> | ||
6833 | Here are some examples: | ||
6834 | |||
6835 | <pre> | ||
6836 | x = string.gsub("hello world", "(%w+)", "%1 %1") | ||
6837 | --> x="hello hello world world" | ||
6838 | |||
6839 | x = string.gsub("hello world", "%w+", "%0 %0", 1) | ||
6840 | --> x="hello hello world" | ||
6841 | |||
6842 | x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1") | ||
6843 | --> x="world hello Lua from" | ||
6844 | |||
6845 | x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv) | ||
6846 | --> x="home = /home/roberto, user = roberto" | ||
6847 | |||
6848 | x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s) | ||
6849 | return loadstring(s)() | ||
6850 | end) | ||
6851 | --> x="4+5 = 9" | ||
6852 | |||
6853 | local t = {name="lua", version="5.1"} | ||
6854 | x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t) | ||
6855 | --> x="lua-5.1.tar.gz" | ||
6856 | </pre> | ||
6857 | |||
6858 | |||
6859 | |||
6860 | <p> | ||
6861 | <hr><h3><a name="pdf-string.len"><code>string.len (s)</code></a></h3> | ||
6862 | Receives a string and returns its length. | ||
6863 | The empty string <code>""</code> has length 0. | ||
6864 | Embedded zeros are counted, | ||
6865 | so <code>"a\000bc\000"</code> has length 5. | ||
6866 | |||
6867 | |||
6868 | |||
6869 | |||
6870 | <p> | ||
6871 | <hr><h3><a name="pdf-string.lower"><code>string.lower (s)</code></a></h3> | ||
6872 | Receives a string and returns a copy of this string with all | ||
6873 | uppercase letters changed to lowercase. | ||
6874 | All other characters are left unchanged. | ||
6875 | The definition of what an uppercase letter is depends on the current locale. | ||
6876 | |||
6877 | |||
6878 | |||
6879 | |||
6880 | <p> | ||
6881 | <hr><h3><a name="pdf-string.match"><code>string.match (s, pattern [, init])</code></a></h3> | ||
6882 | Looks for the first <em>match</em> of | ||
6883 | <code>pattern</code> in the string <code>s</code>. | ||
6884 | If it finds one, then <code>match</code> returns | ||
6885 | the captures from the pattern; | ||
6886 | otherwise it returns <b>nil</b>. | ||
6887 | If <code>pattern</code> specifies no captures, | ||
6888 | then the whole match is returned. | ||
6889 | A third, optional numerical argument <code>init</code> specifies | ||
6890 | where to start the search; | ||
6891 | its default value is 1 and can be negative. | ||
6892 | |||
6893 | |||
6894 | |||
6895 | |||
6896 | <p> | ||
6897 | <hr><h3><a name="pdf-string.rep"><code>string.rep (s, n)</code></a></h3> | ||
6898 | Returns a string that is the concatenation of <code>n</code> copies of | ||
6899 | the string <code>s</code>. | ||
6900 | |||
6901 | |||
6902 | |||
6903 | |||
6904 | <p> | ||
6905 | <hr><h3><a name="pdf-string.reverse"><code>string.reverse (s)</code></a></h3> | ||
6906 | Returns a string that is the string <code>s</code> reversed. | ||
6907 | |||
6908 | |||
6909 | |||
6910 | |||
6911 | <p> | ||
6912 | <hr><h3><a name="pdf-string.sub"><code>string.sub (s, i [, j])</code></a></h3> | ||
6913 | Returns the substring of <code>s</code> that | ||
6914 | starts at <code>i</code> and continues until <code>j</code>; | ||
6915 | <code>i</code> and <code>j</code> can be negative. | ||
6916 | If <code>j</code> is absent, then it is assumed to be equal to -1 | ||
6917 | (which is the same as the string length). | ||
6918 | In particular, | ||
6919 | the call <code>string.sub(s,1,j)</code> returns a prefix of <code>s</code> | ||
6920 | with length <code>j</code>, | ||
6921 | and <code>string.sub(s, -i)</code> returns a suffix of <code>s</code> | ||
6922 | with length <code>i</code>. | ||
6923 | |||
6924 | |||
6925 | |||
6926 | |||
6927 | <p> | ||
6928 | <hr><h3><a name="pdf-string.upper"><code>string.upper (s)</code></a></h3> | ||
6929 | Receives a string and returns a copy of this string with all | ||
6930 | lowercase letters changed to uppercase. | ||
6931 | All other characters are left unchanged. | ||
6932 | The definition of what a lowercase letter is depends on the current locale. | ||
6933 | |||
6934 | |||
6935 | |||
6936 | <h3>5.4.1 - <a name="5.4.1">Patterns</a></h3> | ||
6937 | |||
6938 | |||
6939 | <h4>Character Class:</h4><p> | ||
6940 | A <em>character class</em> is used to represent a set of characters. | ||
6941 | The following combinations are allowed in describing a character class: | ||
6942 | |||
6943 | <ul> | ||
6944 | |||
6945 | <li><b><em>x</em>:</b> | ||
6946 | (where <em>x</em> is not one of the <em>magic characters</em> | ||
6947 | <code>^$()%.[]*+-?</code>) | ||
6948 | represents the character <em>x</em> itself. | ||
6949 | </li> | ||
6950 | |||
6951 | <li><b><code>.</code>:</b> (a dot) represents all characters.</li> | ||
6952 | |||
6953 | <li><b><code>%a</code>:</b> represents all letters.</li> | ||
6954 | |||
6955 | <li><b><code>%c</code>:</b> represents all control characters.</li> | ||
6956 | |||
6957 | <li><b><code>%d</code>:</b> represents all digits.</li> | ||
6958 | |||
6959 | <li><b><code>%l</code>:</b> represents all lowercase letters.</li> | ||
6960 | |||
6961 | <li><b><code>%p</code>:</b> represents all punctuation characters.</li> | ||
6962 | |||
6963 | <li><b><code>%s</code>:</b> represents all space characters.</li> | ||
6964 | |||
6965 | <li><b><code>%u</code>:</b> represents all uppercase letters.</li> | ||
6966 | |||
6967 | <li><b><code>%w</code>:</b> represents all alphanumeric characters.</li> | ||
6968 | |||
6969 | <li><b><code>%x</code>:</b> represents all hexadecimal digits.</li> | ||
6970 | |||
6971 | <li><b><code>%z</code>:</b> represents the character with representation 0.</li> | ||
6972 | |||
6973 | <li><b><code>%<em>x</em></code>:</b> (where <em>x</em> is any non-alphanumeric character) | ||
6974 | represents the character <em>x</em>. | ||
6975 | This is the standard way to escape the magic characters. | ||
6976 | Any punctuation character (even the non magic) | ||
6977 | can be preceded by a '<code>%</code>' | ||
6978 | when used to represent itself in a pattern. | ||
6979 | </li> | ||
6980 | |||
6981 | <li><b><code>[<em>set</em>]</code>:</b> | ||
6982 | represents the class which is the union of all | ||
6983 | characters in <em>set</em>. | ||
6984 | A range of characters can be specified by | ||
6985 | separating the end characters of the range with a '<code>-</code>'. | ||
6986 | All classes <code>%</code><em>x</em> described above can also be used as | ||
6987 | components in <em>set</em>. | ||
6988 | All other characters in <em>set</em> represent themselves. | ||
6989 | For example, <code>[%w_]</code> (or <code>[_%w]</code>) | ||
6990 | represents all alphanumeric characters plus the underscore, | ||
6991 | <code>[0-7]</code> represents the octal digits, | ||
6992 | and <code>[0-7%l%-]</code> represents the octal digits plus | ||
6993 | the lowercase letters plus the '<code>-</code>' character. | ||
6994 | |||
6995 | |||
6996 | <p> | ||
6997 | The interaction between ranges and classes is not defined. | ||
6998 | Therefore, patterns like <code>[%a-z]</code> or <code>[a-%%]</code> | ||
6999 | have no meaning. | ||
7000 | </li> | ||
7001 | |||
7002 | <li><b><code>[^<em>set</em>]</code>:</b> | ||
7003 | represents the complement of <em>set</em>, | ||
7004 | where <em>set</em> is interpreted as above. | ||
7005 | </li> | ||
7006 | |||
7007 | </ul><p> | ||
7008 | For all classes represented by single letters (<code>%a</code>, <code>%c</code>, etc.), | ||
7009 | the corresponding uppercase letter represents the complement of the class. | ||
7010 | For instance, <code>%S</code> represents all non-space characters. | ||
7011 | |||
7012 | |||
7013 | <p> | ||
7014 | The definitions of letter, space, and other character groups | ||
7015 | depend on the current locale. | ||
7016 | In particular, the class <code>[a-z]</code> may not be equivalent to <code>%l</code>. | ||
7017 | |||
7018 | |||
7019 | |||
7020 | |||
7021 | |||
7022 | <h4>Pattern Item:</h4><p> | ||
7023 | A <em>pattern item</em> can be | ||
7024 | |||
7025 | <ul> | ||
7026 | |||
7027 | <li> | ||
7028 | a single character class, | ||
7029 | which matches any single character in the class; | ||
7030 | </li> | ||
7031 | |||
7032 | <li> | ||
7033 | a single character class followed by '<code>*</code>', | ||
7034 | which matches 0 or more repetitions of characters in the class. | ||
7035 | These repetition items will always match the longest possible sequence; | ||
7036 | </li> | ||
7037 | |||
7038 | <li> | ||
7039 | a single character class followed by '<code>+</code>', | ||
7040 | which matches 1 or more repetitions of characters in the class. | ||
7041 | These repetition items will always match the longest possible sequence; | ||
7042 | </li> | ||
7043 | |||
7044 | <li> | ||
7045 | a single character class followed by '<code>-</code>', | ||
7046 | which also matches 0 or more repetitions of characters in the class. | ||
7047 | Unlike '<code>*</code>', | ||
7048 | these repetition items will always match the <em>shortest</em> possible sequence; | ||
7049 | </li> | ||
7050 | |||
7051 | <li> | ||
7052 | a single character class followed by '<code>?</code>', | ||
7053 | which matches 0 or 1 occurrence of a character in the class; | ||
7054 | </li> | ||
7055 | |||
7056 | <li> | ||
7057 | <code>%<em>n</em></code>, for <em>n</em> between 1 and 9; | ||
7058 | such item matches a substring equal to the <em>n</em>-th captured string | ||
7059 | (see below); | ||
7060 | </li> | ||
7061 | |||
7062 | <li> | ||
7063 | <code>%b<em>xy</em></code>, where <em>x</em> and <em>y</em> are two distinct characters; | ||
7064 | such item matches strings that start with <em>x</em>, end with <em>y</em>, | ||
7065 | and where the <em>x</em> and <em>y</em> are <em>balanced</em>. | ||
7066 | This means that, if one reads the string from left to right, | ||
7067 | counting <em>+1</em> for an <em>x</em> and <em>-1</em> for a <em>y</em>, | ||
7068 | the ending <em>y</em> is the first <em>y</em> where the count reaches 0. | ||
7069 | For instance, the item <code>%b()</code> matches expressions with | ||
7070 | balanced parentheses. | ||
7071 | </li> | ||
7072 | |||
7073 | </ul> | ||
7074 | |||
7075 | |||
7076 | |||
7077 | |||
7078 | <h4>Pattern:</h4><p> | ||
7079 | A <em>pattern</em> is a sequence of pattern items. | ||
7080 | A '<code>^</code>' at the beginning of a pattern anchors the match at the | ||
7081 | beginning of the subject string. | ||
7082 | A '<code>$</code>' at the end of a pattern anchors the match at the | ||
7083 | end of the subject string. | ||
7084 | At other positions, | ||
7085 | '<code>^</code>' and '<code>$</code>' have no special meaning and represent themselves. | ||
7086 | |||
7087 | |||
7088 | |||
7089 | |||
7090 | |||
7091 | <h4>Captures:</h4><p> | ||
7092 | A pattern can contain sub-patterns enclosed in parentheses; | ||
7093 | they describe <em>captures</em>. | ||
7094 | When a match succeeds, the substrings of the subject string | ||
7095 | that match captures are stored (<em>captured</em>) for future use. | ||
7096 | Captures are numbered according to their left parentheses. | ||
7097 | For instance, in the pattern <code>"(a*(.)%w(%s*))"</code>, | ||
7098 | the part of the string matching <code>"a*(.)%w(%s*)"</code> is | ||
7099 | stored as the first capture (and therefore has number 1); | ||
7100 | the character matching "<code>.</code>" is captured with number 2, | ||
7101 | and the part matching "<code>%s*</code>" has number 3. | ||
7102 | |||
7103 | |||
7104 | <p> | ||
7105 | As a special case, the empty capture <code>()</code> captures | ||
7106 | the current string position (a number). | ||
7107 | For instance, if we apply the pattern <code>"()aa()"</code> on the | ||
7108 | string <code>"flaaap"</code>, there will be two captures: 3 and 5. | ||
7109 | |||
7110 | |||
7111 | <p> | ||
7112 | A pattern cannot contain embedded zeros. Use <code>%z</code> instead. | ||
7113 | |||
7114 | |||
7115 | |||
7116 | |||
7117 | |||
7118 | |||
7119 | |||
7120 | |||
7121 | |||
7122 | |||
7123 | |||
7124 | <h2>5.5 - <a name="5.5">Table Manipulation</a></h2><p> | ||
7125 | This library provides generic functions for table manipulation. | ||
7126 | It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>. | ||
7127 | |||
7128 | |||
7129 | <p> | ||
7130 | Most functions in the table library assume that the table | ||
7131 | represents an array or a list. | ||
7132 | For these functions, when we talk about the "length" of a table | ||
7133 | we mean the result of the length operator. | ||
7134 | |||
7135 | |||
7136 | <p> | ||
7137 | <hr><h3><a name="pdf-table.concat"><code>table.concat (table [, sep [, i [, j]]])</code></a></h3> | ||
7138 | Given an array where all elements are strings or numbers, | ||
7139 | returns <code>table[i]..sep..table[i+1] ··· sep..table[j]</code>. | ||
7140 | The default value for <code>sep</code> is the empty string, | ||
7141 | the default for <code>i</code> is 1, | ||
7142 | and the default for <code>j</code> is the length of the table. | ||
7143 | If <code>i</code> is greater than <code>j</code>, returns the empty string. | ||
7144 | |||
7145 | |||
7146 | |||
7147 | |||
7148 | <p> | ||
7149 | <hr><h3><a name="pdf-table.insert"><code>table.insert (table, [pos,] value)</code></a></h3> | ||
7150 | |||
7151 | |||
7152 | <p> | ||
7153 | Inserts element <code>value</code> at position <code>pos</code> in <code>table</code>, | ||
7154 | shifting up other elements to open space, if necessary. | ||
7155 | The default value for <code>pos</code> is <code>n+1</code>, | ||
7156 | where <code>n</code> is the length of the table (see <a href="#2.5.5">§2.5.5</a>), | ||
7157 | so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end | ||
7158 | of table <code>t</code>. | ||
7159 | |||
7160 | |||
7161 | |||
7162 | |||
7163 | <p> | ||
7164 | <hr><h3><a name="pdf-table.maxn"><code>table.maxn (table)</code></a></h3> | ||
7165 | |||
7166 | |||
7167 | <p> | ||
7168 | Returns the largest positive numerical index of the given table, | ||
7169 | or zero if the table has no positive numerical indices. | ||
7170 | (To do its job this function does a linear traversal of | ||
7171 | the whole table.) | ||
7172 | |||
7173 | |||
7174 | |||
7175 | |||
7176 | <p> | ||
7177 | <hr><h3><a name="pdf-table.remove"><code>table.remove (table [, pos])</code></a></h3> | ||
7178 | |||
7179 | |||
7180 | <p> | ||
7181 | Removes from <code>table</code> the element at position <code>pos</code>, | ||
7182 | shifting down other elements to close the space, if necessary. | ||
7183 | Returns the value of the removed element. | ||
7184 | The default value for <code>pos</code> is <code>n</code>, | ||
7185 | where <code>n</code> is the length of the table, | ||
7186 | so that a call <code>table.remove(t)</code> removes the last element | ||
7187 | of table <code>t</code>. | ||
7188 | |||
7189 | |||
7190 | |||
7191 | |||
7192 | <p> | ||
7193 | <hr><h3><a name="pdf-table.sort"><code>table.sort (table [, comp])</code></a></h3> | ||
7194 | Sorts table elements in a given order, <em>in-place</em>, | ||
7195 | from <code>table[1]</code> to <code>table[n]</code>, | ||
7196 | where <code>n</code> is the length of the table. | ||
7197 | If <code>comp</code> is given, | ||
7198 | then it must be a function that receives two table elements, | ||
7199 | and returns true | ||
7200 | when the first is less than the second | ||
7201 | (so that <code>not comp(a[i+1],a[i])</code> will be true after the sort). | ||
7202 | If <code>comp</code> is not given, | ||
7203 | then the standard Lua operator <code><</code> is used instead. | ||
7204 | |||
7205 | |||
7206 | <p> | ||
7207 | The sort algorithm is not stable; | ||
7208 | that is, elements considered equal by the given order | ||
7209 | may have their relative positions changed by the sort. | ||
7210 | |||
7211 | |||
7212 | |||
7213 | |||
7214 | |||
7215 | |||
7216 | |||
7217 | <h2>5.6 - <a name="5.6">Mathematical Functions</a></h2> | ||
7218 | |||
7219 | <p> | ||
7220 | This library is an interface to the standard C math library. | ||
7221 | It provides all its functions inside the table <a name="pdf-math"><code>math</code></a>. | ||
7222 | |||
7223 | |||
7224 | <p> | ||
7225 | <hr><h3><a name="pdf-math.abs"><code>math.abs (x)</code></a></h3> | ||
7226 | |||
7227 | |||
7228 | <p> | ||
7229 | Returns the absolute value of <code>x</code>. | ||
7230 | |||
7231 | |||
7232 | |||
7233 | |||
7234 | <p> | ||
7235 | <hr><h3><a name="pdf-math.acos"><code>math.acos (x)</code></a></h3> | ||
7236 | |||
7237 | |||
7238 | <p> | ||
7239 | Returns the arc cosine of <code>x</code> (in radians). | ||
7240 | |||
7241 | |||
7242 | |||
7243 | |||
7244 | <p> | ||
7245 | <hr><h3><a name="pdf-math.asin"><code>math.asin (x)</code></a></h3> | ||
7246 | |||
7247 | |||
7248 | <p> | ||
7249 | Returns the arc sine of <code>x</code> (in radians). | ||
7250 | |||
7251 | |||
7252 | |||
7253 | |||
7254 | <p> | ||
7255 | <hr><h3><a name="pdf-math.atan"><code>math.atan (x)</code></a></h3> | ||
7256 | |||
7257 | |||
7258 | <p> | ||
7259 | Returns the arc tangent of <code>x</code> (in radians). | ||
7260 | |||
7261 | |||
7262 | |||
7263 | |||
7264 | <p> | ||
7265 | <hr><h3><a name="pdf-math.atan2"><code>math.atan2 (y, x)</code></a></h3> | ||
7266 | |||
7267 | |||
7268 | <p> | ||
7269 | Returns the arc tangent of <code>y/x</code> (in radians), | ||
7270 | but uses the signs of both parameters to find the | ||
7271 | quadrant of the result. | ||
7272 | (It also handles correctly the case of <code>x</code> being zero.) | ||
7273 | |||
7274 | |||
7275 | |||
7276 | |||
7277 | <p> | ||
7278 | <hr><h3><a name="pdf-math.ceil"><code>math.ceil (x)</code></a></h3> | ||
7279 | |||
7280 | |||
7281 | <p> | ||
7282 | Returns the smallest integer larger than or equal to <code>x</code>. | ||
7283 | |||
7284 | |||
7285 | |||
7286 | |||
7287 | <p> | ||
7288 | <hr><h3><a name="pdf-math.cos"><code>math.cos (x)</code></a></h3> | ||
7289 | |||
7290 | |||
7291 | <p> | ||
7292 | Returns the cosine of <code>x</code> (assumed to be in radians). | ||
7293 | |||
7294 | |||
7295 | |||
7296 | |||
7297 | <p> | ||
7298 | <hr><h3><a name="pdf-math.cosh"><code>math.cosh (x)</code></a></h3> | ||
7299 | |||
7300 | |||
7301 | <p> | ||
7302 | Returns the hyperbolic cosine of <code>x</code>. | ||
7303 | |||
7304 | |||
7305 | |||
7306 | |||
7307 | <p> | ||
7308 | <hr><h3><a name="pdf-math.deg"><code>math.deg (x)</code></a></h3> | ||
7309 | |||
7310 | |||
7311 | <p> | ||
7312 | Returns the angle <code>x</code> (given in radians) in degrees. | ||
7313 | |||
7314 | |||
7315 | |||
7316 | |||
7317 | <p> | ||
7318 | <hr><h3><a name="pdf-math.exp"><code>math.exp (x)</code></a></h3> | ||
7319 | |||
7320 | |||
7321 | <p> | ||
7322 | Returns the value <em>e<sup>x</sup></em>. | ||
7323 | |||
7324 | |||
7325 | |||
7326 | |||
7327 | <p> | ||
7328 | <hr><h3><a name="pdf-math.floor"><code>math.floor (x)</code></a></h3> | ||
7329 | |||
7330 | |||
7331 | <p> | ||
7332 | Returns the largest integer smaller than or equal to <code>x</code>. | ||
7333 | |||
7334 | |||
7335 | |||
7336 | |||
7337 | <p> | ||
7338 | <hr><h3><a name="pdf-math.fmod"><code>math.fmod (x, y)</code></a></h3> | ||
7339 | |||
7340 | |||
7341 | <p> | ||
7342 | Returns the remainder of the division of <code>x</code> by <code>y</code> | ||
7343 | that rounds the quotient towards zero. | ||
7344 | |||
7345 | |||
7346 | |||
7347 | |||
7348 | <p> | ||
7349 | <hr><h3><a name="pdf-math.frexp"><code>math.frexp (x)</code></a></h3> | ||
7350 | |||
7351 | |||
7352 | <p> | ||
7353 | Returns <code>m</code> and <code>e</code> such that <em>x = m2<sup>e</sup></em>, | ||
7354 | <code>e</code> is an integer and the absolute value of <code>m</code> is | ||
7355 | in the range <em>[0.5, 1)</em> | ||
7356 | (or zero when <code>x</code> is zero). | ||
7357 | |||
7358 | |||
7359 | |||
7360 | |||
7361 | <p> | ||
7362 | <hr><h3><a name="pdf-math.huge"><code>math.huge</code></a></h3> | ||
7363 | |||
7364 | |||
7365 | <p> | ||
7366 | The value <code>HUGE_VAL</code>, | ||
7367 | a value larger than or equal to any other numerical value. | ||
7368 | |||
7369 | |||
7370 | |||
7371 | |||
7372 | <p> | ||
7373 | <hr><h3><a name="pdf-math.ldexp"><code>math.ldexp (m, e)</code></a></h3> | ||
7374 | |||
7375 | |||
7376 | <p> | ||
7377 | Returns <em>m2<sup>e</sup></em> (<code>e</code> should be an integer). | ||
7378 | |||
7379 | |||
7380 | |||
7381 | |||
7382 | <p> | ||
7383 | <hr><h3><a name="pdf-math.log"><code>math.log (x)</code></a></h3> | ||
7384 | |||
7385 | |||
7386 | <p> | ||
7387 | Returns the natural logarithm of <code>x</code>. | ||
7388 | |||
7389 | |||
7390 | |||
7391 | |||
7392 | <p> | ||
7393 | <hr><h3><a name="pdf-math.log10"><code>math.log10 (x)</code></a></h3> | ||
7394 | |||
7395 | |||
7396 | <p> | ||
7397 | Returns the base-10 logarithm of <code>x</code>. | ||
7398 | |||
7399 | |||
7400 | |||
7401 | |||
7402 | <p> | ||
7403 | <hr><h3><a name="pdf-math.max"><code>math.max (x, ···)</code></a></h3> | ||
7404 | |||
7405 | |||
7406 | <p> | ||
7407 | Returns the maximum value among its arguments. | ||
7408 | |||
7409 | |||
7410 | |||
7411 | |||
7412 | <p> | ||
7413 | <hr><h3><a name="pdf-math.min"><code>math.min (x, ···)</code></a></h3> | ||
7414 | |||
7415 | |||
7416 | <p> | ||
7417 | Returns the minimum value among its arguments. | ||
7418 | |||
7419 | |||
7420 | |||
7421 | |||
7422 | <p> | ||
7423 | <hr><h3><a name="pdf-math.modf"><code>math.modf (x)</code></a></h3> | ||
7424 | |||
7425 | |||
7426 | <p> | ||
7427 | Returns two numbers, | ||
7428 | the integral part of <code>x</code> and the fractional part of <code>x</code>. | ||
7429 | |||
7430 | |||
7431 | |||
7432 | |||
7433 | <p> | ||
7434 | <hr><h3><a name="pdf-math.pi"><code>math.pi</code></a></h3> | ||
7435 | |||
7436 | |||
7437 | <p> | ||
7438 | The value of <em>pi</em>. | ||
7439 | |||
7440 | |||
7441 | |||
7442 | |||
7443 | <p> | ||
7444 | <hr><h3><a name="pdf-math.pow"><code>math.pow (x, y)</code></a></h3> | ||
7445 | |||
7446 | |||
7447 | <p> | ||
7448 | Returns <em>x<sup>y</sup></em>. | ||
7449 | (You can also use the expression <code>x^y</code> to compute this value.) | ||
7450 | |||
7451 | |||
7452 | |||
7453 | |||
7454 | <p> | ||
7455 | <hr><h3><a name="pdf-math.rad"><code>math.rad (x)</code></a></h3> | ||
7456 | |||
7457 | |||
7458 | <p> | ||
7459 | Returns the angle <code>x</code> (given in degrees) in radians. | ||
7460 | |||
7461 | |||
7462 | |||
7463 | |||
7464 | <p> | ||
7465 | <hr><h3><a name="pdf-math.random"><code>math.random ([m [, n]])</code></a></h3> | ||
7466 | |||
7467 | |||
7468 | <p> | ||
7469 | This function is an interface to the simple | ||
7470 | pseudo-random generator function <code>rand</code> provided by ANSI C. | ||
7471 | (No guarantees can be given for its statistical properties.) | ||
7472 | |||
7473 | |||
7474 | <p> | ||
7475 | When called without arguments, | ||
7476 | returns a uniform pseudo-random real number | ||
7477 | in the range <em>[0,1)</em>. | ||
7478 | When called with an integer number <code>m</code>, | ||
7479 | <code>math.random</code> returns | ||
7480 | a uniform pseudo-random integer in the range <em>[1, m]</em>. | ||
7481 | When called with two integer numbers <code>m</code> and <code>n</code>, | ||
7482 | <code>math.random</code> returns a uniform pseudo-random | ||
7483 | integer in the range <em>[m, n]</em>. | ||
7484 | |||
7485 | |||
7486 | |||
7487 | |||
7488 | <p> | ||
7489 | <hr><h3><a name="pdf-math.randomseed"><code>math.randomseed (x)</code></a></h3> | ||
7490 | |||
7491 | |||
7492 | <p> | ||
7493 | Sets <code>x</code> as the "seed" | ||
7494 | for the pseudo-random generator: | ||
7495 | equal seeds produce equal sequences of numbers. | ||
7496 | |||
7497 | |||
7498 | |||
7499 | |||
7500 | <p> | ||
7501 | <hr><h3><a name="pdf-math.sin"><code>math.sin (x)</code></a></h3> | ||
7502 | |||
7503 | |||
7504 | <p> | ||
7505 | Returns the sine of <code>x</code> (assumed to be in radians). | ||
7506 | |||
7507 | |||
7508 | |||
7509 | |||
7510 | <p> | ||
7511 | <hr><h3><a name="pdf-math.sinh"><code>math.sinh (x)</code></a></h3> | ||
7512 | |||
7513 | |||
7514 | <p> | ||
7515 | Returns the hyperbolic sine of <code>x</code>. | ||
7516 | |||
7517 | |||
7518 | |||
7519 | |||
7520 | <p> | ||
7521 | <hr><h3><a name="pdf-math.sqrt"><code>math.sqrt (x)</code></a></h3> | ||
7522 | |||
7523 | |||
7524 | <p> | ||
7525 | Returns the square root of <code>x</code>. | ||
7526 | (You can also use the expression <code>x^0.5</code> to compute this value.) | ||
7527 | |||
7528 | |||
7529 | |||
7530 | |||
7531 | <p> | ||
7532 | <hr><h3><a name="pdf-math.tan"><code>math.tan (x)</code></a></h3> | ||
7533 | |||
7534 | |||
7535 | <p> | ||
7536 | Returns the tangent of <code>x</code> (assumed to be in radians). | ||
7537 | |||
7538 | |||
7539 | |||
7540 | |||
7541 | <p> | ||
7542 | <hr><h3><a name="pdf-math.tanh"><code>math.tanh (x)</code></a></h3> | ||
7543 | |||
7544 | |||
7545 | <p> | ||
7546 | Returns the hyperbolic tangent of <code>x</code>. | ||
7547 | |||
7548 | |||
7549 | |||
7550 | |||
7551 | |||
7552 | |||
7553 | |||
7554 | <h2>5.7 - <a name="5.7">Input and Output Facilities</a></h2> | ||
7555 | |||
7556 | <p> | ||
7557 | The I/O library provides two different styles for file manipulation. | ||
7558 | The first one uses implicit file descriptors; | ||
7559 | that is, there are operations to set a default input file and a | ||
7560 | default output file, | ||
7561 | and all input/output operations are over these default files. | ||
7562 | The second style uses explicit file descriptors. | ||
7563 | |||
7564 | |||
7565 | <p> | ||
7566 | When using implicit file descriptors, | ||
7567 | all operations are supplied by table <a name="pdf-io"><code>io</code></a>. | ||
7568 | When using explicit file descriptors, | ||
7569 | the operation <a href="#pdf-io.open"><code>io.open</code></a> returns a file descriptor | ||
7570 | and then all operations are supplied as methods of the file descriptor. | ||
7571 | |||
7572 | |||
7573 | <p> | ||
7574 | The table <code>io</code> also provides | ||
7575 | three predefined file descriptors with their usual meanings from C: | ||
7576 | <a name="pdf-io.stdin"><code>io.stdin</code></a>, <a name="pdf-io.stdout"><code>io.stdout</code></a>, and <a name="pdf-io.stderr"><code>io.stderr</code></a>. | ||
7577 | The I/O library never closes these files. | ||
7578 | |||
7579 | |||
7580 | <p> | ||
7581 | Unless otherwise stated, | ||
7582 | all I/O functions return <b>nil</b> on failure | ||
7583 | (plus an error message as a second result and | ||
7584 | a system-dependent error code as a third result) | ||
7585 | and some value different from <b>nil</b> on success. | ||
7586 | |||
7587 | |||
7588 | <p> | ||
7589 | <hr><h3><a name="pdf-io.close"><code>io.close ([file])</code></a></h3> | ||
7590 | |||
7591 | |||
7592 | <p> | ||
7593 | Equivalent to <code>file:close()</code>. | ||
7594 | Without a <code>file</code>, closes the default output file. | ||
7595 | |||
7596 | |||
7597 | |||
7598 | |||
7599 | <p> | ||
7600 | <hr><h3><a name="pdf-io.flush"><code>io.flush ()</code></a></h3> | ||
7601 | |||
7602 | |||
7603 | <p> | ||
7604 | Equivalent to <code>file:flush</code> over the default output file. | ||
7605 | |||
7606 | |||
7607 | |||
7608 | |||
7609 | <p> | ||
7610 | <hr><h3><a name="pdf-io.input"><code>io.input ([file])</code></a></h3> | ||
7611 | |||
7612 | |||
7613 | <p> | ||
7614 | When called with a file name, it opens the named file (in text mode), | ||
7615 | and sets its handle as the default input file. | ||
7616 | When called with a file handle, | ||
7617 | it simply sets this file handle as the default input file. | ||
7618 | When called without parameters, | ||
7619 | it returns the current default input file. | ||
7620 | |||
7621 | |||
7622 | <p> | ||
7623 | In case of errors this function raises the error, | ||
7624 | instead of returning an error code. | ||
7625 | |||
7626 | |||
7627 | |||
7628 | |||
7629 | <p> | ||
7630 | <hr><h3><a name="pdf-io.lines"><code>io.lines ([filename])</code></a></h3> | ||
7631 | |||
7632 | |||
7633 | <p> | ||
7634 | Opens the given file name in read mode | ||
7635 | and returns an iterator function that, | ||
7636 | each time it is called, | ||
7637 | returns a new line from the file. | ||
7638 | Therefore, the construction | ||
7639 | |||
7640 | <pre> | ||
7641 | for line in io.lines(filename) do <em>body</em> end | ||
7642 | </pre><p> | ||
7643 | will iterate over all lines of the file. | ||
7644 | When the iterator function detects the end of file, | ||
7645 | it returns <b>nil</b> (to finish the loop) and automatically closes the file. | ||
7646 | |||
7647 | |||
7648 | <p> | ||
7649 | The call <code>io.lines()</code> (with no file name) is equivalent | ||
7650 | to <code>io.input():lines()</code>; | ||
7651 | that is, it iterates over the lines of the default input file. | ||
7652 | In this case it does not close the file when the loop ends. | ||
7653 | |||
7654 | |||
7655 | |||
7656 | |||
7657 | <p> | ||
7658 | <hr><h3><a name="pdf-io.open"><code>io.open (filename [, mode])</code></a></h3> | ||
7659 | |||
7660 | |||
7661 | <p> | ||
7662 | This function opens a file, | ||
7663 | in the mode specified in the string <code>mode</code>. | ||
7664 | It returns a new file handle, | ||
7665 | or, in case of errors, <b>nil</b> plus an error message. | ||
7666 | |||
7667 | |||
7668 | <p> | ||
7669 | The <code>mode</code> string can be any of the following: | ||
7670 | |||
7671 | <ul> | ||
7672 | <li><b>"r":</b> read mode (the default);</li> | ||
7673 | <li><b>"w":</b> write mode;</li> | ||
7674 | <li><b>"a":</b> append mode;</li> | ||
7675 | <li><b>"r+":</b> update mode, all previous data is preserved;</li> | ||
7676 | <li><b>"w+":</b> update mode, all previous data is erased;</li> | ||
7677 | <li><b>"a+":</b> append update mode, previous data is preserved, | ||
7678 | writing is only allowed at the end of file.</li> | ||
7679 | </ul><p> | ||
7680 | The <code>mode</code> string can also have a '<code>b</code>' at the end, | ||
7681 | which is needed in some systems to open the file in binary mode. | ||
7682 | This string is exactly what is used in the | ||
7683 | standard C function <code>fopen</code>. | ||
7684 | |||
7685 | |||
7686 | |||
7687 | |||
7688 | <p> | ||
7689 | <hr><h3><a name="pdf-io.output"><code>io.output ([file])</code></a></h3> | ||
7690 | |||
7691 | |||
7692 | <p> | ||
7693 | Similar to <a href="#pdf-io.input"><code>io.input</code></a>, but operates over the default output file. | ||
7694 | |||
7695 | |||
7696 | |||
7697 | |||
7698 | <p> | ||
7699 | <hr><h3><a name="pdf-io.popen"><code>io.popen (prog [, mode])</code></a></h3> | ||
7700 | |||
7701 | |||
7702 | <p> | ||
7703 | Starts program <code>prog</code> in a separated process and returns | ||
7704 | a file handle that you can use to read data from this program | ||
7705 | (if <code>mode</code> is <code>"r"</code>, the default) | ||
7706 | or to write data to this program | ||
7707 | (if <code>mode</code> is <code>"w"</code>). | ||
7708 | |||
7709 | |||
7710 | <p> | ||
7711 | This function is system dependent and is not available | ||
7712 | on all platforms. | ||
7713 | |||
7714 | |||
7715 | |||
7716 | |||
7717 | <p> | ||
7718 | <hr><h3><a name="pdf-io.read"><code>io.read (···)</code></a></h3> | ||
7719 | |||
7720 | |||
7721 | <p> | ||
7722 | Equivalent to <code>io.input():read</code>. | ||
7723 | |||
7724 | |||
7725 | |||
7726 | |||
7727 | <p> | ||
7728 | <hr><h3><a name="pdf-io.tmpfile"><code>io.tmpfile ()</code></a></h3> | ||
7729 | |||
7730 | |||
7731 | <p> | ||
7732 | Returns a handle for a temporary file. | ||
7733 | This file is opened in update mode | ||
7734 | and it is automatically removed when the program ends. | ||
7735 | |||
7736 | |||
7737 | |||
7738 | |||
7739 | <p> | ||
7740 | <hr><h3><a name="pdf-io.type"><code>io.type (obj)</code></a></h3> | ||
7741 | |||
7742 | |||
7743 | <p> | ||
7744 | Checks whether <code>obj</code> is a valid file handle. | ||
7745 | Returns the string <code>"file"</code> if <code>obj</code> is an open file handle, | ||
7746 | <code>"closed file"</code> if <code>obj</code> is a closed file handle, | ||
7747 | or <b>nil</b> if <code>obj</code> is not a file handle. | ||
7748 | |||
7749 | |||
7750 | |||
7751 | |||
7752 | <p> | ||
7753 | <hr><h3><a name="pdf-io.write"><code>io.write (···)</code></a></h3> | ||
7754 | |||
7755 | |||
7756 | <p> | ||
7757 | Equivalent to <code>io.output():write</code>. | ||
7758 | |||
7759 | |||
7760 | |||
7761 | |||
7762 | <p> | ||
7763 | <hr><h3><a name="pdf-file:close"><code>file:close ()</code></a></h3> | ||
7764 | |||
7765 | |||
7766 | <p> | ||
7767 | Closes <code>file</code>. | ||
7768 | Note that files are automatically closed when | ||
7769 | their handles are garbage collected, | ||
7770 | but that takes an unpredictable amount of time to happen. | ||
7771 | |||
7772 | |||
7773 | |||
7774 | |||
7775 | <p> | ||
7776 | <hr><h3><a name="pdf-file:flush"><code>file:flush ()</code></a></h3> | ||
7777 | |||
7778 | |||
7779 | <p> | ||
7780 | Saves any written data to <code>file</code>. | ||
7781 | |||
7782 | |||
7783 | |||
7784 | |||
7785 | <p> | ||
7786 | <hr><h3><a name="pdf-file:lines"><code>file:lines ()</code></a></h3> | ||
7787 | |||
7788 | |||
7789 | <p> | ||
7790 | Returns an iterator function that, | ||
7791 | each time it is called, | ||
7792 | returns a new line from the file. | ||
7793 | Therefore, the construction | ||
7794 | |||
7795 | <pre> | ||
7796 | for line in file:lines() do <em>body</em> end | ||
7797 | </pre><p> | ||
7798 | will iterate over all lines of the file. | ||
7799 | (Unlike <a href="#pdf-io.lines"><code>io.lines</code></a>, this function does not close the file | ||
7800 | when the loop ends.) | ||
7801 | |||
7802 | |||
7803 | |||
7804 | |||
7805 | <p> | ||
7806 | <hr><h3><a name="pdf-file:read"><code>file:read (···)</code></a></h3> | ||
7807 | |||
7808 | |||
7809 | <p> | ||
7810 | Reads the file <code>file</code>, | ||
7811 | according to the given formats, which specify what to read. | ||
7812 | For each format, | ||
7813 | the function returns a string (or a number) with the characters read, | ||
7814 | or <b>nil</b> if it cannot read data with the specified format. | ||
7815 | When called without formats, | ||
7816 | it uses a default format that reads the entire next line | ||
7817 | (see below). | ||
7818 | |||
7819 | |||
7820 | <p> | ||
7821 | The available formats are | ||
7822 | |||
7823 | <ul> | ||
7824 | |||
7825 | <li><b>"*n":</b> | ||
7826 | reads a number; | ||
7827 | this is the only format that returns a number instead of a string. | ||
7828 | </li> | ||
7829 | |||
7830 | <li><b>"*a":</b> | ||
7831 | reads the whole file, starting at the current position. | ||
7832 | On end of file, it returns the empty string. | ||
7833 | </li> | ||
7834 | |||
7835 | <li><b>"*l":</b> | ||
7836 | reads the next line (skipping the end of line), | ||
7837 | returning <b>nil</b> on end of file. | ||
7838 | This is the default format. | ||
7839 | </li> | ||
7840 | |||
7841 | <li><b><em>number</em>:</b> | ||
7842 | reads a string with up to this number of characters, | ||
7843 | returning <b>nil</b> on end of file. | ||
7844 | If number is zero, | ||
7845 | it reads nothing and returns an empty string, | ||
7846 | or <b>nil</b> on end of file. | ||
7847 | </li> | ||
7848 | |||
7849 | </ul> | ||
7850 | |||
7851 | |||
7852 | |||
7853 | <p> | ||
7854 | <hr><h3><a name="pdf-file:seek"><code>file:seek ([whence] [, offset])</code></a></h3> | ||
7855 | |||
7856 | |||
7857 | <p> | ||
7858 | Sets and gets the file position, | ||
7859 | measured from the beginning of the file, | ||
7860 | to the position given by <code>offset</code> plus a base | ||
7861 | specified by the string <code>whence</code>, as follows: | ||
7862 | |||
7863 | <ul> | ||
7864 | <li><b>"set":</b> base is position 0 (beginning of the file);</li> | ||
7865 | <li><b>"cur":</b> base is current position;</li> | ||
7866 | <li><b>"end":</b> base is end of file;</li> | ||
7867 | </ul><p> | ||
7868 | In case of success, function <code>seek</code> returns the final file position, | ||
7869 | measured in bytes from the beginning of the file. | ||
7870 | If this function fails, it returns <b>nil</b>, | ||
7871 | plus a string describing the error. | ||
7872 | |||
7873 | |||
7874 | <p> | ||
7875 | The default value for <code>whence</code> is <code>"cur"</code>, | ||
7876 | and for <code>offset</code> is 0. | ||
7877 | Therefore, the call <code>file:seek()</code> returns the current | ||
7878 | file position, without changing it; | ||
7879 | the call <code>file:seek("set")</code> sets the position to the | ||
7880 | beginning of the file (and returns 0); | ||
7881 | and the call <code>file:seek("end")</code> sets the position to the | ||
7882 | end of the file, and returns its size. | ||
7883 | |||
7884 | |||
7885 | |||
7886 | |||
7887 | <p> | ||
7888 | <hr><h3><a name="pdf-file:setvbuf"><code>file:setvbuf (mode [, size])</code></a></h3> | ||
7889 | |||
7890 | |||
7891 | <p> | ||
7892 | Sets the buffering mode for an output file. | ||
7893 | There are three available modes: | ||
7894 | |||
7895 | <ul> | ||
7896 | |||
7897 | <li><b>"no":</b> | ||
7898 | no buffering; the result of any output operation appears immediately. | ||
7899 | </li> | ||
7900 | |||
7901 | <li><b>"full":</b> | ||
7902 | full buffering; output operation is performed only | ||
7903 | when the buffer is full (or when you explicitly <code>flush</code> the file | ||
7904 | (see <a href="#pdf-io.flush"><code>io.flush</code></a>)). | ||
7905 | </li> | ||
7906 | |||
7907 | <li><b>"line":</b> | ||
7908 | line buffering; output is buffered until a newline is output | ||
7909 | or there is any input from some special files | ||
7910 | (such as a terminal device). | ||
7911 | </li> | ||
7912 | |||
7913 | </ul><p> | ||
7914 | For the last two cases, <code>size</code> | ||
7915 | specifies the size of the buffer, in bytes. | ||
7916 | The default is an appropriate size. | ||
7917 | |||
7918 | |||
7919 | |||
7920 | |||
7921 | <p> | ||
7922 | <hr><h3><a name="pdf-file:write"><code>file:write (···)</code></a></h3> | ||
7923 | |||
7924 | |||
7925 | <p> | ||
7926 | Writes the value of each of its arguments to | ||
7927 | the <code>file</code>. | ||
7928 | The arguments must be strings or numbers. | ||
7929 | To write other values, | ||
7930 | use <a href="#pdf-tostring"><code>tostring</code></a> or <a href="#pdf-string.format"><code>string.format</code></a> before <code>write</code>. | ||
7931 | |||
7932 | |||
7933 | |||
7934 | |||
7935 | |||
7936 | |||
7937 | |||
7938 | <h2>5.8 - <a name="5.8">Operating System Facilities</a></h2> | ||
7939 | |||
7940 | <p> | ||
7941 | This library is implemented through table <a name="pdf-os"><code>os</code></a>. | ||
7942 | |||
7943 | |||
7944 | <p> | ||
7945 | <hr><h3><a name="pdf-os.clock"><code>os.clock ()</code></a></h3> | ||
7946 | |||
7947 | |||
7948 | <p> | ||
7949 | Returns an approximation of the amount in seconds of CPU time | ||
7950 | used by the program. | ||
7951 | |||
7952 | |||
7953 | |||
7954 | |||
7955 | <p> | ||
7956 | <hr><h3><a name="pdf-os.date"><code>os.date ([format [, time]])</code></a></h3> | ||
7957 | |||
7958 | |||
7959 | <p> | ||
7960 | Returns a string or a table containing date and time, | ||
7961 | formatted according to the given string <code>format</code>. | ||
7962 | |||
7963 | |||
7964 | <p> | ||
7965 | If the <code>time</code> argument is present, | ||
7966 | this is the time to be formatted | ||
7967 | (see the <a href="#pdf-os.time"><code>os.time</code></a> function for a description of this value). | ||
7968 | Otherwise, <code>date</code> formats the current time. | ||
7969 | |||
7970 | |||
7971 | <p> | ||
7972 | If <code>format</code> starts with '<code>!</code>', | ||
7973 | then the date is formatted in Coordinated Universal Time. | ||
7974 | After this optional character, | ||
7975 | if <code>format</code> is the string "<code>*t</code>", | ||
7976 | then <code>date</code> returns a table with the following fields: | ||
7977 | <code>year</code> (four digits), <code>month</code> (1--12), <code>day</code> (1--31), | ||
7978 | <code>hour</code> (0--23), <code>min</code> (0--59), <code>sec</code> (0--61), | ||
7979 | <code>wday</code> (weekday, Sunday is 1), | ||
7980 | <code>yday</code> (day of the year), | ||
7981 | and <code>isdst</code> (daylight saving flag, a boolean). | ||
7982 | |||
7983 | |||
7984 | <p> | ||
7985 | If <code>format</code> is not "<code>*t</code>", | ||
7986 | then <code>date</code> returns the date as a string, | ||
7987 | formatted according to the same rules as the C function <code>strftime</code>. | ||
7988 | |||
7989 | |||
7990 | <p> | ||
7991 | When called without arguments, | ||
7992 | <code>date</code> returns a reasonable date and time representation that depends on | ||
7993 | the host system and on the current locale | ||
7994 | (that is, <code>os.date()</code> is equivalent to <code>os.date("%c")</code>). | ||
7995 | |||
7996 | |||
7997 | |||
7998 | |||
7999 | <p> | ||
8000 | <hr><h3><a name="pdf-os.difftime"><code>os.difftime (t2, t1)</code></a></h3> | ||
8001 | |||
8002 | |||
8003 | <p> | ||
8004 | Returns the number of seconds from time <code>t1</code> to time <code>t2</code>. | ||
8005 | In POSIX, Windows, and some other systems, | ||
8006 | this value is exactly <code>t2</code><em>-</em><code>t1</code>. | ||
8007 | |||
8008 | |||
8009 | |||
8010 | |||
8011 | <p> | ||
8012 | <hr><h3><a name="pdf-os.execute"><code>os.execute ([command])</code></a></h3> | ||
8013 | |||
8014 | |||
8015 | <p> | ||
8016 | This function is equivalent to the C function <code>system</code>. | ||
8017 | It passes <code>command</code> to be executed by an operating system shell. | ||
8018 | It returns a status code, which is system-dependent. | ||
8019 | If <code>command</code> is absent, then it returns nonzero if a shell is available | ||
8020 | and zero otherwise. | ||
8021 | |||
8022 | |||
8023 | |||
8024 | |||
8025 | <p> | ||
8026 | <hr><h3><a name="pdf-os.exit"><code>os.exit ([code])</code></a></h3> | ||
8027 | |||
8028 | |||
8029 | <p> | ||
8030 | Calls the C function <code>exit</code>, | ||
8031 | with an optional <code>code</code>, | ||
8032 | to terminate the host program. | ||
8033 | The default value for <code>code</code> is the success code. | ||
8034 | |||
8035 | |||
8036 | |||
8037 | |||
8038 | <p> | ||
8039 | <hr><h3><a name="pdf-os.getenv"><code>os.getenv (varname)</code></a></h3> | ||
8040 | |||
8041 | |||
8042 | <p> | ||
8043 | Returns the value of the process environment variable <code>varname</code>, | ||
8044 | or <b>nil</b> if the variable is not defined. | ||
8045 | |||
8046 | |||
8047 | |||
8048 | |||
8049 | <p> | ||
8050 | <hr><h3><a name="pdf-os.remove"><code>os.remove (filename)</code></a></h3> | ||
8051 | |||
8052 | |||
8053 | <p> | ||
8054 | Deletes the file or directory with the given name. | ||
8055 | Directories must be empty to be removed. | ||
8056 | If this function fails, it returns <b>nil</b>, | ||
8057 | plus a string describing the error. | ||
8058 | |||
8059 | |||
8060 | |||
8061 | |||
8062 | <p> | ||
8063 | <hr><h3><a name="pdf-os.rename"><code>os.rename (oldname, newname)</code></a></h3> | ||
8064 | |||
8065 | |||
8066 | <p> | ||
8067 | Renames file or directory named <code>oldname</code> to <code>newname</code>. | ||
8068 | If this function fails, it returns <b>nil</b>, | ||
8069 | plus a string describing the error. | ||
8070 | |||
8071 | |||
8072 | |||
8073 | |||
8074 | <p> | ||
8075 | <hr><h3><a name="pdf-os.setlocale"><code>os.setlocale (locale [, category])</code></a></h3> | ||
8076 | |||
8077 | |||
8078 | <p> | ||
8079 | Sets the current locale of the program. | ||
8080 | <code>locale</code> is a string specifying a locale; | ||
8081 | <code>category</code> is an optional string describing which category to change: | ||
8082 | <code>"all"</code>, <code>"collate"</code>, <code>"ctype"</code>, | ||
8083 | <code>"monetary"</code>, <code>"numeric"</code>, or <code>"time"</code>; | ||
8084 | the default category is <code>"all"</code>. | ||
8085 | The function returns the name of the new locale, | ||
8086 | or <b>nil</b> if the request cannot be honored. | ||
8087 | |||
8088 | |||
8089 | <p> | ||
8090 | If <code>locale</code> is the empty string, | ||
8091 | the current locale is set to an implementation-defined native locale. | ||
8092 | If <code>locale</code> is the string "<code>C</code>", | ||
8093 | the current locale is set to the standard C locale. | ||
8094 | |||
8095 | |||
8096 | <p> | ||
8097 | When called with <b>nil</b> as the first argument, | ||
8098 | this function only returns the name of the current locale | ||
8099 | for the given category. | ||
8100 | |||
8101 | |||
8102 | |||
8103 | |||
8104 | <p> | ||
8105 | <hr><h3><a name="pdf-os.time"><code>os.time ([table])</code></a></h3> | ||
8106 | |||
8107 | |||
8108 | <p> | ||
8109 | Returns the current time when called without arguments, | ||
8110 | or a time representing the date and time specified by the given table. | ||
8111 | This table must have fields <code>year</code>, <code>month</code>, and <code>day</code>, | ||
8112 | and may have fields <code>hour</code>, <code>min</code>, <code>sec</code>, and <code>isdst</code> | ||
8113 | (for a description of these fields, see the <a href="#pdf-os.date"><code>os.date</code></a> function). | ||
8114 | |||
8115 | |||
8116 | <p> | ||
8117 | The returned value is a number, whose meaning depends on your system. | ||
8118 | In POSIX, Windows, and some other systems, this number counts the number | ||
8119 | of seconds since some given start time (the "epoch"). | ||
8120 | In other systems, the meaning is not specified, | ||
8121 | and the number returned by <code>time</code> can be used only as an argument to | ||
8122 | <code>date</code> and <code>difftime</code>. | ||
8123 | |||
8124 | |||
8125 | |||
8126 | |||
8127 | <p> | ||
8128 | <hr><h3><a name="pdf-os.tmpname"><code>os.tmpname ()</code></a></h3> | ||
8129 | |||
8130 | |||
8131 | <p> | ||
8132 | Returns a string with a file name that can | ||
8133 | be used for a temporary file. | ||
8134 | The file must be explicitly opened before its use | ||
8135 | and explicitly removed when no longer needed. | ||
8136 | |||
8137 | |||
8138 | <p> | ||
8139 | On some systems (POSIX), | ||
8140 | this function also creates a file with that name, | ||
8141 | to avoid security risks. | ||
8142 | (Someone else might create the file with wrong permissions | ||
8143 | in the time between getting the name and creating the file.) | ||
8144 | You still have to open the file to use it | ||
8145 | and to remove it (even if you do not use it). | ||
8146 | |||
8147 | |||
8148 | <p> | ||
8149 | When possible, | ||
8150 | you may prefer to use <a href="#pdf-io.tmpfile"><code>io.tmpfile</code></a>, | ||
8151 | which automatically removes the file when the program ends. | ||
8152 | |||
8153 | |||
8154 | |||
8155 | |||
8156 | |||
8157 | |||
8158 | |||
8159 | <h2>5.9 - <a name="5.9">The Debug Library</a></h2> | ||
8160 | |||
8161 | <p> | ||
8162 | This library provides | ||
8163 | the functionality of the debug interface to Lua programs. | ||
8164 | You should exert care when using this library. | ||
8165 | The functions provided here should be used exclusively for debugging | ||
8166 | and similar tasks, such as profiling. | ||
8167 | Please resist the temptation to use them as a | ||
8168 | usual programming tool: | ||
8169 | they can be very slow. | ||
8170 | Moreover, several of these functions | ||
8171 | violate some assumptions about Lua code | ||
8172 | (e.g., that variables local to a function | ||
8173 | cannot be accessed from outside or | ||
8174 | that userdata metatables cannot be changed by Lua code) | ||
8175 | and therefore can compromise otherwise secure code. | ||
8176 | |||
8177 | |||
8178 | <p> | ||
8179 | All functions in this library are provided | ||
8180 | inside the <a name="pdf-debug"><code>debug</code></a> table. | ||
8181 | All functions that operate over a thread | ||
8182 | have an optional first argument which is the | ||
8183 | thread to operate over. | ||
8184 | The default is always the current thread. | ||
8185 | |||
8186 | |||
8187 | <p> | ||
8188 | <hr><h3><a name="pdf-debug.debug"><code>debug.debug ()</code></a></h3> | ||
8189 | |||
8190 | |||
8191 | <p> | ||
8192 | Enters an interactive mode with the user, | ||
8193 | running each string that the user enters. | ||
8194 | Using simple commands and other debug facilities, | ||
8195 | the user can inspect global and local variables, | ||
8196 | change their values, evaluate expressions, and so on. | ||
8197 | A line containing only the word <code>cont</code> finishes this function, | ||
8198 | so that the caller continues its execution. | ||
8199 | |||
8200 | |||
8201 | <p> | ||
8202 | Note that commands for <code>debug.debug</code> are not lexically nested | ||
8203 | within any function, and so have no direct access to local variables. | ||
8204 | |||
8205 | |||
8206 | |||
8207 | |||
8208 | <p> | ||
8209 | <hr><h3><a name="pdf-debug.getfenv"><code>debug.getfenv (o)</code></a></h3> | ||
8210 | Returns the environment of object <code>o</code>. | ||
8211 | |||
8212 | |||
8213 | |||
8214 | |||
8215 | <p> | ||
8216 | <hr><h3><a name="pdf-debug.gethook"><code>debug.gethook ([thread])</code></a></h3> | ||
8217 | |||
8218 | |||
8219 | <p> | ||
8220 | Returns the current hook settings of the thread, as three values: | ||
8221 | the current hook function, the current hook mask, | ||
8222 | and the current hook count | ||
8223 | (as set by the <a href="#pdf-debug.sethook"><code>debug.sethook</code></a> function). | ||
8224 | |||
8225 | |||
8226 | |||
8227 | |||
8228 | <p> | ||
8229 | <hr><h3><a name="pdf-debug.getinfo"><code>debug.getinfo ([thread,] function [, what])</code></a></h3> | ||
8230 | |||
8231 | |||
8232 | <p> | ||
8233 | Returns a table with information about a function. | ||
8234 | You can give the function directly, | ||
8235 | or you can give a number as the value of <code>function</code>, | ||
8236 | which means the function running at level <code>function</code> of the call stack | ||
8237 | of the given thread: | ||
8238 | level 0 is the current function (<code>getinfo</code> itself); | ||
8239 | level 1 is the function that called <code>getinfo</code>; | ||
8240 | and so on. | ||
8241 | If <code>function</code> is a number larger than the number of active functions, | ||
8242 | then <code>getinfo</code> returns <b>nil</b>. | ||
8243 | |||
8244 | |||
8245 | <p> | ||
8246 | The returned table can contain all the fields returned by <a href="#lua_getinfo"><code>lua_getinfo</code></a>, | ||
8247 | with the string <code>what</code> describing which fields to fill in. | ||
8248 | The default for <code>what</code> is to get all information available, | ||
8249 | except the table of valid lines. | ||
8250 | If present, | ||
8251 | the option '<code>f</code>' | ||
8252 | adds a field named <code>func</code> with the function itself. | ||
8253 | If present, | ||
8254 | the option '<code>L</code>' | ||
8255 | adds a field named <code>activelines</code> with the table of | ||
8256 | valid lines. | ||
8257 | |||
8258 | |||
8259 | <p> | ||
8260 | For instance, the expression <code>debug.getinfo(1,"n").name</code> returns | ||
8261 | a table with a name for the current function, | ||
8262 | if a reasonable name can be found, | ||
8263 | and the expression <code>debug.getinfo(print)</code> | ||
8264 | returns a table with all available information | ||
8265 | about the <a href="#pdf-print"><code>print</code></a> function. | ||
8266 | |||
8267 | |||
8268 | |||
8269 | |||
8270 | <p> | ||
8271 | <hr><h3><a name="pdf-debug.getlocal"><code>debug.getlocal ([thread,] level, local)</code></a></h3> | ||
8272 | |||
8273 | |||
8274 | <p> | ||
8275 | This function returns the name and the value of the local variable | ||
8276 | with index <code>local</code> of the function at level <code>level</code> of the stack. | ||
8277 | (The first parameter or local variable has index 1, and so on, | ||
8278 | until the last active local variable.) | ||
8279 | The function returns <b>nil</b> if there is no local | ||
8280 | variable with the given index, | ||
8281 | and raises an error when called with a <code>level</code> out of range. | ||
8282 | (You can call <a href="#pdf-debug.getinfo"><code>debug.getinfo</code></a> to check whether the level is valid.) | ||
8283 | |||
8284 | |||
8285 | <p> | ||
8286 | Variable names starting with '<code>(</code>' (open parentheses) | ||
8287 | represent internal variables | ||
8288 | (loop control variables, temporaries, and C function locals). | ||
8289 | |||
8290 | |||
8291 | |||
8292 | |||
8293 | <p> | ||
8294 | <hr><h3><a name="pdf-debug.getmetatable"><code>debug.getmetatable (object)</code></a></h3> | ||
8295 | |||
8296 | |||
8297 | <p> | ||
8298 | Returns the metatable of the given <code>object</code> | ||
8299 | or <b>nil</b> if it does not have a metatable. | ||
8300 | |||
8301 | |||
8302 | |||
8303 | |||
8304 | <p> | ||
8305 | <hr><h3><a name="pdf-debug.getregistry"><code>debug.getregistry ()</code></a></h3> | ||
8306 | |||
8307 | |||
8308 | <p> | ||
8309 | Returns the registry table (see <a href="#3.5">§3.5</a>). | ||
8310 | |||
8311 | |||
8312 | |||
8313 | |||
8314 | <p> | ||
8315 | <hr><h3><a name="pdf-debug.getupvalue"><code>debug.getupvalue (func, up)</code></a></h3> | ||
8316 | |||
8317 | |||
8318 | <p> | ||
8319 | This function returns the name and the value of the upvalue | ||
8320 | with index <code>up</code> of the function <code>func</code>. | ||
8321 | The function returns <b>nil</b> if there is no upvalue with the given index. | ||
8322 | |||
8323 | |||
8324 | |||
8325 | |||
8326 | <p> | ||
8327 | <hr><h3><a name="pdf-debug.setfenv"><code>debug.setfenv (object, table)</code></a></h3> | ||
8328 | |||
8329 | |||
8330 | <p> | ||
8331 | Sets the environment of the given <code>object</code> to the given <code>table</code>. | ||
8332 | Returns <code>object</code>. | ||
8333 | |||
8334 | |||
8335 | |||
8336 | |||
8337 | <p> | ||
8338 | <hr><h3><a name="pdf-debug.sethook"><code>debug.sethook ([thread,] hook, mask [, count])</code></a></h3> | ||
8339 | |||
8340 | |||
8341 | <p> | ||
8342 | Sets the given function as a hook. | ||
8343 | The string <code>mask</code> and the number <code>count</code> describe | ||
8344 | when the hook will be called. | ||
8345 | The string mask may have the following characters, | ||
8346 | with the given meaning: | ||
8347 | |||
8348 | <ul> | ||
8349 | <li><b><code>"c"</code>:</b> the hook is called every time Lua calls a function;</li> | ||
8350 | <li><b><code>"r"</code>:</b> the hook is called every time Lua returns from a function;</li> | ||
8351 | <li><b><code>"l"</code>:</b> the hook is called every time Lua enters a new line of code.</li> | ||
8352 | </ul><p> | ||
8353 | With a <code>count</code> different from zero, | ||
8354 | the hook is called after every <code>count</code> instructions. | ||
8355 | |||
8356 | |||
8357 | <p> | ||
8358 | When called without arguments, | ||
8359 | <a href="#pdf-debug.sethook"><code>debug.sethook</code></a> turns off the hook. | ||
8360 | |||
8361 | |||
8362 | <p> | ||
8363 | When the hook is called, its first parameter is a string | ||
8364 | describing the event that has triggered its call: | ||
8365 | <code>"call"</code>, <code>"return"</code> (or <code>"tail return"</code>, | ||
8366 | when simulating a return from a tail call), | ||
8367 | <code>"line"</code>, and <code>"count"</code>. | ||
8368 | For line events, | ||
8369 | the hook also gets the new line number as its second parameter. | ||
8370 | Inside a hook, | ||
8371 | you can call <code>getinfo</code> with level 2 to get more information about | ||
8372 | the running function | ||
8373 | (level 0 is the <code>getinfo</code> function, | ||
8374 | and level 1 is the hook function), | ||
8375 | unless the event is <code>"tail return"</code>. | ||
8376 | In this case, Lua is only simulating the return, | ||
8377 | and a call to <code>getinfo</code> will return invalid data. | ||
8378 | |||
8379 | |||
8380 | |||
8381 | |||
8382 | <p> | ||
8383 | <hr><h3><a name="pdf-debug.setlocal"><code>debug.setlocal ([thread,] level, local, value)</code></a></h3> | ||
8384 | |||
8385 | |||
8386 | <p> | ||
8387 | This function assigns the value <code>value</code> to the local variable | ||
8388 | with index <code>local</code> of the function at level <code>level</code> of the stack. | ||
8389 | The function returns <b>nil</b> if there is no local | ||
8390 | variable with the given index, | ||
8391 | and raises an error when called with a <code>level</code> out of range. | ||
8392 | (You can call <code>getinfo</code> to check whether the level is valid.) | ||
8393 | Otherwise, it returns the name of the local variable. | ||
8394 | |||
8395 | |||
8396 | |||
8397 | |||
8398 | <p> | ||
8399 | <hr><h3><a name="pdf-debug.setmetatable"><code>debug.setmetatable (object, table)</code></a></h3> | ||
8400 | |||
8401 | |||
8402 | <p> | ||
8403 | Sets the metatable for the given <code>object</code> to the given <code>table</code> | ||
8404 | (which can be <b>nil</b>). | ||
8405 | |||
8406 | |||
8407 | |||
8408 | |||
8409 | <p> | ||
8410 | <hr><h3><a name="pdf-debug.setupvalue"><code>debug.setupvalue (func, up, value)</code></a></h3> | ||
8411 | |||
8412 | |||
8413 | <p> | ||
8414 | This function assigns the value <code>value</code> to the upvalue | ||
8415 | with index <code>up</code> of the function <code>func</code>. | ||
8416 | The function returns <b>nil</b> if there is no upvalue | ||
8417 | with the given index. | ||
8418 | Otherwise, it returns the name of the upvalue. | ||
8419 | |||
8420 | |||
8421 | |||
8422 | |||
8423 | <p> | ||
8424 | <hr><h3><a name="pdf-debug.traceback"><code>debug.traceback ([thread,] [message] [, level])</code></a></h3> | ||
8425 | |||
8426 | |||
8427 | <p> | ||
8428 | Returns a string with a traceback of the call stack. | ||
8429 | An optional <code>message</code> string is appended | ||
8430 | at the beginning of the traceback. | ||
8431 | An optional <code>level</code> number tells at which level | ||
8432 | to start the traceback | ||
8433 | (default is 1, the function calling <code>traceback</code>). | ||
8434 | |||
8435 | |||
8436 | |||
8437 | |||
8438 | |||
8439 | |||
8440 | |||
8441 | <h1>6 - <a name="6">Lua Stand-alone</a></h1> | ||
8442 | |||
8443 | <p> | ||
8444 | Although Lua has been designed as an extension language, | ||
8445 | to be embedded in a host C program, | ||
8446 | it is also frequently used as a stand-alone language. | ||
8447 | An interpreter for Lua as a stand-alone language, | ||
8448 | called simply <code>lua</code>, | ||
8449 | is provided with the standard distribution. | ||
8450 | The stand-alone interpreter includes | ||
8451 | all standard libraries, including the debug library. | ||
8452 | Its usage is: | ||
8453 | |||
8454 | <pre> | ||
8455 | lua [options] [script [args]] | ||
8456 | </pre><p> | ||
8457 | The options are: | ||
8458 | |||
8459 | <ul> | ||
8460 | <li><b><code>-e <em>stat</em></code>:</b> executes string <em>stat</em>;</li> | ||
8461 | <li><b><code>-l <em>mod</em></code>:</b> "requires" <em>mod</em>;</li> | ||
8462 | <li><b><code>-i</code>:</b> enters interactive mode after running <em>script</em>;</li> | ||
8463 | <li><b><code>-v</code>:</b> prints version information;</li> | ||
8464 | <li><b><code>--</code>:</b> stops handling options;</li> | ||
8465 | <li><b><code>-</code>:</b> executes <code>stdin</code> as a file and stops handling options.</li> | ||
8466 | </ul><p> | ||
8467 | After handling its options, <code>lua</code> runs the given <em>script</em>, | ||
8468 | passing to it the given <em>args</em> as string arguments. | ||
8469 | When called without arguments, | ||
8470 | <code>lua</code> behaves as <code>lua -v -i</code> | ||
8471 | when the standard input (<code>stdin</code>) is a terminal, | ||
8472 | and as <code>lua -</code> otherwise. | ||
8473 | |||
8474 | |||
8475 | <p> | ||
8476 | Before running any argument, | ||
8477 | the interpreter checks for an environment variable <a name="pdf-LUA_INIT"><code>LUA_INIT</code></a>. | ||
8478 | If its format is <code>@<em>filename</em></code>, | ||
8479 | then <code>lua</code> executes the file. | ||
8480 | Otherwise, <code>lua</code> executes the string itself. | ||
8481 | |||
8482 | |||
8483 | <p> | ||
8484 | All options are handled in order, except <code>-i</code>. | ||
8485 | For instance, an invocation like | ||
8486 | |||
8487 | <pre> | ||
8488 | $ lua -e'a=1' -e 'print(a)' script.lua | ||
8489 | </pre><p> | ||
8490 | will first set <code>a</code> to 1, then print the value of <code>a</code> (which is '<code>1</code>'), | ||
8491 | and finally run the file <code>script.lua</code> with no arguments. | ||
8492 | (Here <code>$</code> is the shell prompt. Your prompt may be different.) | ||
8493 | |||
8494 | |||
8495 | <p> | ||
8496 | Before starting to run the script, | ||
8497 | <code>lua</code> collects all arguments in the command line | ||
8498 | in a global table called <code>arg</code>. | ||
8499 | The script name is stored at index 0, | ||
8500 | the first argument after the script name goes to index 1, | ||
8501 | and so on. | ||
8502 | Any arguments before the script name | ||
8503 | (that is, the interpreter name plus the options) | ||
8504 | go to negative indices. | ||
8505 | For instance, in the call | ||
8506 | |||
8507 | <pre> | ||
8508 | $ lua -la b.lua t1 t2 | ||
8509 | </pre><p> | ||
8510 | the interpreter first runs the file <code>a.lua</code>, | ||
8511 | then creates a table | ||
8512 | |||
8513 | <pre> | ||
8514 | arg = { [-2] = "lua", [-1] = "-la", | ||
8515 | [0] = "b.lua", | ||
8516 | [1] = "t1", [2] = "t2" } | ||
8517 | </pre><p> | ||
8518 | and finally runs the file <code>b.lua</code>. | ||
8519 | The script is called with <code>arg[1]</code>, <code>arg[2]</code>, ··· | ||
8520 | as arguments; | ||
8521 | it can also access these arguments with the vararg expression '<code>...</code>'. | ||
8522 | |||
8523 | |||
8524 | <p> | ||
8525 | In interactive mode, | ||
8526 | if you write an incomplete statement, | ||
8527 | the interpreter waits for its completion | ||
8528 | by issuing a different prompt. | ||
8529 | |||
8530 | |||
8531 | <p> | ||
8532 | If the global variable <a name="pdf-_PROMPT"><code>_PROMPT</code></a> contains a string, | ||
8533 | then its value is used as the prompt. | ||
8534 | Similarly, if the global variable <a name="pdf-_PROMPT2"><code>_PROMPT2</code></a> contains a string, | ||
8535 | its value is used as the secondary prompt | ||
8536 | (issued during incomplete statements). | ||
8537 | Therefore, both prompts can be changed directly on the command line | ||
8538 | or in any Lua programs by assigning to <code>_PROMPT</code>. | ||
8539 | See the next example: | ||
8540 | |||
8541 | <pre> | ||
8542 | $ lua -e"_PROMPT='myprompt> '" -i | ||
8543 | </pre><p> | ||
8544 | (The outer pair of quotes is for the shell, | ||
8545 | the inner pair is for Lua.) | ||
8546 | Note the use of <code>-i</code> to enter interactive mode; | ||
8547 | otherwise, | ||
8548 | the program would just end silently | ||
8549 | right after the assignment to <code>_PROMPT</code>. | ||
8550 | |||
8551 | |||
8552 | <p> | ||
8553 | To allow the use of Lua as a | ||
8554 | script interpreter in Unix systems, | ||
8555 | the stand-alone interpreter skips | ||
8556 | the first line of a chunk if it starts with <code>#</code>. | ||
8557 | Therefore, Lua scripts can be made into executable programs | ||
8558 | by using <code>chmod +x</code> and the <code>#!</code> form, | ||
8559 | as in | ||
8560 | |||
8561 | <pre> | ||
8562 | #!/usr/local/bin/lua | ||
8563 | </pre><p> | ||
8564 | (Of course, | ||
8565 | the location of the Lua interpreter may be different in your machine. | ||
8566 | If <code>lua</code> is in your <code>PATH</code>, | ||
8567 | then | ||
8568 | |||
8569 | <pre> | ||
8570 | #!/usr/bin/env lua | ||
8571 | </pre><p> | ||
8572 | is a more portable solution.) | ||
8573 | |||
8574 | |||
8575 | |||
8576 | <h1>7 - <a name="7">Incompatibilities with the Previous Version</a></h1> | ||
8577 | |||
8578 | <p> | ||
8579 | Here we list the incompatibilities that you may find when moving a program | ||
8580 | from Lua 5.0 to Lua 5.1. | ||
8581 | You can avoid most of the incompatibilities compiling Lua with | ||
8582 | appropriate options (see file <code>luaconf.h</code>). | ||
8583 | However, | ||
8584 | all these compatibility options will be removed in the next version of Lua. | ||
8585 | |||
8586 | |||
8587 | |||
8588 | <h2>7.1 - <a name="7.1">Changes in the Language</a></h2> | ||
8589 | <ul> | ||
8590 | |||
8591 | <li> | ||
8592 | The vararg system changed from the pseudo-argument <code>arg</code> with a | ||
8593 | table with the extra arguments to the vararg expression. | ||
8594 | (See compile-time option <code>LUA_COMPAT_VARARG</code> in <code>luaconf.h</code>.) | ||
8595 | </li> | ||
8596 | |||
8597 | <li> | ||
8598 | There was a subtle change in the scope of the implicit | ||
8599 | variables of the <b>for</b> statement and for the <b>repeat</b> statement. | ||
8600 | </li> | ||
8601 | |||
8602 | <li> | ||
8603 | The long string/long comment syntax (<code>[[<em>string</em>]]</code>) | ||
8604 | does not allow nesting. | ||
8605 | You can use the new syntax (<code>[=[<em>string</em>]=]</code>) in these cases. | ||
8606 | (See compile-time option <code>LUA_COMPAT_LSTR</code> in <code>luaconf.h</code>.) | ||
8607 | </li> | ||
8608 | |||
8609 | </ul> | ||
8610 | |||
8611 | |||
8612 | |||
8613 | |||
8614 | <h2>7.2 - <a name="7.2">Changes in the Libraries</a></h2> | ||
8615 | <ul> | ||
8616 | |||
8617 | <li> | ||
8618 | Function <code>string.gfind</code> was renamed <a href="#pdf-string.gmatch"><code>string.gmatch</code></a>. | ||
8619 | (See compile-time option <code>LUA_COMPAT_GFIND</code> in <code>luaconf.h</code>.) | ||
8620 | </li> | ||
8621 | |||
8622 | <li> | ||
8623 | When <a href="#pdf-string.gsub"><code>string.gsub</code></a> is called with a function as its | ||
8624 | third argument, | ||
8625 | whenever this function returns <b>nil</b> or <b>false</b> the | ||
8626 | replacement string is the whole match, | ||
8627 | instead of the empty string. | ||
8628 | </li> | ||
8629 | |||
8630 | <li> | ||
8631 | Function <code>table.setn</code> was deprecated. | ||
8632 | Function <code>table.getn</code> corresponds | ||
8633 | to the new length operator (<code>#</code>); | ||
8634 | use the operator instead of the function. | ||
8635 | (See compile-time option <code>LUA_COMPAT_GETN</code> in <code>luaconf.h</code>.) | ||
8636 | </li> | ||
8637 | |||
8638 | <li> | ||
8639 | Function <code>loadlib</code> was renamed <a href="#pdf-package.loadlib"><code>package.loadlib</code></a>. | ||
8640 | (See compile-time option <code>LUA_COMPAT_LOADLIB</code> in <code>luaconf.h</code>.) | ||
8641 | </li> | ||
8642 | |||
8643 | <li> | ||
8644 | Function <code>math.mod</code> was renamed <a href="#pdf-math.fmod"><code>math.fmod</code></a>. | ||
8645 | (See compile-time option <code>LUA_COMPAT_MOD</code> in <code>luaconf.h</code>.) | ||
8646 | </li> | ||
8647 | |||
8648 | <li> | ||
8649 | Functions <code>table.foreach</code> and <code>table.foreachi</code> are deprecated. | ||
8650 | You can use a for loop with <code>pairs</code> or <code>ipairs</code> instead. | ||
8651 | </li> | ||
8652 | |||
8653 | <li> | ||
8654 | There were substantial changes in function <a href="#pdf-require"><code>require</code></a> due to | ||
8655 | the new module system. | ||
8656 | However, the new behavior is mostly compatible with the old, | ||
8657 | but <code>require</code> gets the path from <a href="#pdf-package.path"><code>package.path</code></a> instead | ||
8658 | of from <code>LUA_PATH</code>. | ||
8659 | </li> | ||
8660 | |||
8661 | <li> | ||
8662 | Function <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> has different arguments. | ||
8663 | Function <code>gcinfo</code> is deprecated; | ||
8664 | use <code>collectgarbage("count")</code> instead. | ||
8665 | </li> | ||
8666 | |||
8667 | </ul> | ||
8668 | |||
8669 | |||
8670 | |||
8671 | |||
8672 | <h2>7.3 - <a name="7.3">Changes in the API</a></h2> | ||
8673 | <ul> | ||
8674 | |||
8675 | <li> | ||
8676 | The <code>luaopen_*</code> functions (to open libraries) | ||
8677 | cannot be called directly, | ||
8678 | like a regular C function. | ||
8679 | They must be called through Lua, | ||
8680 | like a Lua function. | ||
8681 | </li> | ||
8682 | |||
8683 | <li> | ||
8684 | Function <code>lua_open</code> was replaced by <a href="#lua_newstate"><code>lua_newstate</code></a> to | ||
8685 | allow the user to set a memory-allocation function. | ||
8686 | You can use <a href="#luaL_newstate"><code>luaL_newstate</code></a> from the standard library to | ||
8687 | create a state with a standard allocation function | ||
8688 | (based on <code>realloc</code>). | ||
8689 | </li> | ||
8690 | |||
8691 | <li> | ||
8692 | Functions <code>luaL_getn</code> and <code>luaL_setn</code> | ||
8693 | (from the auxiliary library) are deprecated. | ||
8694 | Use <a href="#lua_objlen"><code>lua_objlen</code></a> instead of <code>luaL_getn</code> | ||
8695 | and nothing instead of <code>luaL_setn</code>. | ||
8696 | </li> | ||
8697 | |||
8698 | <li> | ||
8699 | Function <code>luaL_openlib</code> was replaced by <a href="#luaL_register"><code>luaL_register</code></a>. | ||
8700 | </li> | ||
8701 | |||
8702 | <li> | ||
8703 | Function <code>luaL_checkudata</code> now throws an error when the given value | ||
8704 | is not a userdata of the expected type. | ||
8705 | (In Lua 5.0 it returned <code>NULL</code>.) | ||
8706 | </li> | ||
8707 | |||
8708 | </ul> | ||
8709 | |||
8710 | |||
8711 | |||
8712 | |||
8713 | <h1>8 - <a name="8">The Complete Syntax of Lua</a></h1> | ||
8714 | |||
8715 | <p> | ||
8716 | Here is the complete syntax of Lua in extended BNF. | ||
8717 | (It does not describe operator precedences.) | ||
8718 | |||
8719 | |||
8720 | |||
8721 | |||
8722 | <pre> | ||
8723 | |||
8724 | chunk ::= {stat [`<b>;</b>´]} [laststat [`<b>;</b>´]] | ||
8725 | |||
8726 | block ::= chunk | ||
8727 | |||
8728 | stat ::= varlist `<b>=</b>´ explist | | ||
8729 | functioncall | | ||
8730 | <b>do</b> block <b>end</b> | | ||
8731 | <b>while</b> exp <b>do</b> block <b>end</b> | | ||
8732 | <b>repeat</b> block <b>until</b> exp | | ||
8733 | <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b> | | ||
8734 | <b>for</b> Name `<b>=</b>´ exp `<b>,</b>´ exp [`<b>,</b>´ exp] <b>do</b> block <b>end</b> | | ||
8735 | <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b> | | ||
8736 | <b>function</b> funcname funcbody | | ||
8737 | <b>local</b> <b>function</b> Name funcbody | | ||
8738 | <b>local</b> namelist [`<b>=</b>´ explist] | ||
8739 | |||
8740 | laststat ::= <b>return</b> [explist] | <b>break</b> | ||
8741 | |||
8742 | funcname ::= Name {`<b>.</b>´ Name} [`<b>:</b>´ Name] | ||
8743 | |||
8744 | varlist ::= var {`<b>,</b>´ var} | ||
8745 | |||
8746 | var ::= Name | prefixexp `<b>[</b>´ exp `<b>]</b>´ | prefixexp `<b>.</b>´ Name | ||
8747 | |||
8748 | namelist ::= Name {`<b>,</b>´ Name} | ||
8749 | |||
8750 | explist ::= {exp `<b>,</b>´} exp | ||
8751 | |||
8752 | exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Number | String | `<b>...</b>´ | function | | ||
8753 | prefixexp | tableconstructor | exp binop exp | unop exp | ||
8754 | |||
8755 | prefixexp ::= var | functioncall | `<b>(</b>´ exp `<b>)</b>´ | ||
8756 | |||
8757 | functioncall ::= prefixexp args | prefixexp `<b>:</b>´ Name args | ||
8758 | |||
8759 | args ::= `<b>(</b>´ [explist] `<b>)</b>´ | tableconstructor | String | ||
8760 | |||
8761 | function ::= <b>function</b> funcbody | ||
8762 | |||
8763 | funcbody ::= `<b>(</b>´ [parlist] `<b>)</b>´ block <b>end</b> | ||
8764 | |||
8765 | parlist ::= namelist [`<b>,</b>´ `<b>...</b>´] | `<b>...</b>´ | ||
8766 | |||
8767 | tableconstructor ::= `<b>{</b>´ [fieldlist] `<b>}</b>´ | ||
8768 | |||
8769 | fieldlist ::= field {fieldsep field} [fieldsep] | ||
8770 | |||
8771 | field ::= `<b>[</b>´ exp `<b>]</b>´ `<b>=</b>´ exp | Name `<b>=</b>´ exp | exp | ||
8772 | |||
8773 | fieldsep ::= `<b>,</b>´ | `<b>;</b>´ | ||
8774 | |||
8775 | binop ::= `<b>+</b>´ | `<b>-</b>´ | `<b>*</b>´ | `<b>/</b>´ | `<b>^</b>´ | `<b>%</b>´ | `<b>..</b>´ | | ||
8776 | `<b><</b>´ | `<b><=</b>´ | `<b>></b>´ | `<b>>=</b>´ | `<b>==</b>´ | `<b>~=</b>´ | | ||
8777 | <b>and</b> | <b>or</b> | ||
8778 | |||
8779 | unop ::= `<b>-</b>´ | <b>not</b> | `<b>#</b>´ | ||
8780 | |||
8781 | </pre> | ||
8782 | |||
8783 | <p> | ||
8784 | |||
8785 | |||
8786 | |||
8787 | |||
8788 | |||
8789 | |||
8790 | |||
8791 | <HR> | ||
8792 | <SMALL> | ||
8793 | Last update: | ||
8794 | Mon Aug 18 13:25:46 BRT 2008 | ||
8795 | </SMALL> | ||
8796 | <!-- | ||
8797 | Last change: revised for Lua 5.1.4 | ||
8798 | --> | ||
8799 | |||
8800 | </body></html> | ||
8801 | |||
diff --git a/libraries/LuaJIT-1.1.7/doc/readme.html b/libraries/LuaJIT-1.1.7/doc/readme.html new file mode 100644 index 0000000..38be6db --- /dev/null +++ b/libraries/LuaJIT-1.1.7/doc/readme.html | |||
@@ -0,0 +1,40 @@ | |||
1 | <HTML> | ||
2 | <HEAD> | ||
3 | <TITLE>Lua documentation</TITLE> | ||
4 | <LINK REL="stylesheet" TYPE="text/css" HREF="lua.css"> | ||
5 | </HEAD> | ||
6 | |||
7 | <BODY> | ||
8 | |||
9 | <HR> | ||
10 | <H1> | ||
11 | <A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A> | ||
12 | Documentation | ||
13 | </H1> | ||
14 | |||
15 | This is the documentation included in the source distribution of Lua 5.1.4. | ||
16 | |||
17 | <UL> | ||
18 | <LI><A HREF="contents.html">Reference manual</A> | ||
19 | <LI><A HREF="lua.html">lua man page</A> | ||
20 | <LI><A HREF="luac.html">luac man page</A> | ||
21 | <LI><A HREF="../README">lua/README</A> | ||
22 | <LI><A HREF="../etc/README">lua/etc/README</A> | ||
23 | <LI><A HREF="../test/README">lua/test/README</A> | ||
24 | </UL> | ||
25 | |||
26 | Lua's | ||
27 | <A HREF="http://www.lua.org/">official web site</A> | ||
28 | contains updated documentation, | ||
29 | especially the | ||
30 | <A HREF="http://www.lua.org/manual/5.1/">reference manual</A>. | ||
31 | <P> | ||
32 | |||
33 | <HR> | ||
34 | <SMALL> | ||
35 | Last update: | ||
36 | Tue Aug 12 14:46:07 BRT 2008 | ||
37 | </SMALL> | ||
38 | |||
39 | </BODY> | ||
40 | </HTML> | ||
diff --git a/libraries/LuaJIT-1.1.7/dynasm/dasm_proto.h b/libraries/LuaJIT-1.1.7/dynasm/dasm_proto.h new file mode 100644 index 0000000..c194cba --- /dev/null +++ b/libraries/LuaJIT-1.1.7/dynasm/dasm_proto.h | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | ** DynASM encoding engine prototypes. | ||
3 | ** Copyright (C) 2005-2008 Mike Pall. All rights reserved. | ||
4 | ** Released under the MIT/X license. See dynasm.lua for full copyright notice. | ||
5 | */ | ||
6 | |||
7 | #ifndef _DASM_PROTO_H | ||
8 | #define _DASM_PROTO_H | ||
9 | |||
10 | #include <stddef.h> | ||
11 | #include <stdarg.h> | ||
12 | |||
13 | #define DASM_VERSION 10104 /* 1.1.4 */ | ||
14 | |||
15 | #ifndef Dst_DECL | ||
16 | #define Dst_DECL dasm_State *Dst | ||
17 | #endif | ||
18 | |||
19 | #ifndef Dst_GET | ||
20 | #define Dst_GET (Dst) | ||
21 | #endif | ||
22 | |||
23 | #ifndef DASM_FDEF | ||
24 | #define DASM_FDEF extern | ||
25 | #endif | ||
26 | |||
27 | |||
28 | /* Internal DynASM encoder state. */ | ||
29 | typedef struct dasm_State dasm_State; | ||
30 | |||
31 | /* Action list type. */ | ||
32 | typedef const unsigned char *dasm_ActList; | ||
33 | |||
34 | |||
35 | /* Initialize and free DynASM state. */ | ||
36 | DASM_FDEF void dasm_init(Dst_DECL, int maxsection); | ||
37 | DASM_FDEF void dasm_free(Dst_DECL); | ||
38 | |||
39 | /* Setup global array. Must be called before dasm_setup(). */ | ||
40 | DASM_FDEF void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl); | ||
41 | |||
42 | /* Grow PC label array. Can be called after dasm_setup(), too. */ | ||
43 | DASM_FDEF void dasm_growpc(Dst_DECL, unsigned int maxpc); | ||
44 | |||
45 | /* Setup encoder. */ | ||
46 | DASM_FDEF void dasm_setup(Dst_DECL, dasm_ActList actionlist); | ||
47 | |||
48 | /* Feed encoder with actions. Calls are generated by pre-processor. */ | ||
49 | DASM_FDEF void dasm_put(Dst_DECL, int start, ...); | ||
50 | |||
51 | /* Link sections and return the resulting size. */ | ||
52 | DASM_FDEF int dasm_link(Dst_DECL, size_t *szp); | ||
53 | |||
54 | /* Encode sections into buffer. */ | ||
55 | DASM_FDEF int dasm_encode(Dst_DECL, void *buffer); | ||
56 | |||
57 | /* Get PC label offset. */ | ||
58 | DASM_FDEF int dasm_getpclabel(Dst_DECL, unsigned int pc); | ||
59 | |||
60 | #ifdef DASM_CHECKS | ||
61 | /* Optional sanity checker to call between isolated encoding steps. */ | ||
62 | DASM_FDEF int dasm_checkstep(Dst_DECL, int secmatch); | ||
63 | #else | ||
64 | #define dasm_checkstep(a, b) 0 | ||
65 | #endif | ||
66 | |||
67 | |||
68 | #endif /* _DASM_PROTO_H */ | ||
diff --git a/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.h b/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.h new file mode 100644 index 0000000..2d4fb26 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.h | |||
@@ -0,0 +1,455 @@ | |||
1 | /* | ||
2 | ** DynASM x86 encoding engine. | ||
3 | ** Copyright (C) 2005-2008 Mike Pall. All rights reserved. | ||
4 | ** Released under the MIT/X license. See dynasm.lua for full copyright notice. | ||
5 | */ | ||
6 | |||
7 | #include <stddef.h> | ||
8 | #include <stdarg.h> | ||
9 | #include <string.h> | ||
10 | #include <stdlib.h> | ||
11 | |||
12 | #define DASM_ARCH "x86" | ||
13 | |||
14 | /* Action definitions. DASM_STOP must be 255. */ | ||
15 | enum { | ||
16 | DASM_DISP = 235, | ||
17 | DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB, | ||
18 | DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC, DASM_IMM_LG, | ||
19 | DASM_IMM_PC, DASM_LABEL_LG, DASM_LABEL_PC, DASM_ALIGN, DASM_ESC, DASM_MARK, | ||
20 | DASM_SECTION, DASM_STOP | ||
21 | }; | ||
22 | |||
23 | /* Maximum number of section buffer positions for a single dasm_put() call. */ | ||
24 | #define DASM_MAXSECPOS 25 | ||
25 | |||
26 | /* DynASM encoder status codes. Action list offset or number are or'ed in. */ | ||
27 | #define DASM_S_OK 0x00000000 | ||
28 | #define DASM_S_NOMEM 0x01000000 | ||
29 | #define DASM_S_PHASE 0x02000000 | ||
30 | #define DASM_S_MATCH_SEC 0x03000000 | ||
31 | #define DASM_S_RANGE_I 0x11000000 | ||
32 | #define DASM_S_RANGE_SEC 0x12000000 | ||
33 | #define DASM_S_RANGE_LG 0x13000000 | ||
34 | #define DASM_S_RANGE_PC 0x14000000 | ||
35 | #define DASM_S_UNDEF_L 0x21000000 | ||
36 | #define DASM_S_UNDEF_PC 0x22000000 | ||
37 | |||
38 | /* Macros to convert positions (8 bit section + 24 bit index). */ | ||
39 | #define DASM_POS2IDX(pos) ((pos)&0x00ffffff) | ||
40 | #define DASM_POS2BIAS(pos) ((pos)&0xff000000) | ||
41 | #define DASM_SEC2POS(sec) ((sec)<<24) | ||
42 | #define DASM_POS2SEC(pos) ((pos)>>24) | ||
43 | #define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos)) | ||
44 | |||
45 | /* Per-section structure. */ | ||
46 | typedef struct dasm_Section { | ||
47 | int *rbuf; /* Biased buffer pointer (negative section bias). */ | ||
48 | int *buf; /* True buffer pointer. */ | ||
49 | size_t bsize; /* Buffer size in bytes. */ | ||
50 | int pos; /* Biased buffer position. */ | ||
51 | int epos; /* End of biased buffer position - max single put. */ | ||
52 | int ofs; /* Byte offset into section. */ | ||
53 | } dasm_Section; | ||
54 | |||
55 | /* Core structure holding the DynASM encoding state. */ | ||
56 | struct dasm_State { | ||
57 | size_t psize; /* Allocated size of this structure. */ | ||
58 | dasm_ActList actionlist; /* Current actionlist pointer. */ | ||
59 | int *lglabels; /* Local/global chain/pos ptrs. */ | ||
60 | size_t lgsize; | ||
61 | int *pclabels; /* PC label chains/pos ptrs. */ | ||
62 | size_t pcsize; | ||
63 | void **globals; /* Array of globals (bias -10). */ | ||
64 | dasm_Section *section; /* Pointer to active section. */ | ||
65 | size_t codesize; /* Total size of all code sections. */ | ||
66 | int maxsection; /* 0 <= sectionidx < maxsection. */ | ||
67 | int status; /* Status code. */ | ||
68 | dasm_Section sections[1]; /* All sections. Alloc-extended. */ | ||
69 | }; | ||
70 | |||
71 | /* The size of the core structure depends on the max. number of sections. */ | ||
72 | #define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section)) | ||
73 | |||
74 | |||
75 | /* Initialize DynASM state. */ | ||
76 | void dasm_init(Dst_DECL, int maxsection) | ||
77 | { | ||
78 | dasm_State *D; | ||
79 | size_t psz = 0; | ||
80 | int i; | ||
81 | Dst_REF = NULL; | ||
82 | DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection)); | ||
83 | D = Dst_REF; | ||
84 | D->psize = psz; | ||
85 | D->lglabels = NULL; | ||
86 | D->lgsize = 0; | ||
87 | D->pclabels = NULL; | ||
88 | D->pcsize = 0; | ||
89 | D->globals = NULL; | ||
90 | D->maxsection = maxsection; | ||
91 | for (i = 0; i < maxsection; i++) { | ||
92 | D->sections[i].buf = NULL; /* Need this for pass3. */ | ||
93 | D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i); | ||
94 | D->sections[i].bsize = 0; | ||
95 | D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */ | ||
96 | } | ||
97 | } | ||
98 | |||
99 | /* Free DynASM state. */ | ||
100 | void dasm_free(Dst_DECL) | ||
101 | { | ||
102 | dasm_State *D = Dst_REF; | ||
103 | int i; | ||
104 | for (i = 0; i < D->maxsection; i++) | ||
105 | if (D->sections[i].buf) | ||
106 | DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize); | ||
107 | if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize); | ||
108 | if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize); | ||
109 | DASM_M_FREE(Dst, D, D->psize); | ||
110 | } | ||
111 | |||
112 | /* Setup global label array. Must be called before dasm_setup(). */ | ||
113 | void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl) | ||
114 | { | ||
115 | dasm_State *D = Dst_REF; | ||
116 | D->globals = gl - 10; /* Negative bias to compensate for locals. */ | ||
117 | DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int)); | ||
118 | } | ||
119 | |||
120 | /* Grow PC label array. Can be called after dasm_setup(), too. */ | ||
121 | void dasm_growpc(Dst_DECL, unsigned int maxpc) | ||
122 | { | ||
123 | dasm_State *D = Dst_REF; | ||
124 | size_t osz = D->pcsize; | ||
125 | DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int)); | ||
126 | memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz); | ||
127 | } | ||
128 | |||
129 | /* Setup encoder. */ | ||
130 | void dasm_setup(Dst_DECL, dasm_ActList actionlist) | ||
131 | { | ||
132 | dasm_State *D = Dst_REF; | ||
133 | int i; | ||
134 | D->actionlist = actionlist; | ||
135 | D->status = DASM_S_OK; | ||
136 | D->section = &D->sections[0]; | ||
137 | memset((void *)D->lglabels, 0, D->lgsize); | ||
138 | if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize); | ||
139 | for (i = 0; i < D->maxsection; i++) { | ||
140 | D->sections[i].pos = DASM_SEC2POS(i); | ||
141 | D->sections[i].ofs = 0; | ||
142 | } | ||
143 | } | ||
144 | |||
145 | |||
146 | #ifdef DASM_CHECKS | ||
147 | #define CK(x, st) \ | ||
148 | do { if (!(x)) { \ | ||
149 | D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0) | ||
150 | #define CKPL(kind, st) \ | ||
151 | do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \ | ||
152 | D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0) | ||
153 | #else | ||
154 | #define CK(x, st) ((void)0) | ||
155 | #define CKPL(kind, st) ((void)0) | ||
156 | #endif | ||
157 | |||
158 | /* Pass 1: Store actions and args, link branches/labels, estimate offsets. */ | ||
159 | void dasm_put(Dst_DECL, int start, ...) | ||
160 | { | ||
161 | va_list ap; | ||
162 | dasm_State *D = Dst_REF; | ||
163 | dasm_ActList p = D->actionlist + start; | ||
164 | dasm_Section *sec = D->section; | ||
165 | int pos = sec->pos, ofs = sec->ofs, mrm = 4; | ||
166 | int *b; | ||
167 | |||
168 | if (pos >= sec->epos) { | ||
169 | DASM_M_GROW(Dst, int, sec->buf, sec->bsize, | ||
170 | sec->bsize + 2*DASM_MAXSECPOS*sizeof(int)); | ||
171 | sec->rbuf = sec->buf - DASM_POS2BIAS(pos); | ||
172 | sec->epos = sec->bsize/sizeof(int) - DASM_MAXSECPOS + DASM_POS2BIAS(pos); | ||
173 | } | ||
174 | |||
175 | b = sec->rbuf; | ||
176 | b[pos++] = start; | ||
177 | |||
178 | va_start(ap, start); | ||
179 | while (1) { | ||
180 | int action = *p++; | ||
181 | if (action < DASM_DISP) { | ||
182 | ofs++; | ||
183 | } else if (action <= DASM_REL_A) { | ||
184 | int n = va_arg(ap, int); | ||
185 | b[pos++] = n; | ||
186 | switch (action) { | ||
187 | case DASM_DISP: | ||
188 | if (n == 0) { if ((mrm&7) == 4) mrm = p[-2]; if ((mrm&7) != 5) break; } | ||
189 | case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob; | ||
190 | case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */ | ||
191 | case DASM_IMM_D: ofs += 4; break; | ||
192 | case DASM_IMM_S: CK(((n+128)&-256) == 0, RANGE_I); goto ob; | ||
193 | case DASM_IMM_B: CK((n&-256) == 0, RANGE_I); ob: ofs++; break; | ||
194 | case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob; | ||
195 | case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break; | ||
196 | case DASM_SPACE: p++; ofs += n; break; | ||
197 | case DASM_SETLABEL: b[pos-2] = -0x40000000; break; /* Neg. label ofs. */ | ||
198 | } | ||
199 | mrm = 4; | ||
200 | } else { | ||
201 | int *pl, n; | ||
202 | switch (action) { | ||
203 | case DASM_REL_LG: | ||
204 | case DASM_IMM_LG: | ||
205 | n = *p++; pl = D->lglabels + n; | ||
206 | if (n <= 246) { CKPL(lg, LG); goto putrel; } /* Bkwd rel or global. */ | ||
207 | pl -= 246; n = *pl; | ||
208 | if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */ | ||
209 | goto linkrel; | ||
210 | case DASM_REL_PC: | ||
211 | case DASM_IMM_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC); | ||
212 | putrel: | ||
213 | n = *pl; | ||
214 | if (n < 0) { /* Label exists. Get label pos and store it. */ | ||
215 | b[pos] = -n; | ||
216 | } else { | ||
217 | linkrel: | ||
218 | b[pos] = n; /* Else link to rel chain, anchored at label. */ | ||
219 | *pl = pos; | ||
220 | } | ||
221 | pos++; | ||
222 | ofs += 4; /* Maximum offset needed. */ | ||
223 | if (action == DASM_REL_LG || action == DASM_REL_PC) | ||
224 | b[pos++] = ofs; /* Store pass1 offset estimate. */ | ||
225 | break; | ||
226 | case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel; | ||
227 | case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC); | ||
228 | putlabel: | ||
229 | n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */ | ||
230 | while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos; } | ||
231 | *pl = -pos; /* Label exists now. */ | ||
232 | b[pos++] = ofs; /* Store pass1 offset estimate. */ | ||
233 | break; | ||
234 | case DASM_ALIGN: | ||
235 | ofs += *p++; /* Maximum alignment needed (arg is 2**n-1). */ | ||
236 | b[pos++] = ofs; /* Store pass1 offset estimate. */ | ||
237 | break; | ||
238 | case DASM_ESC: p++; ofs++; break; | ||
239 | case DASM_MARK: mrm = p[-2]; break; | ||
240 | case DASM_SECTION: | ||
241 | n = *p; CK(n < D->maxsection, RANGE_SEC); D->section = &D->sections[n]; | ||
242 | case DASM_STOP: goto stop; | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | stop: | ||
247 | va_end(ap); | ||
248 | sec->pos = pos; | ||
249 | sec->ofs = ofs; | ||
250 | } | ||
251 | #undef CK | ||
252 | |||
253 | /* Pass 2: Link sections, shrink branches/aligns, fix label offsets. */ | ||
254 | int dasm_link(Dst_DECL, size_t *szp) | ||
255 | { | ||
256 | dasm_State *D = Dst_REF; | ||
257 | int secnum; | ||
258 | int ofs = 0; | ||
259 | |||
260 | #ifdef DASM_CHECKS | ||
261 | *szp = 0; | ||
262 | if (D->status != DASM_S_OK) return D->status; | ||
263 | { | ||
264 | int pc; | ||
265 | for (pc = 0; pc*sizeof(int) < D->pcsize; pc++) | ||
266 | if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc; | ||
267 | } | ||
268 | #endif | ||
269 | |||
270 | { /* Handle globals not defined in this translation unit. */ | ||
271 | int idx; | ||
272 | for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) { | ||
273 | int n = D->lglabels[idx]; | ||
274 | /* Undefined label: Collapse rel chain and replace with marker (< 0). */ | ||
275 | while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; } | ||
276 | } | ||
277 | } | ||
278 | |||
279 | /* Combine all code sections. No support for data sections (yet). */ | ||
280 | for (secnum = 0; secnum < D->maxsection; secnum++) { | ||
281 | dasm_Section *sec = D->sections + secnum; | ||
282 | int *b = sec->rbuf; | ||
283 | int pos = DASM_SEC2POS(secnum); | ||
284 | int lastpos = sec->pos; | ||
285 | |||
286 | while (pos != lastpos) { | ||
287 | dasm_ActList p = D->actionlist + b[pos++]; | ||
288 | while (1) { | ||
289 | int op, action = *p++; | ||
290 | switch (action) { | ||
291 | case DASM_REL_LG: p++; op = p[-3]; goto rel_pc; | ||
292 | case DASM_REL_PC: op = p[-2]; rel_pc: { | ||
293 | int shrink = op == 0xe9 ? 3 : ((op&0xf0) == 0x80 ? 4 : 0); | ||
294 | if (shrink) { /* Shrinkable branch opcode? */ | ||
295 | int lofs, lpos = b[pos]; | ||
296 | if (lpos < 0) goto noshrink; /* Ext global? */ | ||
297 | lofs = *DASM_POS2PTR(D, lpos); | ||
298 | if (lpos > pos) { /* Fwd label: add cumulative section offsets. */ | ||
299 | int i; | ||
300 | for (i = secnum; i < DASM_POS2SEC(lpos); i++) | ||
301 | lofs += D->sections[i].ofs; | ||
302 | } else { | ||
303 | lofs -= ofs; /* Bkwd label: unfix offset. */ | ||
304 | } | ||
305 | lofs -= b[pos+1]; /* Short branch ok? */ | ||
306 | if (lofs >= -128-shrink && lofs <= 127) ofs -= shrink; /* Yes. */ | ||
307 | else { noshrink: shrink = 0; } /* No, cannot shrink op. */ | ||
308 | } | ||
309 | b[pos+1] = shrink; | ||
310 | pos += 2; | ||
311 | break; | ||
312 | } | ||
313 | case DASM_SPACE: case DASM_IMM_LG: p++; | ||
314 | case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W: | ||
315 | case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB: | ||
316 | case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break; | ||
317 | case DASM_LABEL_LG: p++; | ||
318 | case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */ | ||
319 | case DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */ | ||
320 | case DASM_ESC: p++; | ||
321 | case DASM_MARK: break; | ||
322 | case DASM_SECTION: case DASM_STOP: goto stop; | ||
323 | } | ||
324 | } | ||
325 | stop: (void)0; | ||
326 | } | ||
327 | ofs += sec->ofs; /* Next section starts right after current section. */ | ||
328 | } | ||
329 | |||
330 | D->codesize = ofs; /* Total size of all code sections */ | ||
331 | *szp = ofs; | ||
332 | return DASM_S_OK; | ||
333 | } | ||
334 | |||
335 | #define dasmb(x) *cp++ = (unsigned char)(x) | ||
336 | #ifndef DASM_ALIGNED_WRITES | ||
337 | #define dasmw(x) \ | ||
338 | do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0) | ||
339 | #define dasmd(x) \ | ||
340 | do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0) | ||
341 | #else | ||
342 | #define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0) | ||
343 | #define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0) | ||
344 | #endif | ||
345 | |||
346 | /* Pass 3: Encode sections. */ | ||
347 | int dasm_encode(Dst_DECL, void *buffer) | ||
348 | { | ||
349 | dasm_State *D = Dst_REF; | ||
350 | unsigned char *base = (unsigned char *)buffer; | ||
351 | unsigned char *cp = base; | ||
352 | int secnum; | ||
353 | |||
354 | /* Encode all code sections. No support for data sections (yet). */ | ||
355 | for (secnum = 0; secnum < D->maxsection; secnum++) { | ||
356 | dasm_Section *sec = D->sections + secnum; | ||
357 | int *b = sec->buf; | ||
358 | int *endb = sec->rbuf + sec->pos; | ||
359 | |||
360 | while (b != endb) { | ||
361 | dasm_ActList p = D->actionlist + *b++; | ||
362 | unsigned char *mark = NULL; | ||
363 | while (1) { | ||
364 | int action = *p++; | ||
365 | int n = (action >= DASM_DISP && action <= DASM_ALIGN) ? *b++ : 0; | ||
366 | switch (action) { | ||
367 | case DASM_DISP: if (!mark) mark = cp; { | ||
368 | unsigned char *mm = mark; | ||
369 | if (*p != DASM_IMM_DB && *p != DASM_IMM_WB) mark = NULL; | ||
370 | if (n == 0) { int mrm = mm[-1]&7; if (mrm == 4) mrm = mm[0]&7; | ||
371 | if (mrm != 5) { mm[-1] -= 0x80; break; } } | ||
372 | if (((n+128) & -256) != 0) goto wd; else mm[-1] -= 0x40; | ||
373 | } | ||
374 | case DASM_IMM_S: case DASM_IMM_B: wb: dasmb(n); break; | ||
375 | case DASM_IMM_DB: if (((n+128)&-256) == 0) { | ||
376 | db: if (!mark) mark = cp; mark[-2] += 2; mark = NULL; goto wb; | ||
377 | } else mark = NULL; | ||
378 | case DASM_IMM_D: wd: dasmd(n); break; | ||
379 | case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL; | ||
380 | case DASM_IMM_W: dasmw(n); break; | ||
381 | case DASM_REL_LG: p++; if (n >= 0) goto rel_pc; | ||
382 | b++; n = (int)D->globals[-n]; | ||
383 | case DASM_REL_A: rel_a: n -= (int)(cp+4); goto wd; /* !x64 */ | ||
384 | case DASM_REL_PC: rel_pc: { | ||
385 | int shrink = *b++; | ||
386 | int *pb = DASM_POS2PTR(D, n); if (*pb < 0) { n = pb[1]; goto rel_a; } | ||
387 | n = *pb - ((cp-base) + 4-shrink); | ||
388 | if (shrink == 0) goto wd; | ||
389 | if (shrink == 4) { cp--; cp[-1] = *cp-0x10; } else cp[-1] = 0xeb; | ||
390 | goto wb; | ||
391 | } | ||
392 | case DASM_IMM_LG: p++; if (n < 0) { n = (int)D->globals[-n]; goto wd; } | ||
393 | case DASM_IMM_PC: { | ||
394 | int *pb = DASM_POS2PTR(D, n); | ||
395 | n = *pb < 0 ? pb[1] : (*pb + (ptrdiff_t)base); | ||
396 | goto wd; | ||
397 | } | ||
398 | case DASM_LABEL_LG: { | ||
399 | int idx = *p++; | ||
400 | if (idx >= 10) | ||
401 | D->globals[idx] = (void *)(base + (*p == DASM_SETLABEL ? *b : n)); | ||
402 | break; | ||
403 | } | ||
404 | case DASM_LABEL_PC: case DASM_SETLABEL: break; | ||
405 | case DASM_SPACE: { int fill = *p++; while (n--) *cp++ = fill; break; } | ||
406 | case DASM_ALIGN: | ||
407 | n = *p++; | ||
408 | while (((cp-base) & n)) *cp++ = 0x90; /* nop */ | ||
409 | break; | ||
410 | case DASM_MARK: mark = cp; break; | ||
411 | case DASM_ESC: action = *p++; | ||
412 | default: *cp++ = action; break; | ||
413 | case DASM_SECTION: case DASM_STOP: goto stop; | ||
414 | } | ||
415 | } | ||
416 | stop: (void)0; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | if (base + D->codesize != cp) /* Check for phase errors. */ | ||
421 | return DASM_S_PHASE; | ||
422 | return DASM_S_OK; | ||
423 | } | ||
424 | |||
425 | /* Get PC label offset. */ | ||
426 | int dasm_getpclabel(Dst_DECL, unsigned int pc) | ||
427 | { | ||
428 | dasm_State *D = Dst_REF; | ||
429 | if (pc*sizeof(int) < D->pcsize) { | ||
430 | int pos = D->pclabels[pc]; | ||
431 | if (pos < 0) return *DASM_POS2PTR(D, -pos); | ||
432 | if (pos > 0) return -1; /* Undefined. */ | ||
433 | } | ||
434 | return -2; /* Unused or out of range. */ | ||
435 | } | ||
436 | |||
437 | #ifdef DASM_CHECKS | ||
438 | /* Optional sanity checker to call between isolated encoding steps. */ | ||
439 | int dasm_checkstep(Dst_DECL, int secmatch) | ||
440 | { | ||
441 | dasm_State *D = Dst_REF; | ||
442 | if (D->status == DASM_S_OK) { | ||
443 | int i; | ||
444 | for (i = 1; i <= 9; i++) { | ||
445 | if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_L|i; break; } | ||
446 | D->lglabels[i] = 0; | ||
447 | } | ||
448 | } | ||
449 | if (D->status == DASM_S_OK && secmatch >= 0 && | ||
450 | D->section != &D->sections[secmatch]) | ||
451 | D->status = DASM_S_MATCH_SEC|(D->section-D->sections); | ||
452 | return D->status; | ||
453 | } | ||
454 | #endif | ||
455 | |||
diff --git a/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.lua b/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.lua new file mode 100644 index 0000000..026c3b0 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.lua | |||
@@ -0,0 +1,1581 @@ | |||
1 | ------------------------------------------------------------------------------ | ||
2 | -- DynASM x86 module. | ||
3 | -- | ||
4 | -- Copyright (C) 2005-2008 Mike Pall. All rights reserved. | ||
5 | -- See dynasm.lua for full copyright notice. | ||
6 | ------------------------------------------------------------------------------ | ||
7 | |||
8 | -- Module information: | ||
9 | local _info = { | ||
10 | arch = "x86", | ||
11 | description = "DynASM x86 (i386) module", | ||
12 | version = "1.1.4", | ||
13 | vernum = 10104, | ||
14 | release = "2008-01-29", | ||
15 | author = "Mike Pall", | ||
16 | license = "MIT", | ||
17 | } | ||
18 | |||
19 | -- Exported glue functions for the arch-specific module. | ||
20 | local _M = { _info = _info } | ||
21 | |||
22 | -- Cache library functions. | ||
23 | local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs | ||
24 | local assert, unpack = assert, unpack | ||
25 | local _s = string | ||
26 | local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char | ||
27 | local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub | ||
28 | local concat, sort = table.concat, table.sort | ||
29 | local char, unpack = string.char, unpack | ||
30 | |||
31 | -- Inherited tables and callbacks. | ||
32 | local g_opt, g_arch | ||
33 | local wline, werror, wfatal, wwarn | ||
34 | |||
35 | -- Action name list. | ||
36 | -- CHECK: Keep this in sync with the C code! | ||
37 | local action_names = { | ||
38 | -- int arg, 1 buffer pos: | ||
39 | "DISP", "IMM_S", "IMM_B", "IMM_W", "IMM_D", "IMM_WB", "IMM_DB", | ||
40 | -- action arg (1 byte), int arg, 1 buffer pos (num): | ||
41 | "SPACE", | ||
42 | -- ptrdiff_t arg, 1 buffer pos (address): !x64 | ||
43 | "SETLABEL", "REL_A", | ||
44 | -- action arg (1 byte) or int arg, 2 buffer pos (link, offset): | ||
45 | "REL_LG", "REL_PC", | ||
46 | -- action arg (1 byte) or int arg, 1 buffer pos (link): | ||
47 | "IMM_LG", "IMM_PC", | ||
48 | -- action arg (1 byte) or int arg, 1 buffer pos (offset): | ||
49 | "LABEL_LG", "LABEL_PC", | ||
50 | -- action arg (1 byte), 1 buffer pos (offset): | ||
51 | "ALIGN", | ||
52 | -- action arg (1 byte), no buffer pos. | ||
53 | "ESC", | ||
54 | -- no action arg, no buffer pos. | ||
55 | "MARK", | ||
56 | -- action arg (1 byte), no buffer pos, terminal action: | ||
57 | "SECTION", | ||
58 | -- no args, no buffer pos, terminal action: | ||
59 | "STOP" | ||
60 | } | ||
61 | |||
62 | -- Maximum number of section buffer positions for dasm_put(). | ||
63 | -- CHECK: Keep this in sync with the C code! | ||
64 | local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines. | ||
65 | |||
66 | -- Action name -> action number (dynamically generated below). | ||
67 | local map_action = {} | ||
68 | -- First action number. Everything below does not need to be escaped. | ||
69 | local actfirst = 256-#action_names | ||
70 | |||
71 | -- Action list buffer and string (only used to remove dupes). | ||
72 | local actlist = {} | ||
73 | local actstr = "" | ||
74 | |||
75 | -- Argument list for next dasm_put(). Start with offset 0 into action list. | ||
76 | local actargs = { 0 } | ||
77 | |||
78 | -- Current number of section buffer positions for dasm_put(). | ||
79 | local secpos = 1 | ||
80 | |||
81 | ------------------------------------------------------------------------------ | ||
82 | |||
83 | -- Compute action numbers for action names. | ||
84 | for n,name in ipairs(action_names) do | ||
85 | local num = actfirst + n - 1 | ||
86 | map_action[name] = num | ||
87 | end | ||
88 | |||
89 | -- Dump action names and numbers. | ||
90 | local function dumpactions(out) | ||
91 | out:write("DynASM encoding engine action codes:\n") | ||
92 | for n,name in ipairs(action_names) do | ||
93 | local num = map_action[name] | ||
94 | out:write(format(" %-10s %02X %d\n", name, num, num)) | ||
95 | end | ||
96 | out:write("\n") | ||
97 | end | ||
98 | |||
99 | -- Write action list buffer as a huge static C array. | ||
100 | local function writeactions(out, name) | ||
101 | local nn = #actlist | ||
102 | local last = actlist[nn] or 255 | ||
103 | actlist[nn] = nil -- Remove last byte. | ||
104 | if nn == 0 then nn = 1 end | ||
105 | out:write("static const unsigned char ", name, "[", nn, "] = {\n") | ||
106 | local s = " " | ||
107 | for n,b in ipairs(actlist) do | ||
108 | s = s..b.."," | ||
109 | if #s >= 75 then | ||
110 | assert(out:write(s, "\n")) | ||
111 | s = " " | ||
112 | end | ||
113 | end | ||
114 | out:write(s, last, "\n};\n\n") -- Add last byte back. | ||
115 | end | ||
116 | |||
117 | ------------------------------------------------------------------------------ | ||
118 | |||
119 | -- Add byte to action list. | ||
120 | local function wputxb(n) | ||
121 | assert(n >= 0 and n <= 255 and n % 1 == 0, "byte out of range") | ||
122 | actlist[#actlist+1] = n | ||
123 | end | ||
124 | |||
125 | -- Add action to list with optional arg. Advance buffer pos, too. | ||
126 | local function waction(action, a, num) | ||
127 | wputxb(assert(map_action[action], "bad action name `"..action.."'")) | ||
128 | if a then actargs[#actargs+1] = a end | ||
129 | if a or num then secpos = secpos + (num or 1) end | ||
130 | end | ||
131 | |||
132 | -- Add call to embedded DynASM C code. | ||
133 | local function wcall(func, args) | ||
134 | wline(format("dasm_%s(Dst, %s);", func, concat(args, ", ")), true) | ||
135 | end | ||
136 | |||
137 | -- Delete duplicate action list chunks. A tad slow, but so what. | ||
138 | local function dedupechunk(offset) | ||
139 | local al, as = actlist, actstr | ||
140 | local chunk = char(unpack(al, offset+1, #al)) | ||
141 | local orig = find(as, chunk, 1, true) | ||
142 | if orig then | ||
143 | actargs[1] = orig-1 -- Replace with original offset. | ||
144 | for i=offset+1,#al do al[i] = nil end -- Kill dupe. | ||
145 | else | ||
146 | actstr = as..chunk | ||
147 | end | ||
148 | end | ||
149 | |||
150 | -- Flush action list (intervening C code or buffer pos overflow). | ||
151 | local function wflush(term) | ||
152 | local offset = actargs[1] | ||
153 | if #actlist == offset then return end -- Nothing to flush. | ||
154 | if not term then waction("STOP") end -- Terminate action list. | ||
155 | dedupechunk(offset) | ||
156 | wcall("put", actargs) -- Add call to dasm_put(). | ||
157 | actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put(). | ||
158 | secpos = 1 -- The actionlist offset occupies a buffer position, too. | ||
159 | end | ||
160 | |||
161 | -- Put escaped byte. | ||
162 | local function wputb(n) | ||
163 | if n >= actfirst then waction("ESC") end -- Need to escape byte. | ||
164 | wputxb(n) | ||
165 | end | ||
166 | |||
167 | ------------------------------------------------------------------------------ | ||
168 | |||
169 | -- Global label name -> global label number. With auto assignment on 1st use. | ||
170 | local next_global = 10 | ||
171 | local map_global = setmetatable({}, { __index = function(t, name) | ||
172 | if not match(name, "^[%a_][%w_]*$") then werror("bad global label") end | ||
173 | local n = next_global | ||
174 | if n > 246 then werror("too many global labels") end | ||
175 | next_global = n + 1 | ||
176 | t[name] = n | ||
177 | return n | ||
178 | end}) | ||
179 | |||
180 | -- Dump global labels. | ||
181 | local function dumpglobals(out, lvl) | ||
182 | local t = {} | ||
183 | for name, n in pairs(map_global) do t[n] = name end | ||
184 | out:write("Global labels:\n") | ||
185 | for i=10,next_global-1 do | ||
186 | out:write(format(" %s\n", t[i])) | ||
187 | end | ||
188 | out:write("\n") | ||
189 | end | ||
190 | |||
191 | -- Write global label enum. | ||
192 | local function writeglobals(out, prefix) | ||
193 | local t = {} | ||
194 | for name, n in pairs(map_global) do t[n] = name end | ||
195 | out:write("enum {\n") | ||
196 | for i=10,next_global-1 do | ||
197 | out:write(" ", prefix, t[i], ",\n") | ||
198 | end | ||
199 | out:write(" ", prefix, "_MAX\n};\n") | ||
200 | end | ||
201 | |||
202 | ------------------------------------------------------------------------------ | ||
203 | |||
204 | -- Arch-specific maps. | ||
205 | local map_archdef = {} -- Ext. register name -> int. name. | ||
206 | local map_reg_rev = {} -- Int. register name -> ext. name. | ||
207 | local map_reg_num = {} -- Int. register name -> register number. | ||
208 | local map_reg_opsize = {} -- Int. register name -> operand size. | ||
209 | local map_reg_valid_base = {} -- Int. register name -> valid base register? | ||
210 | local map_reg_valid_index = {} -- Int. register name -> valid index register? | ||
211 | local reg_list = {} -- Canonical list of int. register names. | ||
212 | |||
213 | local map_type = {} -- Type name -> { ctype, reg } | ||
214 | local ctypenum = 0 -- Type number (for _PTx macros). | ||
215 | |||
216 | local addrsize = "d" -- Size for address operands. !x64 | ||
217 | |||
218 | -- Helper function to fill register maps. | ||
219 | local function mkrmap(sz, names) | ||
220 | for n,name in ipairs(names) do | ||
221 | local iname = format("@%s%x", sz, n-1) | ||
222 | reg_list[#reg_list+1] = iname | ||
223 | map_archdef[name] = iname | ||
224 | map_reg_rev[iname] = name | ||
225 | map_reg_num[iname] = n-1 | ||
226 | map_reg_opsize[iname] = sz | ||
227 | if sz == addrsize then | ||
228 | map_reg_valid_base[iname] = true | ||
229 | map_reg_valid_index[iname] = true | ||
230 | end | ||
231 | end | ||
232 | reg_list[#reg_list+1] = "" | ||
233 | end | ||
234 | |||
235 | -- Integer registers (dword, word and byte sized). | ||
236 | mkrmap("d", {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"}) | ||
237 | map_reg_valid_index[map_archdef.esp] = nil | ||
238 | mkrmap("w", {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"}) | ||
239 | mkrmap("b", {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"}) | ||
240 | |||
241 | -- FP registers (internally tword sized, but use "f" as operand size). | ||
242 | mkrmap("f", {"st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7"}) | ||
243 | |||
244 | -- SSE registers (oword sized, but qword and dword accessible). | ||
245 | mkrmap("o", {"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"}) | ||
246 | |||
247 | -- Operand size prefixes to codes. | ||
248 | local map_opsize = { | ||
249 | byte = "b", word = "w", dword = "d", qword = "q", oword = "o", tword = "t", | ||
250 | aword = addrsize, | ||
251 | } | ||
252 | |||
253 | -- Operand size code to number. | ||
254 | local map_opsizenum = { | ||
255 | b = 1, w = 2, d = 4, q = 8, o = 16, t = 10, | ||
256 | } | ||
257 | |||
258 | -- Operand size code to name. | ||
259 | local map_opsizename = { | ||
260 | b = "byte", w = "word", d = "dword", q = "qword", o = "oword", t = "tword", | ||
261 | f = "fpword", | ||
262 | } | ||
263 | |||
264 | -- Valid index register scale factors. | ||
265 | local map_xsc = { | ||
266 | ["1"] = 0, ["2"] = 1, ["4"] = 2, ["8"] = 3, | ||
267 | } | ||
268 | |||
269 | -- Condition codes. | ||
270 | local map_cc = { | ||
271 | o = 0, no = 1, b = 2, nb = 3, e = 4, ne = 5, be = 6, nbe = 7, | ||
272 | s = 8, ns = 9, p = 10, np = 11, l = 12, nl = 13, le = 14, nle = 15, | ||
273 | c = 2, nae = 2, nc = 3, ae = 3, z = 4, nz = 5, na = 6, a = 7, | ||
274 | nge = 12, ge = 13, ng = 14, g = 15, | ||
275 | } | ||
276 | |||
277 | |||
278 | -- Reverse defines for registers. | ||
279 | function _M.revdef(s) | ||
280 | return gsub(s, "@%w+", map_reg_rev) | ||
281 | end | ||
282 | |||
283 | -- Dump register names and numbers | ||
284 | local function dumpregs(out) | ||
285 | out:write("Register names, sizes and internal numbers:\n") | ||
286 | for _,reg in ipairs(reg_list) do | ||
287 | if reg == "" then | ||
288 | out:write("\n") | ||
289 | else | ||
290 | local name = map_reg_rev[reg] | ||
291 | local num = map_reg_num[reg] | ||
292 | local opsize = map_opsizename[map_reg_opsize[reg]] | ||
293 | out:write(format(" %-5s %-8s %d\n", name, opsize, num)) | ||
294 | end | ||
295 | end | ||
296 | end | ||
297 | |||
298 | ------------------------------------------------------------------------------ | ||
299 | |||
300 | -- Put action for label arg (IMM_LG, IMM_PC, REL_LG, REL_PC). | ||
301 | local function wputlabel(aprefix, imm, num) | ||
302 | if type(imm) == "number" then | ||
303 | waction(aprefix.."LG", nil, num); | ||
304 | wputxb(imm) | ||
305 | else | ||
306 | waction(aprefix.."PC", imm, num) | ||
307 | end | ||
308 | end | ||
309 | |||
310 | -- Put signed byte or arg. | ||
311 | local function wputsbarg(n) | ||
312 | if type(n) == "number" then | ||
313 | if n < -128 or n > 127 then | ||
314 | werror("signed immediate byte out of range") | ||
315 | end | ||
316 | if n < 0 then n = n + 256 end | ||
317 | wputb(n) | ||
318 | else waction("IMM_S", n) end | ||
319 | end | ||
320 | |||
321 | -- Put unsigned byte or arg. | ||
322 | local function wputbarg(n) | ||
323 | if type(n) == "number" then | ||
324 | if n < 0 or n > 255 then | ||
325 | werror("unsigned immediate byte out of range") | ||
326 | end | ||
327 | wputb(n) | ||
328 | else waction("IMM_B", n) end | ||
329 | end | ||
330 | |||
331 | -- Put unsigned word or arg. | ||
332 | local function wputwarg(n) | ||
333 | if type(n) == "number" then | ||
334 | if n < 0 or n > 65535 then | ||
335 | werror("unsigned immediate word out of range") | ||
336 | end | ||
337 | local r = n%256; n = (n-r)/256; wputb(r); wputb(n); | ||
338 | else waction("IMM_W", n) end | ||
339 | end | ||
340 | |||
341 | -- Put signed or unsigned dword or arg. | ||
342 | local function wputdarg(n) | ||
343 | local tn = type(n) | ||
344 | if tn == "number" then | ||
345 | if n < 0 then n = n + 4294967296 end | ||
346 | local r = n%256; n = (n-r)/256; wputb(r); | ||
347 | r = n%256; n = (n-r)/256; wputb(r); | ||
348 | r = n%256; n = (n-r)/256; wputb(r); wputb(n); | ||
349 | elseif tn == "table" then | ||
350 | wputlabel("IMM_", n[1], 1) | ||
351 | else | ||
352 | waction("IMM_D", n) | ||
353 | end | ||
354 | end | ||
355 | |||
356 | -- Put operand-size dependent number or arg (defaults to dword). | ||
357 | local function wputszarg(sz, n) | ||
358 | if not sz or sz == "d" then wputdarg(n) | ||
359 | elseif sz == "w" then wputwarg(n) | ||
360 | elseif sz == "b" then wputbarg(n) | ||
361 | elseif sz == "s" then wputsbarg(n) | ||
362 | else werror("bad operand size") end | ||
363 | end | ||
364 | |||
365 | -- Put multi-byte opcode with operand-size dependent modifications. | ||
366 | local function wputop(sz, op) | ||
367 | local r | ||
368 | if sz == "w" then wputb(102) end | ||
369 | if op >= 16777216 then r = op % 16777216 wputb((op-r) / 16777216) op = r end | ||
370 | if op >= 65536 then r = op % 65536 wputb((op-r) / 65536) op = r end | ||
371 | if op >= 256 then r = op % 256 wputb((op-r) / 256) op = r end | ||
372 | if sz == "b" then op = op - 1 end | ||
373 | wputb(op) | ||
374 | end | ||
375 | |||
376 | -- Put ModRM or SIB formatted byte. | ||
377 | local function wputmodrm(m, s, rm) | ||
378 | assert(m < 4 and s < 8 and rm < 8, "bad modrm operands") | ||
379 | wputb(64*m + 8*s + rm) | ||
380 | end | ||
381 | |||
382 | -- Put ModRM/SIB plus optional displacement. | ||
383 | local function wputmrmsib(t, s, imark) | ||
384 | -- Register mode. | ||
385 | if sub(t.mode, 1, 1) == "r" then | ||
386 | wputmodrm(3, s, t.reg) | ||
387 | return | ||
388 | end | ||
389 | |||
390 | local disp = t.disp | ||
391 | local tdisp = type(disp) | ||
392 | -- No base register? | ||
393 | if not t.reg then | ||
394 | if t.xreg then | ||
395 | -- Indexed mode with index register only. | ||
396 | wputmodrm(0, s, 4) -- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp) | ||
397 | wputmodrm(t.xsc, t.xreg, 5) | ||
398 | else | ||
399 | -- Pure displacement. | ||
400 | wputmodrm(0, s, 5) -- [disp] -> (0, s, ebp) | ||
401 | end | ||
402 | wputdarg(disp) | ||
403 | return | ||
404 | end | ||
405 | |||
406 | local m | ||
407 | if tdisp == "number" then -- Check displacement size at assembly time. | ||
408 | if disp == 0 and t.reg ~= 5 then m = 0 -- [ebp] -> [ebp+0] (in SIB, too) | ||
409 | elseif disp >= -128 and disp <= 127 then m = 1 | ||
410 | else m = 2 end | ||
411 | elseif tdisp == "table" then | ||
412 | m = 2 | ||
413 | end | ||
414 | |||
415 | -- Index register present or esp as base register: need SIB encoding. | ||
416 | if t.xreg or t.reg == 4 then | ||
417 | wputmodrm(m or 2, s, 4) -- ModRM. | ||
418 | if (m == nil or imark) and tdisp ~= "table" then waction("MARK") end | ||
419 | wputmodrm(t.xsc or 0, t.xreg or 4, t.reg) -- SIB. | ||
420 | else | ||
421 | wputmodrm(m or 2, s, t.reg) -- ModRM. | ||
422 | if imark and (m == 1 or m == 2) then waction("MARK") end | ||
423 | end | ||
424 | |||
425 | -- Put displacement. | ||
426 | if m == 1 then wputsbarg(disp) | ||
427 | elseif m == 2 then wputdarg(disp) | ||
428 | elseif not m then waction("DISP", disp) end | ||
429 | end | ||
430 | |||
431 | ------------------------------------------------------------------------------ | ||
432 | |||
433 | -- Return human-readable operand mode string. | ||
434 | local function opmodestr(op, args) | ||
435 | local m = {} | ||
436 | for i=1,#args do | ||
437 | local a = args[i] | ||
438 | m[#m+1] = sub(a.mode, 1, 1)..(a.opsize or "?") | ||
439 | end | ||
440 | return op.." "..concat(m, ",") | ||
441 | end | ||
442 | |||
443 | -- Convert number to valid integer or nil. | ||
444 | local function toint(expr) | ||
445 | local n = tonumber(expr) | ||
446 | if n then | ||
447 | if n % 1 ~= 0 or n < -2147483648 or n > 4294967295 then | ||
448 | werror("bad integer number `"..expr.."'") | ||
449 | end | ||
450 | return n | ||
451 | end | ||
452 | end | ||
453 | |||
454 | -- Parse immediate expression. | ||
455 | local function immexpr(expr) | ||
456 | -- &expr (pointer) | ||
457 | if sub(expr, 1, 1) == "&" then | ||
458 | return "iPJ", format("(ptrdiff_t)(%s)", sub(expr,2)) | ||
459 | end | ||
460 | |||
461 | local prefix = sub(expr, 1, 2) | ||
462 | -- =>expr (pc label reference) | ||
463 | if prefix == "=>" then | ||
464 | return "iJ", sub(expr, 3) | ||
465 | end | ||
466 | -- ->name (global label reference) | ||
467 | if prefix == "->" then | ||
468 | return "iJ", map_global[sub(expr, 3)] | ||
469 | end | ||
470 | |||
471 | -- [<>][1-9] (local label reference) | ||
472 | local dir, lnum = match(expr, "^([<>])([1-9])$") | ||
473 | if dir then -- Fwd: 247-255, Bkwd: 1-9. | ||
474 | return "iJ", lnum + (dir == ">" and 246 or 0) | ||
475 | end | ||
476 | |||
477 | -- expr (interpreted as immediate) | ||
478 | return "iI", expr | ||
479 | end | ||
480 | |||
481 | -- Parse displacement expression: +-num, +-expr, +-opsize*num | ||
482 | local function dispexpr(expr) | ||
483 | local disp = expr == "" and 0 or toint(expr) | ||
484 | if disp then return disp end | ||
485 | local c, dispt = match(expr, "^([+-])%s*(.+)$") | ||
486 | if c == "+" then | ||
487 | expr = dispt | ||
488 | elseif not c then | ||
489 | werror("bad displacement expression `"..expr.."'") | ||
490 | end | ||
491 | local opsize, tailops = match(dispt, "^(%w+)%s*%*%s*(.+)$") | ||
492 | local ops, imm = map_opsize[opsize], toint(tailops) | ||
493 | if ops and imm then | ||
494 | if c == "-" then imm = -imm end | ||
495 | return imm*map_opsizenum[ops] | ||
496 | end | ||
497 | local mode, iexpr = immexpr(dispt) | ||
498 | if mode == "iJ" then | ||
499 | if c == "-" then werror("cannot invert label reference") end | ||
500 | return { iexpr } | ||
501 | end | ||
502 | return expr -- Need to return original signed expression. | ||
503 | end | ||
504 | |||
505 | -- Parse register or type expression. | ||
506 | local function rtexpr(expr) | ||
507 | if not expr then return end | ||
508 | local tname, ovreg = match(expr, "^([%w_]+):(@[%w_]+)$") | ||
509 | local tp = map_type[tname or expr] | ||
510 | if tp then | ||
511 | local reg = ovreg or tp.reg | ||
512 | local rnum = map_reg_num[reg] | ||
513 | if not rnum then | ||
514 | werror("type `"..(tname or expr).."' needs a register override") | ||
515 | end | ||
516 | if not map_reg_valid_base[reg] then | ||
517 | werror("bad base register override `"..(map_reg_rev[reg] or reg).."'") | ||
518 | end | ||
519 | return reg, rnum, tp | ||
520 | end | ||
521 | return expr, map_reg_num[expr] | ||
522 | end | ||
523 | |||
524 | -- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }. | ||
525 | local function parseoperand(param) | ||
526 | local t = {} | ||
527 | |||
528 | local expr = param | ||
529 | local opsize, tailops = match(param, "^(%w+)%s*(.+)$") | ||
530 | if opsize then | ||
531 | t.opsize = map_opsize[opsize] | ||
532 | if t.opsize then expr = tailops end | ||
533 | end | ||
534 | |||
535 | local br = match(expr, "^%[%s*(.-)%s*%]$") | ||
536 | repeat | ||
537 | if br then | ||
538 | t.mode = "xm" | ||
539 | |||
540 | -- [disp] | ||
541 | t.disp = toint(br) | ||
542 | if t.disp then | ||
543 | t.mode = "xmO" | ||
544 | break | ||
545 | end | ||
546 | |||
547 | -- [reg...] | ||
548 | local tp | ||
549 | local reg, tailr = match(br, "^([@%w_:]+)%s*(.*)$") | ||
550 | reg, t.reg, tp = rtexpr(reg) | ||
551 | if not t.reg then | ||
552 | -- [expr] | ||
553 | t.mode = "xmO" | ||
554 | t.disp = dispexpr("+"..br) | ||
555 | break | ||
556 | end | ||
557 | |||
558 | -- [xreg*xsc] or [xreg*xsc+-disp] or [xreg*xsc+-expr] | ||
559 | local xsc, tailsc = match(tailr, "^%*%s*([1248])%s*(.*)$") | ||
560 | if xsc then | ||
561 | if not map_reg_valid_index[reg] then | ||
562 | werror("bad index register `"..map_reg_rev[reg].."'") | ||
563 | end | ||
564 | t.xsc = map_xsc[xsc] | ||
565 | t.xreg = t.reg | ||
566 | t.reg = nil | ||
567 | t.disp = dispexpr(tailsc) | ||
568 | break | ||
569 | end | ||
570 | if not map_reg_valid_base[reg] then | ||
571 | werror("bad base register `"..map_reg_rev[reg].."'") | ||
572 | end | ||
573 | |||
574 | -- [reg] or [reg+-disp] | ||
575 | t.disp = toint(tailr) or (tailr == "" and 0) | ||
576 | if t.disp then break end | ||
577 | |||
578 | -- [reg+xreg...] | ||
579 | local xreg, tailx = match(tailr, "^+%s*([@%w_:]+)%s*(.*)$") | ||
580 | xreg, t.xreg, tp = rtexpr(xreg) | ||
581 | if not t.xreg then | ||
582 | -- [reg+-expr] | ||
583 | t.disp = dispexpr(tailr) | ||
584 | break | ||
585 | end | ||
586 | if not map_reg_valid_index[xreg] then | ||
587 | werror("bad index register `"..map_reg_rev[xreg].."'") | ||
588 | end | ||
589 | |||
590 | -- [reg+xreg*xsc...] | ||
591 | local xsc, tailsc = match(tailx, "^%*%s*([1248])%s*(.*)$") | ||
592 | if xsc then | ||
593 | t.xsc = map_xsc[xsc] | ||
594 | tailx = tailsc | ||
595 | end | ||
596 | |||
597 | -- [...] or [...+-disp] or [...+-expr] | ||
598 | t.disp = dispexpr(tailx) | ||
599 | else | ||
600 | -- imm or opsize*imm | ||
601 | local imm = toint(expr) | ||
602 | if not imm and sub(expr, 1, 1) == "*" and t.opsize then | ||
603 | imm = toint(sub(expr, 2)) | ||
604 | if imm then | ||
605 | imm = imm * map_opsizenum[t.opsize] | ||
606 | t.opsize = nil | ||
607 | end | ||
608 | end | ||
609 | if imm then | ||
610 | if t.opsize then werror("bad operand size override") end | ||
611 | local m = "i" | ||
612 | if imm == 1 then m = m.."1" end | ||
613 | if imm >= 4294967168 and imm <= 4294967295 then imm = imm-4294967296 end | ||
614 | if imm >= -128 and imm <= 127 then m = m.."S" end | ||
615 | t.imm = imm | ||
616 | t.mode = m | ||
617 | break | ||
618 | end | ||
619 | |||
620 | local tp | ||
621 | local reg, tailr = match(expr, "^([@%w_:]+)%s*(.*)$") | ||
622 | reg, t.reg, tp = rtexpr(reg) | ||
623 | if t.reg then | ||
624 | -- reg | ||
625 | if tailr == "" then | ||
626 | if t.opsize then werror("bad operand size override") end | ||
627 | t.opsize = map_reg_opsize[reg] | ||
628 | if t.opsize == "f" then | ||
629 | t.mode = t.reg == 0 and "fF" or "f" | ||
630 | else | ||
631 | if reg == "@w4" then wwarn("bad idea, try again with `esp'") end | ||
632 | t.mode = t.reg == 0 and "rmR" or (reg == "@b1" and "rmC" or "rm") | ||
633 | end | ||
634 | break | ||
635 | end | ||
636 | |||
637 | -- type[idx], type[idx].field, type->field -> [reg+offset_expr] | ||
638 | if not tp then werror("bad operand `"..param.."'") end | ||
639 | t.mode = "xm" | ||
640 | t.disp = format(tp.ctypefmt, tailr) | ||
641 | else | ||
642 | t.mode, t.imm = immexpr(expr) | ||
643 | if sub(t.mode, -1) == "J" then | ||
644 | if t.opsize and t.opsize ~= addrsize then | ||
645 | werror("bad operand size override") | ||
646 | end | ||
647 | t.opsize = addrsize | ||
648 | end | ||
649 | end | ||
650 | end | ||
651 | until true | ||
652 | return t | ||
653 | end | ||
654 | |||
655 | ------------------------------------------------------------------------------ | ||
656 | -- x86 Template String Description | ||
657 | -- =============================== | ||
658 | -- | ||
659 | -- Each template string is a list of [match:]pattern pairs, | ||
660 | -- separated by "|". The first match wins. No match means a | ||
661 | -- bad or unsupported combination of operand modes or sizes. | ||
662 | -- | ||
663 | -- The match part and the ":" is omitted if the operation has | ||
664 | -- no operands. Otherwise the first N characters are matched | ||
665 | -- against the mode strings of each of the N operands. | ||
666 | -- | ||
667 | -- The mode string for each operand type is (see parseoperand()): | ||
668 | -- Integer register: "rm", +"R" for eax, ax, al, +"C" for cl | ||
669 | -- FP register: "f", +"F" for st0 | ||
670 | -- Index operand: "xm", +"O" for [disp] (pure offset) | ||
671 | -- Immediate: "i", +"S" for signed 8 bit, +"1" for 1, | ||
672 | -- +"I" for arg, +"P" for pointer | ||
673 | -- Any: +"J" for valid jump targets | ||
674 | -- | ||
675 | -- So a match character "m" (mixed) matches both an integer register | ||
676 | -- and an index operand (to be encoded with the ModRM/SIB scheme). | ||
677 | -- But "r" matches only a register and "x" only an index operand | ||
678 | -- (e.g. for FP memory access operations). | ||
679 | -- | ||
680 | -- The operand size match string starts right after the mode match | ||
681 | -- characters and ends before the ":". "dwb" is assumed, if empty. | ||
682 | -- The effective data size of the operation is matched against this list. | ||
683 | -- | ||
684 | -- If only the regular "b", "w", "d", "q", "t" operand sizes are | ||
685 | -- present, then all operands must be the same size. Unspecified sizes | ||
686 | -- are ignored, but at least one operand must have a size or the pattern | ||
687 | -- won't match (use the "byte", "word", "dword", "qword", "tword" | ||
688 | -- operand size overrides. E.g.: mov dword [eax], 1). | ||
689 | -- | ||
690 | -- If the list has a "1" or "2" prefix, the operand size is taken | ||
691 | -- from the respective operand and any other operand sizes are ignored. | ||
692 | -- If the list contains only ".", all operand sizes are ignored. | ||
693 | -- If the list has a "/" prefix, the concatenated (mixed) operand sizes | ||
694 | -- are compared to the match. | ||
695 | -- | ||
696 | -- E.g. "rrdw" matches for either two dword registers or two word | ||
697 | -- registers. "Fx2dq" matches an st0 operand plus an index operand | ||
698 | -- pointing to a dword (float) or qword (double). | ||
699 | -- | ||
700 | -- Every character after the ":" is part of the pattern string: | ||
701 | -- Hex chars are accumulated to form the opcode (left to right). | ||
702 | -- "n" disables the standard opcode mods | ||
703 | -- (otherwise: -1 for "b", o16 prefix for "w") | ||
704 | -- "r"/"R" adds the reg. number from the 1st/2nd operand to the opcode. | ||
705 | -- "m"/"M" generates ModRM/SIB from the 1st/2nd operand. | ||
706 | -- The spare 3 bits are either filled with the last hex digit or | ||
707 | -- the result from a previous "r"/"R". The opcode is restored. | ||
708 | -- | ||
709 | -- All of the following characters force a flush of the opcode: | ||
710 | -- "o"/"O" stores a pure 32 bit disp (offset) from the 1st/2nd operand. | ||
711 | -- "S" stores a signed 8 bit immediate from the last operand. | ||
712 | -- "U" stores an unsigned 8 bit immediate from the last operand. | ||
713 | -- "W" stores an unsigned 16 bit immediate from the last operand. | ||
714 | -- "i" stores an operand sized immediate from the last operand. | ||
715 | -- "I" dito, but generates an action code to optionally modify | ||
716 | -- the opcode (+2) for a signed 8 bit immediate. | ||
717 | -- "J" generates one of the REL action codes from the last operand. | ||
718 | -- | ||
719 | ------------------------------------------------------------------------------ | ||
720 | |||
721 | -- Template strings for x86 instructions. Ordered by first opcode byte. | ||
722 | -- Unimplemented opcodes (deliberate omissions) are marked with *. | ||
723 | local map_op = { | ||
724 | -- 00-05: add... | ||
725 | -- 06: *push es | ||
726 | -- 07: *pop es | ||
727 | -- 08-0D: or... | ||
728 | -- 0E: *push cs | ||
729 | -- 0F: two byte opcode prefix | ||
730 | -- 10-15: adc... | ||
731 | -- 16: *push ss | ||
732 | -- 17: *pop ss | ||
733 | -- 18-1D: sbb... | ||
734 | -- 1E: *push ds | ||
735 | -- 1F: *pop ds | ||
736 | -- 20-25: and... | ||
737 | es_0 = "26", | ||
738 | -- 27: *daa | ||
739 | -- 28-2D: sub... | ||
740 | cs_0 = "2E", | ||
741 | -- 2F: *das | ||
742 | -- 30-35: xor... | ||
743 | ss_0 = "36", | ||
744 | -- 37: *aaa | ||
745 | -- 38-3D: cmp... | ||
746 | ds_0 = "3E", | ||
747 | -- 3F: *aas | ||
748 | inc_1 = "rdw:40r|m:FF0m", | ||
749 | dec_1 = "rdw:48r|m:FF1m", | ||
750 | push_1 = "rdw:50r|mdw:FF6m|S.:6AS|ib:n6Ai|i.:68i", | ||
751 | pop_1 = "rdw:58r|mdw:8F0m", | ||
752 | -- 60: *pusha, *pushad, *pushaw | ||
753 | -- 61: *popa, *popad, *popaw | ||
754 | -- 62: *bound rdw,x | ||
755 | -- 63: *arpl mw,rw | ||
756 | fs_0 = "64", | ||
757 | gs_0 = "65", | ||
758 | o16_0 = "66", | ||
759 | a16_0 = "67", | ||
760 | -- 68: push idw | ||
761 | -- 69: imul rdw,mdw,idw | ||
762 | -- 6A: push ib | ||
763 | -- 6B: imul rdw,mdw,S | ||
764 | -- 6C: *insb | ||
765 | -- 6D: *insd, *insw | ||
766 | -- 6E: *outsb | ||
767 | -- 6F: *outsd, *outsw | ||
768 | -- 70-7F: jcc lb | ||
769 | -- 80: add... mb,i | ||
770 | -- 81: add... mdw,i | ||
771 | -- 82: *undefined | ||
772 | -- 83: add... mdw,S | ||
773 | test_2 = "mr:85Rm|rm:85rM|Ri:A9i|mi:F70mi", | ||
774 | -- 86: xchg rb,mb | ||
775 | -- 87: xchg rdw,mdw | ||
776 | -- 88: mov mb,r | ||
777 | -- 89: mov mdw,r | ||
778 | -- 8A: mov r,mb | ||
779 | -- 8B: mov r,mdw | ||
780 | -- 8C: *mov mdw,seg | ||
781 | lea_2 = "rxd:8DrM", | ||
782 | -- 8E: *mov seg,mdw | ||
783 | -- 8F: pop mdw | ||
784 | nop_0 = "90", | ||
785 | xchg_2 = "Rrdw:90R|rRdw:90r|rm:87rM|mr:87Rm", | ||
786 | cbw_0 = "6698", | ||
787 | cwde_0 = "98", | ||
788 | cwd_0 = "6699", | ||
789 | cdq_0 = "99", | ||
790 | -- 9A: *call iw:idw | ||
791 | wait_0 = "9B", | ||
792 | fwait_0 = "9B", | ||
793 | pushf_0 = "9C", | ||
794 | pushfw_0 = "669C", | ||
795 | pushfd_0 = "9C", | ||
796 | popf_0 = "9D", | ||
797 | popfw_0 = "669D", | ||
798 | popfd_0 = "9D", | ||
799 | sahf_0 = "9E", | ||
800 | lahf_0 = "9F", | ||
801 | mov_2 = "OR:A3o|RO:A1O|mr:89Rm|rm:8BrM|rib:nB0ri|ridw:B8ri|mi:C70mi", | ||
802 | movsb_0 = "A4", | ||
803 | movsw_0 = "66A5", | ||
804 | movsd_0 = "A5", | ||
805 | cmpsb_0 = "A6", | ||
806 | cmpsw_0 = "66A7", | ||
807 | cmpsd_0 = "A7", | ||
808 | -- A8: test Rb,i | ||
809 | -- A9: test Rdw,i | ||
810 | stosb_0 = "AA", | ||
811 | stosw_0 = "66AB", | ||
812 | stosd_0 = "AB", | ||
813 | lodsb_0 = "AC", | ||
814 | lodsw_0 = "66AD", | ||
815 | lodsd_0 = "AD", | ||
816 | scasb_0 = "AE", | ||
817 | scasw_0 = "66AF", | ||
818 | scasd_0 = "AF", | ||
819 | -- B0-B7: mov rb,i | ||
820 | -- B8-BF: mov rdw,i | ||
821 | -- C0: rol... mb,i | ||
822 | -- C1: rol... mdw,i | ||
823 | ret_1 = "i.:nC2W", | ||
824 | ret_0 = "C3", | ||
825 | -- C4: *les rdw,mq | ||
826 | -- C5: *lds rdw,mq | ||
827 | -- C6: mov mb,i | ||
828 | -- C7: mov mdw,i | ||
829 | -- C8: *enter iw,ib | ||
830 | leave_0 = "C9", | ||
831 | -- CA: *retf iw | ||
832 | -- CB: *retf | ||
833 | int3_0 = "CC", | ||
834 | int_1 = "i.:nCDU", | ||
835 | into_0 = "CE", | ||
836 | -- CF: *iret | ||
837 | -- D0: rol... mb,1 | ||
838 | -- D1: rol... mdw,1 | ||
839 | -- D2: rol... mb,cl | ||
840 | -- D3: rol... mb,cl | ||
841 | -- D4: *aam ib | ||
842 | -- D5: *aad ib | ||
843 | -- D6: *salc | ||
844 | -- D7: *xlat | ||
845 | -- D8-DF: floating point ops | ||
846 | -- E0: *loopne | ||
847 | -- E1: *loope | ||
848 | -- E2: *loop | ||
849 | -- E3: *jcxz, *jecxz | ||
850 | -- E4: *in Rb,ib | ||
851 | -- E5: *in Rdw,ib | ||
852 | -- E6: *out ib,Rb | ||
853 | -- E7: *out ib,Rdw | ||
854 | call_1 = "md:FF2m|J.:E8J", | ||
855 | jmp_1 = "md:FF4m|J.:E9J", -- short: EB | ||
856 | -- EA: *jmp iw:idw | ||
857 | -- EB: jmp ib | ||
858 | -- EC: *in Rb,dx | ||
859 | -- ED: *in Rdw,dx | ||
860 | -- EE: *out dx,Rb | ||
861 | -- EF: *out dx,Rdw | ||
862 | -- F0: *lock | ||
863 | int1_0 = "F1", | ||
864 | repne_0 = "F2", | ||
865 | repnz_0 = "F2", | ||
866 | rep_0 = "F3", | ||
867 | repe_0 = "F3", | ||
868 | repz_0 = "F3", | ||
869 | -- F4: *hlt | ||
870 | cmc_0 = "F5", | ||
871 | -- F6: test... mb,i; div... mb | ||
872 | -- F7: test... mdw,i; div... mdw | ||
873 | clc_0 = "F8", | ||
874 | stc_0 = "F9", | ||
875 | -- FA: *cli | ||
876 | cld_0 = "FC", | ||
877 | std_0 = "FD", | ||
878 | -- FE: inc... mb | ||
879 | -- FF: inc... mdw | ||
880 | |||
881 | -- misc ops | ||
882 | not_1 = "m:F72m", | ||
883 | neg_1 = "m:F73m", | ||
884 | mul_1 = "m:F74m", | ||
885 | imul_1 = "m:F75m", | ||
886 | div_1 = "m:F76m", | ||
887 | idiv_1 = "m:F77m", | ||
888 | |||
889 | imul_2 = "rmdw:0FAFrM|rIdw:69rmI|rSdw:6BrmS|ridw:69rmi", | ||
890 | imul_3 = "rmIdw:69rMI|rmSdw:6BrMS|rmidw:69rMi", | ||
891 | |||
892 | movzx_2 = "rm/db:0FB6rM|rm/wb:0FB6rM|rm/dw:0FB7rM", | ||
893 | movsx_2 = "rm/db:0FBErM|rm/wb:0FBErM|rm/dw:0FBFrM", | ||
894 | |||
895 | bswap_1 = "rd:0FC8r", | ||
896 | bsf_2 = "rmdw:0FBCrM", | ||
897 | bsr_2 = "rmdw:0FBDrM", | ||
898 | bt_2 = "mrdw:0FA3Rm|midw:0FBA4mU", | ||
899 | btc_2 = "mrdw:0FBBRm|midw:0FBA7mU", | ||
900 | btr_2 = "mrdw:0FB3Rm|midw:0FBA6mU", | ||
901 | bts_2 = "mrdw:0FABRm|midw:0FBA5mU", | ||
902 | |||
903 | rdtsc_0 = "0F31", -- P1+ | ||
904 | cpuid_0 = "0FA2", -- P1+ | ||
905 | |||
906 | -- floating point ops | ||
907 | fst_1 = "ff:DDD0r|xd:D92m|xq:DD2m", | ||
908 | fstp_1 = "ff:DDD8r|xd:D93m|xq:DD3m|xt:DB7m", | ||
909 | fld_1 = "ff:D9C0r|xd:D90m|xq:DD0m|xt:DB5m", | ||
910 | |||
911 | fpop_0 = "DDD8", -- Alias for fstp st0. | ||
912 | |||
913 | fist_1 = "xw:nDF2m|xd:DB2m", | ||
914 | fistp_1 = "xw:nDF3m|xd:DB3m|xq:DF7m", | ||
915 | fisttp_1 = "xw:nDF1m|xd:DB1m|xq:DD1m", -- SSE3 | ||
916 | fild_1 = "xw:nDF0m|xd:DB0m|xq:DF5m", | ||
917 | |||
918 | fxch_0 = "D9C9", | ||
919 | fxch_1 = "ff:D9C8r", | ||
920 | fxch_2 = "fFf:D9C8r|Fff:D9C8R", | ||
921 | |||
922 | fucom_1 = "ff:DDE0r", | ||
923 | fucom_2 = "Fff:DDE0R", | ||
924 | fucomp_1 = "ff:DDE8r", | ||
925 | fucomp_2 = "Fff:DDE8R", | ||
926 | fucomi_1 = "ff:DBE8r", -- P6+ | ||
927 | fucomi_2 = "Fff:DBE8R", -- P6+ | ||
928 | fucomip_1 = "ff:DFE8r", -- P6+ | ||
929 | fucomip_2 = "Fff:DFE8R", -- P6+ | ||
930 | fcomi_1 = "ff:DBF0r", -- P6+ | ||
931 | fcomi_2 = "Fff:DBF0R", -- P6+ | ||
932 | fcomip_1 = "ff:DFF0r", -- P6+ | ||
933 | fcomip_2 = "Fff:DFF0R", -- P6+ | ||
934 | fucompp_0 = "DAE9", | ||
935 | fcompp_0 = "DED9", | ||
936 | |||
937 | fldcw_1 = "xw:nD95m", | ||
938 | fstcw_1 = "xw:n9BD97m", | ||
939 | fnstcw_1 = "xw:nD97m", | ||
940 | fstsw_1 = "Rw:n9BDFE0|xw:n9BDD7m", | ||
941 | fnstsw_1 = "Rw:nDFE0|xw:nDD7m", | ||
942 | fclex_0 = "9BDBE2", | ||
943 | fnclex_0 = "DBE2", | ||
944 | |||
945 | fnop_0 = "D9D0", | ||
946 | -- D9D1-D9DF: unassigned | ||
947 | |||
948 | fchs_0 = "D9E0", | ||
949 | fabs_0 = "D9E1", | ||
950 | -- D9E2: unassigned | ||
951 | -- D9E3: unassigned | ||
952 | ftst_0 = "D9E4", | ||
953 | fxam_0 = "D9E5", | ||
954 | -- D9E6: unassigned | ||
955 | -- D9E7: unassigned | ||
956 | fld1_0 = "D9E8", | ||
957 | fldl2t_0 = "D9E9", | ||
958 | fldl2e_0 = "D9EA", | ||
959 | fldpi_0 = "D9EB", | ||
960 | fldlg2_0 = "D9EC", | ||
961 | fldln2_0 = "D9ED", | ||
962 | fldz_0 = "D9EE", | ||
963 | -- D9EF: unassigned | ||
964 | |||
965 | f2xm1_0 = "D9F0", | ||
966 | fyl2x_0 = "D9F1", | ||
967 | fptan_0 = "D9F2", | ||
968 | fpatan_0 = "D9F3", | ||
969 | fxtract_0 = "D9F4", | ||
970 | fprem1_0 = "D9F5", | ||
971 | fdecstp_0 = "D9F6", | ||
972 | fincstp_0 = "D9F7", | ||
973 | fprem_0 = "D9F8", | ||
974 | fyl2xp1_0 = "D9F9", | ||
975 | fsqrt_0 = "D9FA", | ||
976 | fsincos_0 = "D9FB", | ||
977 | frndint_0 = "D9FC", | ||
978 | fscale_0 = "D9FD", | ||
979 | fsin_0 = "D9FE", | ||
980 | fcos_0 = "D9FF", | ||
981 | |||
982 | -- SSE, SSE2, SSE3, SSSE3 ops | ||
983 | addsubpd_2 = "rmo:660FD0rM", | ||
984 | addsubps_2 = "rmo:F20FD0rM", | ||
985 | andnpd_2 = "rmo:660F55rM", | ||
986 | andnps_2 = "rmo:0F55rM", | ||
987 | andpd_2 = "rmo:660F54rM", | ||
988 | andps_2 = "rmo:0F54rM", | ||
989 | clflush_1 = "x.:0FAE7m", | ||
990 | cmppd_3 = "rmio:660FC2rMU", | ||
991 | cmpps_3 = "rmio:0FC2rMU", | ||
992 | cmpsd_3 = "rmio:F20FC2rMU", | ||
993 | cmpss_3 = "rmio:F30FC2rMU", | ||
994 | comisd_2 = "rmo:660F2FrM", | ||
995 | comiss_2 = "rmo:0F2FrM", | ||
996 | cvtdq2pd_2 = "rro:F30FE6rM|rx/oq:", | ||
997 | cvtdq2ps_2 = "rmo:0F5BrM", | ||
998 | cvtpd2dq_2 = "rmo:F20FE6rM", | ||
999 | cvtpd2ps_2 = "rmo:660F5ArM", | ||
1000 | cvtpi2pd_2 = "rx/oq:660F2ArM", | ||
1001 | cvtpi2ps_2 = "rx/oq:0F2ArM", | ||
1002 | cvtps2dq_2 = "rmo:660F5BrM", | ||
1003 | cvtps2pd_2 = "rro:0F5ArM|rx/oq:", | ||
1004 | cvtsd2si_2 = "rr/do:F20F2DrM|rx/dq:", | ||
1005 | cvtsd2ss_2 = "rro:F20F5ArM|rx/oq:", | ||
1006 | cvtsi2sd_2 = "rm/od:F20F2ArM", | ||
1007 | cvtsi2ss_2 = "rm/od:F30F2ArM", | ||
1008 | cvtss2sd_2 = "rro:F30F5ArM|rx/od:", | ||
1009 | cvtss2si_2 = "rr/do:F20F2CrM|rx/dd:", | ||
1010 | cvttpd2dq_2 = "rmo:660FE6rM", | ||
1011 | cvttps2dq_2 = "rmo:F30F5BrM", | ||
1012 | cvttsd2si_2 = "rr/do:F20F2CrM|rx/dq:", | ||
1013 | cvttss2si_2 = "rr/do:F30F2CrM|rx/dd:", | ||
1014 | haddpd_2 = "rmo:660F7CrM", | ||
1015 | haddps_2 = "rmo:F20F7CrM", | ||
1016 | hsubpd_2 = "rmo:660F7DrM", | ||
1017 | hsubps_2 = "rmo:F20F7DrM", | ||
1018 | lddqu_2 = "rxo:F20FF0rM", | ||
1019 | ldmxcsr_1 = "xd:0FAE2m", | ||
1020 | lfence_0 = "0FAEE8", | ||
1021 | maskmovdqu_2 = "rro:660FF7rM", | ||
1022 | mfence_0 = "0FAEF0", | ||
1023 | movapd_2 = "rmo:660F28rM|mro:660F29Rm", | ||
1024 | movaps_2 = "rmo:0F28rM|mro:0F29Rm", | ||
1025 | movd_2 = "rm/od:660F6ErM|mr/do:660F7ERm", | ||
1026 | movddup_2 = "rmo:F20F12rM", | ||
1027 | movdqa_2 = "rmo:660F6FrM|mro:660F7FRm", | ||
1028 | movdqu_2 = "rmo:F30F6FrM|mro:F30F7FRm", | ||
1029 | movhlps_2 = "rro:0F12rM", | ||
1030 | movhpd_2 = "rx/oq:660F16rM|xr/qo:660F17Rm", | ||
1031 | movhps_2 = "rx/oq:0F16rM|xr/qo:0F17Rm", | ||
1032 | movlhps_2 = "rro:0F16rM", | ||
1033 | movlpd_2 = "rx/oq:660F12rM|xr/qo:660F13Rm", | ||
1034 | movlps_2 = "rx/oq:0F12rM|xr/qo:0F13Rm", | ||
1035 | movmskpd_2 = "rr/do:660F50rM", | ||
1036 | movmskps_2 = "rr/do:0F50rM", | ||
1037 | movntdq_2 = "xro:660FE7Rm", | ||
1038 | movnti_2 = "xrd:0FC3Rm", | ||
1039 | movntpd_2 = "xro:660F2BRm", | ||
1040 | movntps_2 = "xro:0F2BRm", | ||
1041 | movq_2 = "rro:F30F7ErM|rx/oq:|xr/qo:660FD6Rm", | ||
1042 | movsd_2 = "rro:F20F10rM|rx/oq:|xr/qo:F20F11Rm", | ||
1043 | movshdup_2 = "rmo:F30F16rM", | ||
1044 | movsldup_2 = "rmo:F30F12rM", | ||
1045 | movss_2 = "rro:F30F10rM|rx/od:|xr/do:F30F11Rm", | ||
1046 | movupd_2 = "rmo:660F10rM|mro:660F11Rm", | ||
1047 | movups_2 = "rmo:0F10rM|mro:0F11Rm", | ||
1048 | orpd_2 = "rmo:660F56rM", | ||
1049 | orps_2 = "rmo:0F56rM", | ||
1050 | pabsb_2 = "rmo:660F381CrM", | ||
1051 | pabsd_2 = "rmo:660F381ErM", | ||
1052 | pabsw_2 = "rmo:660F381DrM", | ||
1053 | packssdw_2 = "rmo:660F6BrM", | ||
1054 | packsswb_2 = "rmo:660F63rM", | ||
1055 | packuswb_2 = "rmo:660F67rM", | ||
1056 | paddb_2 = "rmo:660FFCrM", | ||
1057 | paddd_2 = "rmo:660FFErM", | ||
1058 | paddq_2 = "rmo:660FD4rM", | ||
1059 | paddsb_2 = "rmo:660FECrM", | ||
1060 | paddsw_2 = "rmo:660FEDrM", | ||
1061 | paddusb_2 = "rmo:660FDCrM", | ||
1062 | paddusw_2 = "rmo:660FDDrM", | ||
1063 | paddw_2 = "rmo:660FFDrM", | ||
1064 | palignr_3 = "rmio:660F3A0FrMU", | ||
1065 | pand_2 = "rmo:660FDBrM", | ||
1066 | pandn_2 = "rmo:660FDFrM", | ||
1067 | pause_0 = "F390", | ||
1068 | pavgb_2 = "rmo:660FE0rM", | ||
1069 | pavgw_2 = "rmo:660FE3rM", | ||
1070 | pcmpeqb_2 = "rmo:660F74rM", | ||
1071 | pcmpeqd_2 = "rmo:660F76rM", | ||
1072 | pcmpeqw_2 = "rmo:660F75rM", | ||
1073 | pcmpgtb_2 = "rmo:660F64rM", | ||
1074 | pcmpgtd_2 = "rmo:660F66rM", | ||
1075 | pcmpgtw_2 = "rmo:660F65rM", | ||
1076 | pextrw_3 = "rri/do:660FC5rMU", | ||
1077 | phaddd_2 = "rmo:660F3802rM", | ||
1078 | phaddsw_2 = "rmo:660F3803rM", | ||
1079 | phaddw_2 = "rmo:660F3801rM", | ||
1080 | phsubd_2 = "rmo:660F3806rM", | ||
1081 | phsubsw_2 = "rmo:660F3807rM", | ||
1082 | phsubw_2 = "rmo:660F3805rM", | ||
1083 | pinsrw_3 = "rri/od:660FC4rMU|rmi/ow:", | ||
1084 | pmaddubsw_2 = "rmo:660F3804rM", | ||
1085 | pmaddwd_2 = "rmo:660FF5rM", | ||
1086 | pmaxsw_2 = "rmo:660FEErM", | ||
1087 | pmaxub_2 = "rmo:660FDErM", | ||
1088 | pminsw_2 = "rmo:660FEArM", | ||
1089 | pminub_2 = "rmo:660FDArM", | ||
1090 | pmovmskb_2 = "rr/do:660FD7rM", | ||
1091 | pmulhrsw_2 = "rmo:660F380BrM", | ||
1092 | pmulhuw_2 = "rmo:660FE4rM", | ||
1093 | pmulhw_2 = "rmo:660FE5rM", | ||
1094 | pmullw_2 = "rmo:660FD5rM", | ||
1095 | pmuludq_2 = "rmo:660FF4rM", | ||
1096 | por_2 = "rmo:660FEBrM", | ||
1097 | prefetchnta_1 = "xb:n0F180m", | ||
1098 | prefetcht0_1 = "xb:n0F181m", | ||
1099 | prefetcht1_1 = "xb:n0F182m", | ||
1100 | prefetcht2_1 = "xb:n0F183m", | ||
1101 | psadbw_2 = "rmo:660FF6rM", | ||
1102 | pshufb_2 = "rmo:660F3800rM", | ||
1103 | pshufd_3 = "rmio:660F70rMU", | ||
1104 | pshufhw_3 = "rmio:F30F70rMU", | ||
1105 | pshuflw_3 = "rmio:F20F70rMU", | ||
1106 | psignb_2 = "rmo:660F3808rM", | ||
1107 | psignd_2 = "rmo:660F380ArM", | ||
1108 | psignw_2 = "rmo:660F3809rM", | ||
1109 | pslld_2 = "rmo:660FF2rM|rio:660F726mU", | ||
1110 | pslldq_2 = "rio:660F737mU", | ||
1111 | psllq_2 = "rmo:660FF3rM|rio:660F736mU", | ||
1112 | psllw_2 = "rmo:660FF1rM|rio:660F716mU", | ||
1113 | psrad_2 = "rmo:660FE2rM|rio:660F724mU", | ||
1114 | psraw_2 = "rmo:660FE1rM|rio:660F714mU", | ||
1115 | psrld_2 = "rmo:660FD2rM|rio:660F722mU", | ||
1116 | psrldq_2 = "rio:660F733mU", | ||
1117 | psrlq_2 = "rmo:660FD3rM|rio:660F732mU", | ||
1118 | psrlw_2 = "rmo:660FD1rM|rio:660F712mU", | ||
1119 | psubb_2 = "rmo:660FF8rM", | ||
1120 | psubd_2 = "rmo:660FFArM", | ||
1121 | psubq_2 = "rmo:660FFBrM", | ||
1122 | psubsb_2 = "rmo:660FE8rM", | ||
1123 | psubsw_2 = "rmo:660FE9rM", | ||
1124 | psubusb_2 = "rmo:660FD8rM", | ||
1125 | psubusw_2 = "rmo:660FD9rM", | ||
1126 | psubw_2 = "rmo:660FF9rM", | ||
1127 | punpckhbw_2 = "rmo:660F68rM", | ||
1128 | punpckhdq_2 = "rmo:660F6ArM", | ||
1129 | punpckhqdq_2 = "rmo:660F6DrM", | ||
1130 | punpckhwd_2 = "rmo:660F69rM", | ||
1131 | punpcklbw_2 = "rmo:660F60rM", | ||
1132 | punpckldq_2 = "rmo:660F62rM", | ||
1133 | punpcklqdq_2 = "rmo:660F6CrM", | ||
1134 | punpcklwd_2 = "rmo:660F61rM", | ||
1135 | pxor_2 = "rmo:660FEFrM", | ||
1136 | rcpps_2 = "rmo:0F53rM", | ||
1137 | rcpss_2 = "rmo:F30F53rM", | ||
1138 | rsqrtps_2 = "rmo:0F52rM", | ||
1139 | rsqrtss_2 = "rmo:F30F52rM", | ||
1140 | sfence_0 = "0FAEF8", | ||
1141 | shufpd_3 = "rmio:660FC6rMU", | ||
1142 | shufps_3 = "rmio:0FC6rMU", | ||
1143 | stmxcsr_1 = "xd:0FAE3m", | ||
1144 | ucomisd_2 = "rmo:660F2ErM", | ||
1145 | ucomiss_2 = "rmo:0F2ErM", | ||
1146 | unpckhpd_2 = "rmo:660F15rM", | ||
1147 | unpckhps_2 = "rmo:0F15rM", | ||
1148 | unpcklpd_2 = "rmo:660F14rM", | ||
1149 | unpcklps_2 = "rmo:0F14rM", | ||
1150 | xorpd_2 = "rmo:660F57rM", | ||
1151 | xorps_2 = "rmo:0F57rM", | ||
1152 | } | ||
1153 | |||
1154 | ------------------------------------------------------------------------------ | ||
1155 | |||
1156 | -- Arithmetic ops. | ||
1157 | for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3, | ||
1158 | ["and"] = 4, sub = 5, xor = 6, cmp = 7 } do | ||
1159 | local n8 = n * 8 | ||
1160 | map_op[name.."_2"] = format( | ||
1161 | "mr:%02XRm|rm:%02XrM|mI1dw:81%XmI|mS1dw:83%XmS|Ri1dwb:%02Xi|mi1dwb:81%Xmi", | ||
1162 | 1+n8, 3+n8, n, n, 5+n8, n) | ||
1163 | end | ||
1164 | |||
1165 | -- Shift ops. | ||
1166 | for name,n in pairs{ rol = 0, ror = 1, rcl = 2, rcr = 3, | ||
1167 | shl = 4, shr = 5, sar = 7, sal = 4 } do | ||
1168 | map_op[name.."_2"] = format("m1:D1%Xm|mC1dwb:D3%Xm|mi:C1%XmU", n, n, n) | ||
1169 | end | ||
1170 | |||
1171 | -- Conditional ops. | ||
1172 | for cc,n in pairs(map_cc) do | ||
1173 | map_op["j"..cc.."_1"] = format("J.:0F8%XJ", n) -- short: 7%X | ||
1174 | map_op["set"..cc.."_1"] = format("mb:n0F9%X2m", n) | ||
1175 | map_op["cmov"..cc.."_2"] = format("rmdw:0F4%XrM", n) -- P6+ | ||
1176 | end | ||
1177 | |||
1178 | -- FP arithmetic ops. | ||
1179 | for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3, | ||
1180 | sub = 4, subr = 5, div = 6, divr = 7 } do | ||
1181 | local nc = 192 + n * 8 | ||
1182 | local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8)) | ||
1183 | local fn = "f"..name | ||
1184 | map_op[fn.."_1"] = format("ff:D8%02Xr|xd:D8%Xm|xq:DC%Xm", nc, n, n) | ||
1185 | if n == 2 or n == 3 then | ||
1186 | map_op[fn.."_2"] = format("Fff:D8%02XR|Fx2d:D8%XM|Fx2q:DC%XM", nc, n, n) | ||
1187 | else | ||
1188 | map_op[fn.."_2"] = format("Fff:D8%02XR|fFf:DC%02Xr|Fx2d:D8%XM|Fx2q:DC%XM", nc, nr, n, n) | ||
1189 | map_op[fn.."p_1"] = format("ff:DE%02Xr", nr) | ||
1190 | map_op[fn.."p_2"] = format("fFf:DE%02Xr", nr) | ||
1191 | end | ||
1192 | map_op["fi"..name.."_1"] = format("xd:DA%Xm|xw:nDE%Xm", n, n) | ||
1193 | end | ||
1194 | |||
1195 | -- FP conditional moves. | ||
1196 | for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do | ||
1197 | local n4 = n % 4 | ||
1198 | local nc = 56000 + n4 * 8 + (n-n4) * 64 | ||
1199 | map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+ | ||
1200 | map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+ | ||
1201 | end | ||
1202 | |||
1203 | -- SSE FP arithmetic ops. | ||
1204 | for name,n in pairs{ sqrt = 1, add = 8, mul = 9, | ||
1205 | sub = 12, min = 13, div = 14, max = 15 } do | ||
1206 | map_op[name.."ps_2"] = format("rmo:0F5%XrM", n) | ||
1207 | map_op[name.."ss_2"] = format("rro:F30F5%XrM|rx/od:", n) | ||
1208 | map_op[name.."pd_2"] = format("rmo:660F5%XrM", n) | ||
1209 | map_op[name.."sd_2"] = format("rro:F20F5%XrM|rx/oq:", n) | ||
1210 | end | ||
1211 | |||
1212 | ------------------------------------------------------------------------------ | ||
1213 | |||
1214 | -- Process pattern string. | ||
1215 | local function dopattern(pat, args, sz, op) | ||
1216 | local digit, addin | ||
1217 | local opcode = 0 | ||
1218 | local szov = sz | ||
1219 | |||
1220 | -- Limit number of section buffer positions used by a single dasm_put(). | ||
1221 | -- A single opcode needs a maximum of 2 positions. !x64 | ||
1222 | if secpos+2 > maxsecpos then wflush() end | ||
1223 | |||
1224 | -- Process each character. | ||
1225 | for c in gmatch(pat, ".") do | ||
1226 | if match(c, "%x") then -- Hex digit. | ||
1227 | digit = byte(c) - 48 | ||
1228 | if digit > 48 then digit = digit - 39 | ||
1229 | elseif digit > 16 then digit = digit - 7 end | ||
1230 | opcode = opcode*16 + digit | ||
1231 | addin = nil | ||
1232 | elseif c == "n" then -- Disable operand size mods for opcode. | ||
1233 | szov = nil | ||
1234 | elseif c == "r" then -- Merge 1st operand regno. into opcode. | ||
1235 | addin = args[1].reg; opcode = opcode + addin | ||
1236 | elseif c == "R" then -- Merge 2nd operand regno. into opcode. | ||
1237 | addin = args[2].reg; opcode = opcode + addin | ||
1238 | elseif c == "m" or c == "M" then -- Encode ModRM/SIB. | ||
1239 | if addin then | ||
1240 | opcode = opcode - addin -- Undo regno opcode merge. | ||
1241 | else | ||
1242 | addin = opcode % 16 -- Undo last digit. | ||
1243 | opcode = (opcode - addin) / 16 | ||
1244 | end | ||
1245 | wputop(szov, opcode); opcode = nil | ||
1246 | local imark = (sub(pat, -1) == "I") -- Force a mark (ugly). | ||
1247 | -- Put ModRM/SIB with regno/last digit as spare. | ||
1248 | wputmrmsib(args[c == "m" and 1 or 2], addin, imark) | ||
1249 | else | ||
1250 | if opcode then wputop(szov, opcode); opcode = nil end -- Flush opcode. | ||
1251 | if c == "o" or c == "O" then -- Offset (pure 32 bit displacement). | ||
1252 | wputdarg(args[c == "o" and 1 or 2].disp) | ||
1253 | else | ||
1254 | -- Anything else is an immediate operand. | ||
1255 | local a = args[#args] | ||
1256 | local mode, imm = a.mode, a.imm | ||
1257 | if mode == "iJ" and not match("iIJ", c) then | ||
1258 | werror("bad operand size for label") | ||
1259 | end | ||
1260 | if c == "S" then | ||
1261 | wputsbarg(imm) | ||
1262 | elseif c == "U" then | ||
1263 | wputbarg(imm) | ||
1264 | elseif c == "W" then | ||
1265 | wputwarg(imm) | ||
1266 | elseif c == "i" or c == "I" then | ||
1267 | if mode == "iJ" then | ||
1268 | wputlabel("IMM_", imm, 1) | ||
1269 | elseif mode == "iI" and c == "I" then | ||
1270 | waction(sz == "w" and "IMM_WB" or "IMM_DB", imm) | ||
1271 | else | ||
1272 | wputszarg(sz, imm) | ||
1273 | end | ||
1274 | elseif c == "J" then | ||
1275 | if mode == "iPJ" then | ||
1276 | waction("REL_A", imm) -- !x64 (secpos) | ||
1277 | else | ||
1278 | wputlabel("REL_", imm, 2) | ||
1279 | end | ||
1280 | else | ||
1281 | werror("bad char `"..c.."' in pattern `"..pat.."' for `"..op.."'") | ||
1282 | end | ||
1283 | end | ||
1284 | end | ||
1285 | end | ||
1286 | if opcode then wputop(szov, opcode) end | ||
1287 | end | ||
1288 | |||
1289 | ------------------------------------------------------------------------------ | ||
1290 | |||
1291 | -- Mapping of operand modes to short names. Suppress output with '#'. | ||
1292 | local map_modename = { | ||
1293 | r = "reg", R = "eax", C = "cl", x = "mem", m = "mrm", i = "imm", | ||
1294 | f = "stx", F = "st0", J = "lbl", ["1"] = "1", | ||
1295 | I = "#", S = "#", O = "#", | ||
1296 | } | ||
1297 | |||
1298 | -- Return a table/string showing all possible operand modes. | ||
1299 | local function templatehelp(template, nparams) | ||
1300 | if nparams == 0 then return "" end | ||
1301 | local t = {} | ||
1302 | for tm in gmatch(template, "[^%|]+") do | ||
1303 | local s = map_modename[sub(tm, 1, 1)] | ||
1304 | s = s..gsub(sub(tm, 2, nparams), ".", function(c) | ||
1305 | return ", "..map_modename[c] | ||
1306 | end) | ||
1307 | if not match(s, "#") then t[#t+1] = s end | ||
1308 | end | ||
1309 | return t | ||
1310 | end | ||
1311 | |||
1312 | -- Match operand modes against mode match part of template. | ||
1313 | local function matchtm(tm, args) | ||
1314 | for i=1,#args do | ||
1315 | if not match(args[i].mode, sub(tm, i, i)) then return end | ||
1316 | end | ||
1317 | return true | ||
1318 | end | ||
1319 | |||
1320 | -- Handle opcodes defined with template strings. | ||
1321 | map_op[".template__"] = function(params, template, nparams) | ||
1322 | if not params then return templatehelp(template, nparams) end | ||
1323 | local args = {} | ||
1324 | |||
1325 | -- Zero-operand opcodes have no match part. | ||
1326 | if #params == 0 then | ||
1327 | dopattern(template, args, "d", params.op) | ||
1328 | return | ||
1329 | end | ||
1330 | |||
1331 | -- Determine common operand size (coerce undefined size) or flag as mixed. | ||
1332 | local sz, szmix | ||
1333 | for i,p in ipairs(params) do | ||
1334 | args[i] = parseoperand(p) | ||
1335 | local nsz = args[i].opsize | ||
1336 | if nsz then | ||
1337 | if sz and sz ~= nsz then szmix = true else sz = nsz end | ||
1338 | end | ||
1339 | end | ||
1340 | |||
1341 | -- Try all match:pattern pairs (separated by '|'). | ||
1342 | local gotmatch, lastpat | ||
1343 | for tm in gmatch(template, "[^%|]+") do | ||
1344 | -- Split off size match (starts after mode match) and pattern string. | ||
1345 | local szm, pat = match(tm, "^(.-):(.*)$", #args+1) | ||
1346 | if pat == "" then pat = lastpat else lastpat = pat end | ||
1347 | if matchtm(tm, args) then | ||
1348 | local prefix = sub(szm, 1, 1) | ||
1349 | if prefix == "/" then -- Match both operand sizes. | ||
1350 | if args[1].opsize == sub(szm, 2, 2) and | ||
1351 | args[2].opsize == sub(szm, 3, 3) then | ||
1352 | dopattern(pat, args, sz, params.op) -- Process pattern string. | ||
1353 | return | ||
1354 | end | ||
1355 | else -- Match common operand size. | ||
1356 | local szp = sz | ||
1357 | if szm == "" then szm = "dwb" end -- Default size match. | ||
1358 | if prefix == "1" then szp = args[1].opsize; szmix = nil | ||
1359 | elseif prefix == "2" then szp = args[2].opsize; szmix = nil end | ||
1360 | if not szmix and (prefix == "." or match(szm, szp or "#")) then | ||
1361 | dopattern(pat, args, szp, params.op) -- Process pattern string. | ||
1362 | return | ||
1363 | end | ||
1364 | end | ||
1365 | gotmatch = true | ||
1366 | end | ||
1367 | end | ||
1368 | |||
1369 | local msg = "bad operand mode" | ||
1370 | if gotmatch then | ||
1371 | if szmix then | ||
1372 | msg = "mixed operand size" | ||
1373 | else | ||
1374 | msg = sz and "bad operand size" or "missing operand size" | ||
1375 | end | ||
1376 | end | ||
1377 | |||
1378 | werror(msg.." in `"..opmodestr(params.op, args).."'") | ||
1379 | end | ||
1380 | |||
1381 | ------------------------------------------------------------------------------ | ||
1382 | |||
1383 | -- Pseudo-opcodes for data storage. | ||
1384 | local function op_data(params) | ||
1385 | if not params then return "imm..." end | ||
1386 | local sz = sub(params.op, 2, 2) | ||
1387 | if sz == "a" then sz = addrsize end | ||
1388 | for _,p in ipairs(params) do | ||
1389 | local a = parseoperand(p) | ||
1390 | if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then | ||
1391 | werror("bad mode or size in `"..p.."'") | ||
1392 | end | ||
1393 | if a.mode == "iJ" then | ||
1394 | wputlabel("IMM_", a.imm, 1) | ||
1395 | else | ||
1396 | wputszarg(sz, a.imm) | ||
1397 | end | ||
1398 | end | ||
1399 | end | ||
1400 | |||
1401 | map_op[".byte_*"] = op_data | ||
1402 | map_op[".sbyte_*"] = op_data | ||
1403 | map_op[".word_*"] = op_data | ||
1404 | map_op[".dword_*"] = op_data | ||
1405 | map_op[".aword_*"] = op_data | ||
1406 | |||
1407 | ------------------------------------------------------------------------------ | ||
1408 | |||
1409 | -- Pseudo-opcode to mark the position where the action list is to be emitted. | ||
1410 | map_op[".actionlist_1"] = function(params) | ||
1411 | if not params then return "cvar" end | ||
1412 | local name = params[1] -- No syntax check. You get to keep the pieces. | ||
1413 | wline(function(out) writeactions(out, name) end) | ||
1414 | end | ||
1415 | |||
1416 | -- Pseudo-opcode to mark the position where the global enum is to be emitted. | ||
1417 | map_op[".globals_1"] = function(params) | ||
1418 | if not params then return "prefix" end | ||
1419 | local prefix = params[1] -- No syntax check. You get to keep the pieces. | ||
1420 | wline(function(out) writeglobals(out, prefix) end) | ||
1421 | end | ||
1422 | |||
1423 | ------------------------------------------------------------------------------ | ||
1424 | |||
1425 | -- Label pseudo-opcode (converted from trailing colon form). | ||
1426 | map_op[".label_2"] = function(params) | ||
1427 | if not params then return "[1-9] | ->global | =>pcexpr [, addr]" end | ||
1428 | local a = parseoperand(params[1]) | ||
1429 | local mode, imm = a.mode, a.imm | ||
1430 | if type(imm) == "number" and (mode == "iJ" or (imm >= 1 and imm <= 9)) then | ||
1431 | -- Local label (1: ... 9:) or global label (->global:). | ||
1432 | waction("LABEL_LG", nil, 1) | ||
1433 | wputxb(imm) | ||
1434 | elseif mode == "iJ" then | ||
1435 | -- PC label (=>pcexpr:). | ||
1436 | waction("LABEL_PC", imm) | ||
1437 | else | ||
1438 | werror("bad label definition") | ||
1439 | end | ||
1440 | -- SETLABEL must immediately follow LABEL_LG/LABEL_PC. | ||
1441 | local addr = params[2] | ||
1442 | if addr then | ||
1443 | local a = parseoperand(params[2]) | ||
1444 | if a.mode == "iPJ" then | ||
1445 | waction("SETLABEL", a.imm) -- !x64 (secpos) | ||
1446 | else | ||
1447 | werror("bad label assignment") | ||
1448 | end | ||
1449 | end | ||
1450 | end | ||
1451 | map_op[".label_1"] = map_op[".label_2"] | ||
1452 | |||
1453 | ------------------------------------------------------------------------------ | ||
1454 | |||
1455 | -- Alignment pseudo-opcode. | ||
1456 | map_op[".align_1"] = function(params) | ||
1457 | if not params then return "numpow2" end | ||
1458 | local align = tonumber(params[1]) or map_opsizenum[map_opsize[params[1]]] | ||
1459 | if align then | ||
1460 | local x = align | ||
1461 | -- Must be a power of 2 in the range (2 ... 256). | ||
1462 | for i=1,8 do | ||
1463 | x = x / 2 | ||
1464 | if x == 1 then | ||
1465 | waction("ALIGN", nil, 1) | ||
1466 | wputxb(align-1) -- Action byte is 2**n-1. | ||
1467 | return | ||
1468 | end | ||
1469 | end | ||
1470 | end | ||
1471 | werror("bad alignment") | ||
1472 | end | ||
1473 | |||
1474 | -- Spacing pseudo-opcode. | ||
1475 | map_op[".space_2"] = function(params) | ||
1476 | if not params then return "num [, filler]" end | ||
1477 | waction("SPACE", params[1]) | ||
1478 | local fill = params[2] | ||
1479 | if fill then | ||
1480 | fill = tonumber(fill) | ||
1481 | if not fill or fill < 0 or fill > 255 then werror("bad filler") end | ||
1482 | end | ||
1483 | wputxb(fill or 0) | ||
1484 | end | ||
1485 | map_op[".space_1"] = map_op[".space_2"] | ||
1486 | |||
1487 | ------------------------------------------------------------------------------ | ||
1488 | |||
1489 | -- Pseudo-opcode for (primitive) type definitions (map to C types). | ||
1490 | map_op[".type_3"] = function(params, nparams) | ||
1491 | if not params then | ||
1492 | return nparams == 2 and "name, ctype" or "name, ctype, reg" | ||
1493 | end | ||
1494 | local name, ctype, reg = params[1], params[2], params[3] | ||
1495 | if not match(name, "^[%a_][%w_]*$") then | ||
1496 | werror("bad type name `"..name.."'") | ||
1497 | end | ||
1498 | local tp = map_type[name] | ||
1499 | if tp then | ||
1500 | werror("duplicate type `"..name.."'") | ||
1501 | end | ||
1502 | if reg and not map_reg_valid_base[reg] then | ||
1503 | werror("bad base register `"..(map_reg_rev[reg] or reg).."'") | ||
1504 | end | ||
1505 | -- Add #type to defines. A bit unclean to put it in map_archdef. | ||
1506 | map_archdef["#"..name] = "sizeof("..ctype..")" | ||
1507 | -- Add new type and emit shortcut define. | ||
1508 | local num = ctypenum + 1 | ||
1509 | map_type[name] = { | ||
1510 | ctype = ctype, | ||
1511 | ctypefmt = format("Dt%X(%%s)", num), | ||
1512 | reg = reg, | ||
1513 | } | ||
1514 | wline(format("#define Dt%X(_V) (int)&(((%s *)0)_V)", num, ctype)) | ||
1515 | ctypenum = num | ||
1516 | end | ||
1517 | map_op[".type_2"] = map_op[".type_3"] | ||
1518 | |||
1519 | -- Dump type definitions. | ||
1520 | local function dumptypes(out, lvl) | ||
1521 | local t = {} | ||
1522 | for name in pairs(map_type) do t[#t+1] = name end | ||
1523 | sort(t) | ||
1524 | out:write("Type definitions:\n") | ||
1525 | for _,name in ipairs(t) do | ||
1526 | local tp = map_type[name] | ||
1527 | local reg = tp.reg and map_reg_rev[tp.reg] or "" | ||
1528 | out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg)) | ||
1529 | end | ||
1530 | out:write("\n") | ||
1531 | end | ||
1532 | |||
1533 | ------------------------------------------------------------------------------ | ||
1534 | |||
1535 | -- Set the current section. | ||
1536 | function _M.section(num) | ||
1537 | waction("SECTION") | ||
1538 | wputxb(num) | ||
1539 | wflush(true) -- SECTION is a terminal action. | ||
1540 | end | ||
1541 | |||
1542 | ------------------------------------------------------------------------------ | ||
1543 | |||
1544 | -- Dump architecture description. | ||
1545 | function _M.dumparch(out) | ||
1546 | out:write(format("DynASM %s version %s, released %s\n\n", | ||
1547 | _info.arch, _info.version, _info.release)) | ||
1548 | dumpregs(out) | ||
1549 | dumpactions(out) | ||
1550 | end | ||
1551 | |||
1552 | -- Dump all user defined elements. | ||
1553 | function _M.dumpdef(out, lvl) | ||
1554 | dumptypes(out, lvl) | ||
1555 | dumpglobals(out, lvl) | ||
1556 | end | ||
1557 | |||
1558 | ------------------------------------------------------------------------------ | ||
1559 | |||
1560 | -- Pass callbacks from/to the DynASM core. | ||
1561 | function _M.passcb(wl, we, wf, ww) | ||
1562 | wline, werror, wfatal, wwarn = wl, we, wf, ww | ||
1563 | return wflush | ||
1564 | end | ||
1565 | |||
1566 | -- Setup the arch-specific module. | ||
1567 | function _M.setup(arch, opt) | ||
1568 | g_arch, g_opt = arch, opt | ||
1569 | end | ||
1570 | |||
1571 | -- Merge the core maps and the arch-specific maps. | ||
1572 | function _M.mergemaps(map_coreop, map_def) | ||
1573 | setmetatable(map_op, { __index = map_coreop }) | ||
1574 | setmetatable(map_def, { __index = map_archdef }) | ||
1575 | return map_op, map_def | ||
1576 | end | ||
1577 | |||
1578 | return _M | ||
1579 | |||
1580 | ------------------------------------------------------------------------------ | ||
1581 | |||
diff --git a/libraries/LuaJIT-1.1.7/dynasm/dynasm.lua b/libraries/LuaJIT-1.1.7/dynasm/dynasm.lua new file mode 100644 index 0000000..264a4bb --- /dev/null +++ b/libraries/LuaJIT-1.1.7/dynasm/dynasm.lua | |||
@@ -0,0 +1,1070 @@ | |||
1 | ------------------------------------------------------------------------------ | ||
2 | -- DynASM. A dynamic assembler for code generation engines. | ||
3 | -- Originally designed and implemented for LuaJIT. | ||
4 | -- | ||
5 | -- Copyright (C) 2005-2008 Mike Pall. All rights reserved. | ||
6 | -- See below for full copyright notice. | ||
7 | ------------------------------------------------------------------------------ | ||
8 | |||
9 | -- Application information. | ||
10 | local _info = { | ||
11 | name = "DynASM", | ||
12 | description = "A dynamic assembler for code generation engines", | ||
13 | version = "1.1.4", | ||
14 | vernum = 10104, | ||
15 | release = "2008-01-29", | ||
16 | author = "Mike Pall", | ||
17 | url = "http://luajit.org/dynasm.html", | ||
18 | license = "MIT", | ||
19 | copyright = [[ | ||
20 | Copyright (C) 2005-2008 Mike Pall. All rights reserved. | ||
21 | |||
22 | Permission is hereby granted, free of charge, to any person obtaining | ||
23 | a copy of this software and associated documentation files (the | ||
24 | "Software"), to deal in the Software without restriction, including | ||
25 | without limitation the rights to use, copy, modify, merge, publish, | ||
26 | distribute, sublicense, and/or sell copies of the Software, and to | ||
27 | permit persons to whom the Software is furnished to do so, subject to | ||
28 | the following conditions: | ||
29 | |||
30 | The above copyright notice and this permission notice shall be | ||
31 | included in all copies or substantial portions of the Software. | ||
32 | |||
33 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
34 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
35 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
36 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
37 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
38 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
39 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
40 | |||
41 | [ MIT license: http://www.opensource.org/licenses/mit-license.php ] | ||
42 | ]], | ||
43 | } | ||
44 | |||
45 | -- Cache library functions. | ||
46 | local type, pairs, ipairs = type, pairs, ipairs | ||
47 | local pcall, error, assert = pcall, error, assert | ||
48 | local _s = string | ||
49 | local sub, match, gmatch, gsub = _s.sub, _s.match, _s.gmatch, _s.gsub | ||
50 | local format, rep, upper = _s.format, _s.rep, _s.upper | ||
51 | local _t = table | ||
52 | local insert, remove, concat, sort = _t.insert, _t.remove, _t.concat, _t.sort | ||
53 | local exit = os.exit | ||
54 | local io = io | ||
55 | local stdin, stdout, stderr = io.stdin, io.stdout, io.stderr | ||
56 | |||
57 | ------------------------------------------------------------------------------ | ||
58 | |||
59 | -- Program options. | ||
60 | local g_opt = {} | ||
61 | |||
62 | -- Global state for current file. | ||
63 | local g_fname, g_curline, g_indent, g_lineno, g_synclineno, g_arch | ||
64 | local g_errcount = 0 | ||
65 | |||
66 | -- Write buffer for output file. | ||
67 | local g_wbuffer, g_capbuffer | ||
68 | |||
69 | ------------------------------------------------------------------------------ | ||
70 | |||
71 | -- Write an output line (or callback function) to the buffer. | ||
72 | local function wline(line, needindent) | ||
73 | local buf = g_capbuffer or g_wbuffer | ||
74 | buf[#buf+1] = needindent and g_indent..line or line | ||
75 | g_synclineno = g_synclineno + 1 | ||
76 | end | ||
77 | |||
78 | -- Write assembler line as a comment, if requestd. | ||
79 | local function wcomment(aline) | ||
80 | if g_opt.comment then | ||
81 | wline(g_opt.comment..aline..g_opt.endcomment, true) | ||
82 | end | ||
83 | end | ||
84 | |||
85 | -- Resync CPP line numbers. | ||
86 | local function wsync() | ||
87 | if g_synclineno ~= g_lineno and g_opt.cpp then | ||
88 | wline("# "..g_lineno..' "'..g_fname..'"') | ||
89 | g_synclineno = g_lineno | ||
90 | end | ||
91 | end | ||
92 | |||
93 | -- Dummy action flush function. Replaced with arch-specific function later. | ||
94 | local function wflush(term) | ||
95 | end | ||
96 | |||
97 | -- Dump all buffered output lines. | ||
98 | local function wdumplines(out, buf) | ||
99 | for _,line in ipairs(buf) do | ||
100 | if type(line) == "string" then | ||
101 | assert(out:write(line, "\n")) | ||
102 | else | ||
103 | -- Special callback to dynamically insert lines after end of processing. | ||
104 | line(out) | ||
105 | end | ||
106 | end | ||
107 | end | ||
108 | |||
109 | ------------------------------------------------------------------------------ | ||
110 | |||
111 | -- Emit an error. Processing continues with next statement. | ||
112 | local function werror(msg) | ||
113 | error(format("%s:%s: error: %s:\n%s", g_fname, g_lineno, msg, g_curline), 0) | ||
114 | end | ||
115 | |||
116 | -- Emit a fatal error. Processing stops. | ||
117 | local function wfatal(msg) | ||
118 | g_errcount = "fatal" | ||
119 | werror(msg) | ||
120 | end | ||
121 | |||
122 | -- Print a warning. Processing continues. | ||
123 | local function wwarn(msg) | ||
124 | stderr:write(format("%s:%s: warning: %s:\n%s\n", | ||
125 | g_fname, g_lineno, msg, g_curline)) | ||
126 | end | ||
127 | |||
128 | -- Print caught error message. But suppress excessive errors. | ||
129 | local function wprinterr(...) | ||
130 | if type(g_errcount) == "number" then | ||
131 | -- Regular error. | ||
132 | g_errcount = g_errcount + 1 | ||
133 | if g_errcount < 21 then -- Seems to be a reasonable limit. | ||
134 | stderr:write(...) | ||
135 | elseif g_errcount == 21 then | ||
136 | stderr:write(g_fname, | ||
137 | ":*: warning: too many errors (suppressed further messages).\n") | ||
138 | end | ||
139 | else | ||
140 | -- Fatal error. | ||
141 | stderr:write(...) | ||
142 | return true -- Stop processing. | ||
143 | end | ||
144 | end | ||
145 | |||
146 | ------------------------------------------------------------------------------ | ||
147 | |||
148 | -- Map holding all option handlers. | ||
149 | local opt_map = {} | ||
150 | local opt_current | ||
151 | |||
152 | -- Print error and exit with error status. | ||
153 | local function opterror(...) | ||
154 | stderr:write("dynasm.lua: ERROR: ", ...) | ||
155 | stderr:write("\n") | ||
156 | exit(1) | ||
157 | end | ||
158 | |||
159 | -- Get option parameter. | ||
160 | local function optparam(args) | ||
161 | local argn = args.argn | ||
162 | local p = args[argn] | ||
163 | if not p then | ||
164 | opterror("missing parameter for option `", opt_current, "'.") | ||
165 | end | ||
166 | args.argn = argn + 1 | ||
167 | return p | ||
168 | end | ||
169 | |||
170 | ------------------------------------------------------------------------------ | ||
171 | |||
172 | -- Core pseudo-opcodes. | ||
173 | local map_coreop = {} | ||
174 | -- Dummy opcode map. Replaced by arch-specific map. | ||
175 | local map_op = {} | ||
176 | |||
177 | -- Forward declarations. | ||
178 | local dostmt | ||
179 | local readfile | ||
180 | |||
181 | ------------------------------------------------------------------------------ | ||
182 | |||
183 | -- Map for defines (initially empty, chains to arch-specific map). | ||
184 | local map_def = {} | ||
185 | |||
186 | -- Pseudo-opcode to define a substitution. | ||
187 | map_coreop[".define_2"] = function(params, nparams) | ||
188 | if not params then return nparams == 1 and "name" or "name, subst" end | ||
189 | local name, def = params[1], params[2] or "1" | ||
190 | if not match(name, "^[%a_][%w_]*$") then werror("bad or duplicate define") end | ||
191 | map_def[name] = def | ||
192 | end | ||
193 | map_coreop[".define_1"] = map_coreop[".define_2"] | ||
194 | |||
195 | -- Define a substitution on the command line. | ||
196 | function opt_map.D(args) | ||
197 | local namesubst = optparam(args) | ||
198 | local name, subst = match(namesubst, "^([%a_][%w_]*)=(.*)$") | ||
199 | if name then | ||
200 | map_def[name] = subst | ||
201 | elseif match(namesubst, "^[%a_][%w_]*$") then | ||
202 | map_def[namesubst] = "1" | ||
203 | else | ||
204 | opterror("bad define") | ||
205 | end | ||
206 | end | ||
207 | |||
208 | -- Undefine a substitution on the command line. | ||
209 | function opt_map.U(args) | ||
210 | local name = optparam(args) | ||
211 | if match(name, "^[%a_][%w_]*$") then | ||
212 | map_def[name] = nil | ||
213 | else | ||
214 | opterror("bad define") | ||
215 | end | ||
216 | end | ||
217 | |||
218 | -- Helper for definesubst. | ||
219 | local gotsubst | ||
220 | |||
221 | local function definesubst_one(word) | ||
222 | local subst = map_def[word] | ||
223 | if subst then gotsubst = word; return subst else return word end | ||
224 | end | ||
225 | |||
226 | -- Iteratively substitute defines. | ||
227 | local function definesubst(stmt) | ||
228 | -- Limit number of iterations. | ||
229 | for i=1,100 do | ||
230 | gotsubst = false | ||
231 | stmt = gsub(stmt, "#?[%w_]+", definesubst_one) | ||
232 | if not gotsubst then break end | ||
233 | end | ||
234 | if gotsubst then wfatal("recursive define involving `"..gotsubst.."'") end | ||
235 | return stmt | ||
236 | end | ||
237 | |||
238 | -- Dump all defines. | ||
239 | local function dumpdefines(out, lvl) | ||
240 | local t = {} | ||
241 | for name in pairs(map_def) do | ||
242 | t[#t+1] = name | ||
243 | end | ||
244 | sort(t) | ||
245 | out:write("Defines:\n") | ||
246 | for _,name in ipairs(t) do | ||
247 | local subst = map_def[name] | ||
248 | if g_arch then subst = g_arch.revdef(subst) end | ||
249 | out:write(format(" %-20s %s\n", name, subst)) | ||
250 | end | ||
251 | out:write("\n") | ||
252 | end | ||
253 | |||
254 | ------------------------------------------------------------------------------ | ||
255 | |||
256 | -- Support variables for conditional assembly. | ||
257 | local condlevel = 0 | ||
258 | local condstack = {} | ||
259 | |||
260 | -- Evaluate condition with a Lua expression. Substitutions already performed. | ||
261 | local function cond_eval(cond) | ||
262 | local func, err = loadstring("return "..cond) | ||
263 | if func then | ||
264 | setfenv(func, {}) -- No globals. All unknown identifiers evaluate to nil. | ||
265 | local ok, res = pcall(func) | ||
266 | if ok then | ||
267 | if res == 0 then return false end -- Oh well. | ||
268 | return not not res | ||
269 | end | ||
270 | err = res | ||
271 | end | ||
272 | wfatal("bad condition: "..err) | ||
273 | end | ||
274 | |||
275 | -- Skip statements until next conditional pseudo-opcode at the same level. | ||
276 | local function stmtskip() | ||
277 | local dostmt_save = dostmt | ||
278 | local lvl = 0 | ||
279 | dostmt = function(stmt) | ||
280 | local op = match(stmt, "^%s*(%S+)") | ||
281 | if op == ".if" then | ||
282 | lvl = lvl + 1 | ||
283 | elseif lvl ~= 0 then | ||
284 | if op == ".endif" then lvl = lvl - 1 end | ||
285 | elseif op == ".elif" or op == ".else" or op == ".endif" then | ||
286 | dostmt = dostmt_save | ||
287 | dostmt(stmt) | ||
288 | end | ||
289 | end | ||
290 | end | ||
291 | |||
292 | -- Pseudo-opcodes for conditional assembly. | ||
293 | map_coreop[".if_1"] = function(params) | ||
294 | if not params then return "condition" end | ||
295 | local lvl = condlevel + 1 | ||
296 | local res = cond_eval(params[1]) | ||
297 | condlevel = lvl | ||
298 | condstack[lvl] = res | ||
299 | if not res then stmtskip() end | ||
300 | end | ||
301 | |||
302 | map_coreop[".elif_1"] = function(params) | ||
303 | if not params then return "condition" end | ||
304 | if condlevel == 0 then wfatal(".elif without .if") end | ||
305 | local lvl = condlevel | ||
306 | local res = condstack[lvl] | ||
307 | if res then | ||
308 | if res == "else" then wfatal(".elif after .else") end | ||
309 | else | ||
310 | res = cond_eval(params[1]) | ||
311 | if res then | ||
312 | condstack[lvl] = res | ||
313 | return | ||
314 | end | ||
315 | end | ||
316 | stmtskip() | ||
317 | end | ||
318 | |||
319 | map_coreop[".else_0"] = function(params) | ||
320 | if condlevel == 0 then wfatal(".else without .if") end | ||
321 | local lvl = condlevel | ||
322 | local res = condstack[lvl] | ||
323 | condstack[lvl] = "else" | ||
324 | if res then | ||
325 | if res == "else" then wfatal(".else after .else") end | ||
326 | stmtskip() | ||
327 | end | ||
328 | end | ||
329 | |||
330 | map_coreop[".endif_0"] = function(params) | ||
331 | local lvl = condlevel | ||
332 | if lvl == 0 then wfatal(".endif without .if") end | ||
333 | condlevel = lvl - 1 | ||
334 | end | ||
335 | |||
336 | -- Check for unfinished conditionals. | ||
337 | local function checkconds() | ||
338 | if g_errcount ~= "fatal" and condlevel ~= 0 then | ||
339 | wprinterr(g_fname, ":*: error: unbalanced conditional\n") | ||
340 | end | ||
341 | end | ||
342 | |||
343 | ------------------------------------------------------------------------------ | ||
344 | |||
345 | -- Search for a file in the given path and open it for reading. | ||
346 | local function pathopen(path, name) | ||
347 | local dirsep = match(package.path, "\\") and "\\" or "/" | ||
348 | for _,p in ipairs(path) do | ||
349 | local fullname = p == "" and name or p..dirsep..name | ||
350 | local fin = io.open(fullname, "r") | ||
351 | if fin then | ||
352 | g_fname = fullname | ||
353 | return fin | ||
354 | end | ||
355 | end | ||
356 | end | ||
357 | |||
358 | -- Include a file. | ||
359 | map_coreop[".include_1"] = function(params) | ||
360 | if not params then return "filename" end | ||
361 | local name = params[1] | ||
362 | -- Save state. Ugly, I know. but upvalues are fast. | ||
363 | local gf, gl, gcl, gi = g_fname, g_lineno, g_curline, g_indent | ||
364 | -- Read the included file. | ||
365 | local fatal = readfile(pathopen(g_opt.include, name) or | ||
366 | wfatal("include file `"..name.."' not found")) | ||
367 | -- Restore state. | ||
368 | g_synclineno = -1 | ||
369 | g_fname, g_lineno, g_curline, g_indent = gf, gl, gcl, gi | ||
370 | if fatal then wfatal("in include file") end | ||
371 | end | ||
372 | |||
373 | -- Make .include initially available, too. | ||
374 | map_op[".include_1"] = map_coreop[".include_1"] | ||
375 | |||
376 | ------------------------------------------------------------------------------ | ||
377 | |||
378 | -- Support variables for macros. | ||
379 | local mac_capture, mac_lineno, mac_name | ||
380 | local mac_active = {} | ||
381 | local mac_list = {} | ||
382 | |||
383 | -- Pseudo-opcode to define a macro. | ||
384 | map_coreop[".macro_*"] = function(mparams) | ||
385 | if not mparams then return "name [, params...]" end | ||
386 | -- Split off and validate macro name. | ||
387 | local name = remove(mparams, 1) | ||
388 | if not name then werror("missing macro name") end | ||
389 | if not (match(name, "^[%a_][%w_%.]*$") or match(name, "^%.[%w_%.]+$")) then | ||
390 | wfatal("bad macro name `"..name.."'") | ||
391 | end | ||
392 | -- Validate macro parameter names. | ||
393 | local mdup = {} | ||
394 | for _,mp in ipairs(mparams) do | ||
395 | if not match(mp, "^[%a_][%w_]*$") then | ||
396 | wfatal("bad macro parameter name `"..mp.."'") | ||
397 | end | ||
398 | if mdup[mp] then wfatal("duplicate macro parameter name `"..mp.."'") end | ||
399 | mdup[mp] = true | ||
400 | end | ||
401 | -- Check for duplicate or recursive macro definitions. | ||
402 | local opname = name.."_"..#mparams | ||
403 | if map_op[opname] or map_op[name.."_*"] then | ||
404 | wfatal("duplicate macro `"..name.."' ("..#mparams.." parameters)") | ||
405 | end | ||
406 | if mac_capture then wfatal("recursive macro definition") end | ||
407 | |||
408 | -- Enable statement capture. | ||
409 | local lines = {} | ||
410 | mac_lineno = g_lineno | ||
411 | mac_name = name | ||
412 | mac_capture = function(stmt) -- Statement capture function. | ||
413 | -- Stop macro definition with .endmacro pseudo-opcode. | ||
414 | if not match(stmt, "^%s*.endmacro%s*$") then | ||
415 | lines[#lines+1] = stmt | ||
416 | return | ||
417 | end | ||
418 | mac_capture = nil | ||
419 | mac_lineno = nil | ||
420 | mac_name = nil | ||
421 | mac_list[#mac_list+1] = opname | ||
422 | -- Add macro-op definition. | ||
423 | map_op[opname] = function(params) | ||
424 | if not params then return mparams, lines end | ||
425 | -- Protect against recursive macro invocation. | ||
426 | if mac_active[opname] then wfatal("recursive macro invocation") end | ||
427 | mac_active[opname] = true | ||
428 | -- Setup substitution map. | ||
429 | local subst = {} | ||
430 | for i,mp in ipairs(mparams) do subst[mp] = params[i] end | ||
431 | local mcom | ||
432 | if g_opt.maccomment and g_opt.comment then | ||
433 | mcom = " MACRO "..name.." ("..#mparams..")" | ||
434 | wcomment("{"..mcom) | ||
435 | end | ||
436 | -- Loop through all captured statements | ||
437 | for _,stmt in ipairs(lines) do | ||
438 | -- Substitute macro parameters. | ||
439 | local st = gsub(stmt, "[%w_]+", subst) | ||
440 | st = definesubst(st) | ||
441 | st = gsub(st, "%s*%.%.%s*", "") -- Token paste a..b. | ||
442 | if mcom and sub(st, 1, 1) ~= "|" then wcomment(st) end | ||
443 | -- Emit statement. Use a protected call for better diagnostics. | ||
444 | local ok, err = pcall(dostmt, st) | ||
445 | if not ok then | ||
446 | -- Add the captured statement to the error. | ||
447 | wprinterr(err, "\n", g_indent, "| ", stmt, | ||
448 | "\t[MACRO ", name, " (", #mparams, ")]\n") | ||
449 | end | ||
450 | end | ||
451 | if mcom then wcomment("}"..mcom) end | ||
452 | mac_active[opname] = nil | ||
453 | end | ||
454 | end | ||
455 | end | ||
456 | |||
457 | -- An .endmacro pseudo-opcode outside of a macro definition is an error. | ||
458 | map_coreop[".endmacro_0"] = function(params) | ||
459 | wfatal(".endmacro without .macro") | ||
460 | end | ||
461 | |||
462 | -- Dump all macros and their contents (with -PP only). | ||
463 | local function dumpmacros(out, lvl) | ||
464 | sort(mac_list) | ||
465 | out:write("Macros:\n") | ||
466 | for _,opname in ipairs(mac_list) do | ||
467 | local name = sub(opname, 1, -3) | ||
468 | local params, lines = map_op[opname]() | ||
469 | out:write(format(" %-20s %s\n", name, concat(params, ", "))) | ||
470 | if lvl > 1 then | ||
471 | for _,line in ipairs(lines) do | ||
472 | out:write(" |", line, "\n") | ||
473 | end | ||
474 | out:write("\n") | ||
475 | end | ||
476 | end | ||
477 | out:write("\n") | ||
478 | end | ||
479 | |||
480 | -- Check for unfinished macro definitions. | ||
481 | local function checkmacros() | ||
482 | if mac_capture then | ||
483 | wprinterr(g_fname, ":", mac_lineno, | ||
484 | ": error: unfinished .macro `", mac_name ,"'\n") | ||
485 | end | ||
486 | end | ||
487 | |||
488 | ------------------------------------------------------------------------------ | ||
489 | |||
490 | -- Support variables for captures. | ||
491 | local cap_lineno, cap_name | ||
492 | local cap_buffers = {} | ||
493 | local cap_used = {} | ||
494 | |||
495 | -- Start a capture. | ||
496 | map_coreop[".capture_1"] = function(params) | ||
497 | if not params then return "name" end | ||
498 | wflush() | ||
499 | local name = params[1] | ||
500 | if not match(name, "^[%a_][%w_]*$") then | ||
501 | wfatal("bad capture name `"..name.."'") | ||
502 | end | ||
503 | if cap_name then | ||
504 | wfatal("already capturing to `"..cap_name.."' since line "..cap_lineno) | ||
505 | end | ||
506 | cap_name = name | ||
507 | cap_lineno = g_lineno | ||
508 | -- Create or continue a capture buffer and start the output line capture. | ||
509 | local buf = cap_buffers[name] | ||
510 | if not buf then buf = {}; cap_buffers[name] = buf end | ||
511 | g_capbuffer = buf | ||
512 | g_synclineno = 0 | ||
513 | end | ||
514 | |||
515 | -- Stop a capture. | ||
516 | map_coreop[".endcapture_0"] = function(params) | ||
517 | wflush() | ||
518 | if not cap_name then wfatal(".endcapture without a valid .capture") end | ||
519 | cap_name = nil | ||
520 | cap_lineno = nil | ||
521 | g_capbuffer = nil | ||
522 | g_synclineno = 0 | ||
523 | end | ||
524 | |||
525 | -- Dump a capture buffer. | ||
526 | map_coreop[".dumpcapture_1"] = function(params) | ||
527 | if not params then return "name" end | ||
528 | wflush() | ||
529 | local name = params[1] | ||
530 | if not match(name, "^[%a_][%w_]*$") then | ||
531 | wfatal("bad capture name `"..name.."'") | ||
532 | end | ||
533 | cap_used[name] = true | ||
534 | wline(function(out) | ||
535 | local buf = cap_buffers[name] | ||
536 | if buf then wdumplines(out, buf) end | ||
537 | end) | ||
538 | g_synclineno = 0 | ||
539 | end | ||
540 | |||
541 | -- Dump all captures and their buffers (with -PP only). | ||
542 | local function dumpcaptures(out, lvl) | ||
543 | out:write("Captures:\n") | ||
544 | for name,buf in pairs(cap_buffers) do | ||
545 | out:write(format(" %-20s %4s)\n", name, "("..#buf)) | ||
546 | if lvl > 1 then | ||
547 | local bar = rep("=", 76) | ||
548 | out:write(" ", bar, "\n") | ||
549 | for _,line in ipairs(buf) do | ||
550 | out:write(" ", line, "\n") | ||
551 | end | ||
552 | out:write(" ", bar, "\n\n") | ||
553 | end | ||
554 | end | ||
555 | out:write("\n") | ||
556 | end | ||
557 | |||
558 | -- Check for unfinished or unused captures. | ||
559 | local function checkcaptures() | ||
560 | if cap_name then | ||
561 | wprinterr(g_fname, ":", cap_lineno, | ||
562 | ": error: unfinished .capture `", cap_name,"'\n") | ||
563 | return | ||
564 | end | ||
565 | for name in pairs(cap_buffers) do | ||
566 | if not cap_used[name] then | ||
567 | wprinterr(g_fname, ":*: error: missing .dumpcapture ", name ,"\n") | ||
568 | end | ||
569 | end | ||
570 | end | ||
571 | |||
572 | ------------------------------------------------------------------------------ | ||
573 | |||
574 | -- Sections names. | ||
575 | local map_sections = {} | ||
576 | |||
577 | -- Pseudo-opcode to define code sections. | ||
578 | -- TODO: Data sections, BSS sections. Needs extra C code and API. | ||
579 | map_coreop[".section_*"] = function(params) | ||
580 | if not params then return "name..." end | ||
581 | if #map_sections > 0 then werror("duplicate section definition") end | ||
582 | wflush() | ||
583 | for sn,name in ipairs(params) do | ||
584 | local opname = "."..name.."_0" | ||
585 | if not match(name, "^[%a][%w_]*$") or | ||
586 | map_op[opname] or map_op["."..name.."_*"] then | ||
587 | werror("bad section name `"..name.."'") | ||
588 | end | ||
589 | map_sections[#map_sections+1] = name | ||
590 | wline(format("#define DASM_SECTION_%s\t%d", upper(name), sn-1)) | ||
591 | map_op[opname] = function(params) g_arch.section(sn-1) end | ||
592 | end | ||
593 | wline(format("#define DASM_MAXSECTION\t\t%d", #map_sections)) | ||
594 | end | ||
595 | |||
596 | -- Dump all sections. | ||
597 | local function dumpsections(out, lvl) | ||
598 | out:write("Sections:\n") | ||
599 | for _,name in ipairs(map_sections) do | ||
600 | out:write(format(" %s\n", name)) | ||
601 | end | ||
602 | out:write("\n") | ||
603 | end | ||
604 | |||
605 | ------------------------------------------------------------------------------ | ||
606 | |||
607 | -- Load architecture-specific module. | ||
608 | local function loadarch(arch) | ||
609 | if not match(arch, "^[%w_]+$") then return "bad arch name" end | ||
610 | local ok, m_arch = pcall(require, "dasm_"..arch) | ||
611 | if not ok then return "cannot load module: "..m_arch end | ||
612 | g_arch = m_arch | ||
613 | wflush = m_arch.passcb(wline, werror, wfatal, wwarn) | ||
614 | m_arch.setup(arch, g_opt) | ||
615 | map_op, map_def = m_arch.mergemaps(map_coreop, map_def) | ||
616 | end | ||
617 | |||
618 | -- Dump architecture description. | ||
619 | function opt_map.dumparch(args) | ||
620 | local name = optparam(args) | ||
621 | if not g_arch then | ||
622 | local err = loadarch(name) | ||
623 | if err then opterror(err) end | ||
624 | end | ||
625 | |||
626 | local t = {} | ||
627 | for name in pairs(map_coreop) do t[#t+1] = name end | ||
628 | for name in pairs(map_op) do t[#t+1] = name end | ||
629 | sort(t) | ||
630 | |||
631 | local out = stdout | ||
632 | local _arch = g_arch._info | ||
633 | out:write(format("%s version %s, released %s, %s\n", | ||
634 | _info.name, _info.version, _info.release, _info.url)) | ||
635 | g_arch.dumparch(out) | ||
636 | |||
637 | local pseudo = true | ||
638 | out:write("Pseudo-Opcodes:\n") | ||
639 | for _,sname in ipairs(t) do | ||
640 | local name, nparam = match(sname, "^(.+)_([0-9%*])$") | ||
641 | if name then | ||
642 | if pseudo and sub(name, 1, 1) ~= "." then | ||
643 | out:write("\nOpcodes:\n") | ||
644 | pseudo = false | ||
645 | end | ||
646 | local f = map_op[sname] | ||
647 | local s | ||
648 | if nparam ~= "*" then nparam = nparam + 0 end | ||
649 | if nparam == 0 then | ||
650 | s = "" | ||
651 | elseif type(f) == "string" then | ||
652 | s = map_op[".template__"](nil, f, nparam) | ||
653 | else | ||
654 | s = f(nil, nparam) | ||
655 | end | ||
656 | if type(s) == "table" then | ||
657 | for _,s2 in ipairs(s) do | ||
658 | out:write(format(" %-12s %s\n", name, s2)) | ||
659 | end | ||
660 | else | ||
661 | out:write(format(" %-12s %s\n", name, s)) | ||
662 | end | ||
663 | end | ||
664 | end | ||
665 | out:write("\n") | ||
666 | exit(0) | ||
667 | end | ||
668 | |||
669 | -- Pseudo-opcode to set the architecture. | ||
670 | -- Only initially available (map_op is replaced when called). | ||
671 | map_op[".arch_1"] = function(params) | ||
672 | if not params then return "name" end | ||
673 | local err = loadarch(params[1]) | ||
674 | if err then wfatal(err) end | ||
675 | end | ||
676 | |||
677 | -- Dummy .arch pseudo-opcode to improve the error report. | ||
678 | map_coreop[".arch_1"] = function(params) | ||
679 | if not params then return "name" end | ||
680 | wfatal("duplicate .arch statement") | ||
681 | end | ||
682 | |||
683 | ------------------------------------------------------------------------------ | ||
684 | |||
685 | -- Dummy pseudo-opcode. Don't confuse '.nop' with 'nop'. | ||
686 | map_coreop[".nop_*"] = function(params) | ||
687 | if not params then return "[ignored...]" end | ||
688 | end | ||
689 | |||
690 | -- Pseudo-opcodes to raise errors. | ||
691 | map_coreop[".error_1"] = function(params) | ||
692 | if not params then return "message" end | ||
693 | werror(params[1]) | ||
694 | end | ||
695 | |||
696 | map_coreop[".fatal_1"] = function(params) | ||
697 | if not params then return "message" end | ||
698 | wfatal(params[1]) | ||
699 | end | ||
700 | |||
701 | -- Dump all user defined elements. | ||
702 | local function dumpdef(out) | ||
703 | local lvl = g_opt.dumpdef | ||
704 | if lvl == 0 then return end | ||
705 | dumpsections(out, lvl) | ||
706 | dumpdefines(out, lvl) | ||
707 | if g_arch then g_arch.dumpdef(out, lvl) end | ||
708 | dumpmacros(out, lvl) | ||
709 | dumpcaptures(out, lvl) | ||
710 | end | ||
711 | |||
712 | ------------------------------------------------------------------------------ | ||
713 | |||
714 | -- Helper for splitstmt. | ||
715 | local splitlvl | ||
716 | |||
717 | local function splitstmt_one(c) | ||
718 | if c == "(" then | ||
719 | splitlvl = ")"..splitlvl | ||
720 | elseif c == "[" then | ||
721 | splitlvl = "]"..splitlvl | ||
722 | elseif c == ")" or c == "]" then | ||
723 | if sub(splitlvl, 1, 1) ~= c then werror("unbalanced () or []") end | ||
724 | splitlvl = sub(splitlvl, 2) | ||
725 | elseif splitlvl == "" then | ||
726 | return " \0 " | ||
727 | end | ||
728 | return c | ||
729 | end | ||
730 | |||
731 | -- Split statement into (pseudo-)opcode and params. | ||
732 | local function splitstmt(stmt) | ||
733 | -- Convert label with trailing-colon into .label statement. | ||
734 | local label = match(stmt, "^%s*(.+):%s*$") | ||
735 | if label then return ".label", {label} end | ||
736 | |||
737 | -- Split at commas and equal signs, but obey parentheses and brackets. | ||
738 | splitlvl = "" | ||
739 | stmt = gsub(stmt, "[,%(%)%[%]]", splitstmt_one) | ||
740 | if splitlvl ~= "" then werror("unbalanced () or []") end | ||
741 | |||
742 | -- Split off opcode. | ||
743 | local op, other = match(stmt, "^%s*([^%s%z]+)%s*(.*)$") | ||
744 | if not op then werror("bad statement syntax") end | ||
745 | |||
746 | -- Split parameters. | ||
747 | local params = {} | ||
748 | for p in gmatch(other, "%s*(%Z+)%z?") do | ||
749 | params[#params+1] = gsub(p, "%s+$", "") | ||
750 | end | ||
751 | if #params > 16 then werror("too many parameters") end | ||
752 | |||
753 | params.op = op | ||
754 | return op, params | ||
755 | end | ||
756 | |||
757 | -- Process a single statement. | ||
758 | dostmt = function(stmt) | ||
759 | -- Ignore empty statements. | ||
760 | if match(stmt, "^%s*$") then return end | ||
761 | |||
762 | -- Capture macro defs before substitution. | ||
763 | if mac_capture then return mac_capture(stmt) end | ||
764 | stmt = definesubst(stmt) | ||
765 | |||
766 | -- Emit C code without parsing the line. | ||
767 | if sub(stmt, 1, 1) == "|" then | ||
768 | local tail = sub(stmt, 2) | ||
769 | wflush() | ||
770 | if sub(tail, 1, 2) == "//" then wcomment(tail) else wline(tail, true) end | ||
771 | return | ||
772 | end | ||
773 | |||
774 | -- Split into (pseudo-)opcode and params. | ||
775 | local op, params = splitstmt(stmt) | ||
776 | |||
777 | -- Get opcode handler (matching # of parameters or generic handler). | ||
778 | local f = map_op[op.."_"..#params] or map_op[op.."_*"] | ||
779 | if not f then | ||
780 | if not g_arch then wfatal("first statement must be .arch") end | ||
781 | -- Improve error report. | ||
782 | for i=0,16 do | ||
783 | if map_op[op.."_"..i] then | ||
784 | werror("wrong number of parameters for `"..op.."'") | ||
785 | end | ||
786 | end | ||
787 | werror("unknown statement `"..op.."'") | ||
788 | end | ||
789 | |||
790 | -- Call opcode handler or special handler for template strings. | ||
791 | if type(f) == "string" then | ||
792 | map_op[".template__"](params, f) | ||
793 | else | ||
794 | f(params) | ||
795 | end | ||
796 | end | ||
797 | |||
798 | -- Process a single line. | ||
799 | local function doline(line) | ||
800 | if g_opt.flushline then wflush() end | ||
801 | |||
802 | -- Assembler line? | ||
803 | local indent, aline = match(line, "^(%s*)%|(.*)$") | ||
804 | if not aline then | ||
805 | -- No, plain C code line, need to flush first. | ||
806 | wflush() | ||
807 | wsync() | ||
808 | wline(line, false) | ||
809 | return | ||
810 | end | ||
811 | |||
812 | g_indent = indent -- Remember current line indentation. | ||
813 | |||
814 | -- Emit C code (even from macros). Avoids echo and line parsing. | ||
815 | if sub(aline, 1, 1) == "|" then | ||
816 | if not mac_capture then | ||
817 | wsync() | ||
818 | elseif g_opt.comment then | ||
819 | wsync() | ||
820 | wcomment(aline) | ||
821 | end | ||
822 | dostmt(aline) | ||
823 | return | ||
824 | end | ||
825 | |||
826 | -- Echo assembler line as a comment. | ||
827 | if g_opt.comment then | ||
828 | wsync() | ||
829 | wcomment(aline) | ||
830 | end | ||
831 | |||
832 | -- Strip assembler comments. | ||
833 | aline = gsub(aline, "//.*$", "") | ||
834 | |||
835 | -- Split line into statements at semicolons. | ||
836 | if match(aline, ";") then | ||
837 | for stmt in gmatch(aline, "[^;]+") do dostmt(stmt) end | ||
838 | else | ||
839 | dostmt(aline) | ||
840 | end | ||
841 | end | ||
842 | |||
843 | ------------------------------------------------------------------------------ | ||
844 | |||
845 | -- Write DynASM header. | ||
846 | local function dasmhead(out) | ||
847 | out:write(format([[ | ||
848 | /* | ||
849 | ** This file has been pre-processed with DynASM. | ||
850 | ** %s | ||
851 | ** DynASM version %s, DynASM %s version %s | ||
852 | ** DO NOT EDIT! The original file is in "%s". | ||
853 | */ | ||
854 | |||
855 | #if DASM_VERSION != %d | ||
856 | #error "Version mismatch between DynASM and included encoding engine" | ||
857 | #endif | ||
858 | |||
859 | ]], _info.url, | ||
860 | _info.version, g_arch._info.arch, g_arch._info.version, | ||
861 | g_fname, _info.vernum)) | ||
862 | end | ||
863 | |||
864 | -- Read input file. | ||
865 | readfile = function(fin) | ||
866 | g_indent = "" | ||
867 | g_lineno = 0 | ||
868 | g_synclineno = -1 | ||
869 | |||
870 | -- Process all lines. | ||
871 | for line in fin:lines() do | ||
872 | g_lineno = g_lineno + 1 | ||
873 | g_curline = line | ||
874 | local ok, err = pcall(doline, line) | ||
875 | if not ok and wprinterr(err, "\n") then return true end | ||
876 | end | ||
877 | wflush() | ||
878 | |||
879 | -- Close input file. | ||
880 | assert(fin == stdin or fin:close()) | ||
881 | end | ||
882 | |||
883 | -- Write output file. | ||
884 | local function writefile(outfile) | ||
885 | local fout | ||
886 | |||
887 | -- Open output file. | ||
888 | if outfile == nil or outfile == "-" then | ||
889 | fout = stdout | ||
890 | else | ||
891 | fout = assert(io.open(outfile, "w")) | ||
892 | end | ||
893 | |||
894 | -- Write all buffered lines | ||
895 | wdumplines(fout, g_wbuffer) | ||
896 | |||
897 | -- Close output file. | ||
898 | assert(fout == stdout or fout:close()) | ||
899 | |||
900 | -- Optionally dump definitions. | ||
901 | dumpdef(fout == stdout and stderr or stdout) | ||
902 | end | ||
903 | |||
904 | -- Translate an input file to an output file. | ||
905 | local function translate(infile, outfile) | ||
906 | g_wbuffer = {} | ||
907 | g_indent = "" | ||
908 | g_lineno = 0 | ||
909 | g_synclineno = -1 | ||
910 | |||
911 | -- Put header. | ||
912 | wline(dasmhead) | ||
913 | |||
914 | -- Read input file. | ||
915 | local fin | ||
916 | if infile == "-" then | ||
917 | g_fname = "(stdin)" | ||
918 | fin = stdin | ||
919 | else | ||
920 | g_fname = infile | ||
921 | fin = assert(io.open(infile, "r")) | ||
922 | end | ||
923 | readfile(fin) | ||
924 | |||
925 | -- Check for errors. | ||
926 | if not g_arch then | ||
927 | wprinterr(g_fname, ":*: error: missing .arch directive\n") | ||
928 | end | ||
929 | checkconds() | ||
930 | checkmacros() | ||
931 | checkcaptures() | ||
932 | |||
933 | if g_errcount ~= 0 then | ||
934 | stderr:write(g_fname, ":*: info: ", g_errcount, " error", | ||
935 | (type(g_errcount) == "number" and g_errcount > 1) and "s" or "", | ||
936 | " in input file -- no output file generated.\n") | ||
937 | dumpdef(stderr) | ||
938 | exit(1) | ||
939 | end | ||
940 | |||
941 | -- Write output file. | ||
942 | writefile(outfile) | ||
943 | end | ||
944 | |||
945 | ------------------------------------------------------------------------------ | ||
946 | |||
947 | -- Print help text. | ||
948 | function opt_map.help() | ||
949 | stdout:write("DynASM -- ", _info.description, ".\n") | ||
950 | stdout:write("DynASM ", _info.version, " ", _info.release, " ", _info.url, "\n") | ||
951 | stdout:write[[ | ||
952 | |||
953 | Usage: dynasm [OPTION]... INFILE.dasc|- | ||
954 | |||
955 | -h, --help Display this help text. | ||
956 | -V, --version Display version and copyright information. | ||
957 | |||
958 | -o, --outfile FILE Output file name (default is stdout). | ||
959 | -I, --include DIR Add directory to the include search path. | ||
960 | |||
961 | -c, --ccomment Use /* */ comments for assembler lines. | ||
962 | -C, --cppcomment Use // comments for assembler lines (default). | ||
963 | -N, --nocomment Suppress assembler lines in output. | ||
964 | -M, --maccomment Show macro expansions as comments (default off). | ||
965 | |||
966 | -L, --nolineno Suppress CPP line number information in output. | ||
967 | -F, --flushline Flush action list for every line. | ||
968 | |||
969 | -D NAME[=SUBST] Define a substitution. | ||
970 | -U NAME Undefine a substitution. | ||
971 | |||
972 | -P, --dumpdef Dump defines, macros, etc. Repeat for more output. | ||
973 | -A, --dumparch ARCH Load architecture ARCH and dump description. | ||
974 | ]] | ||
975 | exit(0) | ||
976 | end | ||
977 | |||
978 | -- Print version information. | ||
979 | function opt_map.version() | ||
980 | stdout:write(format("%s version %s, released %s\n%s\n\n%s", | ||
981 | _info.name, _info.version, _info.release, _info.url, _info.copyright)) | ||
982 | exit(0) | ||
983 | end | ||
984 | |||
985 | -- Misc. options. | ||
986 | function opt_map.outfile(args) g_opt.outfile = optparam(args) end | ||
987 | function opt_map.include(args) insert(g_opt.include, 1, optparam(args)) end | ||
988 | function opt_map.ccomment() g_opt.comment = "/*|"; g_opt.endcomment = " */" end | ||
989 | function opt_map.cppcomment() g_opt.comment = "//|"; g_opt.endcomment = "" end | ||
990 | function opt_map.nocomment() g_opt.comment = false end | ||
991 | function opt_map.maccomment() g_opt.maccomment = true end | ||
992 | function opt_map.nolineno() g_opt.cpp = false end | ||
993 | function opt_map.flushline() g_opt.flushline = true end | ||
994 | function opt_map.dumpdef() g_opt.dumpdef = g_opt.dumpdef + 1 end | ||
995 | |||
996 | ------------------------------------------------------------------------------ | ||
997 | |||
998 | -- Short aliases for long options. | ||
999 | local opt_alias = { | ||
1000 | h = "help", ["?"] = "help", V = "version", | ||
1001 | o = "outfile", I = "include", | ||
1002 | c = "ccomment", C = "cppcomment", N = "nocomment", M = "maccomment", | ||
1003 | L = "nolineno", F = "flushline", | ||
1004 | P = "dumpdef", A = "dumparch", | ||
1005 | } | ||
1006 | |||
1007 | -- Parse single option. | ||
1008 | local function parseopt(opt, args) | ||
1009 | opt_current = #opt == 1 and "-"..opt or "--"..opt | ||
1010 | local f = opt_map[opt] or opt_map[opt_alias[opt]] | ||
1011 | if not f then | ||
1012 | opterror("unrecognized option `", opt_current, "'. Try `--help'.\n") | ||
1013 | end | ||
1014 | f(args) | ||
1015 | end | ||
1016 | |||
1017 | -- Parse arguments. | ||
1018 | local function parseargs(args) | ||
1019 | -- Default options. | ||
1020 | g_opt.comment = "//|" | ||
1021 | g_opt.endcomment = "" | ||
1022 | g_opt.cpp = true | ||
1023 | g_opt.dumpdef = 0 | ||
1024 | g_opt.include = { "" } | ||
1025 | |||
1026 | -- Process all option arguments. | ||
1027 | args.argn = 1 | ||
1028 | repeat | ||
1029 | local a = args[args.argn] | ||
1030 | if not a then break end | ||
1031 | local lopt, opt = match(a, "^%-(%-?)(.+)") | ||
1032 | if not opt then break end | ||
1033 | args.argn = args.argn + 1 | ||
1034 | if lopt == "" then | ||
1035 | -- Loop through short options. | ||
1036 | for o in gmatch(opt, ".") do parseopt(o, args) end | ||
1037 | else | ||
1038 | -- Long option. | ||
1039 | parseopt(opt, args) | ||
1040 | end | ||
1041 | until false | ||
1042 | |||
1043 | -- Check for proper number of arguments. | ||
1044 | local nargs = #args - args.argn + 1 | ||
1045 | if nargs ~= 1 then | ||
1046 | if nargs == 0 then | ||
1047 | if g_opt.dumpdef > 0 then return dumpdef(stdout) end | ||
1048 | end | ||
1049 | opt_map.help() | ||
1050 | end | ||
1051 | |||
1052 | -- Translate a single input file to a single output file | ||
1053 | -- TODO: Handle multiple files? | ||
1054 | translate(args[args.argn], g_opt.outfile) | ||
1055 | end | ||
1056 | |||
1057 | ------------------------------------------------------------------------------ | ||
1058 | |||
1059 | -- Add the directory dynasm.lua resides in to the Lua module search path. | ||
1060 | local arg = arg | ||
1061 | if arg and arg[0] then | ||
1062 | local prefix = match(arg[0], "^(.*/)") | ||
1063 | if prefix then package.path = prefix.."?.lua;"..package.path end | ||
1064 | end | ||
1065 | |||
1066 | -- Start DynASM. | ||
1067 | parseargs{...} | ||
1068 | |||
1069 | ------------------------------------------------------------------------------ | ||
1070 | |||
diff --git a/libraries/LuaJIT-1.1.7/etc/README b/libraries/LuaJIT-1.1.7/etc/README new file mode 100644 index 0000000..98117d0 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/etc/README | |||
@@ -0,0 +1,20 @@ | |||
1 | This directory contains some useful files and code. | ||
2 | Unlike the code in ../src, everything here is in the public domain. | ||
3 | |||
4 | lua.hpp | ||
5 | Lua header files for C++ using 'extern "C"'. | ||
6 | |||
7 | luajit.ico | ||
8 | A LuaJIT icon for Windows (and web sites: save as favicon.ico). | ||
9 | Lua icon drawn by hand by Markus Gritsch. Modified for LuaJIT. | ||
10 | |||
11 | luajit.pc | ||
12 | pkg-config data for LuaJIT | ||
13 | |||
14 | luavs.bat | ||
15 | Script to build LuaJIT under "Visual Studio .NET Command Prompt". | ||
16 | Run it from the toplevel as etc\luavs.bat. | ||
17 | |||
18 | strict.lua | ||
19 | Traps uses of undeclared global variables. | ||
20 | |||
diff --git a/libraries/LuaJIT-1.1.7/etc/lua.hpp b/libraries/LuaJIT-1.1.7/etc/lua.hpp new file mode 100644 index 0000000..ec417f5 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/etc/lua.hpp | |||
@@ -0,0 +1,9 @@ | |||
1 | // lua.hpp | ||
2 | // Lua header files for C++ | ||
3 | // <<extern "C">> not supplied automatically because Lua also compiles as C++ | ||
4 | |||
5 | extern "C" { | ||
6 | #include "lua.h" | ||
7 | #include "lualib.h" | ||
8 | #include "lauxlib.h" | ||
9 | } | ||
diff --git a/libraries/LuaJIT-1.1.7/etc/luajit.ico b/libraries/LuaJIT-1.1.7/etc/luajit.ico new file mode 100644 index 0000000..bdd7a90 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/etc/luajit.ico | |||
Binary files differ | |||
diff --git a/libraries/LuaJIT-1.1.7/etc/luajit.pc b/libraries/LuaJIT-1.1.7/etc/luajit.pc new file mode 100644 index 0000000..1444076 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/etc/luajit.pc | |||
@@ -0,0 +1,28 @@ | |||
1 | # luajit.pc -- pkg-config data for LuaJIT | ||
2 | |||
3 | # vars from install Makefile | ||
4 | |||
5 | # grep '^J*V=' ../Makefile | ||
6 | V= 5.1 | ||
7 | JV= 1.1.7 | ||
8 | |||
9 | # grep '^INSTALL_.*=' ../Makefile | sed 's/INSTALL_TOP/prefix/' | ||
10 | prefix= /usr/local | ||
11 | INSTALL_BIN= ${prefix}/bin | ||
12 | INSTALL_INC= ${prefix}/include | ||
13 | INSTALL_LIB= ${prefix}/lib | ||
14 | INSTALL_MAN= ${prefix}/man/man1 | ||
15 | INSTALL_LMOD= ${prefix}/share/lua/${V} | ||
16 | INSTALL_CMOD= ${prefix}/lib/lua/${V} | ||
17 | |||
18 | exec_prefix=${prefix} | ||
19 | libdir=${exec_prefix}/lib | ||
20 | includedir=${prefix}/include | ||
21 | |||
22 | Name: LuaJIT | ||
23 | Description: An Extensible Extension Language (JIT compiled for speed) | ||
24 | Version: ${JV} | ||
25 | Requires: | ||
26 | Libs: -L${libdir} -llua -lm | ||
27 | Cflags: -I${includedir} | ||
28 | |||
diff --git a/libraries/LuaJIT-1.1.7/etc/luavs.bat b/libraries/LuaJIT-1.1.7/etc/luavs.bat new file mode 100755 index 0000000..4f311e2 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/etc/luavs.bat | |||
@@ -0,0 +1,22 @@ | |||
1 | @rem Script to build LuaJIT under "Visual Studio .NET Command Prompt". | ||
2 | @rem Do not run from this directory; run it from the toplevel: etc\luavs.bat . | ||
3 | @rem It creates lua51.dll, lua51.lib and luajit.exe in src. | ||
4 | @rem (contributed by David Manura and Mike Pall) | ||
5 | |||
6 | @setlocal | ||
7 | @set MYCOMPILE=cl /nologo /MD /O2 /W3 /c /D_CRT_SECURE_NO_DEPRECATE /I . /I ..\dynasm | ||
8 | @set MYLINK=link /nologo | ||
9 | @set MYMT=mt /nologo | ||
10 | |||
11 | cd src | ||
12 | %MYCOMPILE% /DLUA_BUILD_AS_DLL l*.c | ||
13 | del lua.obj luac.obj | ||
14 | %MYLINK% /DLL /out:lua51.dll l*.obj | ||
15 | if exist lua51.dll.manifest^ | ||
16 | %MYMT% -manifest lua51.dll.manifest -outputresource:lua51.dll;2 | ||
17 | %MYCOMPILE% /DLUA_BUILD_AS_DLL lua.c | ||
18 | %MYLINK% /out:luajit.exe lua.obj lua51.lib | ||
19 | if exist luajit.exe.manifest^ | ||
20 | %MYMT% -manifest luajit.exe.manifest -outputresource:luajit.exe | ||
21 | del *.obj *.manifest | ||
22 | cd .. | ||
diff --git a/libraries/LuaJIT-1.1.7/etc/strict.lua b/libraries/LuaJIT-1.1.7/etc/strict.lua new file mode 100644 index 0000000..604619d --- /dev/null +++ b/libraries/LuaJIT-1.1.7/etc/strict.lua | |||
@@ -0,0 +1,41 @@ | |||
1 | -- | ||
2 | -- strict.lua | ||
3 | -- checks uses of undeclared global variables | ||
4 | -- All global variables must be 'declared' through a regular assignment | ||
5 | -- (even assigning nil will do) in a main chunk before being used | ||
6 | -- anywhere or assigned to inside a function. | ||
7 | -- | ||
8 | |||
9 | local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget | ||
10 | |||
11 | local mt = getmetatable(_G) | ||
12 | if mt == nil then | ||
13 | mt = {} | ||
14 | setmetatable(_G, mt) | ||
15 | end | ||
16 | |||
17 | mt.__declared = {} | ||
18 | |||
19 | local function what () | ||
20 | local d = getinfo(3, "S") | ||
21 | return d and d.what or "C" | ||
22 | end | ||
23 | |||
24 | mt.__newindex = function (t, n, v) | ||
25 | if not mt.__declared[n] then | ||
26 | local w = what() | ||
27 | if w ~= "main" and w ~= "C" then | ||
28 | error("assign to undeclared variable '"..n.."'", 2) | ||
29 | end | ||
30 | mt.__declared[n] = true | ||
31 | end | ||
32 | rawset(t, n, v) | ||
33 | end | ||
34 | |||
35 | mt.__index = function (t, n) | ||
36 | if not mt.__declared[n] and what() ~= "C" then | ||
37 | error("variable '"..n.."' is not declared", 2) | ||
38 | end | ||
39 | return rawget(t, n) | ||
40 | end | ||
41 | |||
diff --git a/libraries/LuaJIT-1.1.7/jit/dis_x86.lua b/libraries/LuaJIT-1.1.7/jit/dis_x86.lua new file mode 100644 index 0000000..b9ca150 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jit/dis_x86.lua | |||
@@ -0,0 +1,622 @@ | |||
1 | ---------------------------------------------------------------------------- | ||
2 | -- LuaJIT x86 disassembler module. | ||
3 | -- | ||
4 | -- Copyright (C) 2005-2011 Mike Pall. All rights reserved. | ||
5 | -- Released under the MIT/X license. See luajit.h for full copyright notice. | ||
6 | ---------------------------------------------------------------------------- | ||
7 | -- This is a helper module used by the LuaJIT machine code dumper module. | ||
8 | -- | ||
9 | -- Sending small code snippets to an external disassembler and mixing the | ||
10 | -- output with our own stuff was too fragile. So I had to bite the bullet | ||
11 | -- and write yet another x86 disassembler. Oh well ... | ||
12 | -- | ||
13 | -- The output format is very similar to what ndisasm generates. But it has | ||
14 | -- been developed independently by looking at the opcode tables from the | ||
15 | -- Intel and AMD manuals. The supported instruction set is quite extensive | ||
16 | -- and reflects what a current generation P4 or K8 implements in 32 bit | ||
17 | -- mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3 and even privileged | ||
18 | -- instructions. | ||
19 | -- | ||
20 | -- Notes: | ||
21 | -- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported. | ||
22 | -- * No attempt at optimization has been made -- it's fast enough for my needs. | ||
23 | -- * The public API may change when more architectures are added. | ||
24 | -- | ||
25 | -- TODO: | ||
26 | -- * More testing with arbitrary x86 code (not just LuaJIT generated code). | ||
27 | -- * The output for a few MMX/SSE opcodes could be improved. | ||
28 | -- * Adding x64 support would be straightforward. | ||
29 | -- * Better input API (iterator) and output API (structured access to instr). | ||
30 | ------------------------------------------------------------------------------ | ||
31 | |||
32 | local type = type | ||
33 | local sub, byte, format = string.sub, string.byte, string.format | ||
34 | local match, gmatch, gsub = string.match, string.gmatch, string.gsub | ||
35 | |||
36 | -- Map for 1st opcode byte. Ugly? Well ... read on. | ||
37 | local map_opc1 = { | ||
38 | --0x | ||
39 | [0]="addBmr","addVmr","addBrm","addVrm","addBai","addVai","push es","pop es", | ||
40 | "orBmr","orVmr","orBrm","orVrm","orBai","orVai","push cs","opc2*", | ||
41 | --1x | ||
42 | "adcBmr","adcVmr","adcBrm","adcVrm","adcBai","adcVai","push ss","pop ss", | ||
43 | "sbbBmr","sbbVmr","sbbBrm","sbbVrm","sbbBai","sbbVai","push ds","pop ds", | ||
44 | --2x | ||
45 | "andBmr","andVmr","andBrm","andVrm","andBai","andVai","es:seg","daa", | ||
46 | "subBmr","subVmr","subBrm","subVrm","subBai","subVai","cs:seg","das", | ||
47 | --3x | ||
48 | "xorBmr","xorVmr","xorBrm","xorVrm","xorBai","xorVai","ss:seg","aaa", | ||
49 | "cmpBmr","cmpVmr","cmpBrm","cmpVrm","cmpBai","cmpVai","ds:seg","aas", | ||
50 | --4x | ||
51 | "incVR","incVR","incVR","incVR","incVR","incVR","incVR","incVR", | ||
52 | "decVR","decVR","decVR","decVR","decVR","decVR","decVR","decVR", | ||
53 | --5x | ||
54 | "pushVR","pushVR","pushVR","pushVR","pushVR","pushVR","pushVR","pushVR", | ||
55 | "popVR","popVR","popVR","popVR","popVR","popVR","popVR","popVR", | ||
56 | --6x | ||
57 | "pusha/pushaw","popa/popaw","boundVrm","arplWmr", | ||
58 | "fs:seg","gs:seg","o16:","a16", | ||
59 | "pushVi","imulVrmi","pushBs","imulVrms", | ||
60 | "insb","insd/insw","outsb","outsd/outsw", | ||
61 | --7x | ||
62 | "joBj","jnoBj","jbBj","jnbBj","jzBj","jnzBj","jbeBj","jaBj", | ||
63 | "jsBj","jnsBj","jpeBj","jpoBj","jlBj","jgeBj","jleBj","jgBj", | ||
64 | --8x | ||
65 | "arith!Bmi","arith!Vmi","arith!Bmi","arith!Vms", | ||
66 | "testBmr","testVmr","xchgBrm","xchgVrm", | ||
67 | "movBmr","movVmr","movBrm","movVrm", | ||
68 | "movVmg","leaVrm","movWgm","popVm", | ||
69 | --9x | ||
70 | "nop|pause|xchgWaR|repne nop","xchgVaR","xchgVaR","xchgVaR", | ||
71 | "xchgVaR","xchgVaR","xchgVaR","xchgVaR", | ||
72 | "cwde/cbw","cdq/cwd","call farViw","wait", | ||
73 | "pushf/pushfw","popf/popfw","sahf","lahf", | ||
74 | --Ax | ||
75 | "movBao","movVao","movBoa","movVoa", | ||
76 | "movsb","movsd/movsb","cmpsb","cmpsd/cmpsw", | ||
77 | "testBai","testVai","stosb","stosd/stosw", | ||
78 | "lodsb","lodsd/lodsw","scasb","scasd/scasw", | ||
79 | --Bx | ||
80 | "movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi", | ||
81 | "movVRi","movVRi","movVRi","movVRi","movVRi","movVRi","movVRi","movVRi", | ||
82 | --Cx | ||
83 | "shift!Bmu","shift!Vmu","retBw","ret","lesVrm","ldsVrm","movBmi","movVmi", | ||
84 | "enterBwu","leave","retfBw","retf","int3","intBu","into","iret/iretw", | ||
85 | --Dx | ||
86 | "shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb", | ||
87 | "fp*0","fp*1","fp*2","fp*3","fp*4","fp*5","fp*6","fp*7", | ||
88 | --Ex | ||
89 | "loopneBj","loopeBj","loopBj","jecxz/jcxzBj","inBau","inVau","outBua","outVua", | ||
90 | "callDj","jmpDj","jmp farViw","jmpBj","inBad","inVad","outBda","outVda", | ||
91 | --Fx | ||
92 | "lock:","int1","repne:rep","rep:","hlt","cmc","testb!Bm","testv!Vm", | ||
93 | "clc","stc","cli","sti","cld","std","inc!Bm","inc!Vm", | ||
94 | } | ||
95 | assert(#map_opc1 == 255) | ||
96 | |||
97 | -- Map for 2nd opcode byte (0f xx). True CISC hell. Hey, I told you. | ||
98 | -- Prefix dependent MMX/SSE opcodes: (none)|rep|o16|repne | ||
99 | local map_opc2 = { | ||
100 | --0x | ||
101 | [0]="sldt!Dmp","sgdt!Dmp","larVrm","lslVrm",nil,"syscall","clts","sysret", | ||
102 | "invd","wbinvd",nil,"ud1",nil,"prefetch!Bm","femms","3dnowMrmu", | ||
103 | --1x | ||
104 | "movupsXrm|movssXrm|movupdXrm|movsdXrm", | ||
105 | "movupsXmr|movssXmr|movupdXmr|movsdXmr", | ||
106 | "movhlpsXrm|movsldupXrm|movlpdXrm|movddupXrm", -- TODO: movlpsXrMm (mem case). | ||
107 | "movlpsXmr||movlpdXmr", | ||
108 | "unpcklpsXrm||unpcklpdXrm", | ||
109 | "unpckhpsXrm||unpckhpdXrm", | ||
110 | "movlhpsXrm|movshdupXrm|movhpdXrm", -- TODO: movhpsXrMm (mem case). | ||
111 | "movhpsXmr||movhpdXmr", | ||
112 | "prefetcht!Bm","hintnopBm","hintnopBm","hintnopBm", | ||
113 | "hintnopBm","hintnopBm","hintnopBm","hintnopBm", | ||
114 | --2x | ||
115 | "movDmx","movDmy","movDxm","movDym","movDmz",nil,"movDzm",nil, | ||
116 | "movapsXrm||movapdXrm", | ||
117 | "movapsXmr||movapdXmr", | ||
118 | "cvtpi2psXrMm|cvtsi2ssXrDm|cvtpi2pdXrMm|cvtsi2sdXrDm", | ||
119 | "movntpsXmr||movntpdXmr", | ||
120 | "cvttps2piMrXm|cvttss2siDrXm|cvttpd2piMrXm|cvttsd2siDrXm", | ||
121 | "cvtps2piMrXm|cvtss2siDrXm|cvtpd2piMrXm|cvtsd2siDrXm", | ||
122 | "ucomissXrm||ucomisdXrm", | ||
123 | "comissXrm||comisdXrm", | ||
124 | --3x | ||
125 | "wrmsr","rdtsc","rdmsr","rdpmc","sysenter","sysexit",nil,nil, | ||
126 | "ssse3*38",nil,"ssse3*3a",nil,nil,nil,nil,nil, | ||
127 | --4x | ||
128 | "cmovoVrm","cmovnoVrm","cmovbVrm","cmovnbVrm", | ||
129 | "cmovzVrm","cmovnzVrm","cmovbeVrm","cmovaVrm", | ||
130 | "cmovsVrm","cmovnsVrm","cmovpeVrm","cmovpoVrm", | ||
131 | "cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm", | ||
132 | --5x | ||
133 | "movmskpsDrXm||movmskpdDrXm","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm", | ||
134 | "rsqrtpsXrm|rsqrtssXrm","rcppsXrm|rcpssXrm", | ||
135 | "andpsXrm||andpdXrm","andnpsXrm||andnpdXrm", | ||
136 | "orpsXrm||orpdXrm","xorpsXrm||xorpdXrm", | ||
137 | "addpsXrm|addssXrm|addpdXrm|addsdXrm","mulpsXrm|mulssXrm|mulpdXrm|mulsdXrm", | ||
138 | "cvtps2pdXrm|cvtss2sdXrm|cvtpd2psXrm|cvtsd2ssXrm", | ||
139 | "cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm", | ||
140 | "subpsXrm|subssXrm|subpdXrm|subsdXrm","minpsXrm|minssXrm|minpdXrm|minsdXrm", | ||
141 | "divpsXrm|divssXrm|divpdXrm|divsdXrm","maxpsXrm|maxssXrm|maxpdXrm|maxsdXrm", | ||
142 | --6x | ||
143 | "punpcklbwMrm||punpcklbqXrm","punpcklwdPrm","punpckldqPrm","packsswbPrm", | ||
144 | "pcmpgtbPrm","pcmpgtwPrm","pcmpgtdPrm","packuswbPrm", | ||
145 | "punpckhbwPrm","punpckhwdPrm","punpckhdqPrm","packssdwPrm", | ||
146 | "||punpcklqdqXrm","||punpckhqdqXrm", | ||
147 | "movdPrDm","movqMrm|movdquXrm|movdqaXrm", | ||
148 | --7x | ||
149 | "pshufwPrmu","pshiftw!Pmu","pshiftd!Pmu","pshiftq!Mmu||pshiftdq!Xmu", | ||
150 | "pcmpeqbPrm","pcmpeqwPrm","pcmpeqdPrm","emms|", | ||
151 | nil,nil,nil,nil, | ||
152 | "||haddpdXrm|haddpsXrm","||hsubpdXrm|hsubpsXrm", | ||
153 | "movdDmMr|movqXrm|movdDmXr","movqMmr|movdquXmr|movdqaXmr", | ||
154 | --8x | ||
155 | "joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj", | ||
156 | "jsVj","jnsVj","jpeVj","jpoVj","jlVj","jgeVj","jleVj","jgVj", | ||
157 | --9x | ||
158 | "setoBm","setnoBm","setbBm","setnbBm","setzBm","setnzBm","setbeBm","setaBm", | ||
159 | "setsBm","setnsBm","setpeBm","setpoBm","setlBm","setgeBm","setleBm","setgBm", | ||
160 | --Ax | ||
161 | "push fs","pop fs","cpuid","btVmr","shldVmru","shldVmrc",nil,nil, | ||
162 | "push gs","pop gs","rsm","btsVmr","shrdVmru","shrdVmrc","fxsave!Dmp","imulVrm", | ||
163 | --Bx | ||
164 | "cmpxchgBmr","cmpxchgVmr","lssVrm","btrVmr", | ||
165 | "lfsVrm","lgsVrm","movzxVrBm","movzxDrWm", | ||
166 | nil,"ud2","bt!Vmu","btcVmr", | ||
167 | "bsfVrm","bsrVrm","movsxVrBm","movsxDrWm", | ||
168 | --Cx | ||
169 | "xaddBmr","xaddVmr", | ||
170 | "cmppsXrmu|cmpssXrmu|cmppdXrmu|cmpsdXrmu","movntiDmr|", | ||
171 | "pinsrwPrWmu","pextrwDrPmu", | ||
172 | "shufpsXrmu||shufpdXrmu","cmpxchg!Dmp", | ||
173 | "bswapDR","bswapDR","bswapDR","bswapDR","bswapDR","bswapDR","bswapDR","bswapDR", | ||
174 | --Dx | ||
175 | "||addsubpdXrm|addsubpsXrm","psrlwPrm","psrldPrm","psrlqPrm", | ||
176 | "paddqPrm","pmullwPrm", | ||
177 | "|movq2dqXrMm|movqXmr|movdq2qMrXm","pmovmskbDrPm", | ||
178 | "psubusbPrm","psubuswPrm","pminubPrm","pandPrm", | ||
179 | "paddusbPrm","padduswPrm","pmaxubPrm","pandnPrm", | ||
180 | --Ex | ||
181 | "pavgbPrm","psrawPrm","psradPrm","pavgwPrm", | ||
182 | "pmulhuwPrm","pmulhwPrm", | ||
183 | "|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","movntqMmr||movntdqXmr", | ||
184 | "psubsbPrm","psubswPrm","pminswPrm","porPrm", | ||
185 | "paddsbPrm","paddswPrm","pmaxswPrm","pxorPrm", | ||
186 | --Fx | ||
187 | "|||lddquXrm","psllwPrm","pslldPrm","psllqPrm", | ||
188 | "pmuludqPrm","pmaddwdPrm","psadbwPrm","maskmovqMrm||maskmovdquXrm", | ||
189 | "psubbPrm","psubwPrm","psubdPrm","psubqPrm", | ||
190 | "paddbPrm","paddwPrm","padddPrm","ud", | ||
191 | } | ||
192 | assert(map_opc2[255] == "ud") | ||
193 | |||
194 | -- Map for SSSE3 opcodes. | ||
195 | local map_ssse3 = { | ||
196 | ["38"] = { -- [66] 0f 38 xx | ||
197 | --0x | ||
198 | [0]="pshufbPrm","phaddwPrm","phadddPrm","phaddswPrm", | ||
199 | "pmaddubswPrm","phsubwPrm","phsubdPrm","phsubswPrm", | ||
200 | "psignbPrm","psignwPrm","psigndPrm","pmulhrswPrm", | ||
201 | nil,nil,nil,nil, | ||
202 | --1x | ||
203 | nil,nil,nil,nil,nil,nil,nil,nil, | ||
204 | nil,nil,nil,nil,"pabsbPrm","pabswPrm","pabsdPrm",nil, | ||
205 | }, | ||
206 | ["3a"] = { -- [66] 0f 3a xx | ||
207 | [0x0f] = "palignrPrmu", | ||
208 | }, | ||
209 | } | ||
210 | |||
211 | -- Map for FP opcodes. And you thought stack machines are simple? | ||
212 | local map_opcfp = { | ||
213 | -- D8-DF 00-BF: opcodes with a memory operand. | ||
214 | -- D8 | ||
215 | [0]="faddFm","fmulFm","fcomFm","fcompFm","fsubFm","fsubrFm","fdivFm","fdivrFm", | ||
216 | "fldFm",nil,"fstFm","fstpFm","fldenvDmp","fldcwWm","fnstenvDmp","fnstcwWm", | ||
217 | -- DA | ||
218 | "fiaddDm","fimulDm","ficomDm","ficompDm", | ||
219 | "fisubDm","fisubrDm","fidivDm","fidivrDm", | ||
220 | -- DB | ||
221 | "fildDm","fisttpDm","fistDm","fistpDm",nil,"fld twordFmp",nil,"fstp twordFmp", | ||
222 | -- DC | ||
223 | "faddGm","fmulGm","fcomGm","fcompGm","fsubGm","fsubrGm","fdivGm","fdivrGm", | ||
224 | -- DD | ||
225 | "fldGm","fisttpQm","fstGm","fstpGm","frstorDmp",nil,"fnsaveDmp","fnstswWm", | ||
226 | -- DE | ||
227 | "fiaddWm","fimulWm","ficomWm","ficompWm", | ||
228 | "fisubWm","fisubrWm","fidivWm","fidivrWm", | ||
229 | -- DF | ||
230 | "fildWm","fisttpWm","fistWm","fistpWm", | ||
231 | "fbld twordFmp","fildQm","fbstp twordFmp","fistpQm", | ||
232 | -- xx C0-FF: opcodes with a pseudo-register operand. | ||
233 | -- D8 | ||
234 | "faddFf","fmulFf","fcomFf","fcompFf","fsubFf","fsubrFf","fdivFf","fdivrFf", | ||
235 | -- D9 | ||
236 | "fldFf","fxchFf",{"fnop"},nil, | ||
237 | {"fchs","fabs",nil,nil,"ftst","fxam"}, | ||
238 | {"fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz"}, | ||
239 | {"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp"}, | ||
240 | {"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"}, | ||
241 | -- DA | ||
242 | "fcmovbFf","fcmoveFf","fcmovbeFf","fcmovuFf",nil,{nil,"fucompp"},nil,nil, | ||
243 | -- DB | ||
244 | "fcmovnbFf","fcmovneFf","fcmovnbeFf","fcmovnuFf", | ||
245 | {nil,nil,"fnclex","fninit"},"fucomiFf","fcomiFf",nil, | ||
246 | -- DC | ||
247 | "fadd toFf","fmul toFf",nil,nil, | ||
248 | "fsub toFf","fsubr toFf","fdivr toFf","fdiv toFf", | ||
249 | -- DD | ||
250 | "ffreeFf",nil,"fstFf","fstpFf","fucomFf","fucompFf",nil,nil, | ||
251 | -- DE | ||
252 | "faddpFf","fmulpFf",nil,{nil,"fcompp"}, | ||
253 | "fsubrpFf","fsubpFf","fdivrpFf","fdivpFf", | ||
254 | -- DF | ||
255 | nil,nil,nil,nil,{"fnstsw ax"},"fucomipFf","fcomipFf",nil, | ||
256 | } | ||
257 | assert(map_opcfp[126] == "fcomipFf") | ||
258 | |||
259 | -- Map for opcode groups. The subkey is sp from the ModRM byte. | ||
260 | local map_opcgroup = { | ||
261 | arith = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" }, | ||
262 | shift = { "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar" }, | ||
263 | testb = { "testBmi", "testBmi", "not", "neg", "mul", "imul", "div", "idiv" }, | ||
264 | testv = { "testVmi", "testVmi", "not", "neg", "mul", "imul", "div", "idiv" }, | ||
265 | inc = { "inc", "dec", "callDmp", "call farDmp", | ||
266 | "jmpDmp", "jmp farDmp", "push" }, | ||
267 | sldt = { "sldt", "str", "lldt", "ltr", "verr", "verw" }, | ||
268 | sgdt = { "sgdt", "sidt", "lgdt", "lidt", "smsw", nil, "lmsw", "invlpg" }, | ||
269 | bt = { nil, nil, nil, nil, "bt", "bts", "btr", "btc" }, | ||
270 | cmpxchg = { nil, "cmpxchg8b" }, | ||
271 | pshiftw = { nil, nil, "psrlw", nil, "psraw", nil, "psllw" }, | ||
272 | pshiftd = { nil, nil, "psrld", nil, "psrad", nil, "pslld" }, | ||
273 | pshiftq = { nil, nil, "psrlq", nil, nil, nil, "psllq" }, | ||
274 | pshiftdq = { nil, nil, "psrlq", "psrldq", nil, nil, "psllq", "pslldq" }, | ||
275 | fxsave = { "fxsave", "fxrstor", "ldmxcsr", "stmxcsr", | ||
276 | nil, "lfenceDp", "mfenceDp", "sfenceDp" }, -- TODO: clflush. | ||
277 | prefetch = { "prefetch", "prefetchw" }, | ||
278 | prefetcht = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2" }, | ||
279 | } | ||
280 | |||
281 | ------------------------------------------------------------------------------ | ||
282 | |||
283 | -- Maps for register names. | ||
284 | local map_aregs = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" } | ||
285 | local map_regs = { | ||
286 | B = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" }, | ||
287 | W = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" }, | ||
288 | D = map_aregs, | ||
289 | M = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, | ||
290 | X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" }, | ||
291 | } | ||
292 | local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" } | ||
293 | |||
294 | -- Maps for size names. | ||
295 | local map_sz2n = { | ||
296 | B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, | ||
297 | } | ||
298 | local map_sz2prefix = { | ||
299 | B = "byte", W = "word", D = "dword", | ||
300 | Q = "qword", -- No associated reg in 32 bit mode. | ||
301 | F = "dword", G = "qword", -- No need for sizes/register names for these two. | ||
302 | M = "qword", X = "xword", | ||
303 | } | ||
304 | |||
305 | ------------------------------------------------------------------------------ | ||
306 | |||
307 | -- Output a nicely formatted line with an opcode and operands. | ||
308 | local function putop(ctx, text, operands) | ||
309 | local code, pos, hex = ctx.code, ctx.pos, "" | ||
310 | for i=ctx.start,pos-1 do | ||
311 | hex = hex..format("%02X", byte(code, i, i)) | ||
312 | end | ||
313 | if #hex > 16 then hex = sub(hex, 1, 16).."." end | ||
314 | if operands then text = text.." "..operands end | ||
315 | if ctx.o16 then text = "o16 "..text; ctx.o16 = false end | ||
316 | if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end | ||
317 | if ctx.seg then | ||
318 | local text2, n = gsub(text, "%[", "["..ctx.seg..":") | ||
319 | if n == 0 then text = ctx.seg.." "..text else text = text2 end | ||
320 | ctx.seg = false | ||
321 | end | ||
322 | if ctx.lock then text = "lock "..text; ctx.lock = false end | ||
323 | local imm = ctx.imm | ||
324 | if imm then | ||
325 | local sym = ctx.symtab[imm] | ||
326 | if sym then text = text.."\t->"..sym end | ||
327 | end | ||
328 | ctx.out(format("%08x %-18s%s\n", ctx.addr+ctx.start, hex, text)) | ||
329 | ctx.mrm = false | ||
330 | ctx.start = pos | ||
331 | ctx.imm = nil | ||
332 | end | ||
333 | |||
334 | -- Fallback for incomplete opcodes at the end. | ||
335 | local function incomplete(ctx) | ||
336 | ctx.pos = ctx.stop+1 | ||
337 | ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false | ||
338 | return putop(ctx, "(incomplete)") | ||
339 | end | ||
340 | |||
341 | -- Fallback for unknown opcodes. | ||
342 | local function unknown(ctx) | ||
343 | ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false | ||
344 | return putop(ctx, "(unknown)") | ||
345 | end | ||
346 | |||
347 | -- Return an immediate of the specified size. | ||
348 | local function getimm(ctx, pos, n) | ||
349 | if pos+n-1 > ctx.stop then return incomplete(ctx) end | ||
350 | local code = ctx.code | ||
351 | if n == 1 then | ||
352 | local b1 = byte(code, pos, pos) | ||
353 | return b1 | ||
354 | elseif n == 2 then | ||
355 | local b1, b2 = byte(code, pos, pos+1) | ||
356 | return b1+b2*256 | ||
357 | else | ||
358 | local b1, b2, b3, b4 = byte(code, pos, pos+3) | ||
359 | local imm = b1+b2*256+b3*65536+b4*16777216 | ||
360 | ctx.imm = imm | ||
361 | return imm | ||
362 | end | ||
363 | end | ||
364 | |||
365 | -- Process pattern string and generate the operands. | ||
366 | local function putpat(ctx, name, pat) | ||
367 | local operands, regs, sz, mode, sp, rm, sc, rx, disp, sdisp | ||
368 | local code, pos, stop = ctx.code, ctx.pos, ctx.stop | ||
369 | |||
370 | -- Chars used: 1DFGMPQRVWXacdfgijmoprsuwxyz | ||
371 | for p in gmatch(pat, ".") do | ||
372 | local x = nil | ||
373 | if p == "V" then | ||
374 | sz = ctx.o16 and "W" or "D"; ctx.o16 = false | ||
375 | regs = map_regs[sz] | ||
376 | elseif match(p, "[BWDQFGMX]") then | ||
377 | sz = p | ||
378 | regs = map_regs[sz] | ||
379 | elseif p == "P" then | ||
380 | sz = ctx.o16 and "X" or "M"; ctx.o16 = false | ||
381 | regs = map_regs[sz] | ||
382 | elseif p == "s" then | ||
383 | local imm = getimm(ctx, pos, 1); if not imm then return end | ||
384 | x = imm <= 127 and format("byte +0x%02x", imm) | ||
385 | or format("byte -0x%02x", 256-imm) | ||
386 | pos = pos+1 | ||
387 | elseif p == "u" then | ||
388 | local imm = getimm(ctx, pos, 1); if not imm then return end | ||
389 | x = format("0x%02x", imm) | ||
390 | pos = pos+1 | ||
391 | elseif p == "w" then | ||
392 | local imm = getimm(ctx, pos, 2); if not imm then return end | ||
393 | x = format("0x%x", imm) | ||
394 | pos = pos+2 | ||
395 | elseif p == "o" then -- [offset] | ||
396 | local imm = getimm(ctx, pos, 4); if not imm then return end | ||
397 | x = format("[0x%08x]", imm) | ||
398 | pos = pos+4 | ||
399 | elseif p == "i" then | ||
400 | local n = map_sz2n[sz] | ||
401 | local imm = getimm(ctx, pos, n); if not imm then return end | ||
402 | x = format(imm > 65535 and "0x%08x" or "0x%x", imm) | ||
403 | pos = pos+n | ||
404 | elseif p == "j" then | ||
405 | local n = map_sz2n[sz] | ||
406 | local imm = getimm(ctx, pos, n); if not imm then return end | ||
407 | if sz == "B" and imm > 127 then imm = imm-256 | ||
408 | elseif imm > 2147483647 then imm = imm-4294967296 end | ||
409 | pos = pos+n | ||
410 | imm = imm + pos + ctx.addr | ||
411 | ctx.imm = imm | ||
412 | x = sz == "W" and format("word 0x%04x", imm%65536) | ||
413 | or format("0x%08x", imm) | ||
414 | elseif p == "R" then x = regs[byte(code, pos-1, pos-1)%8+1] | ||
415 | elseif p == "a" then x = regs[1] | ||
416 | elseif p == "c" then x = "cl" | ||
417 | elseif p == "d" then x = "dx" | ||
418 | elseif p == "1" then x = "1" | ||
419 | else | ||
420 | if not mode then | ||
421 | mode = ctx.mrm | ||
422 | if not mode then | ||
423 | if pos > stop then return incomplete(ctx) end | ||
424 | mode = byte(code, pos, pos) | ||
425 | pos = pos+1 | ||
426 | end | ||
427 | rm = mode%8; mode = (mode-rm)/8 | ||
428 | sp = mode%8; mode = (mode-sp)/8 | ||
429 | sdisp = "" | ||
430 | if mode < 3 then | ||
431 | if rm == 4 then | ||
432 | if pos > stop then return incomplete(ctx) end | ||
433 | sc = byte(code, pos, pos) | ||
434 | pos = pos+1 | ||
435 | rm = sc%8; sc = (sc-rm)/8 | ||
436 | rx = sc%8; sc = (sc-rx)/8 | ||
437 | if rx == 4 then rx = nil end | ||
438 | end | ||
439 | if mode > 0 or rm == 5 then | ||
440 | local dsz = mode | ||
441 | if dsz ~= 1 then dsz = 4 end | ||
442 | disp = getimm(ctx, pos, dsz); if not disp then return end | ||
443 | sdisp = (dsz == 4 or disp <= 127) and | ||
444 | format(disp > 65535 and "+0x%08x" or "+0x%x", disp) or | ||
445 | format("-0x%x", 256-disp) | ||
446 | pos = pos+dsz | ||
447 | end | ||
448 | end | ||
449 | end | ||
450 | if p == "m" then | ||
451 | if mode == 3 then x = regs[rm+1] | ||
452 | else | ||
453 | local srm, srx = map_aregs[rm+1], "" | ||
454 | if rx then | ||
455 | srm = srm.."+" | ||
456 | srx = map_aregs[rx+1] | ||
457 | if sc > 0 then srx = srx.."*"..(2^sc) end | ||
458 | end | ||
459 | if mode == 0 and rm == 5 then | ||
460 | srm = "" | ||
461 | sdisp = format("%s0x%08x", rx and "+" or "", disp) | ||
462 | end | ||
463 | x = format("[%s%s%s]", srm, srx, sdisp) | ||
464 | end | ||
465 | if mode < 3 and | ||
466 | (not match(pat, "[aRrgp]") or | ||
467 | name == "movzx" or name == "movsx") then -- Yuck. | ||
468 | x = map_sz2prefix[sz].." "..x | ||
469 | end | ||
470 | elseif p == "r" then x = regs[sp+1] | ||
471 | elseif p == "g" then x = map_segregs[sp+1] | ||
472 | elseif p == "p" then -- Suppress prefix. | ||
473 | elseif p == "f" then x = "st"..rm | ||
474 | elseif p == "x" then x = "CR"..sp | ||
475 | elseif p == "y" then x = "DR"..sp | ||
476 | elseif p == "z" then x = "TR"..sp | ||
477 | else | ||
478 | error("bad pattern `"..pat.."'") | ||
479 | end | ||
480 | end | ||
481 | if x then operands = operands and operands..","..x or x end | ||
482 | end | ||
483 | ctx.pos = pos | ||
484 | return putop(ctx, name, operands) | ||
485 | end | ||
486 | |||
487 | -- Forward declaration. | ||
488 | local map_act | ||
489 | |||
490 | -- Get a pattern from an opcode map and dispatch to handler. | ||
491 | local function opcdispatch(ctx, opcmap) | ||
492 | local pos = ctx.pos | ||
493 | local opat = opcmap[byte(ctx.code, pos, pos)] | ||
494 | if not opat then return unknown(ctx) end | ||
495 | if match(opat, "%|") then -- MMX/SSE variants depending on prefix. | ||
496 | local p | ||
497 | if ctx.rep then p = ctx.rep=="rep" and "%|([^%|]*)" or "%|.-%|.-%|([^%|]*)" | ||
498 | elseif ctx.o16 then p = "%|.-%|([^%|]*)" | ||
499 | else p = "^[^%|]*" end | ||
500 | opat = match(opat, p) | ||
501 | if not opat or opat == "" then return unknown(ctx) end | ||
502 | ctx.rep = false; ctx.o16 = false | ||
503 | end | ||
504 | local name, pat, act = match(opat, "^([a-z0-9 ]*)((.?).*)") | ||
505 | ctx.pos = pos + 1 | ||
506 | return map_act[act](ctx, name, pat) | ||
507 | end | ||
508 | |||
509 | -- Map for action codes. The key is the first char after the name. | ||
510 | map_act = { | ||
511 | -- Simple opcodes without operands. | ||
512 | [""] = function(ctx, name, pat) | ||
513 | return putop(ctx, name) | ||
514 | end, | ||
515 | |||
516 | -- Operand size chars fall right through. | ||
517 | B = putpat, W = putpat, D = putpat, V = putpat, | ||
518 | F = putpat, G = putpat, | ||
519 | M = putpat, X = putpat, P = putpat, | ||
520 | |||
521 | -- Collect prefixes. | ||
522 | [":"] = function(ctx, name, pat) | ||
523 | ctx[pat == ":" and name or sub(pat, 2)] = name | ||
524 | end, | ||
525 | |||
526 | -- Select alternate opcode name when prefixed with o16. | ||
527 | ["/"] = function(ctx, name, pat) | ||
528 | local wname, rpat = match(pat, "^/([a-z0-9 ]+)(.*)") | ||
529 | if ctx.o16 then name = wname; ctx.o16 = false end | ||
530 | return putpat(ctx, name, rpat) | ||
531 | end, | ||
532 | |||
533 | -- Chain to special handler specified by name. | ||
534 | ["*"] = function(ctx, name, pat) | ||
535 | return map_act[name](ctx, name, sub(pat, 2)) | ||
536 | end, | ||
537 | |||
538 | -- Use named subtable for opcode group. | ||
539 | ["!"] = function(ctx, name, pat) | ||
540 | |||
541 | local pos = ctx.pos | ||
542 | if pos > ctx.stop then return incomplete(ctx) end | ||
543 | local mrm = byte(ctx.code, pos, pos) | ||
544 | ctx.pos = pos+1 | ||
545 | ctx.mrm = mrm | ||
546 | |||
547 | local opat = map_opcgroup[name][((mrm-(mrm%8))/8)%8+1] | ||
548 | if not opat then return unknown(ctx) end | ||
549 | local name, pat2 = match(opat, "^([a-z0-9 ]*)(.*)") | ||
550 | return putpat(ctx, name, pat2 ~= "" and pat2 or sub(pat, 2)) | ||
551 | end, | ||
552 | |||
553 | -- Two-byte opcode dispatch. | ||
554 | opc2 = function(ctx, name, pat) | ||
555 | return opcdispatch(ctx, map_opc2) | ||
556 | end, | ||
557 | |||
558 | -- SSSE3 dispatch. | ||
559 | ssse3 = function(ctx, name, pat) | ||
560 | return opcdispatch(ctx, map_ssse3[pat]) | ||
561 | end, | ||
562 | |||
563 | -- Floating point opcode dispatch. | ||
564 | fp = function(ctx, name, pat) | ||
565 | |||
566 | local pos = ctx.pos | ||
567 | if pos > ctx.stop then return incomplete(ctx) end | ||
568 | local mrm = byte(ctx.code, pos, pos) | ||
569 | ctx.pos = pos+1 | ||
570 | ctx.mrm = mrm | ||
571 | |||
572 | local rm = mrm%8 | ||
573 | local idx = pat*8 + ((mrm-rm)/8)%8 | ||
574 | if mrm >= 192 then idx = idx + 64 end | ||
575 | local opat = map_opcfp[idx] | ||
576 | if type(opat) == "table" then opat = opat[rm+1] end | ||
577 | if not opat then return unknown(ctx) end | ||
578 | local name, pat2 = match(opat, "^([a-z0-9 ]*)(.*)") | ||
579 | return putpat(ctx, name, pat2) | ||
580 | end, | ||
581 | } | ||
582 | |||
583 | ------------------------------------------------------------------------------ | ||
584 | |||
585 | -- Disassemble a block of code. | ||
586 | local function disass_block(ctx, ofs, len) | ||
587 | if not ofs then ofs = 0 end | ||
588 | local stop = len and ofs+len or #ctx.code | ||
589 | ofs = ofs + 1 | ||
590 | ctx.start = ofs | ||
591 | ctx.pos = ofs | ||
592 | ctx.stop = stop | ||
593 | ctx.imm = nil | ||
594 | ctx.mrm = false | ||
595 | ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false | ||
596 | while ctx.pos <= stop do opcdispatch(ctx, map_opc1) end | ||
597 | if ctx.pos ~= ctx.start then incomplete(ctx) end | ||
598 | end | ||
599 | |||
600 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). | ||
601 | local function create_(code, addr, out) | ||
602 | local ctx = {} | ||
603 | ctx.code = code | ||
604 | ctx.addr = (addr or 0) - 1 | ||
605 | ctx.out = out or io.write | ||
606 | ctx.symtab = {} | ||
607 | ctx.disass = disass_block | ||
608 | return ctx | ||
609 | end | ||
610 | |||
611 | -- Simple API: disassemble code (a string) at address and output via out. | ||
612 | local function disass_(code, addr, out) | ||
613 | create_(code, addr, out):disass() | ||
614 | end | ||
615 | |||
616 | |||
617 | -- Public module functions. | ||
618 | module(...) | ||
619 | |||
620 | create = create_ | ||
621 | disass = disass_ | ||
622 | |||
diff --git a/libraries/LuaJIT-1.1.7/jit/dump.lua b/libraries/LuaJIT-1.1.7/jit/dump.lua new file mode 100644 index 0000000..2287c23 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jit/dump.lua | |||
@@ -0,0 +1,265 @@ | |||
1 | ---------------------------------------------------------------------------- | ||
2 | -- LuaJIT machine code dumper module. | ||
3 | -- | ||
4 | -- Copyright (C) 2005-2011 Mike Pall. All rights reserved. | ||
5 | -- Released under the MIT/X license. See luajit.h for full copyright notice. | ||
6 | ---------------------------------------------------------------------------- | ||
7 | -- Activate this module to dump the machine code for all functions | ||
8 | -- immediately after they have been compiled. The disassembler | ||
9 | -- output is mixed with the bytecode listing. | ||
10 | -- | ||
11 | -- Try: luajit -j dump -e 'print "foo"' | ||
12 | -- luajit -j dump=foo.dump foo.lua | ||
13 | -- luajit -j off -j dump -e 'jit.compile(assert(loadfile"foo.lua")))' | ||
14 | -- | ||
15 | -- Default output is to stderr. To redirect output to a file, | ||
16 | -- pass a filename as an argument or set the environment variable | ||
17 | -- "LUAJIT_DUMPFILE". | ||
18 | -- Note: The file is overwritten each time you run luajit. | ||
19 | -- | ||
20 | -- TODO: Find a way to be more selective on what to dump. | ||
21 | ------------------------------------------------------------------------------ | ||
22 | |||
23 | -- Priority for compiler pipeline. Must run after backend (negative) | ||
24 | -- and should be even because we only catch successful compiles. | ||
25 | local PRIORITY = -98 | ||
26 | |||
27 | -- Cache some library functions and objects. | ||
28 | local jit = require("jit") | ||
29 | assert(jit.version_num == 10107, "LuaJIT core/library version mismatch") | ||
30 | local jutil = require("jit.util") | ||
31 | local type, format, gsub = type, string.format, string.gsub | ||
32 | local bytecode, const = jutil.bytecode, jutil.const | ||
33 | local getinfo = debug.getinfo | ||
34 | local stdout, stderr = io.stdout, io.stderr | ||
35 | |||
36 | -- Load the right disassembler. | ||
37 | local dis = require("jit.dis_"..jit.arch) | ||
38 | local discreate, disass_ = dis.create, dis.disass | ||
39 | |||
40 | -- Turn compilation off for the whole module. LuaJIT would do that anyway. | ||
41 | jit.off(true, true) | ||
42 | |||
43 | -- Separator line. | ||
44 | local sepline = "-------------------------------" | ||
45 | |||
46 | -- Map JSUB indices to names. | ||
47 | -- CHECK: must match the order in ljit_x86.h. Regenerate with: | ||
48 | -- grep '^ *JSUB_[^_].*,' ljit_x86.h | sed -e 's/^ *JSUB_/ "/' -e 's/,.*/",/' | ||
49 | local jsubnames = { | ||
50 | "STACKPTR", | ||
51 | "GATE_LJ", | ||
52 | "GATE_JL", | ||
53 | "GATE_JC", | ||
54 | "GROW_STACK", | ||
55 | "GROW_CI", | ||
56 | "GATE_JC_PATCH", | ||
57 | "GATE_JC_DEBUG", | ||
58 | "DEOPTIMIZE_CALLER", | ||
59 | "DEOPTIMIZE", | ||
60 | "DEOPTIMIZE_OPEN", | ||
61 | "HOOKINS", | ||
62 | "GCSTEP", | ||
63 | "STRING_SUB3", | ||
64 | "STRING_SUB2", | ||
65 | "HOOKCALL", | ||
66 | "HOOKRET", | ||
67 | "METACALL", | ||
68 | "METATAILCALL", | ||
69 | "BARRIERF", | ||
70 | "GETGLOBAL", | ||
71 | "GETTABLE_KSTR", | ||
72 | "GETTABLE_STR", | ||
73 | "BARRIERBACK", | ||
74 | "SETGLOBAL", | ||
75 | "SETTABLE_KSTR", | ||
76 | "SETTABLE_STR", | ||
77 | "GETTABLE_KNUM", | ||
78 | "GETTABLE_NUM", | ||
79 | "SETTABLE_KNUM", | ||
80 | "SETTABLE_NUM", | ||
81 | "LOG2_TWORD", | ||
82 | "CONCAT_STR2", | ||
83 | } | ||
84 | |||
85 | -- Generate map from JSUB addresses to JSUB names. | ||
86 | local jsubmap = {} | ||
87 | do | ||
88 | local jsubmcode = jutil.jsubmcode | ||
89 | for pc=0,100000 do | ||
90 | local addr = jsubmcode(pc) | ||
91 | if not addr then break end | ||
92 | jsubmap[addr] = jsubnames[pc+1] or "JSUB#"..pc | ||
93 | end | ||
94 | end | ||
95 | |||
96 | -- Pretty-print a constant. | ||
97 | local function conststr(func, idx) | ||
98 | local k = const(func, idx) | ||
99 | if k == nil then return "nil" | ||
100 | elseif k == true then return "true" | ||
101 | elseif k == false then return "false" | ||
102 | elseif type(k) == "string" then | ||
103 | if #k > 10 then return format('"%.10s"~', k) | ||
104 | else return '"'..k..'"' end | ||
105 | else return k.."" end | ||
106 | end | ||
107 | |||
108 | -- Pretty-print a bytecode instruction (one or two lines). | ||
109 | local function bytecodeout(out, func, pc) | ||
110 | local op, a, b, c = bytecode(func, pc) | ||
111 | if not op then | ||
112 | return true | ||
113 | elseif op == "JMP" then | ||
114 | out:write(format("\n--%04d-- JMP => %04d", pc, pc+1+b)) | ||
115 | elseif op == "FORLOOP" or op == "FORPREP" then | ||
116 | out:write(format("\n--%04d-- %-9s %3d => %04d", pc, op, a, pc+1+b)) | ||
117 | else | ||
118 | out:write(format("\n--%04d-- %-9s %3d %4s %4s", | ||
119 | pc, op, a, b or "", c or "")) | ||
120 | if b and b < 0 then out:write(" ; ", conststr(func, b)) end | ||
121 | if c and c < 0 then out:write(" ; ", conststr(func, c)) end | ||
122 | end | ||
123 | end | ||
124 | |||
125 | -- Dump machine code and mix it with the bytecode listing. | ||
126 | local function dumpfunc(func, out, deopt) | ||
127 | if not out then out = stderr end | ||
128 | local info = getinfo(func, "S") | ||
129 | |||
130 | -- Don't bother checking for the right blocks to dump. | ||
131 | -- Dump the main block (if not deopt) and always all deopt blocks. | ||
132 | for block=deopt and 2 or 1,1000000 do | ||
133 | local addr, code, mfmiter = jutil.mcode(func, block) | ||
134 | if not addr then | ||
135 | if code then return code end -- Not compiled: return status. | ||
136 | break -- No more blocks to dump. | ||
137 | end | ||
138 | |||
139 | -- Print header. | ||
140 | out:write(sepline, " ", info.source, ":", info.linedefined) | ||
141 | if block ~= 1 then out:write(" DEOPT block ", block) end | ||
142 | |||
143 | -- Create disassembler context. | ||
144 | local ctx = discreate(code, addr, function(s) out:write(s) end) | ||
145 | ctx.symtab = jsubmap | ||
146 | |||
147 | -- Dump an mcode block. | ||
148 | local pc, ofs = 1, 0 | ||
149 | local len, isdeopt = mfmiter() | ||
150 | if isdeopt then pc = len; len = 0 | ||
151 | elseif block ~= 1 then break end -- Stop before next main block. | ||
152 | for t, m in mfmiter do | ||
153 | if t == "COMBINE" then | ||
154 | bytecodeout(out, func, pc) | ||
155 | else | ||
156 | if len ~= 0 then | ||
157 | out:write("\n") | ||
158 | if len > 0 then | ||
159 | ctx:disass(ofs, len) | ||
160 | ofs = ofs + len | ||
161 | else | ||
162 | out:write(format("%08x ** deoptimized\n", addr+ofs)) | ||
163 | ofs = ofs - len | ||
164 | end | ||
165 | len = 0 | ||
166 | end | ||
167 | if type(t) == "number" then | ||
168 | if m then | ||
169 | if isdeopt then | ||
170 | pc = t - 1 | ||
171 | else | ||
172 | bytecodeout(out, func, pc) | ||
173 | len = -t | ||
174 | end | ||
175 | else | ||
176 | len = t | ||
177 | if bytecodeout(out, func, pc) then break end | ||
178 | end | ||
179 | end | ||
180 | end | ||
181 | pc = pc + 1 | ||
182 | end | ||
183 | if len and len ~= 0 then | ||
184 | out:write(sepline, " tail code\n") | ||
185 | ctx:disass(ofs, len) | ||
186 | end | ||
187 | end | ||
188 | |||
189 | -- Print footer. | ||
190 | out:write(sepline, "\n") | ||
191 | out:flush() | ||
192 | end | ||
193 | |||
194 | -- Dump the internal JIT subroutines. | ||
195 | local function dumpjsub_(out) | ||
196 | if not out then out = stderr end | ||
197 | local addr, code = jutil.jsubmcode() | ||
198 | |||
199 | -- Create disassembler context. | ||
200 | local ctx = discreate(code, addr, function(s) out:write(s) end) | ||
201 | ctx.symtab = jsubmap | ||
202 | |||
203 | -- Collect addresses and sort them. | ||
204 | local t = {} | ||
205 | for addr in pairs(jsubmap) do t[#t+1] = addr end | ||
206 | t[#t+1] = addr + #code | ||
207 | table.sort(t) | ||
208 | |||
209 | -- Go through the addresses in ascending order. | ||
210 | local ofs = addr | ||
211 | for i=2,#t do | ||
212 | local next = t[i] | ||
213 | out:write("\n->", jsubmap[ofs], ":\n") -- Output label for JSUB. | ||
214 | ctx:disass(ofs-addr, next-ofs) -- Disassemble corresponding code block. | ||
215 | ofs = next | ||
216 | end | ||
217 | out:flush() | ||
218 | end | ||
219 | |||
220 | |||
221 | -- Active flag and output file handle. | ||
222 | local active, out | ||
223 | |||
224 | -- Dump handler for compiler pipeline. | ||
225 | local function h_dump(st) | ||
226 | local ok, err = pcall(dumpfunc, st.func, out, st.deopt) | ||
227 | if not ok then | ||
228 | stderr:write("\nERROR: jit.dump disabled: ", err, "\n") | ||
229 | jit.attach(h_dump) -- Better turn ourselves off after a failure. | ||
230 | if out and out ~= stdout then out:close() end | ||
231 | out = nil | ||
232 | active = nil | ||
233 | end | ||
234 | end | ||
235 | |||
236 | -- Detach dump handler from compiler pipeline. | ||
237 | local function dumpoff() | ||
238 | if active then | ||
239 | active = false | ||
240 | jit.attach(h_dump) | ||
241 | if out and out ~= stdout then out:close() end | ||
242 | out = nil | ||
243 | end | ||
244 | end | ||
245 | |||
246 | -- Open the output file and attach dump handler to compiler pipeline. | ||
247 | local function dumpon(filename) | ||
248 | if active then dumpoff() end | ||
249 | local outfile = filename or os.getenv("LUAJIT_DUMPFILE") | ||
250 | out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w"))) | ||
251 | jit.attach(h_dump, PRIORITY) | ||
252 | active = true | ||
253 | end | ||
254 | |||
255 | |||
256 | -- Public module functions. | ||
257 | module(...) | ||
258 | |||
259 | disass = disass_ | ||
260 | dump = dumpfunc | ||
261 | dumpjsub = dumpjsub_ | ||
262 | on = dumpon | ||
263 | off = dumpoff | ||
264 | start = dumpon -- For -j command line option. | ||
265 | |||
diff --git a/libraries/LuaJIT-1.1.7/jit/dumphints.lua b/libraries/LuaJIT-1.1.7/jit/dumphints.lua new file mode 100644 index 0000000..4a64676 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jit/dumphints.lua | |||
@@ -0,0 +1,239 @@ | |||
1 | ---------------------------------------------------------------------------- | ||
2 | -- LuaJIT hints dumper module. | ||
3 | -- | ||
4 | -- Copyright (C) 2005-2011 Mike Pall. All rights reserved. | ||
5 | -- Released under the MIT/X license. See luajit.h for full copyright notice. | ||
6 | ---------------------------------------------------------------------------- | ||
7 | -- Activate this module to dump the bytecode and the hints from | ||
8 | -- the optimizer for all functions to be compiled. | ||
9 | -- | ||
10 | -- Try: luajit -O -j dumphints -e 'return 1' | ||
11 | -- | ||
12 | -- Default output is to stderr. To redirect output to a file, | ||
13 | -- pass a filename as an argument or set the environment variable | ||
14 | -- "LUAJIT_DUMPHINTSFILE". | ||
15 | -- Note: The file is overwritten each time you run luajit. | ||
16 | -- | ||
17 | -- TODO: Find a way to be more selective on what to dump. | ||
18 | ------------------------------------------------------------------------------ | ||
19 | |||
20 | -- Priority for compiler pipeline. Should run before backend (positive) | ||
21 | -- and should be even because we only catch successful compiles. | ||
22 | local PRIORITY = 10 | ||
23 | |||
24 | -- Cache some library functions and objects. | ||
25 | local jit = require("jit") | ||
26 | assert(jit.version_num == 10107, "LuaJIT core/library version mismatch") | ||
27 | local jutil = require("jit.util") | ||
28 | local type, pairs, format = type, pairs, string.format | ||
29 | local bytecode, const = jutil.bytecode, jutil.const | ||
30 | local hints, fhints = jutil.hints, jutil.fhints | ||
31 | local stdout, stderr = io.stdout, io.stderr | ||
32 | |||
33 | -- Turn compilation off for the whole module. LuaJIT would do that anyway. | ||
34 | jit.off(true, true) | ||
35 | |||
36 | -- Separator line. | ||
37 | local sepline = "-------------------------------" | ||
38 | |||
39 | |||
40 | -- Pretty-print a constant. | ||
41 | local function conststr(func, idx) | ||
42 | local k = const(func, idx) | ||
43 | if k == nil then return "nil" | ||
44 | elseif k == true then return "true" | ||
45 | elseif k == false then return "false" | ||
46 | elseif type(k) == "string" then | ||
47 | if #k > 10 then return format('"%.10s"~', k) | ||
48 | else return '"'..k..'"' end | ||
49 | else return k.."" end | ||
50 | end | ||
51 | |||
52 | -- Pretty-print a bytecode instruction. | ||
53 | local function bytecodeline(func, pc, flag) | ||
54 | local op, a, b, c = bytecode(func, pc) | ||
55 | if not op then return end | ||
56 | if op == "JMP" then | ||
57 | return format("\n%04d %s JMP => %04d", pc, flag, pc+1+b) | ||
58 | end | ||
59 | if op == "FORLOOP" or op == "FORPREP" then | ||
60 | return format("\n%04d %s %-9s %3d => %04d", pc, flag, op, a, pc+1+b) | ||
61 | end | ||
62 | local s = format("\n%04d %s %-9s %3d %4s %4s", | ||
63 | pc, flag, op, a, b or "", c or "") | ||
64 | if b and b < 0 then s = s.." ; "..conststr(func, b) end | ||
65 | if c and c < 0 then s = s.." ; "..conststr(func, c) end | ||
66 | return s | ||
67 | end | ||
68 | |||
69 | -- Precompute inverse hints table. | ||
70 | local invhints = {} | ||
71 | for k,v in pairs(hints) do invhints[v] = k end | ||
72 | |||
73 | -- The inverse resolver for inline functions is loaded on demand. | ||
74 | local getname | ||
75 | |||
76 | -- Helper functions to pretty-print hints. | ||
77 | local function typehint(h, v, st, pc) | ||
78 | if st[pc+hints.INLINE] then return "" end | ||
79 | local tp = type(v) | ||
80 | if tp == "function" then | ||
81 | tp = debug.getinfo(v, "S").what | ||
82 | elseif tp == "number" and v % 1 == 0 then | ||
83 | tp = "integer" | ||
84 | elseif v == false then | ||
85 | tp = "mixed" | ||
86 | end | ||
87 | return " #"..h.."("..tp..")" | ||
88 | end | ||
89 | |||
90 | local hintprint = { | ||
91 | COMBINE = function(h, v, st, pc) | ||
92 | if v == false then return "" end -- Dead instructions are already marked. | ||
93 | end, | ||
94 | TYPE = typehint, | ||
95 | TYPEKEY = typehint, | ||
96 | INLINE = function(h, v, st, pc) | ||
97 | if not getname then getname = require("jit.opt_inline").getname end | ||
98 | return " #INLINE("..getname(st[pc+hints.TYPE], v)..")" | ||
99 | end, | ||
100 | } | ||
101 | |||
102 | -- Generate range string from table: pc[-pc] [,...] | ||
103 | local function rangestring(t) | ||
104 | local s = "" | ||
105 | for i,range in ipairs(t) do | ||
106 | if i ~= 1 then s = s.."," end | ||
107 | local pc = range % 65536 | ||
108 | range = (range - pc) / 65536 | ||
109 | s = s..pc | ||
110 | if range ~= 0 then s = s..(-(pc+range)) end | ||
111 | end | ||
112 | return s | ||
113 | end | ||
114 | |||
115 | -- Dump instructions and hints for a (to be compiled) function. | ||
116 | local function dumphints(st, out) | ||
117 | if not out then out = stderr end | ||
118 | local func = st.func | ||
119 | local COMBINE = hints.COMBINE | ||
120 | |||
121 | -- Need to recompute branch targets (not part of hints). | ||
122 | local target = {} | ||
123 | for pc=1,1e6 do | ||
124 | local op, a, b, c = bytecode(func, pc) | ||
125 | if not op then break end | ||
126 | if op == "JMP" or op == "FORLOOP" then | ||
127 | local t = pc+1+b | ||
128 | if st[pc+COMBINE] ~= false then target[t] = true end | ||
129 | elseif op == "LOADBOOL" and c ~= 0 then | ||
130 | target[pc+2] = true | ||
131 | end | ||
132 | end | ||
133 | |||
134 | -- Map hints to bytecode instructions. | ||
135 | local hintstr = {} | ||
136 | for k,v in pairs(st) do | ||
137 | -- CHECK: must match hint shift in ljit_hints.h:JIT_H2NUM(). | ||
138 | if type(k) == "number" and k >= 65536 then | ||
139 | local pc = k % 65536 | ||
140 | if pc > 0 then | ||
141 | k = k - pc | ||
142 | local h = invhints[k] or (k/65536) | ||
143 | local hp = hintprint[h] | ||
144 | local s = hp and hp(h, v, st, pc) or (" #"..h) | ||
145 | local hs = hintstr[pc] | ||
146 | hintstr[pc] = hs and (hs..s) or s | ||
147 | end | ||
148 | end | ||
149 | end | ||
150 | |||
151 | -- Write header. | ||
152 | local info = debug.getinfo(func, "S") | ||
153 | out:write(sepline, " ", info.source, ":", info.linedefined) | ||
154 | |||
155 | -- Write function hints. | ||
156 | for k,v in pairs(fhints) do | ||
157 | if st[v] then out:write("\n#", k) end | ||
158 | end | ||
159 | |||
160 | -- Write instruction hints and bytecode. | ||
161 | local function dumprange(firstpc, lastpc) | ||
162 | for pc=firstpc,lastpc do | ||
163 | local prefix = " " | ||
164 | if st[pc+COMBINE] == false then prefix = "**" | ||
165 | elseif target[pc] then prefix = "=>" end | ||
166 | local line = bytecodeline(func, pc, prefix) | ||
167 | if not line then break end | ||
168 | local h = hintstr[pc] | ||
169 | if h then | ||
170 | out:write(format("%-40s %s", line, h)) | ||
171 | else | ||
172 | out:write(line) | ||
173 | end | ||
174 | end | ||
175 | end | ||
176 | |||
177 | -- Handle deoptimization range table. | ||
178 | local t = st.deopt | ||
179 | if t then | ||
180 | out:write(" DEOPT=", rangestring(t)) | ||
181 | for i,range in ipairs(t) do | ||
182 | if i ~= 1 then out:write("\n----") end | ||
183 | local pc = range % 65536 | ||
184 | range = (range - pc) / 65536 | ||
185 | dumprange(pc, pc+range) | ||
186 | end | ||
187 | else | ||
188 | dumprange(1, 1000000) | ||
189 | end | ||
190 | |||
191 | -- Write footer. | ||
192 | out:write("\n", sepline, "\n") | ||
193 | out:flush() | ||
194 | end | ||
195 | |||
196 | |||
197 | -- Active flag and output file handle. | ||
198 | local active, out | ||
199 | |||
200 | -- Dump hints handler for compiler pipeline. | ||
201 | local function h_dumphints(st) | ||
202 | local ok, err = pcall(dumphints, st, out) | ||
203 | if not ok then | ||
204 | stderr:write("\nERROR: jit.dumphints disabled: ", err, "\n") | ||
205 | jit.attach(h_dumphints) -- Better turn ourselves off after a failure. | ||
206 | if out and out ~= stdout then out:close() end | ||
207 | out = nil | ||
208 | active = nil | ||
209 | end | ||
210 | end | ||
211 | |||
212 | -- Detach dump handler from compiler pipeline. | ||
213 | local function dumphintsoff() | ||
214 | if active then | ||
215 | active = false | ||
216 | jit.attach(h_dumphints) | ||
217 | if out and out ~= stdout then out:close() end | ||
218 | out = nil | ||
219 | end | ||
220 | end | ||
221 | |||
222 | -- Open the output file and attach dump handler to compiler pipeline. | ||
223 | local function dumphintson(filename) | ||
224 | if active then dumphintsoff() end | ||
225 | local outfile = filename or os.getenv("LUAJIT_DUMPHINTSFILE") | ||
226 | out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w"))) | ||
227 | jit.attach(h_dumphints, PRIORITY) | ||
228 | active = true | ||
229 | end | ||
230 | |||
231 | |||
232 | -- Public module functions. | ||
233 | module(...) | ||
234 | |||
235 | dump = dumphints | ||
236 | on = dumphintson | ||
237 | off = dumphintsoff | ||
238 | start = dumphintson -- For -j command line option. | ||
239 | |||
diff --git a/libraries/LuaJIT-1.1.7/jit/opt.lua b/libraries/LuaJIT-1.1.7/jit/opt.lua new file mode 100644 index 0000000..5fe0f34 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jit/opt.lua | |||
@@ -0,0 +1,508 @@ | |||
1 | ---------------------------------------------------------------------------- | ||
2 | -- LuaJIT optimizer. | ||
3 | -- | ||
4 | -- Copyright (C) 2005-2011 Mike Pall. All rights reserved. | ||
5 | -- Released under the MIT/X license. See luajit.h for full copyright notice. | ||
6 | ---------------------------------------------------------------------------- | ||
7 | -- This module contains a simple optimizer that generates some hints for | ||
8 | -- the compiler backend. | ||
9 | -- | ||
10 | -- Compare: luajit -j dump -e 'return 1' | ||
11 | -- with: luajit -O -j dumphints -j dump -e 'return 1' | ||
12 | -- | ||
13 | -- This module uses a very simplistic (but fast) abstract interpretation | ||
14 | -- algorithm. It mostly ignores control flow and/or basic block boundaries. | ||
15 | -- Thus the results of the analysis are really only predictions (e.g. about | ||
16 | -- monomorphic use of operators). The backend _must_ check all contracts | ||
17 | -- (e.g. verify the object type) and use a (polymorphic) fallback or | ||
18 | -- deoptimization in case a contract is broken. | ||
19 | -- | ||
20 | -- Although simplistic, the generated hints are pretty accurate. Note that | ||
21 | -- some hints are really definitive and don't need to be checked (like | ||
22 | -- COMBINE or FOR_STEP_K). | ||
23 | -- | ||
24 | -- TODO: Try MFP with an extended lattice. But it's unclear whether the | ||
25 | -- added complexity really pays off with the current backend. | ||
26 | ------------------------------------------------------------------------------ | ||
27 | |||
28 | -- Priority for compiler pipeline. Right in the middle before the backend. | ||
29 | local PRIORITY = 50 | ||
30 | |||
31 | -- Default optimizer level, i.e. what you get with -O. | ||
32 | -- Caveat: this may change in the future when more optimizations are added. | ||
33 | local OPTLEVEL = 2 | ||
34 | |||
35 | -- Heuristic limits for what the compiler should reasonably handle. | ||
36 | -- Functions outside these limits are unlikely to be run more than once. | ||
37 | -- Maybe a bit on the generous side. Check ljit.h for backend limits, too. | ||
38 | -- TODO: make it depend on the bytecode distribution, too. | ||
39 | local LIMITS = { | ||
40 | bytecodes = 4000, | ||
41 | stackslots = 150, | ||
42 | params = 20, | ||
43 | consts = 200, | ||
44 | subs = 30, | ||
45 | } | ||
46 | |||
47 | -- Cache some library functions and objects. | ||
48 | local jit = require("jit") | ||
49 | assert(jit.version_num == 10107, "LuaJIT core/library version mismatch") | ||
50 | local jutil = require("jit.util") | ||
51 | local type, rawget, next, pcall = type, rawget, next, pcall | ||
52 | local bytecode, const = jutil.bytecode, jutil.const | ||
53 | local hints, fhints = jutil.hints, jutil.fhints | ||
54 | local getmetatable = getmetatable | ||
55 | |||
56 | -- Turn compilation off for the whole module. LuaJIT would do that anyway. | ||
57 | jit.off(true, true) | ||
58 | |||
59 | -- Default optimizer level after loading. But -O runs setlevel(), too. | ||
60 | local optlevel = -1 | ||
61 | |||
62 | |||
63 | -- Use iterative path marking to mark live instructions and branch targets. | ||
64 | local function marklive(func) | ||
65 | local live, work, workn, pc = {}, {}, 0, 1 | ||
66 | repeat | ||
67 | repeat | ||
68 | local op, a, b, c, test = bytecode(func, pc) | ||
69 | live[pc] = true | ||
70 | pc = pc + 1 | ||
71 | if op == "JMP" then | ||
72 | pc = pc + b | ||
73 | live[-pc] = true | ||
74 | elseif op == "FORLOOP" then | ||
75 | local mpc = -pc | ||
76 | live[mpc - b] = true | ||
77 | live[mpc] = true | ||
78 | elseif op == "RETURN" then | ||
79 | break | ||
80 | elseif test then | ||
81 | local fpc = pc + 1 | ||
82 | -- No need for fallthrough target mark live[-fpc] in our analysis. | ||
83 | if not live[fpc] then -- Add fallthrough path to work list. | ||
84 | workn = workn + 1 | ||
85 | work[workn] = fpc | ||
86 | end | ||
87 | elseif op == "CLOSURE" then | ||
88 | pc = pc + jutil.closurenup(func, b) -- Do not mark pseudo-ins live. | ||
89 | elseif op == "LOADBOOL" and c ~= 0 then | ||
90 | pc = pc + 1 | ||
91 | live[-pc] = true | ||
92 | elseif op == "SETLIST" and c == 0 then | ||
93 | pc = pc + 1 -- Do not mark pseudo-ins live. | ||
94 | end | ||
95 | until live[pc] | ||
96 | if workn == 0 then return live end -- Return if work list is empty. | ||
97 | pc = work[workn] -- Else fetch next path to mark from work list. | ||
98 | workn = workn - 1 | ||
99 | until false | ||
100 | end | ||
101 | |||
102 | |||
103 | -- Empty objects. | ||
104 | local function empty() end | ||
105 | |||
106 | -- Dummy function to set call hints. Replaced when jit.opt_inline is loaded. | ||
107 | local function callhint(st, slot, pc, base, narg, nres) | ||
108 | st[pc+hints.TYPE] = slot[base] | ||
109 | for i=base,base+nres-1 do slot[i] = nil end | ||
110 | end | ||
111 | |||
112 | -- Set TYPE hint, but only for numbers, strings or tables. | ||
113 | local function typehint(st, pc, o) | ||
114 | local tp = type(o) | ||
115 | if tp == "number" or tp == "string" or tp == "table" then | ||
116 | st[pc+hints.TYPE] = o | ||
117 | end | ||
118 | end | ||
119 | |||
120 | -- Set TYPE and TYPEKEY hints for table operations. | ||
121 | local function tablehint(st, slot, pc, t, kslot) | ||
122 | local tp = type(t) | ||
123 | if tp == "table" or tp == "userdata" then st[pc+hints.TYPE] = t end | ||
124 | if kslot >= 0 then -- Don't need this hint for constants. | ||
125 | local key = slot[kslot] | ||
126 | local tp = type(key) | ||
127 | if tp == "number" or tp == "string" then st[pc+hints.TYPEKEY] = key end | ||
128 | end | ||
129 | end | ||
130 | |||
131 | -- Try to lookup a value. Guess the value or at least the value type. | ||
132 | local function trylookup(st, t, k) | ||
133 | if k == nil then return nil end | ||
134 | if type(t) == "table" then | ||
135 | local v = rawget(t, k) | ||
136 | if v ~= nil then return v end | ||
137 | end | ||
138 | local mt = getmetatable(t) | ||
139 | if type(mt) == "table" then | ||
140 | -- One __index level is enough for our purposes. | ||
141 | local it = rawget(mt, "__index") | ||
142 | if type(it) == "table" then | ||
143 | local v = rawget(it, k) | ||
144 | if v ~= nil then return v end | ||
145 | end | ||
146 | end | ||
147 | local v = st.tableval[t] -- Resort to a generic guess. | ||
148 | if v == nil and type(t) == "table" then v = next(t) end -- Getting desperate. | ||
149 | return v | ||
150 | end | ||
151 | |||
152 | -- Check whether the previous instruction sets a const. | ||
153 | local function prevconst(st, slot, pc, reg) | ||
154 | if st.live[-pc] == nil then -- Current instruction must not be a target. | ||
155 | local op, ka, kb = bytecode(st.func, pc-1) | ||
156 | if ka == reg and (op == "LOADK" or op == "LOADBOOL" or | ||
157 | (op == "LOADNIL" and kb == reg)) then | ||
158 | return true, slot[reg] | ||
159 | end | ||
160 | end | ||
161 | end | ||
162 | |||
163 | -- Common handler for arithmetic and comparison opcodes. | ||
164 | local function arithop(st, slot, pc, a, b, c, op) | ||
165 | local sb, sc = slot[b], slot[c] | ||
166 | if sb == nil then sb = sc elseif sc == nil then sc = sb end | ||
167 | local tb, tc = type(sb), type(sc) | ||
168 | if tb == tc then | ||
169 | if tb == "number" then -- Improve the guess for numbers. | ||
170 | if op == "DIV" or sb % 1 ~= 0 or sc % 1 ~= 0 then | ||
171 | sb = 0.5 -- Probably a non-integral number. | ||
172 | else | ||
173 | sb = 1 -- Optimistic guess. | ||
174 | end | ||
175 | end | ||
176 | if sb ~= nil then st[pc+hints.TYPE] = sb end | ||
177 | else | ||
178 | st[pc+hints.TYPE] = false -- Marker for mixed types. | ||
179 | end | ||
180 | if op ~= "LT" and op ~= "LE" then | ||
181 | slot[a] = sb -- Assume coercion to 1st type if different. | ||
182 | end | ||
183 | end | ||
184 | |||
185 | -- Common handler for TEST and TESTSET. | ||
186 | local function testop(st, slot, pc, a, b, c) | ||
187 | -- Optimize the 'expr and k1 or k2' idiom. | ||
188 | local ok, k = prevconst(st, slot, pc, b) | ||
189 | if k and a == b then | ||
190 | st[pc+hints.COMBINE] = false -- Kill the TEST/TESTSET. | ||
191 | if c == 0 then st.live[pc+1] = nil end -- Kill the JMP. | ||
192 | end | ||
193 | slot[a] = slot[b] | ||
194 | end | ||
195 | |||
196 | -- Dispatch table for opcode handlers. | ||
197 | local handler = { | ||
198 | MOVE = function(st, slot, pc, a, b, c) | ||
199 | slot[a] = slot[b] | ||
200 | end, | ||
201 | |||
202 | LOADK = function(st, slot, pc, a, b, c) | ||
203 | slot[a] = const(st.func, b) | ||
204 | end, | ||
205 | |||
206 | LOADBOOL = function(st, slot, pc, a, b, c) | ||
207 | slot[a] = (b == 1) | ||
208 | end, | ||
209 | |||
210 | LOADNIL = function(st, slot, pc, a, b, c) | ||
211 | for i=a,b do slot[i] = nil end | ||
212 | end, | ||
213 | |||
214 | GETUPVAL = function(st, slot, pc, a, b, c) | ||
215 | slot[a] = jutil.upvalue(st.func, b) | ||
216 | end, | ||
217 | |||
218 | GETGLOBAL = function(st, slot, pc, a, b, c) | ||
219 | slot[a] = trylookup(st, st.stats.env, const(st.func, b)) | ||
220 | end, | ||
221 | |||
222 | GETTABLE = function(st, slot, pc, a, b, c) | ||
223 | local t = slot[b] | ||
224 | tablehint(st, slot, pc, t, c) | ||
225 | slot[a] = trylookup(st, t, slot[c]) | ||
226 | end, | ||
227 | |||
228 | SETGLOBAL = empty, | ||
229 | |||
230 | SETUPVAL = empty, -- TODO: shortcut -- but this is rare? | ||
231 | |||
232 | SETTABLE = function(st, slot, pc, a, b, c) | ||
233 | local t = slot[a] | ||
234 | tablehint(st, slot, pc, t, b) | ||
235 | if type(t) == "table" or type(t) == "userdata" then -- Must validate setkey. | ||
236 | local val = slot[c] | ||
237 | if val ~= nil then st.tableval[t] = val end | ||
238 | end | ||
239 | end, | ||
240 | |||
241 | NEWTABLE = function(st, slot, pc, a, b, c) | ||
242 | slot[a] = {} -- Need unique tables for indexing st.tableval. | ||
243 | end, | ||
244 | |||
245 | SELF = function(st, slot, pc, a, b, c) | ||
246 | local t = slot[b] | ||
247 | tablehint(st, slot, pc, t, c) | ||
248 | slot[a+1] = t | ||
249 | slot[a] = trylookup(st, t, slot[c]) | ||
250 | end, | ||
251 | |||
252 | ADD = arithop, SUB = arithop, MUL = arithop, DIV = arithop, | ||
253 | MOD = arithop, POW = arithop, LT = arithop, LE = arithop, | ||
254 | |||
255 | UNM = function(st, slot, pc, a, b, c) | ||
256 | return arithop(st, slot, pc, a, b, b, "UNM") | ||
257 | end, | ||
258 | |||
259 | NOT = function(st, slot, pc, a, b, c) | ||
260 | slot[a] = true | ||
261 | end, | ||
262 | |||
263 | LEN = function(st, slot, pc, a, b, c) | ||
264 | typehint(st, pc, slot[b]) | ||
265 | slot[a] = 1 | ||
266 | end, | ||
267 | |||
268 | CONCAT = function(st, slot, pc, a, b, c) | ||
269 | local mixed | ||
270 | local sb = slot[b] | ||
271 | for i=b+1,c do | ||
272 | local si = slot[i] | ||
273 | if sb == nil then | ||
274 | sb = si | ||
275 | elseif si ~= nil and type(sb) ~= type(si) then | ||
276 | mixed = true | ||
277 | break | ||
278 | end | ||
279 | end | ||
280 | if sb == nil then | ||
281 | sb = "" | ||
282 | else | ||
283 | st[pc+hints.TYPE] = not mixed and sb or false | ||
284 | if type(sb) == "number" then sb = "" end | ||
285 | end | ||
286 | slot[a] = sb -- Assume coercion to 1st type (if different) or string. | ||
287 | end, | ||
288 | |||
289 | JMP = function(st, slot, pc, a, b, c) | ||
290 | if b >= 0 then -- Kill JMPs across dead code. | ||
291 | local tpc = pc + b | ||
292 | while not st.live[tpc] do tpc = tpc - 1 end | ||
293 | if tpc == pc then st[pc+hints.COMBINE] = false end | ||
294 | end | ||
295 | end, | ||
296 | |||
297 | EQ = function(st, slot, pc, a, b, c) | ||
298 | if b >= 0 and c >= 0 then typehint(st, pc, slot[b] or slot[c]) end | ||
299 | end, | ||
300 | |||
301 | TEST = function(st, slot, pc, a, b, c) | ||
302 | return testop(st, slot, pc, a, a, c) | ||
303 | end, | ||
304 | |||
305 | TESTSET = testop, | ||
306 | |||
307 | CALL = function(st, slot, pc, a, b, c) | ||
308 | callhint(st, slot, pc, a, b-1, c-1) | ||
309 | end, | ||
310 | |||
311 | TAILCALL = function(st, slot, pc, a, b, c) | ||
312 | callhint(st, slot, pc, a, b-1, -1) | ||
313 | end, | ||
314 | |||
315 | RETURN = function(st, slot, pc, a, b, c) | ||
316 | if b == 2 and prevconst(st, slot, pc, a) then | ||
317 | st[pc-1+hints.COMBINE] = true -- Set COMBINE hint for prev. instruction. | ||
318 | end | ||
319 | end, | ||
320 | |||
321 | FORLOOP = empty, | ||
322 | |||
323 | FORPREP = function(st, slot, pc, a, b, c) | ||
324 | local ok, step = prevconst(st, slot, pc, a+2) | ||
325 | if type(step) == "number" then | ||
326 | st[pc+hints.FOR_STEP_K] = step | ||
327 | end | ||
328 | local nstart, nstep = slot[a], slot[a+2] | ||
329 | local tnstart, tnstep = type(nstart), type(nstep) | ||
330 | local ntype = ((tnstart == "number" and nstart % 1 ~= 0) or | ||
331 | (tnstep == "number" and nstep % 1 ~= 0)) and 0.5 or 1 | ||
332 | slot[a+3] = ntype | ||
333 | if tnstart == "number" and tnstep == "number" and | ||
334 | type(slot[a+1]) == "number" then | ||
335 | st[pc+hints.TYPE] = ntype | ||
336 | end | ||
337 | end, | ||
338 | |||
339 | -- TFORLOOP is at the end of the loop. Setting slots would be pointless. | ||
340 | -- Inlining is handled by the corresponding iterator constructor (CALL). | ||
341 | TFORLOOP = function(st, slot, pc, a, b, c) | ||
342 | st[pc+hints.TYPE] = slot[a] | ||
343 | end, | ||
344 | |||
345 | SETLIST = function(st, slot, pc, a, b, c) | ||
346 | -- TODO: if only (numeric) const: shortcut (+ nobarrier). | ||
347 | local t = slot[a] | ||
348 | -- Very imprecise. But better than nothing. | ||
349 | if type(t) == "table" then st.tableval[t] = slot[a+1] end | ||
350 | end, | ||
351 | |||
352 | CLOSE = empty, | ||
353 | |||
354 | CLOSURE = function(st, slot, pc, a, b, c) | ||
355 | slot[a] = empty | ||
356 | if st.noclose then | ||
357 | local nup = jutil.closurenup(st.func, b) | ||
358 | for i=pc+1,pc+nup do | ||
359 | local op = bytecode(st.func, i) | ||
360 | if op == "MOVE" then | ||
361 | st.noclose = false | ||
362 | return | ||
363 | end | ||
364 | end | ||
365 | end | ||
366 | end, | ||
367 | |||
368 | VARARG = function(st, slot, pc, a, b, c) | ||
369 | local params = st.stats.params | ||
370 | for i=1,b do slot[a+i-1] = st[params+i] end | ||
371 | end, | ||
372 | } | ||
373 | |||
374 | -- Generate some hints for the compiler backend. | ||
375 | local function optimize(st) | ||
376 | -- Deoptimization is simple: just don't generate any hints. :-) | ||
377 | if st.deopt then return end | ||
378 | |||
379 | local func = st.func | ||
380 | local stats = jutil.stats(func) | ||
381 | if not stats then return jutil.status.COMPILER_ERROR end -- Eh? | ||
382 | |||
383 | -- Check limits. | ||
384 | if stats.bytecodes > LIMITS.bytecodes or | ||
385 | stats.stackslots > LIMITS.stackslots or | ||
386 | stats.params > LIMITS.params or | ||
387 | stats.consts > LIMITS.consts or | ||
388 | stats.subs > LIMITS.subs then | ||
389 | return jutil.status.TOOLARGE | ||
390 | end | ||
391 | |||
392 | -- Mark live instructions (live[pc]) and branch targets (live[-pc]). | ||
393 | local live = marklive(func) | ||
394 | |||
395 | -- Handlers need access to some temporary state fields. | ||
396 | st.noclose = true | ||
397 | st.stats = stats | ||
398 | st.live = live | ||
399 | st.tableval = { [stats.env] = empty } -- Guess: unknown globals are functions. | ||
400 | |||
401 | -- Initialize slots with argument hints and constants. | ||
402 | local slot = {} | ||
403 | for i=1,stats.params do slot[i-1] = st[i] end | ||
404 | for i=-1,-256,-1 do -- No need to copy non-RK-able consts. | ||
405 | local k, ok = const(func, i) | ||
406 | if not ok then break end | ||
407 | slot[i] = k | ||
408 | end | ||
409 | |||
410 | -- Step through all live instructions, update slots and add hints. | ||
411 | for pc=1,stats.bytecodes do | ||
412 | if live[pc] then | ||
413 | local op, a, b, c, test = bytecode(func, pc) | ||
414 | handler[op](st, slot, pc, a, b, c, op) | ||
415 | else | ||
416 | st[pc+hints.COMBINE] = false -- Dead instruction hint. | ||
417 | end | ||
418 | end | ||
419 | |||
420 | -- Update function hints. | ||
421 | if st.noclose then st[fhints.NOCLOSE] = true end | ||
422 | |||
423 | -- Clear temporary state fields. | ||
424 | st.noclose = nil | ||
425 | st.stats = nil | ||
426 | st.live = nil | ||
427 | st.tableval = nil | ||
428 | end | ||
429 | |||
430 | |||
431 | -- Active flags. | ||
432 | local active, active_opt_inline | ||
433 | |||
434 | -- Handler for compiler pipeline. | ||
435 | local function h_opt(st) | ||
436 | if optlevel <= 0 then return end | ||
437 | local ok, err = pcall(optimize, st) | ||
438 | if not ok then | ||
439 | io.stderr:write("\nERROR: jit.opt disabled: ", err, "\n") | ||
440 | jit.attach(h_opt) -- Better turn ourselves off after a failure. | ||
441 | active = nil | ||
442 | else | ||
443 | if err then return err end | ||
444 | end | ||
445 | end | ||
446 | |||
447 | -- Load add-on module. | ||
448 | local function loadaddon(opt) | ||
449 | local name, val = string.match(opt, "^(.-)=(.*)$") -- Strip value. | ||
450 | if not name then name = opt end | ||
451 | name = "jit.opt_"..name | ||
452 | local ok, mod = pcall(require, name) | ||
453 | if not ok then | ||
454 | -- Return error if not installed, but propagate other errors. | ||
455 | if string.sub(mod, 1, 7) ~= "module " then error(mod, 0) end | ||
456 | return "optimizer add-on module "..name.." not found" | ||
457 | end | ||
458 | mod.start(val) | ||
459 | end | ||
460 | |||
461 | -- Attach optimizer and set optimizer level or load add-on module. | ||
462 | local function setlevel_(opt) | ||
463 | -- Easier to always attach the optimizer (even for -O0). | ||
464 | if not active then | ||
465 | jit.attach(h_opt, PRIORITY) | ||
466 | active = true | ||
467 | end | ||
468 | |||
469 | -- Parse -O<level> or -O<name[=value]>. | ||
470 | if opt == nil or opt == "" then | ||
471 | optlevel = OPTLEVEL | ||
472 | else | ||
473 | local level = tonumber(opt) -- Numeric level? | ||
474 | if level then | ||
475 | if level < 0 or level % 1 ~= 0 then | ||
476 | error("bad optimizer level", 0) | ||
477 | end | ||
478 | optlevel = level | ||
479 | else | ||
480 | if optlevel == -1 then optlevel = OPTLEVEL end | ||
481 | local err = loadaddon(opt) | ||
482 | if err then error(err, 0) end | ||
483 | end | ||
484 | end | ||
485 | |||
486 | -- Load add-on module for inlining functions for -O2 and above. | ||
487 | if not active_opt_inline and optlevel >= 2 then | ||
488 | loadaddon("inline") -- Be silent if not installed. | ||
489 | active_opt_inline = true -- Try this only once. | ||
490 | end | ||
491 | end | ||
492 | |||
493 | |||
494 | -- Public module functions. | ||
495 | module(...) | ||
496 | |||
497 | -- Callback to allow attaching a call hinter. Used by jit.opt_inline. | ||
498 | function attach_callhint(f) | ||
499 | callhint = f | ||
500 | end | ||
501 | |||
502 | function getlevel() | ||
503 | return optlevel | ||
504 | end | ||
505 | |||
506 | setlevel = setlevel_ | ||
507 | start = setlevel_ -- For -O command line option. | ||
508 | |||
diff --git a/libraries/LuaJIT-1.1.7/jit/opt_inline.lua b/libraries/LuaJIT-1.1.7/jit/opt_inline.lua new file mode 100644 index 0000000..cc19bf4 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jit/opt_inline.lua | |||
@@ -0,0 +1,397 @@ | |||
1 | ---------------------------------------------------------------------------- | ||
2 | -- LuaJIT optimizer add-on module for function inlining. | ||
3 | -- | ||
4 | -- Copyright (C) 2005-2011 Mike Pall. All rights reserved. | ||
5 | -- Released under the MIT/X license. See luajit.h for full copyright notice. | ||
6 | ---------------------------------------------------------------------------- | ||
7 | -- This is a simple framework for C function signature maps. | ||
8 | -- It helps with type propagation and C function inlining. | ||
9 | -- | ||
10 | -- This module is automatically loaded with -O2 and above. | ||
11 | -- By default most standard library functions are added. | ||
12 | -- | ||
13 | -- TODO: generalize it, e.g. for back propagation (i.e. arg types). | ||
14 | -- TODO: extend it for Lua functions (but need to analyze them before use). | ||
15 | ------------------------------------------------------------------------------ | ||
16 | |||
17 | -- Cache some library functions and objects. | ||
18 | local jit = require("jit") | ||
19 | assert(jit.version_num == 10107, "LuaJIT core/library version mismatch") | ||
20 | local jutil = require("jit.util") | ||
21 | local type, rawget, next = type, rawget, next | ||
22 | local hints, fhints = jutil.hints, jutil.fhints | ||
23 | local sub, match, gsub = string.sub, string.match, string.gsub | ||
24 | |||
25 | -- Turn compilation off for the whole module. LuaJIT would do that anyway. | ||
26 | jit.off(true, true) | ||
27 | |||
28 | -- Prototypical objects used for type hints. | ||
29 | local TABLE = {} | ||
30 | local CFUNC = collectgarbage -- Pretty sure this is never inlined. | ||
31 | |||
32 | |||
33 | -- Map from C closures to signatures. Cannot use a weak table. | ||
34 | -- Closures must be kept alive because inlining checks against their addrs. | ||
35 | local map_sign = {} | ||
36 | |||
37 | -- For jit.dumphints: get printable name for TYPE hint: "#INLINE(foo.bar)". | ||
38 | local function getname_(f, idx) | ||
39 | local sign = map_sign[f] | ||
40 | if sign then | ||
41 | local libname, name = sign.libname, sign.name | ||
42 | if libname then | ||
43 | return libname.."."..name | ||
44 | else | ||
45 | return name | ||
46 | end | ||
47 | elseif idx == 0 then | ||
48 | return "recursive" | ||
49 | else | ||
50 | return "?" | ||
51 | end | ||
52 | end | ||
53 | |||
54 | -- Name, base table and running index for convenience functions. | ||
55 | -- CHECK: the library index and the order below must match with ljit_hints.h | ||
56 | local flibname, flib, fidx | ||
57 | |||
58 | local function fadd(name, results, args, handler) | ||
59 | local f = rawget(flib, name) | ||
60 | if f then | ||
61 | map_sign[f] = { | ||
62 | libname = flibname, name = name, idx = fidx, | ||
63 | results = results, args = args, handler = handler, | ||
64 | } | ||
65 | end | ||
66 | if fidx then fidx = fidx + 1 end | ||
67 | end | ||
68 | |||
69 | local function faddf(name, f, results, args, handler) | ||
70 | map_sign[f] = { | ||
71 | libname = flibname, name = name, idx = fidx, | ||
72 | results = results, args = args, handler = handler, | ||
73 | } | ||
74 | if fidx then fidx = fidx + 1 end | ||
75 | end | ||
76 | |||
77 | |||
78 | -- Signature handler: copy first argument to first result. | ||
79 | local function copyfirst(st, slot, pc, base, narg, nres) | ||
80 | slot[base] = slot[base+1] | ||
81 | end | ||
82 | |||
83 | -- Helper for iterators: check if the function is an iterator constructor. | ||
84 | -- | ||
85 | -- 'for ivars in func(args) do body end' | ||
86 | -- | ||
87 | -- ...load func+args... | ||
88 | -- CALL func <-- pc | ||
89 | -- JMP fwd ---+ | ||
90 | -- back: | <--+ | ||
91 | -- ...body... | | | ||
92 | -- fwd: <--+ | | ||
93 | -- TFORLOOP ivars | <-- tforpc | ||
94 | -- JMP back ---+ | ||
95 | -- | ||
96 | local function itercheck(st, slot, pc, base, idx) | ||
97 | if idx then | ||
98 | local bytecode, func = jutil.bytecode, st.func | ||
99 | local op, _, fwd = bytecode(func, pc+1) | ||
100 | if op == "JMP" then | ||
101 | local tforpc = pc+2+fwd | ||
102 | local op, tfbase, _, tfnres = bytecode(func, tforpc) | ||
103 | if op == "TFORLOOP" and tfbase == base and tfnres <= 2 then | ||
104 | local op, _, back = bytecode(func, tforpc+1) | ||
105 | if op == "JMP" and fwd+back == -2 then | ||
106 | -- Must set inlining hint for TFORLOOP instruction here. | ||
107 | st[tforpc+hints.INLINE] = idx -- Serves as iterator index, too. | ||
108 | return -- Inline it. | ||
109 | end | ||
110 | end | ||
111 | end | ||
112 | end | ||
113 | slot[base] = CFUNC -- Better make it different from pairs. | ||
114 | return true -- Better not inline it, if not used in a for statement. | ||
115 | end | ||
116 | |||
117 | -- Helper for pairs/next: guess result types for standard table iterator. | ||
118 | local function guessnext(st, slot, base, dest) | ||
119 | local t, k, v = slot[base+1] | ||
120 | if type(t) == "table" then | ||
121 | k, v = next(t) | ||
122 | if v == nil then v = st.tableval[t] end | ||
123 | end | ||
124 | slot[dest] = k or "" -- Strings are a good guess for the key type. | ||
125 | slot[dest+1] = v -- But better not guess any fixed value type. | ||
126 | end | ||
127 | |||
128 | |||
129 | -- Signatures for base library functions. | ||
130 | -- Note: Only add functions where result type hints or inlining makes sense. | ||
131 | flibname, flib, fidx = nil, _G, 65536*1 | ||
132 | fadd("pairs", "..0", "T", | ||
133 | function(st, slot, pc, base, narg, nres, idx) | ||
134 | -- Table in slot[base+1] is kept (2nd result = 1st arg). | ||
135 | -- Fill result slots for the iterator here (TFORLOOP is at the end). | ||
136 | guessnext(st, slot, base, base+3) | ||
137 | return itercheck(st, slot, pc, base, idx) | ||
138 | end) | ||
139 | |||
140 | fadd("ipairs", "..I", "T", | ||
141 | function(st, slot, pc, base, narg, nres, idx) | ||
142 | -- Table in slot[base+1] is kept (2nd result = 1st arg). | ||
143 | -- Fill result slots for the iterator here (TFORLOOP is at the end). | ||
144 | local t = slot[base+1] | ||
145 | slot[base+3] = 1 -- Integer key. | ||
146 | local v | ||
147 | if type(t) == "table" then | ||
148 | v = rawget(t, 1) | ||
149 | if v == nil then v = st.tableval[t] end | ||
150 | end | ||
151 | slot[base+4] = v | ||
152 | return itercheck(st, slot, pc, base, idx) | ||
153 | end) | ||
154 | |||
155 | fidx = nil -- Pure result type signatures follow: | ||
156 | fadd("next", "..", "T.?", | ||
157 | function(st, slot, pc, base, narg, nres) | ||
158 | guessnext(st, slot, base, base) | ||
159 | end) | ||
160 | fadd("type", "S", ".") | ||
161 | fadd("getmetatable", "T", ".") | ||
162 | fadd("setmetatable", ".", "TT?", copyfirst) | ||
163 | fadd("rawequal", "B", "..") | ||
164 | fadd("rawget", ".", "T.", | ||
165 | function(st, slot, pc, base, narg, nres) | ||
166 | local t = slot[base+1] | ||
167 | slot[base] = type(t) == "table" and rawget(t, slot[base+2]) or "" | ||
168 | end) | ||
169 | fadd("rawset", ".", "T..", copyfirst) | ||
170 | fadd("assert", "*", "..*", | ||
171 | function(st, slot, pc, base, narg, nres) | ||
172 | for i=1,nres do slot[base+i-1] = i <= narg and slot[base+i] or nil end | ||
173 | end) | ||
174 | fadd("tonumber", "I", ".I?") | ||
175 | fadd("tostring", "S", ".") | ||
176 | fadd("require", "T", "S") | ||
177 | |||
178 | -- Signatures for coroutine library functions. | ||
179 | flibname, flib, fidx = "coroutine", coroutine, 65536*2 | ||
180 | if flib then | ||
181 | fadd("yield", "*", ".*") | ||
182 | fadd("resume", "*", "R.*", | ||
183 | function(st, slot, pc, base, narg, nres) | ||
184 | slot[base] = true | ||
185 | for i=1,nres-1 do slot[base+i] = nil end -- No guess. | ||
186 | end) | ||
187 | |||
188 | fidx = nil -- Pure result type signatures follow: | ||
189 | fadd("wrap", "C", "F") | ||
190 | end | ||
191 | |||
192 | -- Signatures for string library functions. | ||
193 | flibname, flib, fidx = "string", string, 65536*3 | ||
194 | if flib then | ||
195 | fadd("len", "I", "S") | ||
196 | fadd("sub", "S", "SII?") | ||
197 | fadd("char", "S", "I*") | ||
198 | |||
199 | fidx = nil -- Pure result type signatures follow: | ||
200 | fadd("byte", "I", "S", | ||
201 | function(st, slot, pc, base, narg, nres) | ||
202 | for i=0,nres-1 do slot[base+i] = 1 end -- Set all result hints. | ||
203 | end) | ||
204 | fadd("rep", "S", "SI") | ||
205 | fadd("reverse", "S", "S") | ||
206 | fadd("upper", "S", "S") | ||
207 | fadd("lower", "S", "S") | ||
208 | |||
209 | fadd("format", "S", "S.*") | ||
210 | fadd("find", "*", "SSI?.?", | ||
211 | function(st, slot, pc, base, narg, nres) | ||
212 | slot[base] = 1 | ||
213 | slot[base+1] = 1 | ||
214 | for i=2,nres-1 do slot[base+i] = "" end -- Hints for matches. | ||
215 | end) | ||
216 | fadd("match", "*", "SSI?", | ||
217 | function(st, slot, pc, base, narg, nres) | ||
218 | for i=0,nres-1 do slot[base+i] = "" end -- Hints for matches. | ||
219 | end) | ||
220 | fadd("gsub", "SI", "SSGI?") | ||
221 | fadd("gmatch", "C00", "SS", | ||
222 | function(st, slot, pc, base, narg, nres) | ||
223 | -- Fill result slots for gmatch_iter here (TFORLOOP is at the end). | ||
224 | for i=base+3,st.stats.stackslots-1 do slot[i] = "" end | ||
225 | end) | ||
226 | -- The gmatch iterator itself is never inlined. No point in adding it. | ||
227 | end | ||
228 | |||
229 | -- Signatures for table library functions. | ||
230 | flibname, flib, fidx = "table", table, 65536*4 | ||
231 | if flib then | ||
232 | fadd("insert", "", "TI?.") | ||
233 | fadd("remove", ".", "T", | ||
234 | function(st, slot, pc, base, narg, nres) | ||
235 | if nres >= 1 then | ||
236 | local t = slot[base+1] | ||
237 | slot[base] = type(t) == "table" and rawget(t, 1) or "" | ||
238 | end | ||
239 | end) | ||
240 | fadd("getn", "I", "T") | ||
241 | |||
242 | fidx = nil -- Pure result type signatures follow: | ||
243 | fadd("concat", "S", "TS?I?I?") | ||
244 | end | ||
245 | |||
246 | -- Signatures for math library functions. | ||
247 | flibname, flib, fidx = "math", math, 65536*5 | ||
248 | if flib then | ||
249 | -- 1 arg, 1 result. | ||
250 | fadd("log", "N", "N") | ||
251 | fadd("log10", "N", "N") | ||
252 | fadd("exp", "N", "N") | ||
253 | fadd("sinh", "N", "N") | ||
254 | fadd("cosh", "N", "N") | ||
255 | fadd("tanh", "N", "N") | ||
256 | fadd("asin", "N", "N") | ||
257 | fadd("acos", "N", "N") | ||
258 | fadd("atan", "N", "N") | ||
259 | fadd("sin", "N", "N") | ||
260 | fadd("cos", "N", "N") | ||
261 | fadd("tan", "N", "N") | ||
262 | fadd("ceil", "I", "N") | ||
263 | fadd("floor", "I", "N") | ||
264 | fadd("abs", ".", "N", copyfirst) | ||
265 | fadd("sqrt", "N", "N") | ||
266 | -- 2 args, 1 result. | ||
267 | -- math.fmod is aliased to math.mod for compatibility. | ||
268 | fadd("fmod", ".", "NN", | ||
269 | function(st, slot, pc, base, narg, nres) | ||
270 | slot[base] = slot[base+2] or 1 -- Copy integer or number hint. | ||
271 | end) | ||
272 | fadd("atan2", "N", "NN") | ||
273 | |||
274 | fidx = nil -- Pure result type signatures follow: | ||
275 | -- 1-n args, 1 result. | ||
276 | fadd("min", ".", "NN*", copyfirst) -- Really depends on all args. | ||
277 | fadd("max", ".", "NN*", copyfirst) -- Really depends on all args. | ||
278 | -- 1 arg, 1 result. | ||
279 | fadd("deg", "N", "N") | ||
280 | fadd("rad", "N", "N") | ||
281 | -- 1 arg, 2 results. | ||
282 | fadd("modf", "IN", "N") | ||
283 | fadd("frexp", "NI", "N") | ||
284 | -- 2 args, 1 result. | ||
285 | fadd("pow", "N", "NN") | ||
286 | fadd("ldexp", ".", "NI", copyfirst) | ||
287 | -- 1 arg, 0 results. | ||
288 | fadd("randomseed", "", "I") | ||
289 | -- 0-2 args, 1 result. | ||
290 | fadd("random", "N", "I?I?", | ||
291 | function(st, slot, pc, base, narg, nres) | ||
292 | if narg > 0 then slot[base] = 1 end | ||
293 | end) | ||
294 | end | ||
295 | |||
296 | -- Signatures for I/O library functions. | ||
297 | -- Not inlined anytime soon. Used for result types only. | ||
298 | flibname, flib, fidx = "io", io, nil | ||
299 | if flib then | ||
300 | fadd("lines", "C00S", "S?") | ||
301 | fadd("read", "S", "") -- Simplified (a lot). | ||
302 | -- Adding io methods doesn't work, because we don't deal with userdata (yet). | ||
303 | end | ||
304 | |||
305 | |||
306 | -- Type names to argument type shorthands. | ||
307 | -- TODO: make the matches more exact? Need to differentiate nil/unknown. | ||
308 | local map_argtype = { | ||
309 | ["nil"] = "0", boolean = "b", number = "n", string = "s", | ||
310 | table = "t", ["function"] = "f", userdata = "u", thread = "r", | ||
311 | } | ||
312 | |||
313 | -- Complex argument match patterns to regexp fragments. | ||
314 | local map_argmatch = { | ||
315 | B = "[b0]", S = "[s0]", T = "[t0]", F = "[f0]", U = "[u0]", R = "[r0]", | ||
316 | N = "[n0]", I = "[n0]", -- Number/int args are the same for now. | ||
317 | G = "[stf0]", -- For string.gsub. | ||
318 | } | ||
319 | |||
320 | -- Result type shorthands to sample types. | ||
321 | local map_restype = { | ||
322 | -- ["0"] = nil, | ||
323 | B = true, S = "", T = {}, | ||
324 | N = 0.5, I = 1, | ||
325 | L = function() end, C = collectgarbage, -- Pretty sure this is never inlined. | ||
326 | } | ||
327 | |||
328 | -- Create argument match regexp and cache it. | ||
329 | local function getargmatch(sign) | ||
330 | local argmatch = "^"..gsub(sign.args, ".", map_argmatch).."0*$" | ||
331 | sign.argmatch = argmatch | ||
332 | return argmatch | ||
333 | end | ||
334 | |||
335 | -- Set INLINE hints and result types for known C functions. | ||
336 | local function inlinehint(sign, st, slot, pc, base, narg, nres) | ||
337 | local idx = sign.idx | ||
338 | if idx then | ||
339 | if narg ~= -1 then | ||
340 | local argpat = "" | ||
341 | for i=1,narg do argpat = argpat..map_argtype[type(slot[base+i])] end | ||
342 | if not match(argpat, sign.argmatch or getargmatch(sign)) then | ||
343 | idx = nil | ||
344 | end | ||
345 | end | ||
346 | end | ||
347 | |||
348 | local results = sign.results | ||
349 | if results ~= "*" and nres ~= -1 then | ||
350 | if nres > #results then idx = nil end | ||
351 | for i=1,#results do | ||
352 | local c = sub(results, i, i) | ||
353 | if c ~= "." then slot[base+i-1] = map_restype[c] end | ||
354 | end | ||
355 | end | ||
356 | |||
357 | local handler = sign.handler | ||
358 | if handler and handler(st, slot, pc, base, narg, nres, idx) then idx = nil end | ||
359 | |||
360 | if idx then st[pc+hints.INLINE] = idx end | ||
361 | end | ||
362 | |||
363 | -- Set call hints and result types during forward propagation. | ||
364 | local function fwdcallhint(st, slot, pc, base, narg, nres) | ||
365 | local f = slot[base] | ||
366 | st[pc+hints.TYPE] = f | ||
367 | if type(f) == "function" then | ||
368 | local sign = map_sign[f] | ||
369 | if sign then | ||
370 | inlinehint(sign, st, slot, pc, base, narg, nres) | ||
371 | return | ||
372 | end | ||
373 | if f == st.func and not st.stats.isvararg and | ||
374 | (narg == -1 or narg == st.stats.params) then | ||
375 | st[pc+hints.INLINE] = 0 -- Recursive call. | ||
376 | end | ||
377 | end | ||
378 | -- Clear result types for unknown functions. | ||
379 | for i=base,base+nres-1 do slot[i] = nil end | ||
380 | end | ||
381 | |||
382 | |||
383 | -- Attach call hinter to optimizer. | ||
384 | local function start_() | ||
385 | local jopt = require "jit.opt" | ||
386 | jopt.attach_callhint(fwdcallhint) | ||
387 | -- Note that just loading the optimizer does not start it, yet. | ||
388 | end | ||
389 | |||
390 | |||
391 | -- Public module functions. | ||
392 | module(...) | ||
393 | |||
394 | -- TODO: Public API to add signatures. Alas, the API is still in flux. | ||
395 | getname = getname_ | ||
396 | start = start_ | ||
397 | |||
diff --git a/libraries/LuaJIT-1.1.7/jit/trace.lua b/libraries/LuaJIT-1.1.7/jit/trace.lua new file mode 100644 index 0000000..42367c6 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jit/trace.lua | |||
@@ -0,0 +1,111 @@ | |||
1 | ---------------------------------------------------------------------------- | ||
2 | -- LuaJIT compiler tracing module. | ||
3 | -- | ||
4 | -- Copyright (C) 2005-2011 Mike Pall. All rights reserved. | ||
5 | -- Released under the MIT/X license. See luajit.h for full copyright notice. | ||
6 | ---------------------------------------------------------------------------- | ||
7 | -- Activate this module to trace the progress of the JIT compiler. | ||
8 | -- | ||
9 | -- Try: luajit -j trace -e 'print "foo"' | ||
10 | -- luajit -j trace=foo.trace foo.lua | ||
11 | -- | ||
12 | -- Default output is to stderr. To redirect output to a file, | ||
13 | -- pass a filename as an argument or set the environment variable | ||
14 | -- "LUAJIT_TRACEFILE". | ||
15 | -- Note: the file is overwritten each time you run luajit. | ||
16 | ------------------------------------------------------------------------------ | ||
17 | |||
18 | -- Priority for compiler pipeline. Must run after backend (negative) | ||
19 | -- and should be odd to catch compiler errors, too. | ||
20 | local PRIORITY = -99 | ||
21 | |||
22 | -- Cache some library functions and objects. | ||
23 | local jit = require("jit") | ||
24 | assert(jit.version_num == 10107, "LuaJIT core/library version mismatch") | ||
25 | local jutil = require("jit.util") | ||
26 | local type, tostring, sub, format = type, tostring, string.sub, string.format | ||
27 | local getinfo, justats = debug.getinfo, jutil.stats | ||
28 | local stdout, stderr = io.stdout, io.stderr | ||
29 | |||
30 | -- Turn compilation off for the whole module. LuaJIT would do that anyway. | ||
31 | jit.off(true, true) | ||
32 | |||
33 | -- Active flag and output file handle. | ||
34 | local active, out | ||
35 | |||
36 | -- Generate range string from table: pc[-pc] [,...] | ||
37 | local function rangestring(t) | ||
38 | local s = "" | ||
39 | for i,range in ipairs(t) do | ||
40 | if i ~= 1 then s = s.."," end | ||
41 | local pc = range % 65536 | ||
42 | range = (range - pc) / 65536 | ||
43 | s = s..pc | ||
44 | if range ~= 0 then s = s..(-(pc+range)) end | ||
45 | end | ||
46 | return s | ||
47 | end | ||
48 | |||
49 | -- Trace handler for compiler pipeline. | ||
50 | local function h_trace(st, status) | ||
51 | local o = out or stderr | ||
52 | local func = st.func | ||
53 | if type(func) ~= "function" then return end | ||
54 | local info = getinfo(func, "S") | ||
55 | local src, line = info.source, info.linedefined or 0 | ||
56 | if src then | ||
57 | if sub(src, 1, 1) == "@" or sub(src, 1, 2) == "=(" then | ||
58 | src = sub(src, 2) | ||
59 | else | ||
60 | src = "**"..string.gsub(sub(src, 1, 40), "%c", " ").."**" | ||
61 | end | ||
62 | else | ||
63 | src = "?" | ||
64 | end | ||
65 | local aux = st.deopt and " DEOPT="..rangestring(st.deopt) or "" | ||
66 | if status == nil then | ||
67 | local stats = justats(func) | ||
68 | if not stats then return end | ||
69 | o:write(format("[LuaJIT: OK %4d %6d %s:%d%s]\n", | ||
70 | stats.bytecodes, stats.mcodesize or -1, src, line, aux)) | ||
71 | return | ||
72 | else | ||
73 | local stname = jit.util.status[status] or status | ||
74 | local pc, err = st.dasm_pc, st.dasm_err | ||
75 | if type(pc) == "number" and type(err) == "number" then | ||
76 | local op = jutil.bytecode(func, pc) or "END" | ||
77 | o:write(format("[LuaJIT: %s %s@%d %08x %s:%d%s]\n", | ||
78 | stname, op, pc, err, src, line, aux)) | ||
79 | else | ||
80 | o:write(format("[LuaJIT: %s %s:%d%s]\n", stname, src, line, aux)) | ||
81 | end | ||
82 | end | ||
83 | end | ||
84 | |||
85 | -- Detach trace handler from compiler pipeline. | ||
86 | local function traceoff() | ||
87 | if active then | ||
88 | active = false | ||
89 | jit.attach(h_trace) | ||
90 | if out and out ~= stdout then out:close() end | ||
91 | out = nil | ||
92 | end | ||
93 | end | ||
94 | |||
95 | -- Open the output file and attach trace handler to compiler pipeline. | ||
96 | local function traceon(filename) | ||
97 | if active then traceoff() end | ||
98 | local outfile = filename or os.getenv("LUAJIT_TRACEFILE") | ||
99 | out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w"))) | ||
100 | jit.attach(h_trace, PRIORITY) | ||
101 | active = true | ||
102 | end | ||
103 | |||
104 | |||
105 | -- Public module functions. | ||
106 | module(...) | ||
107 | |||
108 | on = traceon | ||
109 | off = traceoff | ||
110 | start = traceon -- For -j command line option. | ||
111 | |||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/bluequad-print.css b/libraries/LuaJIT-1.1.7/jitdoc/bluequad-print.css new file mode 100644 index 0000000..69c07d6 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/bluequad-print.css | |||
@@ -0,0 +1,166 @@ | |||
1 | /* Copyright (C) 2004-2011 Mike Pall. | ||
2 | * | ||
3 | * You are welcome to use the general ideas of this design for your own sites. | ||
4 | * But please do not steal the stylesheet, the layout or the color scheme. | ||
5 | */ | ||
6 | body { | ||
7 | font-family: serif; | ||
8 | font-size: 11pt; | ||
9 | margin: 0 3em; | ||
10 | padding: 0; | ||
11 | border: none; | ||
12 | } | ||
13 | a:link, a:visited, a:hover, a:active { | ||
14 | text-decoration: none; | ||
15 | background: transparent; | ||
16 | color: #0000ff; | ||
17 | } | ||
18 | h1, h2, h3 { | ||
19 | font-family: sans-serif; | ||
20 | font-weight: bold; | ||
21 | text-align: left; | ||
22 | margin: 0.5em 0; | ||
23 | padding: 0; | ||
24 | } | ||
25 | h1 { | ||
26 | font-size: 200%; | ||
27 | } | ||
28 | h2 { | ||
29 | font-size: 150%; | ||
30 | } | ||
31 | h3 { | ||
32 | font-size: 125%; | ||
33 | } | ||
34 | p { | ||
35 | margin: 0 0 0.5em 0; | ||
36 | padding: 0; | ||
37 | } | ||
38 | ul, ol { | ||
39 | margin: 0.5em 0; | ||
40 | padding: 0 0 0 2em; | ||
41 | } | ||
42 | ul { | ||
43 | list-style: outside square; | ||
44 | } | ||
45 | ol { | ||
46 | list-style: outside decimal; | ||
47 | } | ||
48 | li { | ||
49 | margin: 0; | ||
50 | padding: 0; | ||
51 | } | ||
52 | dl { | ||
53 | margin: 1em 0; | ||
54 | padding: 1em; | ||
55 | border: 1px solid black; | ||
56 | } | ||
57 | dt { | ||
58 | font-weight: bold; | ||
59 | margin: 0; | ||
60 | padding: 0; | ||
61 | } | ||
62 | dt sup { | ||
63 | float: right; | ||
64 | margin-left: 1em; | ||
65 | } | ||
66 | dd { | ||
67 | margin: 0.5em 0 0 2em; | ||
68 | padding: 0; | ||
69 | } | ||
70 | table { | ||
71 | table-layout: fixed; | ||
72 | width: 100%; | ||
73 | margin: 1em 0; | ||
74 | padding: 0; | ||
75 | border: 1px solid black; | ||
76 | border-spacing: 0; | ||
77 | border-collapse: collapse; | ||
78 | } | ||
79 | tr { | ||
80 | margin: 0; | ||
81 | padding: 0; | ||
82 | border: none; | ||
83 | } | ||
84 | td { | ||
85 | text-align: left; | ||
86 | margin: 0; | ||
87 | padding: 0.2em 0.5em; | ||
88 | border-top: 1px solid black; | ||
89 | border-bottom: 1px solid black; | ||
90 | } | ||
91 | tr.separate td { | ||
92 | border-top: double; | ||
93 | } | ||
94 | tt, pre, code, kbd, samp { | ||
95 | font-family: monospace; | ||
96 | font-size: 75%; | ||
97 | } | ||
98 | kbd { | ||
99 | font-weight: bolder; | ||
100 | } | ||
101 | blockquote, pre { | ||
102 | margin: 1em 2em; | ||
103 | padding: 0; | ||
104 | } | ||
105 | img { | ||
106 | border: none; | ||
107 | vertical-align: baseline; | ||
108 | margin: 0; | ||
109 | padding: 0; | ||
110 | } | ||
111 | img.left { | ||
112 | float: left; | ||
113 | margin: 0.5em 1em 0.5em 0; | ||
114 | } | ||
115 | img.right { | ||
116 | float: right; | ||
117 | margin: 0.5em 0 0.5em 1em; | ||
118 | } | ||
119 | .flush { | ||
120 | clear: both; | ||
121 | visibility: hidden; | ||
122 | } | ||
123 | .hide, .noprint, #nav { | ||
124 | display: none !important; | ||
125 | } | ||
126 | .pagebreak { | ||
127 | page-break-before: always; | ||
128 | } | ||
129 | #site { | ||
130 | text-align: right; | ||
131 | font-family: sans-serif; | ||
132 | font-weight: bold; | ||
133 | margin: 0 1em; | ||
134 | border-bottom: 1pt solid black; | ||
135 | } | ||
136 | #site a { | ||
137 | font-size: 1.2em; | ||
138 | } | ||
139 | #site a:link, #site a:visited { | ||
140 | text-decoration: none; | ||
141 | font-weight: bold; | ||
142 | background: transparent; | ||
143 | color: #ffffff; | ||
144 | } | ||
145 | #logo { | ||
146 | color: #ff8000; | ||
147 | } | ||
148 | #head { | ||
149 | clear: both; | ||
150 | margin: 0 1em; | ||
151 | } | ||
152 | #main { | ||
153 | line-height: 1.3; | ||
154 | text-align: justify; | ||
155 | margin: 1em; | ||
156 | } | ||
157 | #foot { | ||
158 | clear: both; | ||
159 | font-size: 80%; | ||
160 | text-align: center; | ||
161 | margin: 0 1.25em; | ||
162 | padding: 0.5em 0 0 0; | ||
163 | border-top: 1pt solid black; | ||
164 | page-break-before: avoid; | ||
165 | page-break-after: avoid; | ||
166 | } | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/bluequad.css b/libraries/LuaJIT-1.1.7/jitdoc/bluequad.css new file mode 100644 index 0000000..8d72de9 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/bluequad.css | |||
@@ -0,0 +1,292 @@ | |||
1 | /* Copyright (C) 2004-2011 Mike Pall. | ||
2 | * | ||
3 | * You are welcome to use the general ideas of this design for your own sites. | ||
4 | * But please do not steal the stylesheet, the layout or the color scheme. | ||
5 | */ | ||
6 | /* colorscheme: | ||
7 | * | ||
8 | * site | head #4162bf/white | #6078bf/#e6ecff | ||
9 | * ------+------ ----------------+------------------- | ||
10 | * nav | main #bfcfff | #e6ecff/black | ||
11 | * | ||
12 | * nav: hiback loback #c5d5ff #b9c9f9 | ||
13 | * hiborder loborder #e6ecff #97a7d7 | ||
14 | * link hover #2142bf #ff0000 | ||
15 | * | ||
16 | * link: link visited hover #2142bf #8122bf #ff0000 | ||
17 | * | ||
18 | * main: boxback boxborder #f0f4ff #bfcfff | ||
19 | */ | ||
20 | body { | ||
21 | font-family: Verdana, Arial, Helvetica, sans-serif; | ||
22 | font-size: 10pt; | ||
23 | margin: 0; | ||
24 | padding: 0; | ||
25 | border: none; | ||
26 | background: #e0e0e0; | ||
27 | color: #000000; | ||
28 | } | ||
29 | a:link { | ||
30 | text-decoration: none; | ||
31 | background: transparent; | ||
32 | color: #2142bf; | ||
33 | } | ||
34 | a:visited { | ||
35 | text-decoration: none; | ||
36 | background: transparent; | ||
37 | color: #8122bf; | ||
38 | } | ||
39 | a:hover, a:active { | ||
40 | text-decoration: underline; | ||
41 | background: transparent; | ||
42 | color: #ff0000; | ||
43 | } | ||
44 | h1, h2, h3 { | ||
45 | font-weight: bold; | ||
46 | text-align: left; | ||
47 | margin: 0.5em 0; | ||
48 | padding: 0; | ||
49 | background: transparent; | ||
50 | } | ||
51 | h1 { | ||
52 | font-size: 200%; | ||
53 | line-height: 3em; /* really 6em relative to body, match #site span */ | ||
54 | margin: 0; | ||
55 | } | ||
56 | h2 { | ||
57 | font-size: 150%; | ||
58 | color: #606060; | ||
59 | } | ||
60 | h3 { | ||
61 | font-size: 125%; | ||
62 | color: #404040; | ||
63 | } | ||
64 | p { | ||
65 | max-width: 600px; | ||
66 | margin: 0 0 0.5em 0; | ||
67 | padding: 0; | ||
68 | } | ||
69 | ul, ol { | ||
70 | max-width: 600px; | ||
71 | margin: 0.5em 0; | ||
72 | padding: 0 0 0 2em; | ||
73 | } | ||
74 | ul { | ||
75 | list-style: outside square; | ||
76 | } | ||
77 | ol { | ||
78 | list-style: outside decimal; | ||
79 | } | ||
80 | li { | ||
81 | margin: 0; | ||
82 | padding: 0; | ||
83 | } | ||
84 | dl { | ||
85 | max-width: 600px; | ||
86 | margin: 1em 0; | ||
87 | padding: 1em; | ||
88 | border: 1px solid #bfcfff; | ||
89 | background: #f0f4ff; | ||
90 | } | ||
91 | dt { | ||
92 | font-weight: bold; | ||
93 | margin: 0; | ||
94 | padding: 0; | ||
95 | } | ||
96 | dt sup { | ||
97 | float: right; | ||
98 | margin-left: 1em; | ||
99 | color: #808080; | ||
100 | } | ||
101 | dt a:visited { | ||
102 | text-decoration: none; | ||
103 | color: #2142bf; | ||
104 | } | ||
105 | dt a:hover, dt a:active { | ||
106 | text-decoration: none; | ||
107 | color: #ff0000; | ||
108 | } | ||
109 | dd { | ||
110 | margin: 0.5em 0 0 2em; | ||
111 | padding: 0; | ||
112 | } | ||
113 | div.tablewrap { /* for IE *sigh* */ | ||
114 | max-width: 600px; | ||
115 | } | ||
116 | table { | ||
117 | table-layout: fixed; | ||
118 | border-spacing: 0; | ||
119 | border-collapse: collapse; | ||
120 | max-width: 600px; | ||
121 | width: 100%; | ||
122 | margin: 1em 0; | ||
123 | padding: 0; | ||
124 | border: 1px solid #bfcfff; | ||
125 | } | ||
126 | tr { | ||
127 | margin: 0; | ||
128 | padding: 0; | ||
129 | border: none; | ||
130 | } | ||
131 | tr.odd { | ||
132 | background: #f0f4ff; | ||
133 | } | ||
134 | tr.separate td { | ||
135 | border-top: 1px solid #bfcfff; | ||
136 | } | ||
137 | td { | ||
138 | text-align: left; | ||
139 | margin: 0; | ||
140 | padding: 0.2em 0.5em; | ||
141 | border: none; | ||
142 | } | ||
143 | tt, code, kbd, samp { | ||
144 | font-family: Courier New, Courier, monospace; | ||
145 | font-size: 110%; | ||
146 | } | ||
147 | kbd { | ||
148 | font-weight: bolder; | ||
149 | } | ||
150 | blockquote, pre { | ||
151 | max-width: 600px; | ||
152 | margin: 1em 2em; | ||
153 | padding: 0; | ||
154 | } | ||
155 | pre { | ||
156 | line-height: 1.1; | ||
157 | } | ||
158 | img { | ||
159 | border: none; | ||
160 | vertical-align: baseline; | ||
161 | margin: 0; | ||
162 | padding: 0; | ||
163 | } | ||
164 | img.left { | ||
165 | float: left; | ||
166 | margin: 0.5em 1em 0.5em 0; | ||
167 | } | ||
168 | img.right { | ||
169 | float: right; | ||
170 | margin: 0.5em 0 0.5em 1em; | ||
171 | } | ||
172 | .indent { | ||
173 | padding-left: 1em; | ||
174 | } | ||
175 | .flush { | ||
176 | clear: both; | ||
177 | visibility: hidden; | ||
178 | } | ||
179 | .hide, .noscreen { | ||
180 | display: none !important; | ||
181 | } | ||
182 | .ext { | ||
183 | color: #ff8000; | ||
184 | } | ||
185 | #site { | ||
186 | clear: both; | ||
187 | float: left; | ||
188 | width: 13em; | ||
189 | text-align: center; | ||
190 | font-weight: bold; | ||
191 | margin: 0; | ||
192 | padding: 0; | ||
193 | background: transparent; | ||
194 | color: #ffffff; | ||
195 | } | ||
196 | #site a { | ||
197 | font-size: 200%; | ||
198 | } | ||
199 | #site a:link, #site a:visited { | ||
200 | text-decoration: none; | ||
201 | font-weight: bold; | ||
202 | background: transparent; | ||
203 | color: #ffffff; | ||
204 | } | ||
205 | #site span { | ||
206 | line-height: 3em; /* really 6em relative to body, match h1 */ | ||
207 | } | ||
208 | #logo { | ||
209 | color: #ffb380; | ||
210 | } | ||
211 | #head { | ||
212 | margin: 0; | ||
213 | padding: 0 0 0 2em; | ||
214 | border-left: solid 13em #4162bf; | ||
215 | border-right: solid 3em #6078bf; | ||
216 | background: #6078bf; | ||
217 | color: #e6ecff; | ||
218 | } | ||
219 | #nav { | ||
220 | clear: both; | ||
221 | float: left; | ||
222 | overflow: hidden; | ||
223 | text-align: left; | ||
224 | line-height: 1.5; | ||
225 | width: 13em; | ||
226 | padding-top: 1em; | ||
227 | background: transparent; | ||
228 | } | ||
229 | #nav ul { | ||
230 | list-style: none outside; | ||
231 | margin: 0; | ||
232 | padding: 0; | ||
233 | } | ||
234 | #nav li { | ||
235 | margin: 0; | ||
236 | padding: 0; | ||
237 | } | ||
238 | #nav a { | ||
239 | display: block; | ||
240 | text-decoration: none; | ||
241 | font-weight: bold; | ||
242 | margin: 0; | ||
243 | padding: 2px 1em; | ||
244 | border-top: 1px solid transparent; | ||
245 | border-bottom: 1px solid transparent; | ||
246 | background: transparent; | ||
247 | color: #2142bf; | ||
248 | } | ||
249 | #nav a:hover, #nav a:active { | ||
250 | text-decoration: none; | ||
251 | border-top: 1px solid #97a7d7; | ||
252 | border-bottom: 1px solid #e6ecff; | ||
253 | background: #b9c9f9; | ||
254 | color: #ff0000; | ||
255 | } | ||
256 | #nav a.current, #nav a.current:hover, #nav a.current:active { | ||
257 | border-top: 1px solid #e6ecff; | ||
258 | border-bottom: 1px solid #97a7d7; | ||
259 | background: #c5d5ff; | ||
260 | color: #2142bf; | ||
261 | } | ||
262 | #nav ul ul a { | ||
263 | padding: 0 1em 0 2em; | ||
264 | } | ||
265 | #main { | ||
266 | line-height: 1.5; | ||
267 | text-align: left; | ||
268 | margin: 0; | ||
269 | padding: 1em 2em; | ||
270 | border-left: solid 13em #bfcfff; | ||
271 | border-right: solid 3em #e6ecff; | ||
272 | background: #e6ecff; | ||
273 | } | ||
274 | #foot { | ||
275 | clear: both; | ||
276 | font-size: 80%; | ||
277 | text-align: center; | ||
278 | margin: 0; | ||
279 | padding: 0.5em; | ||
280 | background: #6078bf; | ||
281 | color: #ffffff; | ||
282 | } | ||
283 | #foot a:link, #foot a:visited { | ||
284 | text-decoration: underline; | ||
285 | background: transparent; | ||
286 | color: #ffffff; | ||
287 | } | ||
288 | #foot a:hover, #foot a:active { | ||
289 | text-decoration: underline; | ||
290 | background: transparent; | ||
291 | color: #bfcfff; | ||
292 | } | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/coco.html b/libraries/LuaJIT-1.1.7/jitdoc/coco.html new file mode 100644 index 0000000..0ef43f1 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/coco.html | |||
@@ -0,0 +1,132 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>Coco</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>Coco</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a class="current" href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <p> | ||
63 | Coco is a small extension to get <strong>True C Coroutine</strong> | ||
64 | semantics for Lua 5.1. | ||
65 | </p> | ||
66 | <p> | ||
67 | Coco is both available as a stand-alone release and integrated | ||
68 | into <a href="luajit.html">LuaJIT</a> 1.x. | ||
69 | </p> | ||
70 | <p> | ||
71 | The stand-alone release is a patchset against the | ||
72 | <a href="http://www.lua.org/ftp/"><span class="ext">»</span> standard Lua 5.1.4</a> | ||
73 | distribution. There are no dependencies on LuaJIT. However LuaJIT 1.x | ||
74 | depends on Coco to allow yielding for JIT compiled functions. | ||
75 | </p> | ||
76 | <p> | ||
77 | Coco is Copyright © 2004-2011 Mike Pall. | ||
78 | Coco is free software, released under the | ||
79 | <a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">»</span> MIT/X license</a> | ||
80 | (same license as the Lua core). | ||
81 | </p> | ||
82 | <h2>Features</h2> | ||
83 | <p> | ||
84 | True C coroutine semantics mean you can yield from a coroutine | ||
85 | across a C call boundary and resume back to it. | ||
86 | </p> | ||
87 | <p> | ||
88 | Coco allows you to use a dedicated C stack for each coroutine. | ||
89 | Resuming a coroutine and yielding from a coroutine automatically switches | ||
90 | C stacks, too. | ||
91 | </p> | ||
92 | <p> | ||
93 | In particular you can now: | ||
94 | </p> | ||
95 | <ul> | ||
96 | <li>Yield across all metamethods (not advised for <tt>__gc</tt>).</li> | ||
97 | <li>Yield across iterator functions (<tt>for x in func do</tt>).</li> | ||
98 | <li>Yield across callbacks (<tt>table.foreach()</tt>, <tt>dofile()</tt>, ...).</li> | ||
99 | <li>Yield across protected callbacks (<tt>pcall()</tt>, <tt>xpcall()</tt>, ...).</li> | ||
100 | <li>Yield from C functions and resume back to them.</li> | ||
101 | </ul> | ||
102 | <p> | ||
103 | Best of all, you don't need to change your Lua or C sources | ||
104 | and still get the benefits. It's fully integrated into the | ||
105 | Lua core, but tries to minimize the required changes. | ||
106 | </p> | ||
107 | |||
108 | <h2>More ...</h2> | ||
109 | <p> | ||
110 | Please visit the <a href="http://luajit.org/download.html"><span class="ext">»</span> Download</a> page | ||
111 | to fetch the current version of the stand-alone package. | ||
112 | </p> | ||
113 | <p> | ||
114 | Coco needs some machine-specific features — please have a look | ||
115 | at the <a href="coco_portability.html">Portability Requirements</a>. | ||
116 | </p> | ||
117 | <p> | ||
118 | Coco also provides some upwards-compatible | ||
119 | <a href="coco_api.html">API Extensions</a> for Lua. | ||
120 | </p> | ||
121 | <br class="flush"> | ||
122 | </div> | ||
123 | <div id="foot"> | ||
124 | <hr class="hide"> | ||
125 | Copyright © 2005-2011 Mike Pall | ||
126 | <span class="noprint"> | ||
127 | · | ||
128 | <a href="contact.html">Contact</a> | ||
129 | </span> | ||
130 | </div> | ||
131 | </body> | ||
132 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/coco_api.html b/libraries/LuaJIT-1.1.7/jitdoc/coco_api.html new file mode 100644 index 0000000..990ac5b --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/coco_api.html | |||
@@ -0,0 +1,182 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>Coco API Extensions</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>Coco API Extensions</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a class="current" href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <p> | ||
63 | Coco changes the semantics of several standard API functions and | ||
64 | provides a few API extensions for Lua. | ||
65 | </p> | ||
66 | <p> | ||
67 | By default all your coroutines get an associated C stack. | ||
68 | If you want to be more selective, see below. | ||
69 | </p> | ||
70 | |||
71 | <h2>Lua API extensions</h2> | ||
72 | <p> | ||
73 | All <tt>coroutine.*</tt> functions should be fully upwards compatible. | ||
74 | </p> | ||
75 | |||
76 | <h3><tt>coroutine.coco</tt></h3> | ||
77 | <p> | ||
78 | This field is <tt>true</tt> when Coco is present (nil otherwise). | ||
79 | </p> | ||
80 | |||
81 | <h3><tt>coro = coroutine.create(f [, cstacksize])<br> | ||
82 | func = coroutine.wrap(f [, cstacksize])</tt></h3> | ||
83 | <p> | ||
84 | The optional argument <tt>cstacksize</tt> specifies the size of the | ||
85 | C stack to allocate for the coroutine: | ||
86 | </p> | ||
87 | <ul> | ||
88 | <li>A default stack size is used if <tt>cstacksize</tt> is not given | ||
89 | or is nil or zero.</li> | ||
90 | <li>No C stack is allocated if <tt>cstacksize</tt> is -1.</li> | ||
91 | <li>Any other value is rounded up to the minimum size | ||
92 | (i.e. use 1 to get the minimum size).</li> | ||
93 | </ul> | ||
94 | <p> | ||
95 | Important notice for LuaJIT: JIT compiled functions cannot | ||
96 | yield if a coroutine does not have a dedicated C stack. | ||
97 | </p> | ||
98 | |||
99 | <h3><tt>olddefault = coroutine.cstacksize([newdefault])</tt></h3> | ||
100 | <p> | ||
101 | Returns the current default C stack size (may be 0 if the | ||
102 | underlying context switch method has its own default). | ||
103 | Sets a new default C stack size if <tt>newdefault</tt> is present. | ||
104 | Use 0 to reset it to the default C stack size. Any other | ||
105 | value is rounded up to the minimum size. | ||
106 | </p> | ||
107 | |||
108 | <h2>C API extensions</h2> | ||
109 | <p> | ||
110 | All C API functions are either unchanged or upwards compatible. | ||
111 | </p> | ||
112 | |||
113 | <h3><tt>int lua_yield(lua_State *L, int nresults)</tt></h3> | ||
114 | <p> | ||
115 | The semantics for <tt>lua_yield()</tt> have changed slightly. | ||
116 | Existing programs should work fine as long as they follow | ||
117 | the usage conventions from the Lua manual: | ||
118 | </p> | ||
119 | <pre> | ||
120 | return lua_yield(L, nresults); | ||
121 | </pre> | ||
122 | <p> | ||
123 | Previously <tt>lua_yield()</tt> returned a 'magic' value (<tt>-1</tt>) that | ||
124 | indicated a yield. Your C function had to pass this value | ||
125 | on to the Lua core and was <em>not</em> called again. | ||
126 | </p> | ||
127 | <p> | ||
128 | Now, if the current coroutine has an associated C stack, | ||
129 | <tt>lua_yield()</tt> returns the number of arguments passed back from | ||
130 | the resume. This just happens to be the right convention for | ||
131 | returning them as a result from a C function. I.e. if you | ||
132 | used the above convention, you'll never notice the change. | ||
133 | </p> | ||
134 | <p> | ||
135 | But the results <em>are</em> on the Lua stack when <tt>lua_yield()</tt> | ||
136 | returns. So the C function can just continue and process them | ||
137 | or retry an I/O operation etc. And your whole C stack frame | ||
138 | (local variables etc.) is still there, too. You can yield from | ||
139 | anywhere in your C program, even several call levels deeper. | ||
140 | </p> | ||
141 | <p> | ||
142 | Of course all of this only works with Lua+Coco and not with standard Lua. | ||
143 | </p> | ||
144 | |||
145 | <h3><tt>lua_State *lua_newcthread(lua_State *L, int cstacksize)</tt></h3> | ||
146 | <p> | ||
147 | This is an (optional) new function that allows you to create | ||
148 | a coroutine with an associated C stack directly from the C API. | ||
149 | Other than that it works the same as <tt>lua_newthread(L)</tt>. | ||
150 | </p> | ||
151 | <p> | ||
152 | You have to declare this function as <tt>extern</tt> | ||
153 | yourself, since it's not part of the official Lua API. | ||
154 | This means that a C module that uses this call cannot | ||
155 | be loaded with standard Lua. This may be intentional. | ||
156 | </p> | ||
157 | <p> | ||
158 | If you want your C module to work with both standard Lua | ||
159 | and Lua+Coco you can check whether Coco is available with: | ||
160 | </p> | ||
161 | <pre> | ||
162 | lua_getfield(L, LUA_GLOBALSINDEX, "coroutine"); | ||
163 | lua_getfield(L, -1, "coco"); | ||
164 | coco_available = lua_toboolean(L, -1); | ||
165 | lua_pop(L, 2); | ||
166 | </pre> | ||
167 | <p> | ||
168 | You can create coroutines with a C stack by calling | ||
169 | the Lua function <tt>coroutine.create()</tt> from C, too. | ||
170 | </p> | ||
171 | <br class="flush"> | ||
172 | </div> | ||
173 | <div id="foot"> | ||
174 | <hr class="hide"> | ||
175 | Copyright © 2005-2011 Mike Pall | ||
176 | <span class="noprint"> | ||
177 | · | ||
178 | <a href="contact.html">Contact</a> | ||
179 | </span> | ||
180 | </div> | ||
181 | </body> | ||
182 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/coco_changes.html b/libraries/LuaJIT-1.1.7/jitdoc/coco_changes.html new file mode 100644 index 0000000..ea2dc16 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/coco_changes.html | |||
@@ -0,0 +1,146 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>Coco Change History</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>Coco Change History</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a class="current" href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <p> | ||
63 | This is a list of changes between the released versions of Coco. | ||
64 | The current stand-alone release is <strong>Coco 1.1.6</strong>. | ||
65 | </p> | ||
66 | <p> | ||
67 | Please check the | ||
68 | <a href="http://coco.luajit.org/changes.html"><span class="ext">»</span> Online Change History</a> | ||
69 | to see whether newer versions are available. | ||
70 | </p> | ||
71 | |||
72 | <h2 id="Coco-1.1.6">Coco 1.1.6 — 2009-09-08</h2> | ||
73 | <ul> | ||
74 | <li>Fix compilation of the GCC inline assembler code on x64. | ||
75 | Now works when compiled as C++ code (reported by Jonathan Sauer) | ||
76 | or with -fPIC (reported by Jim Pryor).</li> | ||
77 | <li>Added GCC inline assembler for faster context switching on Sparc. | ||
78 | Thanks to Takayuki Usui.</li> | ||
79 | </ul> | ||
80 | |||
81 | <h2 id="Coco-1.1.5">Coco 1.1.5 — 2008-10-25</h2> | ||
82 | <ul> | ||
83 | <li>Upgraded to patch cleanly into Lua 5.1.4.</li> | ||
84 | <li>Added GCC inline assembler for faster context switching on x64. | ||
85 | Thanks to Robert G. Jakabosky.</li> | ||
86 | </ul> | ||
87 | |||
88 | <h2 id="Coco-1.1.4">Coco 1.1.4 — 2008-02-05</h2> | ||
89 | <ul> | ||
90 | <li>Upgraded to patch cleanly into Lua 5.1.3.</li> | ||
91 | <li>Fixed setjmp method for ARM with recent glibc versions. | ||
92 | Thanks to the LuaTeX developers.</li> | ||
93 | <li>Fixed setjmp method for x86 on Mac OS X (rarely used, | ||
94 | default is GCC inline assembler). Thanks to Jason Toffaletti.</li> | ||
95 | </ul> | ||
96 | |||
97 | <h2 id="Coco-1.1.3">Coco 1.1.3 — 2007-05-24</h2> | ||
98 | <ul> | ||
99 | <li>Upgraded to patch cleanly into Lua 5.1.2.</li> | ||
100 | <li>Merged patch from Zachary P. Landau for a Linux/ARM setjmp method (uClibc and glibc).</li> | ||
101 | </ul> | ||
102 | |||
103 | <h2 id="Coco-1.1.1">Coco 1.1.1 — 2006-06-20</h2> | ||
104 | <ul> | ||
105 | <li>Upgraded to patch cleanly into Lua 5.1.1.</li> | ||
106 | <li>C stacks are deallocated early: when a coroutine ends, and not when | ||
107 | the coroutine object is collected. This mainly benefits Windows Fibers.</li> | ||
108 | <li>Windows threads get the required Fiber context when resuming | ||
109 | a coroutine and not just on creation.</li> | ||
110 | </ul> | ||
111 | |||
112 | <h2 id="Coco-1.1.0">Coco 1.1.0 — 2006-02-18</h2> | ||
113 | <ul> | ||
114 | <li>Upgraded to patch cleanly into Lua 5.1 (final).</li> | ||
115 | <li>Added GCC inline assembler for context switching on x86 and MIPS32 | ||
116 | [up to 3x faster].</li> | ||
117 | <li>New targets for setjmp method: | ||
118 | Mac OS X/x86, Solaris/x86 and x64 and Linux/MIPS32.</li> | ||
119 | <li>Workaround for WinXP problem with GetCurrentFiber().</li> | ||
120 | <li>The minimum C stack size has been increased to 32K+4K.</li> | ||
121 | <li>Removed <tt>lcocolib.c</tt> and integrated the (much smaller) changes | ||
122 | into <tt>lbaselib.c</tt>.<br> | ||
123 | Note for embedders: this means you no longer need to call | ||
124 | <tt>luaopen_coco()</tt>.</li> | ||
125 | <li>Optional Valgrind support requires version 3.x. | ||
126 | Renamed define to USE_VALGRIND.</li> | ||
127 | <li>C stacks are now registered with Valgrind.</li> | ||
128 | </ul> | ||
129 | |||
130 | <h2 id="Coco-51w6">Coco pre-release 51w6 — 2005-08-09</h2> | ||
131 | <p> | ||
132 | This is the first pre-release of Coco. It targets Lua 5.1-work6 only | ||
133 | and is no longer available for download. | ||
134 | </p> | ||
135 | <br class="flush"> | ||
136 | </div> | ||
137 | <div id="foot"> | ||
138 | <hr class="hide"> | ||
139 | Copyright © 2005-2011 Mike Pall | ||
140 | <span class="noprint"> | ||
141 | · | ||
142 | <a href="contact.html">Contact</a> | ||
143 | </span> | ||
144 | </div> | ||
145 | </body> | ||
146 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/coco_portability.html b/libraries/LuaJIT-1.1.7/jitdoc/coco_portability.html new file mode 100644 index 0000000..e120ae9 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/coco_portability.html | |||
@@ -0,0 +1,235 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>Portability Requirements for Coco</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | <style type="text/css"> | ||
12 | table.support { | ||
13 | line-height: 1.2; | ||
14 | width: 25em; | ||
15 | } | ||
16 | tr.supporthead td { | ||
17 | font-weight: bold; | ||
18 | } | ||
19 | td.supportcpu { | ||
20 | width: 6em; | ||
21 | } | ||
22 | td.supportsys { | ||
23 | width: 8em; | ||
24 | } | ||
25 | </style> | ||
26 | </head> | ||
27 | <body> | ||
28 | <div id="site"> | ||
29 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
30 | </div> | ||
31 | <div id="head"> | ||
32 | <h1>Portability Requirements for Coco</h1> | ||
33 | </div> | ||
34 | <div id="nav"> | ||
35 | <ul><li> | ||
36 | <a href="index.html">Index</a> | ||
37 | </li><li> | ||
38 | <a href="luajit.html">LuaJIT</a> | ||
39 | <ul><li> | ||
40 | <a href="luajit_features.html">Features</a> | ||
41 | </li><li> | ||
42 | <a href="luajit_install.html">Installation</a> | ||
43 | </li><li> | ||
44 | <a href="luajit_run.html">Running</a> | ||
45 | </li><li> | ||
46 | <a href="luajit_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="luajit_intro.html">Introduction</a> | ||
49 | </li><li> | ||
50 | <a href="luajit_performance.html">Performance</a> | ||
51 | </li><li> | ||
52 | <a href="luajit_debug.html">Debugging</a> | ||
53 | </li><li> | ||
54 | <a href="luajit_changes.html">Changes</a> | ||
55 | </li></ul> | ||
56 | </li><li> | ||
57 | <a href="coco.html">Coco</a> | ||
58 | <ul><li> | ||
59 | <a class="current" href="coco_portability.html">Portability</a> | ||
60 | </li><li> | ||
61 | <a href="coco_api.html">API Extensions</a> | ||
62 | </li><li> | ||
63 | <a href="coco_changes.html">Changes</a> | ||
64 | </li></ul> | ||
65 | </li><li> | ||
66 | <a href="dynasm.html">DynASM</a> | ||
67 | <ul><li> | ||
68 | <a href="dynasm_features.html">Features</a> | ||
69 | </li><li> | ||
70 | <a href="dynasm_examples.html">Examples</a> | ||
71 | </li></ul> | ||
72 | </li><li> | ||
73 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
74 | </li></ul> | ||
75 | </div> | ||
76 | <div id="main"> | ||
77 | <p> | ||
78 | Coco needs some machine-specific features which are | ||
79 | inherently non-portable. Although the coverage is pretty good, | ||
80 | this means that Coco will probably never be a standard part | ||
81 | of the Lua core (which is pure ANSI C). | ||
82 | </p> | ||
83 | |||
84 | <h2>Context Switching Methods</h2> | ||
85 | <p> | ||
86 | Coco relies on four different machine-specific methods | ||
87 | for allocating a C stack and switching context. | ||
88 | The appropriate method is automatically selected at compile time. | ||
89 | </p> | ||
90 | |||
91 | <h3>GCC Inline Assembler</h3> | ||
92 | <p> | ||
93 | This method is only available when GCC 3.x/4.x is used | ||
94 | to compile the source. | ||
95 | This is the fastest method for context switching, but only available | ||
96 | for a few CPUs (see below). | ||
97 | </p> | ||
98 | |||
99 | <h3>Modified setjmp Buffer</h3> | ||
100 | <p> | ||
101 | This method changes a few fields in the setjmp buffer to | ||
102 | redirect the next longjmp to a new function with a new stack | ||
103 | frame. It needs a bit of guesswork and lots of #ifdef's to | ||
104 | handle the supported CPU/OS combinations, but this is quite | ||
105 | manageable. | ||
106 | </p> | ||
107 | <p> | ||
108 | This is the fallback method if inline assembler is not available. | ||
109 | It's pretty fast because it doesn't have to save or restore signals | ||
110 | (which is slow and generally undesirable for Lua coroutines). | ||
111 | </p> | ||
112 | |||
113 | <h3>POSIX ucontext</h3> | ||
114 | <p> | ||
115 | The POSIX calls getcontext, makecontext and switchcontext | ||
116 | are used to set up and switch between different C stacks. | ||
117 | Although highly portable and even available for some | ||
118 | esoteric platforms, it's slower than the setjmp method | ||
119 | because it saves and restores signals, too (using at least one | ||
120 | syscall for each context switch). | ||
121 | </p> | ||
122 | <p> | ||
123 | You can force the use of ucontext (instead of setjmp) by enabling | ||
124 | <tt>-DCOCO_USE_UCONTEXT</tt> in <tt>src/Makefile</tt>. | ||
125 | </p> | ||
126 | |||
127 | <h3>Windows Fibers</h3> | ||
128 | <p> | ||
129 | This is the standard method to set up and switch between | ||
130 | different C stacks on Windows. It's available on Windows 98 | ||
131 | and later. | ||
132 | </p> | ||
133 | <p> | ||
134 | None of the other methods work for Windows because OS specific code | ||
135 | is required to switch exception handling contexts. | ||
136 | </p> | ||
137 | |||
138 | <h2 class="pagebreak">Supported Platforms</h2> | ||
139 | <p> | ||
140 | Coco has support for the following platforms: | ||
141 | </p> | ||
142 | <table class="support"> | ||
143 | <tr class="supporthead"> | ||
144 | <td class="supportcpu">CPU</td> | ||
145 | <td class="supportsys">System</td> | ||
146 | <td>Method</td> | ||
147 | </tr> | ||
148 | <tr class="odd separate"> | ||
149 | <td class="supportcpu">x86</td><td class="supportsys">(any OS)</td><td>gccasm</td></tr> | ||
150 | <tr class="even"> | ||
151 | <td class="supportcpu">x86</td><td class="supportsys">Linux</td><td>setjmp</td></tr> | ||
152 | <tr class="odd"> | ||
153 | <td class="supportcpu">x86</td><td class="supportsys">FreeBSD</td><td>setjmp</td></tr> | ||
154 | <tr class="even"> | ||
155 | <td class="supportcpu">x86</td><td class="supportsys">NetBSD</td><td>setjmp</td></tr> | ||
156 | <tr class="odd"> | ||
157 | <td class="supportcpu">x86</td><td class="supportsys">OpenBSD</td><td>setjmp</td></tr> | ||
158 | <tr class="even"> | ||
159 | <td class="supportcpu">x86</td><td class="supportsys">Solaris</td><td>setjmp</td></tr> | ||
160 | <tr class="odd"> | ||
161 | <td class="supportcpu">x86</td><td class="supportsys">Mac OS X</td><td>setjmp</td></tr> | ||
162 | <tr class="even separate"> | ||
163 | <td class="supportcpu">x64</td><td class="supportsys">(any OS)</td><td>gccasm</td></tr> | ||
164 | <tr class="odd"> | ||
165 | <td class="supportcpu">x64</td><td class="supportsys">Solaris</td><td>setjmp</td></tr> | ||
166 | <tr class="even separate"> | ||
167 | <td class="supportcpu">MIPS32</td><td class="supportsys">(any OS)</td><td>gccasm</td></tr> | ||
168 | <tr class="odd"> | ||
169 | <td class="supportcpu">MIPS32</td><td class="supportsys">Linux</td><td>setjmp</td></tr> | ||
170 | <tr class="even separate"> | ||
171 | <td class="supportcpu">ARM</td><td class="supportsys">Linux</td><td>setjmp</td></tr> | ||
172 | <tr class="odd separate"> | ||
173 | <td class="supportcpu">PPC32</td><td class="supportsys">Mac OS X</td><td>setjmp</td></tr> | ||
174 | <tr class="even separate"> | ||
175 | <td class="supportcpu">(any CPU)</td><td class="supportsys">POSIX</td><td>ucontext</td></tr> | ||
176 | <tr class="odd separate"> | ||
177 | <td class="supportcpu">(any CPU)</td><td class="supportsys">Windows</td><td>fibers</td></tr> | ||
178 | </table> | ||
179 | <pre> | ||
180 | </pre> | ||
181 | <p> | ||
182 | It should work pretty much anywhere where a <em>correct</em> | ||
183 | POSIX ucontext implementation is available. It has been tested | ||
184 | on every systems I could get hold of (e.g. Sparc, PPC32/PPC64, | ||
185 | IA64, Alpha, HPPA with various operating systems). | ||
186 | </p> | ||
187 | |||
188 | <h2>Caveats</h2> | ||
189 | <ul> | ||
190 | <li> | ||
191 | Some older operating systems may have defective ucontext | ||
192 | implementations because this feature is not widely used. E.g. some | ||
193 | implementations don't mix well with other C library functions | ||
194 | like <tt>malloc()</tt> or with native threads. | ||
195 | This is really not the fault of Coco — please upgrade your OS. | ||
196 | </li> | ||
197 | <li> | ||
198 | Note for Windows: Please read the explanation for the default | ||
199 | <a href="http://msdn.microsoft.com/library/en-us/dllproc/base/thread_stack_size.asp"><span class="ext">»</span> Thread Stack Size</a> | ||
200 | in case you want to create large numbers of Fiber-based coroutines. | ||
201 | </li> | ||
202 | <li> | ||
203 | Note for MinGW/Cygwin: Older releases of GCC (before 4.0) generate | ||
204 | wrong unwind information when <tt>-fomit-frame-pointer</tt> is used | ||
205 | with stdcalls. This may lead to crashes when exceptions are thrown. | ||
206 | The workaround is to always use two flags:<br> | ||
207 | <tt>-fomit-frame-pointer -maccumulate-outgoing-args</tt>. | ||
208 | </li> | ||
209 | <li> | ||
210 | Note for MIPS CPUs without FPU: It's recommended to compile | ||
211 | <em>all</em> sources with <tt>-msoft-float</tt>, even if you don't use | ||
212 | any floating point ops anywhere. Otherwise context switching must | ||
213 | save and restore FPU registers (which needs to go through | ||
214 | the slow kernel emulation). | ||
215 | </li> | ||
216 | <li> | ||
217 | To run Coco with <a href="http://valgrind.org/"><span class="ext">»</span> Valgrind</a> | ||
218 | (a memory debugger) you <em>must</em> add <tt>-DUSE_VALGRIND</tt> | ||
219 | to <tt>MYCFLAGS</tt> and recompile. You will get random errors | ||
220 | if you don't! Valgrind 3.x or later is required. Earlier versions | ||
221 | do not work well with newly allocated C stacks. | ||
222 | </li> | ||
223 | </ul> | ||
224 | <br class="flush"> | ||
225 | </div> | ||
226 | <div id="foot"> | ||
227 | <hr class="hide"> | ||
228 | Copyright © 2005-2011 Mike Pall | ||
229 | <span class="noprint"> | ||
230 | · | ||
231 | <a href="contact.html">Contact</a> | ||
232 | </span> | ||
233 | </div> | ||
234 | </body> | ||
235 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/contact.html b/libraries/LuaJIT-1.1.7/jitdoc/contact.html new file mode 100644 index 0000000..5da1ecf --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/contact.html | |||
@@ -0,0 +1,105 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>Contact</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>Contact</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <p> | ||
63 | Please send general questions regarding LuaJIT or Coco to the | ||
64 | <a href="http://www.lua.org/lua-l.html"><span class="ext">»</span> Lua mailing list</a>. | ||
65 | You can also send any questions you have directly to me: | ||
66 | </p> | ||
67 | |||
68 | <script type="text/javascript"> | ||
69 | <!-- | ||
70 | var xS="@-: .0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZa<b>cdefghijklmnopqrstuvwxyz" | ||
71 | function xD(s) | ||
72 | {var len=s.length;var r="";for(var i=0;i<len;i++) | ||
73 | {var c=s.charAt(i);var n=xS.indexOf(c);if(n!=-1) | ||
74 | c=xS.charAt(66-n);r+=c;} | ||
75 | document.write("<"+"p>"+r+"<"+"/p>\n");} | ||
76 | //--> | ||
77 | </script> | ||
78 | <script type="text/javascript"> | ||
79 | <!-- | ||
80 | xD("ewYKA7vu-EIwslx7 K9A.t41C") | ||
81 | //--></script> | ||
82 | <noscript> | ||
83 | <p><img src="img/contact.png" alt="Contact info in image" width="170" height="13"> | ||
84 | </p> | ||
85 | </noscript> | ||
86 | |||
87 | <h2>Copyright</h2> | ||
88 | <p> | ||
89 | All documentation is | ||
90 | Copyright © 2005-2011 Mike Pall. | ||
91 | </p> | ||
92 | |||
93 | |||
94 | <br class="flush"> | ||
95 | </div> | ||
96 | <div id="foot"> | ||
97 | <hr class="hide"> | ||
98 | Copyright © 2005-2011 Mike Pall | ||
99 | <span class="noprint"> | ||
100 | · | ||
101 | <a href="contact.html">Contact</a> | ||
102 | </span> | ||
103 | </div> | ||
104 | </body> | ||
105 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/dynasm.html b/libraries/LuaJIT-1.1.7/jitdoc/dynasm.html new file mode 100644 index 0000000..de8f859 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/dynasm.html | |||
@@ -0,0 +1,116 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>DynASM</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>DynASM</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a class="current" href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <p> | ||
63 | DynASM is a <strong>Dynamic Assembler</strong> for code generation | ||
64 | engines. | ||
65 | </p> | ||
66 | <p> | ||
67 | DynASM has been developed primarily as a tool for | ||
68 | <a href="luajit.html">LuaJIT</a>, but might be useful for other | ||
69 | projects, too. | ||
70 | </p> | ||
71 | <p> | ||
72 | If you are writing a just-in-time compiler or need to generate | ||
73 | code on the fly (e.g. for high-performance graphics or other | ||
74 | CPU-intensive computations), DynASM might be just what you | ||
75 | are looking for. | ||
76 | </p> | ||
77 | <p> | ||
78 | Please have a look at the list of <a href="dynasm_features.html">Features</a> | ||
79 | to find out whether DynASM could be useful for your project. | ||
80 | </p> | ||
81 | <p> | ||
82 | DynASM is Copyright © 2005-2011 Mike Pall. | ||
83 | DynASM is free software, released under the | ||
84 | <a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">»</span> MIT/X license</a>. | ||
85 | </p> | ||
86 | |||
87 | <h2>More ...</h2> | ||
88 | <p> | ||
89 | Sorry, right now there is no proper documentation available other | ||
90 | than some <a href="dynasm_examples.html">Examples</a> and of course | ||
91 | the source code. The source <em>is</em> well documented, though (IMHO). | ||
92 | </p> | ||
93 | <p> | ||
94 | I may add more docs in case someone actually finds DynASM to be | ||
95 | useful outside of LuaJIT. If you do, I'd like to | ||
96 | <a href="contact.html">hear</a> from you, please. Thank you! | ||
97 | </p> | ||
98 | <p> | ||
99 | If you want to check it out please visit the | ||
100 | <a href="http://luajit.org/download.html"><span class="ext">»</span> Download</a> page and fetch the most recent | ||
101 | version of LuaJIT. All you need is in the dynasm directory. | ||
102 | For some complex examples take a peek at the | ||
103 | <tt>*.dasc</tt> and <tt>*.dash</tt> files in LuaJIT, too. | ||
104 | </p> | ||
105 | <br class="flush"> | ||
106 | </div> | ||
107 | <div id="foot"> | ||
108 | <hr class="hide"> | ||
109 | Copyright © 2005-2011 Mike Pall | ||
110 | <span class="noprint"> | ||
111 | · | ||
112 | <a href="contact.html">Contact</a> | ||
113 | </span> | ||
114 | </div> | ||
115 | </body> | ||
116 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/dynasm_examples.html b/libraries/LuaJIT-1.1.7/jitdoc/dynasm_examples.html new file mode 100644 index 0000000..5d2331e --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/dynasm_examples.html | |||
@@ -0,0 +1,188 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>DynASM Examples</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>DynASM Examples</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a class="current" href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <h2>A Simple Example</h2> | ||
63 | <p> | ||
64 | To get you started, here is a simple code snippet to be pre-processed. | ||
65 | The lines starting with '|' (the pipe symbol) are for DynASM: | ||
66 | </p> | ||
67 | <pre> | ||
68 | if (ptr != NULL) { | ||
69 | | mov eax, foo+17 | ||
70 | | mov edx, [eax+esi*2+0x20] | ||
71 | | add ebx, [ecx+bar(ptr, 9)] | ||
72 | } | ||
73 | </pre> | ||
74 | <p> | ||
75 | After pre-processing you get: | ||
76 | </p> | ||
77 | <pre> | ||
78 | if (ptr != NULL) { | ||
79 | dasm_put(Dst, 123, foo+17, bar(ptr, 9)); | ||
80 | } | ||
81 | </pre> | ||
82 | <p style="font-size: 80%;"> | ||
83 | Note: yes, you usually get the assembler code as comments and proper | ||
84 | CPP directives to match them up with the source. I've omitted | ||
85 | them here for clarity. Oh and BTW: the pipe symbols probably | ||
86 | line up much more nicely in your editor than in a browser. | ||
87 | </p> | ||
88 | <p> | ||
89 | Here 123 is an offset into the action list buffer that | ||
90 | holds the partially specified machine code. Without going | ||
91 | into too much detail, the embedded C library implements a | ||
92 | tiny bytecode engine that takes the action list as input and | ||
93 | outputs machine code. It basically copies machine code snippets | ||
94 | from the action list and merges them with the arguments | ||
95 | passed in by <tt>dasm_put()</tt>. | ||
96 | </p> | ||
97 | <p> | ||
98 | The arguments can be any kind of C expressions. In practical | ||
99 | use most of them evaluate to constants (e.g. structure offsets). | ||
100 | Your C compiler should generate very compact code out of it. | ||
101 | </p> | ||
102 | <p> | ||
103 | The embedded C library knows only what's absolutely needed to | ||
104 | generate proper machine code for the target CPU (e.g. variable | ||
105 | displacement sizes, variable branch offset sizes and so on). | ||
106 | It doesn't have a clue about other atrocities like x86 opcode | ||
107 | encodings — and it doesn't need to. This dramatically | ||
108 | reduces the minimum required code size to around 2K [sic!]. | ||
109 | </p> | ||
110 | <p> | ||
111 | The action list buffer itself has a pretty compact encoding, too. | ||
112 | E.g. the whole action list buffer for an early version of LuaJIT | ||
113 | needs only around 3K. | ||
114 | </p> | ||
115 | |||
116 | <h2>Advanced Features</h2> | ||
117 | <p> | ||
118 | Here's a real-life example taken from LuaJIT that shows some | ||
119 | advanced features like type maps, macros and how to access | ||
120 | C structures: | ||
121 | </p> | ||
122 | <pre> | ||
123 | |.type L, lua_State, esi // L. | ||
124 | |.type BASE, TValue, ebx // L->base. | ||
125 | |.type TOP, TValue, edi // L->top. | ||
126 | |.type CI, CallInfo, ecx // L->ci. | ||
127 | |.type LCL, LClosure, eax // L->ci->func->value. | ||
128 | |.type UPVAL, UpVal | ||
129 | |||
130 | |.macro copyslot, D, S, R1, R2, R3 | ||
131 | | mov R1, S.value; mov R2, S.value.na[1]; mov R3, S.tt | ||
132 | | mov D.value, R1; mov D.value.na[1], R2; mov D.tt, R3 | ||
133 | |.endmacro | ||
134 | |||
135 | |.macro copyslot, D, S; copyslot D, S, ecx, edx, eax; .endmacro | ||
136 | |||
137 | |.macro getLCL, reg | ||
138 | ||if (!J->pt->is_vararg) { | ||
139 | | mov LCL:reg, BASE[-1].value | ||
140 | ||} else { | ||
141 | | mov CI, L->ci | ||
142 | | mov TOP, CI->func | ||
143 | | mov LCL:reg, TOP->value | ||
144 | ||} | ||
145 | |.endmacro | ||
146 | |||
147 | |.macro getLCL; getLCL eax; .endmacro | ||
148 | |||
149 | [...] | ||
150 | |||
151 | static void jit_op_getupval(jit_State *J, int dest, int uvidx) | ||
152 | { | ||
153 | | getLCL | ||
154 | | mov UPVAL:ecx, LCL->upvals[uvidx] | ||
155 | | mov TOP, UPVAL:ecx->v | ||
156 | | copyslot BASE[dest], TOP[0] | ||
157 | } | ||
158 | </pre> | ||
159 | <p> | ||
160 | And here is the pre-processed output (stripped a bit for clarity): | ||
161 | </p> | ||
162 | <pre> | ||
163 | #define Dt1(_V) (int)&(((lua_State *)0)_V) | ||
164 | [...] | ||
165 | static void jit_op_getupval(jit_State *J, int dest, int uvidx) | ||
166 | { | ||
167 | if (!J->pt->is_vararg) { | ||
168 | dasm_put(Dst, 1164, Dt2([-1].value)); | ||
169 | } else { | ||
170 | dasm_put(Dst, 1168, Dt1(->ci), Dt4(->func), Dt3(->value)); | ||
171 | } | ||
172 | dasm_put(Dst, 1178, Dt5(->upvals[uvidx]), DtF(->v), Dt3([0].value), | ||
173 | Dt3([0].value.na[1]), Dt3([0].tt), Dt2([dest].value), | ||
174 | Dt2([dest].value.na[1]), Dt2([dest].tt)); | ||
175 | } | ||
176 | </pre> | ||
177 | <br class="flush"> | ||
178 | </div> | ||
179 | <div id="foot"> | ||
180 | <hr class="hide"> | ||
181 | Copyright © 2005-2011 Mike Pall | ||
182 | <span class="noprint"> | ||
183 | · | ||
184 | <a href="contact.html">Contact</a> | ||
185 | </span> | ||
186 | </div> | ||
187 | </body> | ||
188 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/dynasm_features.html b/libraries/LuaJIT-1.1.7/jitdoc/dynasm_features.html new file mode 100644 index 0000000..1b8ce69 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/dynasm_features.html | |||
@@ -0,0 +1,139 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>DynASM Features</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>DynASM Features</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a class="current" href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <h2>DynASM Toolchain Features</h2> | ||
63 | <ul> | ||
64 | <li>DynASM is a pre-processing assembler.</li> | ||
65 | <li>DynASM converts mixed C/Assembler source to plain C code.</li> | ||
66 | <li>The primary knowledge about instruction names, operand modes, | ||
67 | registers, opcodes and how to encode them is <em>only</em> | ||
68 | needed in the pre-processor.</li> | ||
69 | <li>The generated C code is extremely small and fast.</li> | ||
70 | <li>A tiny embeddable C library helps with the process of dynamically | ||
71 | assembling, relocating and linking machine code.</li> | ||
72 | <li>There are no outside dependencies on other tools (such as | ||
73 | stand-alone assemblers or linkers).</li> | ||
74 | <li>Internal consistency checks catch runtime errors | ||
75 | (e.g. undefined labels).</li> | ||
76 | <li>The toolchain is split into a portable subset and | ||
77 | CPU-specific modules.</li> | ||
78 | <li>DynASM itself (the pre-processor) is written in Lua.</li> | ||
79 | <li>There is no machine-dependency for the pre-processor itself. | ||
80 | It should work everywhere you can get Lua 5.1 up and running | ||
81 | (i.e. Linux, *BSD, Solaris, Windows, ... you name it).</li> | ||
82 | </ul> | ||
83 | |||
84 | <h2>DynASM Assembler Features</h2> | ||
85 | <ul> | ||
86 | <li>C code and assembler code can be freely mixed. | ||
87 | <em>Readable</em>, too.</li> | ||
88 | <li>All the usual syntax for instructions and operand modes | ||
89 | you come to expect from a standard assembler.</li> | ||
90 | <li>Access to C variables and CPP defines in assembler statements.</li> | ||
91 | <li>Access to C structures and unions via type mapping.</li> | ||
92 | <li>Convenient shortcuts for accessing C structures.</li> | ||
93 | <li>Local and global labels.</li> | ||
94 | <li>Numbered labels (e.g. for mapping bytecode instruction numbers).</li> | ||
95 | <li>Multiple code sections (e.g. for tailcode).</li> | ||
96 | <li>Defines/substitutions (inline and from command line).</li> | ||
97 | <li>Conditionals (translation time) with proper nesting.</li> | ||
98 | <li>Macros with parameters.</li> | ||
99 | <li>Macros can mix assembler statements and C code.</li> | ||
100 | <li>Captures (output diversion for code reordering).</li> | ||
101 | <li>Simple and extensible template system for instruction definitions.</li> | ||
102 | </ul> | ||
103 | |||
104 | <h2>Restrictions</h2> | ||
105 | <p> | ||
106 | Currently only a subset of x86 (i386+) instructions is supported. | ||
107 | Unsupported instructions are either not usable in user-mode or | ||
108 | are slow on modern CPUs (i.e. not suited for a code generator). | ||
109 | SSE, SSE2, SSE3 and SSSE3 are fully supported. MMX is not supported. | ||
110 | </p> | ||
111 | <p> | ||
112 | The whole toolchain has been designed to support multiple CPU | ||
113 | architectures. As LuaJIT gets support for more architectures, | ||
114 | DynASM will be extended with new CPU-specific modules. | ||
115 | </p> | ||
116 | <p> | ||
117 | The assembler itself will be extended with more features on an | ||
118 | as-needed basis. E.g. I'm thinking about vararg macros. | ||
119 | </p> | ||
120 | <p> | ||
121 | Note that runtime conditionals are not really needed, since you can | ||
122 | just use plain C code for that (and LuaJIT does this <em>a lot</em>). | ||
123 | It's not going to be more (time-) efficient if conditionals are done | ||
124 | by the embedded C library (maybe a bit more space-efficient). | ||
125 | </p> | ||
126 | |||
127 | |||
128 | <br class="flush"> | ||
129 | </div> | ||
130 | <div id="foot"> | ||
131 | <hr class="hide"> | ||
132 | Copyright © 2005-2011 Mike Pall | ||
133 | <span class="noprint"> | ||
134 | · | ||
135 | <a href="contact.html">Contact</a> | ||
136 | </span> | ||
137 | </div> | ||
138 | </body> | ||
139 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/img/backbar.png b/libraries/LuaJIT-1.1.7/jitdoc/img/backbar.png new file mode 100644 index 0000000..3c90029 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/img/backbar.png | |||
Binary files differ | |||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/img/bluebar.png b/libraries/LuaJIT-1.1.7/jitdoc/img/bluebar.png new file mode 100644 index 0000000..70dcf07 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/img/bluebar.png | |||
Binary files differ | |||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/img/contact.png b/libraries/LuaJIT-1.1.7/jitdoc/img/contact.png new file mode 100644 index 0000000..9c73dc5 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/img/contact.png | |||
Binary files differ | |||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/img/magentabar.png b/libraries/LuaJIT-1.1.7/jitdoc/img/magentabar.png new file mode 100644 index 0000000..11ebd2b --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/img/magentabar.png | |||
Binary files differ | |||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/img/spacer.png b/libraries/LuaJIT-1.1.7/jitdoc/img/spacer.png new file mode 100644 index 0000000..75a203c --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/img/spacer.png | |||
Binary files differ | |||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/index.html b/libraries/LuaJIT-1.1.7/jitdoc/index.html new file mode 100644 index 0000000..22236b4 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/index.html | |||
@@ -0,0 +1,103 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>The LuaJIT Project</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>The LuaJIT Project</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a class="current" href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <p> | ||
63 | This is the offline documentation for: | ||
64 | </p> | ||
65 | <ul> | ||
66 | <li> | ||
67 | <a href="luajit.html">LuaJIT</a> — | ||
68 | a <strong>Just-In-Time Compiler</strong> for Lua. | ||
69 | </li> | ||
70 | <li> | ||
71 | <a href="coco.html">Coco</a> — | ||
72 | a Lua extension for <strong>True C Coroutines</strong>. | ||
73 | </li> | ||
74 | <li> | ||
75 | <a href="dynasm.html">DynASM</a> — | ||
76 | a <strong>Dynamic Assembler</strong> for code generation engines. | ||
77 | </li> | ||
78 | </ul> | ||
79 | |||
80 | |||
81 | |||
82 | <h2>More ...</h2> | ||
83 | <p> | ||
84 | Please click on one of the links in the navigation bar to your left | ||
85 | to learn more. | ||
86 | </p> | ||
87 | <p> | ||
88 | Click on the Logo in the upper left corner to visit | ||
89 | the LuaJIT project page on the web. All other links to online | ||
90 | resources are marked with a '<span class="ext">»</span>'. | ||
91 | </p> | ||
92 | <br class="flush"> | ||
93 | </div> | ||
94 | <div id="foot"> | ||
95 | <hr class="hide"> | ||
96 | Copyright © 2005-2011 Mike Pall | ||
97 | <span class="noprint"> | ||
98 | · | ||
99 | <a href="contact.html">Contact</a> | ||
100 | </span> | ||
101 | </div> | ||
102 | </body> | ||
103 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit.html new file mode 100644 index 0000000..f9a7245 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit.html | |||
@@ -0,0 +1,109 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>LuaJIT</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>LuaJIT</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a class="current" href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <p> | ||
63 | LuaJIT is a <strong>Just-In-Time Compiler</strong> for the Lua | ||
64 | programming language. | ||
65 | </p> | ||
66 | <p class="indent"> | ||
67 | Lua is a powerful, light-weight programming language designed | ||
68 | for extending applications. Lua is also frequently used as a | ||
69 | general-purpose, stand-alone language. More information about | ||
70 | Lua can be found at: <a href="http://www.lua.org/"><span class="ext">»</span> http://www.lua.org/</a> | ||
71 | </p> | ||
72 | <p> | ||
73 | LuaJIT 1.x is based on the Lua 5.1.x virtual machine and bytecode interpreter | ||
74 | from lua.org. It compiles bytecode to native x86 (i386+) machine code | ||
75 | to speed up the execution of Lua programs. | ||
76 | </p> | ||
77 | <p> | ||
78 | LuaJIT depends on <a href="coco.html">Coco</a> to allow yielding | ||
79 | from coroutines for JIT compiled functions. Coco is part of the | ||
80 | LuaJIT distribution. | ||
81 | </p> | ||
82 | <p> | ||
83 | LuaJIT is Copyright © 2005-2011 Mike Pall. | ||
84 | LuaJIT is free software, released under the | ||
85 | <a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">»</span> MIT/X license</a> | ||
86 | (same license as the Lua core). | ||
87 | </p> | ||
88 | <h2>More ...</h2> | ||
89 | <p> | ||
90 | Click on the LuaJIT sub-topics in the navigation bar to learn more | ||
91 | about LuaJIT. | ||
92 | </p> | ||
93 | <p style="background: #ffd0d0; text-align: center;"> | ||
94 | LuaJIT 2.0 is available with much improved performance!<br> | ||
95 | Please visit the <a href="http://luajit.org/download.html"><span class="ext">»</span> Download</a> page to fetch | ||
96 | the current version of LuaJIT. | ||
97 | </p> | ||
98 | <br class="flush"> | ||
99 | </div> | ||
100 | <div id="foot"> | ||
101 | <hr class="hide"> | ||
102 | Copyright © 2005-2011 Mike Pall | ||
103 | <span class="noprint"> | ||
104 | · | ||
105 | <a href="contact.html">Contact</a> | ||
106 | </span> | ||
107 | </div> | ||
108 | </body> | ||
109 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_api.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_api.html new file mode 100644 index 0000000..58ac809 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_api.html | |||
@@ -0,0 +1,372 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>LuaJIT API Extensions</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | <style type="text/css"> | ||
12 | td.stname { width: 10em; } | ||
13 | tr.sthead td { font-weight: bold; } | ||
14 | </style> | ||
15 | </head> | ||
16 | <body> | ||
17 | <div id="site"> | ||
18 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
19 | </div> | ||
20 | <div id="head"> | ||
21 | <h1>LuaJIT API Extensions</h1> | ||
22 | </div> | ||
23 | <div id="nav"> | ||
24 | <ul><li> | ||
25 | <a href="index.html">Index</a> | ||
26 | </li><li> | ||
27 | <a href="luajit.html">LuaJIT</a> | ||
28 | <ul><li> | ||
29 | <a href="luajit_features.html">Features</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_install.html">Installation</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_run.html">Running</a> | ||
34 | </li><li> | ||
35 | <a class="current" href="luajit_api.html">API Extensions</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_intro.html">Introduction</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_performance.html">Performance</a> | ||
40 | </li><li> | ||
41 | <a href="luajit_debug.html">Debugging</a> | ||
42 | </li><li> | ||
43 | <a href="luajit_changes.html">Changes</a> | ||
44 | </li></ul> | ||
45 | </li><li> | ||
46 | <a href="coco.html">Coco</a> | ||
47 | <ul><li> | ||
48 | <a href="coco_portability.html">Portability</a> | ||
49 | </li><li> | ||
50 | <a href="coco_api.html">API Extensions</a> | ||
51 | </li><li> | ||
52 | <a href="coco_changes.html">Changes</a> | ||
53 | </li></ul> | ||
54 | </li><li> | ||
55 | <a href="dynasm.html">DynASM</a> | ||
56 | <ul><li> | ||
57 | <a href="dynasm_features.html">Features</a> | ||
58 | </li><li> | ||
59 | <a href="dynasm_examples.html">Examples</a> | ||
60 | </li></ul> | ||
61 | </li><li> | ||
62 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
63 | </li></ul> | ||
64 | </div> | ||
65 | <div id="main"> | ||
66 | <p> | ||
67 | LuaJIT provides several new API functions organized into two | ||
68 | libraries. | ||
69 | </p> | ||
70 | <p> | ||
71 | LuaJIT includes Coco — so have a look at the | ||
72 | <a href="coco_api.html">Coco API Extensions</a>, too. | ||
73 | </p> | ||
74 | |||
75 | <h2>Standard Library Functions</h2> | ||
76 | <p> | ||
77 | All standard library functions have the same behaviour as | ||
78 | in the Lua distribution LuaJIT is based on. | ||
79 | </p> | ||
80 | <p> | ||
81 | The Lua loader used by the standard <tt>require()</tt> library | ||
82 | function has been modified to turn off compilation of the main | ||
83 | chunk of a module. The main chunk is only run once when the module | ||
84 | is loaded for the first time. There is no point in compiling it. | ||
85 | </p> | ||
86 | <p> | ||
87 | You might want to adapt this behaviour if you use your own utility | ||
88 | functions (and not <tt>require()</tt>) to load modules. | ||
89 | </p> | ||
90 | <p> | ||
91 | Note that the subfunctions defined in a loaded module <em>are</em> | ||
92 | of course compiled. See below if you want to override this. | ||
93 | </p> | ||
94 | |||
95 | <h2>The jit.* Library</h2> | ||
96 | <p> | ||
97 | This library holds several functions to control the behaviour | ||
98 | of the JIT engine. | ||
99 | </p> | ||
100 | |||
101 | <h3 id="jit_onoff"><tt>jit.on()<br> | ||
102 | jit.off()</tt></h3> | ||
103 | <p> | ||
104 | Turns the JIT engine on (default) or off. | ||
105 | </p> | ||
106 | <p> | ||
107 | These functions are typically used with the command line options | ||
108 | <tt>-j on</tt> or <tt>-j off</tt>. | ||
109 | </p> | ||
110 | |||
111 | <h3 id="jit_onoff_func"><tt>jit.on(func|true [,true|false])<br> | ||
112 | jit.off(func|true [,true|false])</tt></h3> | ||
113 | <p> | ||
114 | Enable (with <tt>jit.on</tt>, default) or disable (with <tt>jit.off</tt>) | ||
115 | JIT compilation for a Lua function. The current function (the Lua function | ||
116 | calling this library function) can be specified with <tt>true</tt>. | ||
117 | </p> | ||
118 | <p> | ||
119 | If the second argument is <tt>true</tt>, JIT compilation is also | ||
120 | enabled/disabled recursively for all subfunctions of a function. | ||
121 | With <tt>false</tt> only the subfunctions are affected. | ||
122 | </p> | ||
123 | <p> | ||
124 | Both library functions only set a flag which is checked when | ||
125 | the function is executed for the first/next time. They do not | ||
126 | trigger immediate compilation. | ||
127 | </p> | ||
128 | <p> | ||
129 | Typical usage is <tt>jit.off(true, true)</tt> in the main chunk | ||
130 | of a module to turn off JIT compilation for the whole module. | ||
131 | Note that <tt>require()</tt> already turns off compilation for | ||
132 | the main chunk itself. | ||
133 | </p> | ||
134 | |||
135 | <h3 id="jit_compile"><tt>status = jit.compile(func [,args...])</tt></h3> | ||
136 | <p> | ||
137 | Compiles a Lua function and returns the compilation status. | ||
138 | Successful compilation is indicated with a <tt>nil</tt> status. | ||
139 | Failure is indicated with a numeric status (see <tt>jit.util.status</tt>). | ||
140 | </p> | ||
141 | <p> | ||
142 | The optimizer pass of the compiler tries to derive hints from the | ||
143 | passed arguments. Not passing any arguments or passing untypical | ||
144 | arguments (esp. the wrong types) reduces the efficiency of the | ||
145 | optimizer. The compiled function will still run, but probably not | ||
146 | with maximum speed. | ||
147 | </p> | ||
148 | <p> | ||
149 | This library function is typically used for Ahead-Of-Time (AOT) | ||
150 | compilation of time-critical functions or for testing/debugging. | ||
151 | </p> | ||
152 | |||
153 | <h3 id="jit_compilesub"><tt>status = jit.compilesub(func|true [,true])</tt></h3> | ||
154 | <p> | ||
155 | Recursively compile all subfunctions of a Lua function. | ||
156 | The current function (the Lua function calling this library function) | ||
157 | can be specified with <tt>true</tt>. Note that the function | ||
158 | <em>itself</em> is not compiled (use <tt>jit.compile()</tt>). | ||
159 | </p> | ||
160 | <p> | ||
161 | If the second argument is <tt>true</tt>, compilation will stop | ||
162 | when the first error is encountered. Otherwise compilation will | ||
163 | continue with the next subfunction. | ||
164 | </p> | ||
165 | <p> | ||
166 | The returned status is <tt>nil</tt>, if all subfunctions have been | ||
167 | compiled successfully. A numeric status (see <tt>jit.util.status</tt>) | ||
168 | indicates that at least one compilation failed and gives the status | ||
169 | of the last failure (this is only helpful when stop on error | ||
170 | is <tt>true</tt>). | ||
171 | </p> | ||
172 | |||
173 | <h3 id="jit_debug"><tt>jit.debug([level])</tt></h3> | ||
174 | <p> | ||
175 | Set the debug level for JIT compilation. If no <tt>level</tt> is given, | ||
176 | the maximum debug level is set. | ||
177 | </p> | ||
178 | <ul> | ||
179 | <li>Level 0 disables debugging: no checks for hooks are compiled | ||
180 | into the code. This is the default when LuaJIT is started and | ||
181 | provides the maximum performance.</li> | ||
182 | <li>Level 1 enables function call debugging: call hooks and | ||
183 | return hooks are checked in the function prologue and epilogue. | ||
184 | This slows down function calls somewhat (by up to 10%).</li> | ||
185 | <li>Level 2 enables full debugging: all hooks are checked. | ||
186 | This slows down execution quite a bit, even when the hooks | ||
187 | are not active.</li> | ||
188 | </ul> | ||
189 | <p> | ||
190 | Note that some compiler optimizations are turned off when | ||
191 | debugging is enabled. | ||
192 | </p> | ||
193 | <p> | ||
194 | This function is typically used with the command line options | ||
195 | <tt>-j debug</tt> or <tt>-j debug=level</tt>. | ||
196 | </p> | ||
197 | |||
198 | <h3 id="jit_attach"><tt>jit.attach(handler [, priority])</tt></h3> | ||
199 | <p> | ||
200 | Attach a handler to the compiler pipeline with the given priority. | ||
201 | The handler is detached if no priority is given. | ||
202 | </p> | ||
203 | <p> | ||
204 | The inner workings of the compiler pipeline and the API for handlers | ||
205 | are still in flux. Please see the source code for more details. | ||
206 | </p> | ||
207 | |||
208 | <h3 id="jit_version"><tt>jit.version</tt></h3> | ||
209 | <p> | ||
210 | Contains the LuaJIT version string. | ||
211 | </p> | ||
212 | |||
213 | <h3 id="jit_version_num"><tt>jit.version_num</tt></h3> | ||
214 | <p> | ||
215 | Contains the version number of the LuaJIT core. Version xx.yy.zz | ||
216 | is represented by the decimal number xxyyzz. | ||
217 | </p> | ||
218 | |||
219 | <h3 id="jit_arch"><tt>jit.arch</tt></h3> | ||
220 | <p> | ||
221 | Contains the target architecture name (CPU and optional ABI). | ||
222 | </p> | ||
223 | |||
224 | |||
225 | <h2 id="jit_util">The jit.util.* Library</h2> | ||
226 | <p> | ||
227 | This library holds many utility functions used by the provided | ||
228 | extension modules for LuaJIT (e.g. the optimizer). The API may | ||
229 | change in future versions. | ||
230 | </p> | ||
231 | |||
232 | <h3 id="jit_util_stats"><tt>stats = jit.util.stats(func)</tt></h3> | ||
233 | <p> | ||
234 | Retrieves information about a function. Returns <tt>nil</tt> | ||
235 | for C functions. Returns a table with the following fields for | ||
236 | Lua functions: | ||
237 | </p> | ||
238 | <ul> | ||
239 | <li><tt>status</tt>: numeric compilation status (see <tt>jit.util.status</tt>).</li> | ||
240 | <li><tt>stackslots</tt>: number of stack slots.</li> | ||
241 | <li><tt>params</tt>: number of fixed parameters (arguments).</li> | ||
242 | <li><tt>consts</tt>: number of constants.</li> | ||
243 | <li><tt>upvalues</tt>: number of upvalues.</li> | ||
244 | <li><tt>subs</tt>: number of subfunctions (sub prototypes).</li> | ||
245 | <li><tt>bytecodes</tt>: number of bytecode instructions.</li> | ||
246 | <li><tt>isvararg</tt>: fixarg (false) or vararg (true) function.</li> | ||
247 | <li><tt>env</tt>: function environment table.</li> | ||
248 | <li><tt>mcodesize</tt>: size of the compiled machine code.</li> | ||
249 | <li><tt>mcodeaddr</tt>: start address of the compiled machine code.</li> | ||
250 | </ul> | ||
251 | <p> | ||
252 | <tt>mcodesize</tt> and <tt>mcodeaddr</tt> are not set if the | ||
253 | function has not been compiled (yet). | ||
254 | </p> | ||
255 | |||
256 | <h3 id="jit_util_bytecode"><tt>op, a, b, c, test = jit.util.bytecode(func, pc)</tt></h3> | ||
257 | <p> | ||
258 | Returns the fields of the bytecode instruction at the given <tt>pc</tt> | ||
259 | for a Lua function. The first instruction is at <tt>pc</tt> = 1. | ||
260 | Nothing is returned if <tt>pc</tt> is out of range. | ||
261 | </p> | ||
262 | <p> | ||
263 | The opcode name is returned as an uppercase string in <tt>op</tt>. | ||
264 | The opcode arguments are returned as <tt>a</tt>, <tt>b</tt> and | ||
265 | optionally <tt>c</tt>. Arguments that indicate an index into the | ||
266 | array of constants are translated to negative numbers (the first | ||
267 | constant is referred to with -1). Branch targets are signed numbers | ||
268 | relative to the next instruction. | ||
269 | </p> | ||
270 | <p> | ||
271 | <tt>test</tt> is true if the instruction is a test (i.e. followed | ||
272 | by a JMP). | ||
273 | </p> | ||
274 | |||
275 | <h3 id="jit_util_const"><tt>const, ok = jit.util.const(func, idx)</tt></h3> | ||
276 | <p> | ||
277 | Returns a constant from the array of constants for a Lua function. | ||
278 | <tt>ok</tt> is true if <tt>idx</tt> is in range. Otherwise nothing | ||
279 | is returned. | ||
280 | </p> | ||
281 | <p> | ||
282 | Constants are numbered starting with 1. A negative <tt>idx</tt> | ||
283 | is mapped to a positive index. | ||
284 | </p> | ||
285 | |||
286 | <h3 id="jit_util_upvalue"><tt>upvalue, ok = jit.util.upvalue(func, idx)</tt></h3> | ||
287 | <p> | ||
288 | Returns an upvalue from the array of upvalues for a Lua function. | ||
289 | <tt>ok</tt> is true if <tt>idx</tt> is in range. Otherwise nothing | ||
290 | is returned. Upvalues are numbered starting with 0. | ||
291 | </p> | ||
292 | |||
293 | <h3 id="jit_util_closurenup"><tt>nup = jit.util.closurenup(func, idx)</tt></h3> | ||
294 | <p> | ||
295 | Returns the number of upvalues for the subfunction prototype with | ||
296 | the given index <tt>idx</tt> for a Lua function. Nothing is returned | ||
297 | if <tt>idx</tt> is out of range. Subfunctions are numbered starting | ||
298 | with 0. | ||
299 | </p> | ||
300 | |||
301 | <h3 id="jit_util_mcode"><tt>addr, mcode, mfmiter = jit.util.mcode(func, block])</tt></h3> | ||
302 | <p> | ||
303 | Returns the numeric start address, the compiled machine code | ||
304 | (converted to a string) and an iterator for the machine code fragment map | ||
305 | for the specified machine code block associated with a Lua function. | ||
306 | </p> | ||
307 | <p> | ||
308 | Returns <tt>nil</tt> and a numeric status code (see <tt>jit.util.status</tt>) | ||
309 | if the function has not been compiled yet or compilation has failed | ||
310 | or compilation is disabled. Returns nothing if the selected | ||
311 | machine code block does not exist. | ||
312 | </p> | ||
313 | <p> | ||
314 | The machine code fragment map is used for debugging and error handling. | ||
315 | The format may change between versions and is an internal implementation | ||
316 | detail of LuaJIT. | ||
317 | </p> | ||
318 | |||
319 | <h3 id="jit_util_jsubmcode"><tt>addr [, mcode] = jit.util.jsubmcode([idx])</tt></h3> | ||
320 | <p> | ||
321 | If <tt>idx</tt> is omitted or nil: | ||
322 | Returns the numeric start address and the compiled machine code | ||
323 | (converted to a string) for internal subroutines used by the | ||
324 | compiled machine code. | ||
325 | </p> | ||
326 | <p> | ||
327 | If <tt>idx</tt> is given: | ||
328 | Returns the numeric start address of the machine code for a specific | ||
329 | internal subroutine (0 based). Nothing is returned if <tt>idx</tt> is | ||
330 | out of range. | ||
331 | </p> | ||
332 | |||
333 | <h3 id="jit_util_status"><tt>jit.util.status</tt></h3> | ||
334 | <p> | ||
335 | This is a table that bidirectionally maps status numbers and | ||
336 | status names (strings): | ||
337 | </p> | ||
338 | <div class="tablewrap"> | ||
339 | <table> | ||
340 | <tr class="sthead"><td class="stname">Status Name</td><td>Description</td></tr> | ||
341 | <tr class="odd"><td class="stname">OK</td><td>Ok, code has been compiled.</td></tr> | ||
342 | <tr class="even"><td class="stname">NONE</td><td>Nothing analyzed or compiled, yet (default).</td></tr> | ||
343 | <tr class="odd"><td class="stname">OFF</td><td>Compilation disabled for this function.</td></tr> | ||
344 | <tr class="even"><td class="stname">ENGINE_OFF</td><td>JIT engine is turned off.</td></tr> | ||
345 | <tr class="odd"><td class="stname">DELAYED</td><td>Compilation delayed (recursive invocation).</td></tr> | ||
346 | <tr class="even"><td class="stname">TOOLARGE</td><td>Bytecode or machine code is too large.</td></tr> | ||
347 | <tr class="odd"><td class="stname">COMPILER_ERROR</td><td>Error from compiler frontend.</td></tr> | ||
348 | <tr class="even"><td class="stname">DASM_ERROR</td><td>Error from DynASM engine.</td></tr> | ||
349 | </table> | ||
350 | </div> | ||
351 | |||
352 | <h3 id="jit_util_hints"><tt>jit.util.hints<br> | ||
353 | jit.util.fhints</tt></h3> | ||
354 | <p> | ||
355 | These two tables map compiler hint names to internal hint numbers. | ||
356 | </p> | ||
357 | <p> | ||
358 | The hint system is an internal implementation detail of LuaJIT. | ||
359 | Please see the source code for more info. | ||
360 | </p> | ||
361 | <br class="flush"> | ||
362 | </div> | ||
363 | <div id="foot"> | ||
364 | <hr class="hide"> | ||
365 | Copyright © 2005-2011 Mike Pall | ||
366 | <span class="noprint"> | ||
367 | · | ||
368 | <a href="contact.html">Contact</a> | ||
369 | </span> | ||
370 | </div> | ||
371 | </body> | ||
372 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_changes.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_changes.html new file mode 100644 index 0000000..bf42b93 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_changes.html | |||
@@ -0,0 +1,301 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>LuaJIT Change History</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>LuaJIT Change History</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a class="current" href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <p> | ||
63 | This is a list of changes between the released versions of LuaJIT. | ||
64 | The current version is <strong>LuaJIT 1.1.7</strong>. | ||
65 | </p> | ||
66 | <p> | ||
67 | Please check the | ||
68 | <a href="http://luajit.org/changes.html"><span class="ext">»</span> Online Change History</a> | ||
69 | to see whether newer versions are available. | ||
70 | </p> | ||
71 | |||
72 | <h2 id="LuaJIT-1.1.7">LuaJIT 1.1.7 — 2011-05-05</h2> | ||
73 | <ul> | ||
74 | <li>Added fixes for the | ||
75 | <a href="http://www.lua.org/bugs.html#5.1.4"><span class="ext">»</span> currently known bugs in Lua 5.1.4</a>.</li> | ||
76 | </ul> | ||
77 | |||
78 | <h2 id="LuaJIT-1.1.6">LuaJIT 1.1.6 — 2010-03-28</h2> | ||
79 | <ul> | ||
80 | <li>Added fixes for the | ||
81 | <a href="http://www.lua.org/bugs.html#5.1.4"><span class="ext">»</span> currently known bugs in Lua 5.1.4</a>.</li> | ||
82 | <li>Removed wrong GC check in <tt>jit_createstate()</tt>. | ||
83 | Thanks to Tim Mensch.</li> | ||
84 | <li>Fixed bad assertions while compiling <tt>table.insert()</tt> and | ||
85 | <tt>table.remove()</tt>.</li> | ||
86 | </ul> | ||
87 | |||
88 | <h2 id="LuaJIT-1.1.5">LuaJIT 1.1.5 — 2008-10-25</h2> | ||
89 | <ul> | ||
90 | <li>Merged with Lua 5.1.4. Fixes all | ||
91 | <a href="http://www.lua.org/bugs.html#5.1.3"><span class="ext">»</span> known bugs in Lua 5.1.3</a>.</li> | ||
92 | </ul> | ||
93 | |||
94 | <h2 id="LuaJIT-1.1.4">LuaJIT 1.1.4 — 2008-02-05</h2> | ||
95 | <ul> | ||
96 | <li>Merged with Lua 5.1.3. Fixes all | ||
97 | <a href="http://www.lua.org/bugs.html#5.1.2"><span class="ext">»</span> known bugs in Lua 5.1.2</a>.</li> | ||
98 | <li>Fixed possible (but unlikely) stack corruption while compiling | ||
99 | <tt>k^x</tt> expressions.</li> | ||
100 | <li>Fixed DynASM template for cmpss instruction.</li> | ||
101 | </ul> | ||
102 | |||
103 | <h2 id="LuaJIT-1.1.3">LuaJIT 1.1.3 — 2007-05-24</h2> | ||
104 | <ul> | ||
105 | <li>Merged with Lua 5.1.2. Fixes all | ||
106 | <a href="http://www.lua.org/bugs.html#5.1.1"><span class="ext">»</span> known bugs in Lua 5.1.1</a>.</li> | ||
107 | <li>Merged pending Lua 5.1.x fixes: "return -nil" bug, spurious count hook call.</li> | ||
108 | <li>Remove a (sometimes) wrong assertion in <tt>luaJIT_findpc()</tt>.</li> | ||
109 | <li>DynASM now allows labels for displacements and <tt>.aword</tt>.</li> | ||
110 | <li>Fix some compiler warnings for DynASM glue (internal API change).</li> | ||
111 | <li>Correct naming for SSSE3 (temporarily known as SSE4) in DynASM and x86 disassembler.</li> | ||
112 | <li>The loadable debug modules now handle redirection to stdout | ||
113 | (e.g. <tt>-j trace=-</tt>).</li> | ||
114 | </ul> | ||
115 | |||
116 | <h2 id="LuaJIT-1.1.2">LuaJIT 1.1.2 — 2006-06-24</h2> | ||
117 | <ul> | ||
118 | <li>Fix MSVC inline assembly: use only local variables with | ||
119 | <tt>lua_number2int()</tt>.</li> | ||
120 | <li>Fix "attempt to call a thread value" bug on Mac OS X: | ||
121 | make values of consts used as lightuserdata keys unique | ||
122 | to avoid joining by the compiler/linker.</li> | ||
123 | </ul> | ||
124 | |||
125 | <h2 id="LuaJIT-1.1.1">LuaJIT 1.1.1 — 2006-06-20</h2> | ||
126 | <ul> | ||
127 | <li>Merged with Lua 5.1.1. Fixes all | ||
128 | <a href="http://www.lua.org/bugs.html#5.1"><span class="ext">»</span> known bugs in Lua 5.1</a>.</li> | ||
129 | <li>Enforce (dynamic) linker error for EXE/DLL version mismatches.</li> | ||
130 | <li>Minor changes to DynASM: faster preprocessing, smaller encoding | ||
131 | for some immediates.</li> | ||
132 | </ul> | ||
133 | <p> | ||
134 | This release is in sync with Coco 1.1.1 (see the | ||
135 | <a href="coco_changes.html">Coco Change History</a>). | ||
136 | </p> | ||
137 | |||
138 | <h2 id="LuaJIT-1.1.0">LuaJIT 1.1.0 — 2006-03-13</h2> | ||
139 | <ul> | ||
140 | <li>Merged with Lua 5.1 (final).</li> | ||
141 | |||
142 | <li>New JIT call frame setup: | ||
143 | <ul> | ||
144 | <li>The C stack is kept 16 byte aligned (faster). | ||
145 | Mandatory for Mac OS X on Intel, too.</li> | ||
146 | <li>Faster calling conventions for internal C helper functions.</li> | ||
147 | <li>Better instruction scheduling for function prologue, OP_CALL and | ||
148 | OP_RETURN.</li> | ||
149 | </ul></li> | ||
150 | |||
151 | <li>Miscellaneous optimizations: | ||
152 | <ul> | ||
153 | <li>Faster loads of FP constants. Remove narrow-to-wide store-to-load | ||
154 | forwarding stalls.</li> | ||
155 | <li>Use (scalar) SSE2 ops (if the CPU supports it) to speed up slot moves | ||
156 | and FP to integer conversions.</li> | ||
157 | <li>Optimized the two-argument form of <tt>OP_CONCAT</tt> (<tt>a..b</tt>).</li> | ||
158 | <li>Inlined <tt>OP_MOD</tt> (<tt>a%b</tt>). | ||
159 | With better accuracy than the C variant, too.</li> | ||
160 | <li>Inlined <tt>OP_POW</tt> (<tt>a^b</tt>). Unroll <tt>x^k</tt> or | ||
161 | use <tt>k^x = 2^(log2(k)*x)</tt> or call <tt>pow()</tt>.</li> | ||
162 | </ul></li> | ||
163 | |||
164 | <li>Changes in the optimizer: | ||
165 | <ul> | ||
166 | <li>Improved hinting for table keys derived from table values | ||
167 | (<tt>t1[t2[x]]</tt>).</li> | ||
168 | <li>Lookup hinting now works with arbitrary object types and | ||
169 | supports index chains, too.</li> | ||
170 | <li>Generate type hints for arithmetic and comparison operators, | ||
171 | OP_LEN, OP_CONCAT and OP_FORPREP.</li> | ||
172 | <li>Remove several hint definitions in favour of a generic COMBINE hint.</li> | ||
173 | <li>Complete rewrite of <tt>jit.opt_inline</tt> module | ||
174 | (ex <tt>jit.opt_lib</tt>).</li> | ||
175 | </ul></li> | ||
176 | |||
177 | <li>Use adaptive deoptimization: | ||
178 | <ul> | ||
179 | <li>If runtime verification of a contract fails, the affected | ||
180 | instruction is recompiled and patched on-the-fly. | ||
181 | Regular programs will trigger deoptimization only occasionally.</li> | ||
182 | <li>This avoids generating code for uncommon fallback cases | ||
183 | most of the time. Generated code is up to 30% smaller compared to | ||
184 | LuaJIT 1.0.3.</li> | ||
185 | <li>Deoptimization is used for many opcodes and contracts: | ||
186 | <ul> | ||
187 | <li>OP_CALL, OP_TAILCALL: type mismatch for callable.</li> | ||
188 | <li>Inlined calls: closure mismatch, parameter number and type mismatches.</li> | ||
189 | <li>OP_GETTABLE, OP_SETTABLE: table or key type and range mismatches.</li> | ||
190 | <li>All arithmetic and comparison operators, OP_LEN, OP_CONCAT, | ||
191 | OP_FORPREP: operand type and range mismatches.</li> | ||
192 | </ul></li> | ||
193 | <li>Complete redesign of the debug and traceback info | ||
194 | (bytecode ↔ mcode) to support deoptimization. | ||
195 | Much more flexible and needs only 50% of the space.</li> | ||
196 | <li>The modules <tt>jit.trace</tt>, <tt>jit.dumphints</tt> and | ||
197 | <tt>jit.dump</tt> handle deoptimization.</li> | ||
198 | </ul></li> | ||
199 | |||
200 | <li>Inlined many popular library functions | ||
201 | (for commonly used arguments only): | ||
202 | <ul> | ||
203 | <li>Most <tt>math.*</tt> functions (the 18 most used ones) | ||
204 | [2x-10x faster].</li> | ||
205 | <li><tt>string.len</tt>, <tt>string.sub</tt> and <tt>string.char</tt> | ||
206 | [2x-10x faster].</li> | ||
207 | <li><tt>table.insert</tt>, <tt>table.remove</tt> and <tt>table.getn</tt> | ||
208 | [3x-5x faster].</li> | ||
209 | <li><tt>coroutine.yield</tt> and <tt>coroutine.resume</tt> | ||
210 | [3x-5x faster].</li> | ||
211 | <li><tt>pairs</tt>, <tt>ipairs</tt> and the corresponding iterators | ||
212 | [8x-15x faster].</li> | ||
213 | </ul></li> | ||
214 | |||
215 | <li>Changes in the core and loadable modules and the stand-alone executable: | ||
216 | <ul> | ||
217 | <li>Added <tt>jit.version</tt>, <tt>jit.version_num</tt> | ||
218 | and <tt>jit.arch</tt>.</li> | ||
219 | <li>Reorganized some internal API functions (<tt>jit.util.*mcode*</tt>).</li> | ||
220 | <li>The <tt>-j dump</tt> output now shows JSUB names, too.</li> | ||
221 | <li>New x86 disassembler module written in pure Lua. No dependency | ||
222 | on ndisasm anymore. Flexible API, very compact (500 lines) | ||
223 | and complete (x87, MMX, SSE, SSE2, SSE3, SSSE3, privileged instructions).</li> | ||
224 | <li><tt>luajit -v</tt> prints the LuaJIT version and copyright | ||
225 | on a separate line.</li> | ||
226 | </ul></li> | ||
227 | |||
228 | <li>Added SSE, SSE2, SSE3 and SSSE3 support to DynASM.</li> | ||
229 | <li>Miscellaneous doc changes. Added a section about | ||
230 | <a href="luajit_install.html#embedding">embedding LuaJIT</a>.</li> | ||
231 | </ul> | ||
232 | <p> | ||
233 | This release is in sync with Coco 1.1.0 (see the | ||
234 | <a href="coco_changes.html">Coco Change History</a>). | ||
235 | </p> | ||
236 | |||
237 | <h2 id="LuaJIT-1.0.3">LuaJIT 1.0.3 — 2005-09-08</h2> | ||
238 | <ul> | ||
239 | <li>Even more docs.</li> | ||
240 | <li>Unified closure checks in <tt>jit.*</tt>.</li> | ||
241 | <li>Fixed some range checks in <tt>jit.util.*</tt>.</li> | ||
242 | <li>Fixed __newindex call originating from <tt>jit_settable_str()</tt>.</li> | ||
243 | <li>Merged with Lua 5.1 alpha (including early bugfixes).</li> | ||
244 | </ul> | ||
245 | <p> | ||
246 | This is the first public release of LuaJIT. | ||
247 | </p> | ||
248 | |||
249 | <h2 id="LuaJIT-1.0.2">LuaJIT 1.0.2 — 2005-09-02</h2> | ||
250 | <ul> | ||
251 | <li>Add support for flushing the Valgrind translation cache <br> | ||
252 | (<tt>MYCFLAGS= -DUSE_VALGRIND</tt>).</li> | ||
253 | <li>Add support for freeing executable mcode memory to the <tt>mmap()</tt>-based | ||
254 | variant for POSIX systems.</li> | ||
255 | <li>Reorganized the C function signature handling in | ||
256 | <tt>jit.opt_lib</tt>.</li> | ||
257 | <li>Changed to index-based hints for inlining C functions. | ||
258 | Still no support in the backend for inlining.</li> | ||
259 | <li>Hardcode <tt>HEAP_CREATE_ENABLE_EXECUTE</tt> value if undefined.</li> | ||
260 | <li>Misc. changes to the <tt>jit.*</tt> modules.</li> | ||
261 | <li>Misc. changes to the Makefiles.</li> | ||
262 | <li>Lots of new docs.</li> | ||
263 | <li>Complete doc reorg.</li> | ||
264 | </ul> | ||
265 | <p> | ||
266 | Not released because Lua 5.1 alpha came out today. | ||
267 | </p> | ||
268 | |||
269 | <h2 id="LuaJIT-1.0.1">LuaJIT 1.0.1 — 2005-08-31</h2> | ||
270 | <ul> | ||
271 | <li>Missing GC step in <tt>OP_CONCAT</tt>.</li> | ||
272 | <li>Fix result handling for C –> JIT calls.</li> | ||
273 | <li>Detect CPU feature bits.</li> | ||
274 | <li>Encode conditional moves (<tt>fucomip</tt>) only when supported.</li> | ||
275 | <li>Add fallback instructions for FP compares.</li> | ||
276 | <li>Add support for <tt>LUA_COMPAT_VARARG</tt>. Still disabled by default.</li> | ||
277 | <li>MSVC needs a specific place for the <tt>CALLBACK</tt> attribute | ||
278 | (David Burgess).</li> | ||
279 | <li>Misc. doc updates.</li> | ||
280 | </ul> | ||
281 | <p> | ||
282 | Interim non-public release. | ||
283 | Special thanks to Adam D. Moss for reporting most of the bugs. | ||
284 | </p> | ||
285 | |||
286 | <h2 id="LuaJIT-1.0.0">LuaJIT 1.0.0 — 2005-08-29</h2> | ||
287 | <p> | ||
288 | This is the initial non-public release of LuaJIT. | ||
289 | </p> | ||
290 | <br class="flush"> | ||
291 | </div> | ||
292 | <div id="foot"> | ||
293 | <hr class="hide"> | ||
294 | Copyright © 2005-2011 Mike Pall | ||
295 | <span class="noprint"> | ||
296 | · | ||
297 | <a href="contact.html">Contact</a> | ||
298 | </span> | ||
299 | </div> | ||
300 | </body> | ||
301 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_debug.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_debug.html new file mode 100644 index 0000000..95d5565 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_debug.html | |||
@@ -0,0 +1,273 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>Debugging LuaJIT</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>Debugging LuaJIT</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a class="current" href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <p> | ||
63 | LuaJIT is a rather complex application. There will undoubtedly | ||
64 | be bugs lurking in there. You have been warned. :-) | ||
65 | </p> | ||
66 | <p> | ||
67 | If you came here looking for information on how to debug | ||
68 | <em>your application</em> (and not LuaJIT itself) then please | ||
69 | check out <a href="luajit_api.html#jit_debug"><tt>jit.debug()</tt></a> | ||
70 | and the <a href="luajit_run.html#j_debug"><tt>-j debug</tt></a> | ||
71 | command line option. | ||
72 | </p> | ||
73 | <p> | ||
74 | But if you suspect a problem with LuaJIT itself, then try | ||
75 | any of the following suggestions (in order). | ||
76 | </p> | ||
77 | |||
78 | <h2>Is LuaJIT the Problem?</h2> | ||
79 | <p> | ||
80 | Try to run your application in several different ways: | ||
81 | </p> | ||
82 | <ul> | ||
83 | <li><tt>luajit app.lua</tt></li> | ||
84 | <li><tt>luajit -O1 app.lua</tt></li> | ||
85 | <li><tt>luajit -O app.lua</tt></li> | ||
86 | <li><tt>luajit -j off app.lua</tt></li> | ||
87 | <li><tt>lua app.lua</tt> (i.e. with standard Lua)</li> | ||
88 | </ul> | ||
89 | <p> | ||
90 | If the behaviour is the <em>same</em> as with standard Lua then ... | ||
91 | well ... that's what LuaJIT is about: doing the same things, | ||
92 | just faster. Even bugs fly faster. :-) | ||
93 | </p> | ||
94 | <p> | ||
95 | So this is most likely a bug in your application then. It may be easier | ||
96 | to debug this with plain Lua — the remainder of this page | ||
97 | is probably not helpful for you. | ||
98 | </p> | ||
99 | <p> | ||
100 | But if the behaviour is <em>different</em>, there is some likelihood | ||
101 | that you caught a bug in LuaJIT. Oh dear ... | ||
102 | </p> | ||
103 | <p> | ||
104 | Ok, so don't just give up. Please read on and help the community | ||
105 | by finding the bug. Thank you! | ||
106 | </p> | ||
107 | |||
108 | <h2>Get the Latest Version</h2> | ||
109 | <p> | ||
110 | Number one on your list of things to check is the | ||
111 | <a href="http://luajit.org/luajit_changes.html"><span class="ext">»</span> Online Change History</a>. | ||
112 | </p> | ||
113 | <p> | ||
114 | Please check if a newer version is available. Maybe the bug | ||
115 | you have encountered has been fixed already. Always download the | ||
116 | latest version and try it with your application before continuing. | ||
117 | </p> | ||
118 | |||
119 | <h2>Reproduce the Bug</h2> | ||
120 | <p> | ||
121 | First try to make the bug reproducible. Try to isolate the module | ||
122 | and the function the bug occurs in: | ||
123 | </p> | ||
124 | <p> | ||
125 | Either selectively turn off compilation for some modules with<br> | ||
126 | <tt> jit.off(true, true)</tt><br> | ||
127 | until the bug disappears ... | ||
128 | </p> | ||
129 | <p> | ||
130 | And/or turn the whole JIT engine off and selectively compile | ||
131 | functions with<br> | ||
132 | <tt> jit.compile(func)</tt><br> | ||
133 | until it reappears. | ||
134 | </p> | ||
135 | <p> | ||
136 | If you have isolated the point where it happens, it's most helpful | ||
137 | to reduce the affected Lua code to a short code snippet that | ||
138 | still shows the problem. You may need to <tt>print()</tt> some | ||
139 | variables until you can pinpoint the exact spot where it happens. | ||
140 | </p> | ||
141 | <p> | ||
142 | If you've got a <em>reproducible</em> and <em>short</em> test | ||
143 | you can either send it directly to me or the mailing list | ||
144 | (see the <a href="contact.html">Contact Information</a>) | ||
145 | or you can try to debug this a bit further. | ||
146 | </p> | ||
147 | <p> | ||
148 | Well — if you are brave enough. :-) | ||
149 | </p> | ||
150 | |||
151 | <h2>Look at the Generated Code</h2> | ||
152 | <p> | ||
153 | You may want to have a look at the output of <tt>-j dumphints</tt> | ||
154 | first. Try to change things around until you can see which hint | ||
155 | or which instruction is the cause of the bug. If you suspect | ||
156 | an optimizer bug then have a look at the backend (<tt>*.das[ch]</tt>) | ||
157 | and check how the hint is encoded. | ||
158 | </p> | ||
159 | <p> | ||
160 | Otherwise have a look at <tt>-j dump</tt> and see whether | ||
161 | you can spot the problem around the affected instruction. | ||
162 | It's helpful to have a good knowledge of assembler, though | ||
163 | (sorry). | ||
164 | </p> | ||
165 | |||
166 | <h2>Locate a Crash</h2> | ||
167 | <p> | ||
168 | If you get a crash, you should compile LuaJIT with debugging | ||
169 | turned on: | ||
170 | </p> | ||
171 | <p> | ||
172 | Add <tt>-g</tt> to <tt>CFLAGS</tt> and <tt>MYLDFLAGS</tt> | ||
173 | or whatever is needed to turn on debugging. For Windows you | ||
174 | need both an executable and a DLL built with debugging. | ||
175 | </p> | ||
176 | <p> | ||
177 | Then start LuaJIT with your debugger. Run it with | ||
178 | <tt>-j dump=test.dump</tt>. | ||
179 | </p> | ||
180 | <p> | ||
181 | Have a look at the backtrace and compare it with the generated | ||
182 | dump file to find out exactly where it crashes. I'm sorry, but | ||
183 | symbols or instructions for JIT compiled functions are not | ||
184 | displayed in your debugger (this is really hard to solve). | ||
185 | </p> | ||
186 | |||
187 | <h2>Turn on Assertions</h2> | ||
188 | <p> | ||
189 | Another way to debug LuaJIT is to turn on assertions. | ||
190 | They can be turned on only for the JIT engine by adding | ||
191 | <tt>-DLUAJIT_ASSERT</tt> to <tt>JITCFLAGS</tt> in <tt>src/Makefile</tt>. | ||
192 | Then recompile with <tt>make clean</tt> and <tt>make</tt>. | ||
193 | </p> | ||
194 | <p> | ||
195 | Add these two lines to <tt>src/luaconf.h</tt> to turn on all assertions in the Lua core:<br> | ||
196 | <tt> #include <assert.h></tt><br> | ||
197 | <tt> #define lua_assert(x) assert(x)</tt><br> | ||
198 | This turns on the JIT engine assertions, too. | ||
199 | Recompile and see whether any assertions trigger. | ||
200 | Don't forget to turn off the (slow) assertions when you're done! | ||
201 | </p> | ||
202 | |||
203 | <h2>Use Valgrind</h2> | ||
204 | <p> | ||
205 | A tremendously useful (and free) tool for runtime code analysis | ||
206 | is <a href="http://valgrind.org/"><span class="ext">»</span> Valgrind</a>. Regularly | ||
207 | run your applications with <tt>valgrind --memcheck</tt> and | ||
208 | your life will be better. | ||
209 | </p> | ||
210 | <p> | ||
211 | To run LuaJIT under Valgrind you <em>must</em> add | ||
212 | <tt>-DUSE_VALGRIND</tt> to <tt>MYCFLAGS</tt> | ||
213 | and recompile LuaJIT. You will get random errors if you don't! | ||
214 | Valgrind 3.x or later is required. Earlier versions | ||
215 | do not work well with newly allocated C stacks. | ||
216 | </p> | ||
217 | <p> | ||
218 | An executable built with this option runs fine without Valgrind | ||
219 | and without a performance loss. But it needs the Valgrind header | ||
220 | files for compilation (which is why it's not enabled by default). | ||
221 | </p> | ||
222 | <p> | ||
223 | It's helpful to compile LuaJIT with debugging turned on, too | ||
224 | (see above). | ||
225 | </p> | ||
226 | <p> | ||
227 | If Valgrind spots many invalid memory accesses that involve | ||
228 | memory allocation/free functions you've probably found a bug | ||
229 | related to garbage collection. Some object reference must have | ||
230 | gone astray. | ||
231 | </p> | ||
232 | <p> | ||
233 | Try to find out which object is disappearing. You can force | ||
234 | eager garbage collection with repeated calls to | ||
235 | <tt>collectgarbage()</tt> or by setting a very low threshold | ||
236 | with <tt>collectgarbage("setpause", 1)</tt>. | ||
237 | </p> | ||
238 | |||
239 | <h2>Don't Despair</h2> | ||
240 | <p> | ||
241 | If all of this doesn't help to find the bug, please send | ||
242 | a summary of your findings to the mailing list. Describe as much | ||
243 | of the circumstances you think are relevant. | ||
244 | </p> | ||
245 | <p> | ||
246 | Please <em>don't</em> send your whole application to me | ||
247 | (without asking first) and especially not to the mailing list. | ||
248 | Code snippets should preferrably be less than 50 lines and | ||
249 | up to the point. | ||
250 | </p> | ||
251 | <p> | ||
252 | All bug reports are helpful, even if no immediate solution | ||
253 | is available. Often enough someone else finds the same bug | ||
254 | in a different setting and together with your bug report | ||
255 | this may help to track it down. | ||
256 | </p> | ||
257 | <p> | ||
258 | Finally I have to say a <strong>BIG THANK YOU</strong> | ||
259 | to everyone who has helped to make LuaJIT better by finding | ||
260 | and fixing bugs! | ||
261 | </p> | ||
262 | <br class="flush"> | ||
263 | </div> | ||
264 | <div id="foot"> | ||
265 | <hr class="hide"> | ||
266 | Copyright © 2005-2011 Mike Pall | ||
267 | <span class="noprint"> | ||
268 | · | ||
269 | <a href="contact.html">Contact</a> | ||
270 | </span> | ||
271 | </div> | ||
272 | </body> | ||
273 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_features.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_features.html new file mode 100644 index 0000000..b4e896f --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_features.html | |||
@@ -0,0 +1,226 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>LuaJIT Features</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>LuaJIT Features</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a class="current" href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <p> | ||
63 | LuaJIT tries to keep the spirit of Lua — it's <em>light-weight</em>, | ||
64 | <em>efficient</em> and <em>extensible</em>. | ||
65 | </p> | ||
66 | |||
67 | <h2>Features</h2> | ||
68 | <p> | ||
69 | All functions are by default compiled Just-In-Time (JIT) to | ||
70 | machine code: | ||
71 | </p> | ||
72 | <ul> | ||
73 | <li>Functions that are unused are not compiled at all.</li> | ||
74 | <li>Compilation can be enabled/disabled selectively for individual | ||
75 | functions and subfunctions or even whole modules.</li> | ||
76 | <li>Interpreted and compiled functions can be freely mixed.</li> | ||
77 | </ul> | ||
78 | <p> | ||
79 | Ahead-Of-Time (AOT) compilation (at runtime) is supported, too: | ||
80 | </p> | ||
81 | <ul> | ||
82 | <li>A number of API functions and command line options allows | ||
83 | full user control over the compilation process.</li> | ||
84 | </ul> | ||
85 | <p> | ||
86 | The JIT compiler is extensible: | ||
87 | </p> | ||
88 | <ul> | ||
89 | <li>The optimizer is an extra module that attaches to the compiler | ||
90 | pipeline.</li> | ||
91 | <li>Various modules provide trace and debug information about | ||
92 | the compilation process.</li> | ||
93 | <li>All of these features can be activated with command line options.</li> | ||
94 | </ul> | ||
95 | |||
96 | <h2>Performance</h2> | ||
97 | <p> | ||
98 | The compiled machine code is <em>very efficient</em>: | ||
99 | </p> | ||
100 | <ul> | ||
101 | <li>Have a look at some | ||
102 | <a href="luajit_performance.html">Performance Measurements</a>.</li> | ||
103 | <li>Aggressive optimizations (specialization, inlining) are enabled | ||
104 | wherever possible. Inlined contracts catch wrong optimizer predictions | ||
105 | at runtime (undetected polymorphism).</li> | ||
106 | <li>Adaptive deoptimization is used to recompile individual bytecode | ||
107 | instructions with broken contracts. This avoids generating code for the | ||
108 | generic fallback cases most of the time (faster compilation, reduced | ||
109 | I-cache contention).</li> | ||
110 | <li>Special CPU features (such as conditional moves or SSE2) | ||
111 | are automatically used when detected.</li> | ||
112 | </ul> | ||
113 | <p> | ||
114 | The JIT compiler is <em>very fast</em>: | ||
115 | </p> | ||
116 | <ul> | ||
117 | <li>Compilation times vary a great deal (depending on the nature of | ||
118 | the function to be compiled) but are generally in the | ||
119 | <em>microsecond</em> range.</li> | ||
120 | <li>Even compiling large functions (hundreds of lines) with the | ||
121 | maximum optimization level takes only a few milliseconds in the | ||
122 | worst case.</li> | ||
123 | </ul> | ||
124 | <p> | ||
125 | LuaJIT is <em>very small</em>: | ||
126 | </p> | ||
127 | <ul> | ||
128 | <li>The whole JIT compiler engine adds only around <strong>32K</strong> | ||
129 | of code to the Lua core (if compiled with <tt>-Os</tt>).</li> | ||
130 | <li>The optimizer is split into several optional modules that | ||
131 | can be loaded at runtime if requested.</li> | ||
132 | <li>LuaJIT adds around 6.000 lines of C and assembler code and | ||
133 | 2.000 lines of Lua code to the Lua 5.1 core (17.000 lines of C).</li> | ||
134 | <li>Required build tools (<a href="dynasm.html">DynASM</a>) | ||
135 | take another 2.500 lines of Lua code.</li> | ||
136 | </ul> | ||
137 | |||
138 | <h2>Compatibility</h2> | ||
139 | <p> | ||
140 | LuaJIT is designed to be <em>fully compatible</em> with Lua 5.1. | ||
141 | It accepts the same source code and/or precompiled bytecode. | ||
142 | It supports all standard language semantics. In particular: | ||
143 | </p> | ||
144 | <ul> | ||
145 | <li>All standard types, operators and metamethods are supported.</li> | ||
146 | <li>Implicit type coercions (number/string) work as expected.</li> | ||
147 | <li>Full IEEE-754 semantics for floating point arithmetics | ||
148 | (NaN, +-Inf, +-0, ...).</li> | ||
149 | <li>Full support for lexical closures. | ||
150 | Proper tail calls do not consume a call frame.</li> | ||
151 | <li>Exceptions are precise. Backtraces work fine.</li> | ||
152 | <li>Coroutines are supported with the help of <a href="coco.html">Coco</a>.</li> | ||
153 | <li>No changes to the Lua 5.1 incremental garbage collector.</li> | ||
154 | <li>No changes to the standard Lua/C API.</li> | ||
155 | <li>Dynamically loaded C modules are link compatible with Lua 5.1 | ||
156 | (same ABI).</li> | ||
157 | <li>LuaJIT can be <a href="luajit_install.html#embedding">embedded</a> | ||
158 | into an application just like Lua.</li> | ||
159 | </ul> | ||
160 | <p> | ||
161 | Some minor differences are related to debugging: | ||
162 | </p> | ||
163 | <ul> | ||
164 | <li>Debug hooks are only called if debug code generation is enabled.</li> | ||
165 | <li>There is no support for tailcall counting in JIT compiled code. | ||
166 | HOOKTAILRET is not called, too. Note: this won't affect you unless | ||
167 | you are writing a Lua debugger. <sup>*</sup></li> | ||
168 | </ul> | ||
169 | <p style="font-size: 80%;"> | ||
170 | <sup>*</sup> There is not much I can do to improve this situation without undue | ||
171 | complications. A suggestion to modify the behaviour of standard Lua | ||
172 | has been made on the mailing list (it would be beneficial there, too). | ||
173 | </p> | ||
174 | |||
175 | <h2>Restrictions</h2> | ||
176 | <ul> | ||
177 | <li>Only x86 (i386+) CPUs are supported right now (but see below).</li> | ||
178 | <li>Only the default type for <tt>lua_Number</tt> is supported | ||
179 | (<tt>double</tt>).</li> | ||
180 | <li>The interrupt signal (Ctrl-C) is ignored unless you enable | ||
181 | debug hooks (with <tt>-j debug</tt>). But this will seriously | ||
182 | slow down your application. I'm looking for better ways to handle | ||
183 | this. In the meantime you have to press Ctrl-C twice to interrupt | ||
184 | a currently running JIT compiled function (just like C functions).</li> | ||
185 | <li>GDB, Valgrind and other debugging tools can't report symbols | ||
186 | or stack frames for JIT compiled code. This is rather difficult to solve. | ||
187 | Have a look at <a href="luajit_debug.html">Debugging LuaJIT</a>, too.</li> | ||
188 | </ul> | ||
189 | |||
190 | <h2>Caveats</h2> | ||
191 | <ul> | ||
192 | <li>LuaJIT allocates executable memory for the generated machine code | ||
193 | if your OS has support for it: either <tt>HeapCreate()</tt> for Windows or | ||
194 | <tt>mmap()</tt> on POSIX systems.<br> | ||
195 | The fallback is the standard Lua allocator (i.e. malloc()). | ||
196 | But this usually means the allocated memory is not marked executable. | ||
197 | Running compiled code will trap on CPUs/OS with the NX (No eXecute) | ||
198 | extension <em>if you can only use the fallback</em>.</li> | ||
199 | <li><a href="dynasm.html">DynASM</a> is needed to regenerate the | ||
200 | <tt>ljit_x86.h</tt> file. But only in case you want to <em>modify</em> | ||
201 | the <tt>*.dasc</tt>/<tt>*.dash</tt> files. A pre-processed <tt>*.h</tt> | ||
202 | file is supplied with LuaJIT.<br> | ||
203 | DynASM is written in Lua and needs a plain copy of Lua 5.1 | ||
204 | (installed as <tt>lua</tt>). Or you can run it with LuaJIT built from | ||
205 | the <tt>*.h</tt> file supplied with the distribution (modify | ||
206 | <tt>DASM=</tt> in <tt>src/Makefile</tt>). It's a good idea to install | ||
207 | a known good copy of LuaJIT under a different name for this.</li> | ||
208 | <li>LuaJIT ships with <tt>LUA_COMPAT_VARARG</tt> turned off. | ||
209 | I.e. the implicit <tt>arg</tt> parameter is not created anymore. | ||
210 | Please have a look at the comments in <tt>luaconf.h</tt> for | ||
211 | this configuration option. You can turn it on, if you really need it. | ||
212 | Or better yet, convert your code to the new Lua 5.1 vararg syntax.</li> | ||
213 | </ul> | ||
214 | |||
215 | <br class="flush"> | ||
216 | </div> | ||
217 | <div id="foot"> | ||
218 | <hr class="hide"> | ||
219 | Copyright © 2005-2011 Mike Pall | ||
220 | <span class="noprint"> | ||
221 | · | ||
222 | <a href="contact.html">Contact</a> | ||
223 | </span> | ||
224 | </div> | ||
225 | </body> | ||
226 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_install.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_install.html new file mode 100644 index 0000000..bc5a3cd --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_install.html | |||
@@ -0,0 +1,340 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>Installing LuaJIT</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | <style type="text/css"> | ||
12 | table.build { | ||
13 | line-height: 1.2; | ||
14 | } | ||
15 | td.buildsys { | ||
16 | width: 11em; | ||
17 | } | ||
18 | td.buildcmd { | ||
19 | width: 10em; | ||
20 | font-family: Courier New, Courier, monospace; | ||
21 | } | ||
22 | tr.buildhead td { | ||
23 | /* font-family: inherit; ... not supported in IE *sigh* */ | ||
24 | font-family: Verdana, Arial, Helvetica, sans-serif; | ||
25 | font-weight: bold; | ||
26 | } | ||
27 | </style> | ||
28 | </head> | ||
29 | <body> | ||
30 | <div id="site"> | ||
31 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
32 | </div> | ||
33 | <div id="head"> | ||
34 | <h1>Installing LuaJIT</h1> | ||
35 | </div> | ||
36 | <div id="nav"> | ||
37 | <ul><li> | ||
38 | <a href="index.html">Index</a> | ||
39 | </li><li> | ||
40 | <a href="luajit.html">LuaJIT</a> | ||
41 | <ul><li> | ||
42 | <a href="luajit_features.html">Features</a> | ||
43 | </li><li> | ||
44 | <a class="current" href="luajit_install.html">Installation</a> | ||
45 | </li><li> | ||
46 | <a href="luajit_run.html">Running</a> | ||
47 | </li><li> | ||
48 | <a href="luajit_api.html">API Extensions</a> | ||
49 | </li><li> | ||
50 | <a href="luajit_intro.html">Introduction</a> | ||
51 | </li><li> | ||
52 | <a href="luajit_performance.html">Performance</a> | ||
53 | </li><li> | ||
54 | <a href="luajit_debug.html">Debugging</a> | ||
55 | </li><li> | ||
56 | <a href="luajit_changes.html">Changes</a> | ||
57 | </li></ul> | ||
58 | </li><li> | ||
59 | <a href="coco.html">Coco</a> | ||
60 | <ul><li> | ||
61 | <a href="coco_portability.html">Portability</a> | ||
62 | </li><li> | ||
63 | <a href="coco_api.html">API Extensions</a> | ||
64 | </li><li> | ||
65 | <a href="coco_changes.html">Changes</a> | ||
66 | </li></ul> | ||
67 | </li><li> | ||
68 | <a href="dynasm.html">DynASM</a> | ||
69 | <ul><li> | ||
70 | <a href="dynasm_features.html">Features</a> | ||
71 | </li><li> | ||
72 | <a href="dynasm_examples.html">Examples</a> | ||
73 | </li></ul> | ||
74 | </li><li> | ||
75 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
76 | </li></ul> | ||
77 | </div> | ||
78 | <div id="main"> | ||
79 | <p> | ||
80 | LuaJIT is not much more difficult to install than Lua itself. | ||
81 | Just unpack the distribution file, change into the newly created | ||
82 | directory and follow the instructions below. | ||
83 | </p> | ||
84 | <p class="indent"> | ||
85 | For the impatient: <b><tt>make linux && sudo make install</tt></b><br> | ||
86 | Replace <tt>linux</tt> with e.g. <tt>bsd</tt> or <tt>macosx</tt> depending on your OS. | ||
87 | </p> | ||
88 | <p> | ||
89 | In case you've missed this in <a href="luajit_features.html">Features</a>: | ||
90 | LuaJIT only works on x86 (i386+) systems right now. Support for | ||
91 | other architectures may be added in future versions. | ||
92 | </p> | ||
93 | |||
94 | <h2>Configuring LuaJIT</h2> | ||
95 | <p> | ||
96 | LuaJIT is (deliberately) <em>not</em> autoconfigured — the | ||
97 | defaults should work fine on most systems. But please check the | ||
98 | system-specific instructions below. | ||
99 | </p> | ||
100 | <p> | ||
101 | The following three files hold all configuration information: | ||
102 | </p> | ||
103 | <ul> | ||
104 | <li><tt>Makefile</tt> holds settings for installing LuaJIT.</li> | ||
105 | <li><tt>src/Makefile</tt> holds settings for compiling LuaJIT.</li> | ||
106 | <li><tt>src/luaconf.h</tt> sets a multitude of configuration | ||
107 | variables.</li> | ||
108 | </ul> | ||
109 | <p> | ||
110 | If this is your first build then it's better not to give into | ||
111 | the temptation to tweak every little setting. The standard | ||
112 | configuration provides sensible defaults (IMHO). | ||
113 | </p> | ||
114 | <p> | ||
115 | One particular setting you might want to change is the installation | ||
116 | path. Note that you need to modify both the top-level <tt>Makefile</tt> | ||
117 | and <tt>src/luaconf.h</tt> (right at the start) to take | ||
118 | effect. | ||
119 | </p> | ||
120 | <p> | ||
121 | If you have trouble getting Coco to work, you can disable it by | ||
122 | uncommenting the <tt>COCOFLAGS= -DCOCO_DISABLE</tt> line in | ||
123 | <tt>src/Makefile</tt>. But note that this effectively disables | ||
124 | yielding from coroutines for JIT compiled functions. | ||
125 | </p> | ||
126 | <p> | ||
127 | A few more settings need to be changed if you want to | ||
128 | <a href="luajit_debug.html">Debug LuaJIT</a> <em>itself</em>. | ||
129 | Application debugging can be turned on/off at runtime. | ||
130 | </p> | ||
131 | |||
132 | <h3>Upgrading From Previous Versions</h3> | ||
133 | <p> | ||
134 | It's important to keep the LuaJIT core and the add-on modules in sync. | ||
135 | Be sure to delete any old versions of LuaJIT modules from the | ||
136 | Lua module search path (check the current directory, too!). | ||
137 | </p> | ||
138 | <p> | ||
139 | Lua files compiled to bytecode may be incompatible if the underlying | ||
140 | Lua core has changed (like from Lua 5.1 alpha to Lua 5.1 | ||
141 | final between LuaJIT 1.0.3 and LuaJIT 1.1.0). The same | ||
142 | applies to any | ||
143 | <a href="http://lua-users.org/wiki/BuildingModules"><span class="ext">»</span> loadable C modules</a> | ||
144 | (shared libraries, DLLs) which need to be recompiled with the new | ||
145 | Lua header files. | ||
146 | </p> | ||
147 | <p> | ||
148 | Compiled bytecode and loadable C modules are fully compatible and | ||
149 | can be freely exchanged between LuaJIT and the <em>same</em> | ||
150 | version of Lua it is based on. Please verify that <tt>LUA_RELEASE</tt> | ||
151 | in <tt>src/lua.h</tt> is the same in both distributions. | ||
152 | </p> | ||
153 | |||
154 | <h2>Building LuaJIT</h2> | ||
155 | |||
156 | <h3>Makefile Targets</h3> | ||
157 | <p> | ||
158 | The Makefiles have a number of targets for various operating systems: | ||
159 | </p> | ||
160 | |||
161 | <div class="tablewrap"> | ||
162 | <table class="build"> | ||
163 | <tr class="buildhead"><td class="buildsys">System</td><td class="buildcmd">Build Command</td><td>Notes</td></tr> | ||
164 | <tr class="odd"><td class="buildsys">Linux i386</td><td class="buildcmd">make linux</td><td></td></tr> | ||
165 | <tr class="even"><td class="buildsys">BSD i386</td><td class="buildcmd">make bsd</td><td>FreeBSD, NetBSD or OpenBSD</td></tr> | ||
166 | <tr class="odd"><td class="buildsys">Mac OS X on Intel</td><td class="buildcmd">make macosx</td><td>Check <tt>src/Makefile</tt> for OS X < 10.4</td></tr> | ||
167 | <tr class="even"><td class="buildsys">Solaris x86</td><td class="buildcmd">make solaris</td><td>GCC only, SunCC miscompiles LuaJIT</td></tr> | ||
168 | <tr class="odd"><td class="buildsys">MinGW (Win32)</td><td class="buildcmd">make mingw</td><td>cross-MinGW: must be 1st in PATH</td></tr> | ||
169 | <tr class="even"><td class="buildsys">Cygwin</td><td class="buildcmd">make cygwin</td><td></td></tr> | ||
170 | <tr class="odd"><td class="buildsys">POSIX on x86</td><td class="buildcmd">make posix</td><td>Check <a href="coco_portability.html">Portability Req. for Coco</a>, too</td></tr> | ||
171 | <tr class="even"><td class="buildsys">Generic x86</td><td class="buildcmd">make generic</td><td>Check <a href="coco_portability.html">Portability Req. for Coco</a>, too</td></tr> | ||
172 | </table> | ||
173 | </div> | ||
174 | |||
175 | <p> | ||
176 | You may want to enable interactive line editing for the stand-alone | ||
177 | executable. There are extra targets for Linux, BSD and Mac OS X: | ||
178 | <tt>make linux_rl</tt>, <tt>make bsd_rl</tt> | ||
179 | and <tt>make macosx_rl</tt>. | ||
180 | </p> | ||
181 | |||
182 | <h3>MSVC (Win32)</h3> | ||
183 | <p> | ||
184 | First check out <tt>etc\luavs.bat</tt> if it suits your needs. Then try | ||
185 | running it from the MSVC command prompt (start it from the toplevel directory). | ||
186 | </p> | ||
187 | <p> | ||
188 | Another option is to set up your own MSVC project: | ||
189 | </p> | ||
190 | <p> | ||
191 | Change to the <tt>src</tt> directory | ||
192 | and create a new DLL project for <tt>lua51.dll</tt>. | ||
193 | Add all C files to it except for <tt>lua.c</tt>, <tt>luac.c</tt> | ||
194 | and <tt>print.c</tt>. Add the <tt>..\dynasm</tt> directory | ||
195 | to the include path and build the DLL. | ||
196 | </p> | ||
197 | <p> | ||
198 | Next create a new EXE project for <tt>luajit.exe</tt>. | ||
199 | Add <tt>lua.c</tt> to it and link with the import library | ||
200 | <tt>lua51.lib</tt> created for <tt>lua51.dll</tt>. Build | ||
201 | the executable. | ||
202 | </p> | ||
203 | |||
204 | <h2>Installation</h2> | ||
205 | |||
206 | <h3>POSIX systems</h3> | ||
207 | <p> | ||
208 | Run <tt>make install</tt> from the top-level directory. | ||
209 | You probably need to be the root user before doing so, i.e. use | ||
210 | <tt>sudo make install</tt> or <tt>su - root</tt> | ||
211 | before the <tt>make install</tt>. | ||
212 | </p> | ||
213 | <p> | ||
214 | By default this installs only:<br> | ||
215 | <tt> /usr/local/bin/<strong>luajit</strong></tt> — The stand-alone executable.<br> | ||
216 | <tt> /usr/local/lib/lua/5.1</tt> — C module directory.<br> | ||
217 | <tt> /usr/local/share/lua/5.1</tt> — Lua module directory.<br> | ||
218 | <tt> /usr/local/share/lua/5.1/<strong>jit/*.lua</strong></tt> — | ||
219 | <tt>jit.*</tt> modules.<br> | ||
220 | </p> | ||
221 | <p> | ||
222 | The Lua docs and includes are not installed to avoid overwriting | ||
223 | an existing Lua installation. In any case these are identical | ||
224 | to the version of Lua that LuaJIT is based on. If you want | ||
225 | to install them, edit the top-level makefile (look for <tt>###</tt>). | ||
226 | </p> | ||
227 | <p> | ||
228 | The stand-alone Lua bytecode compiler <tt>luac</tt> is neither | ||
229 | built nor installed, for the same reason. If you really need it, | ||
230 | you may be better off with <tt>luac</tt> built from the original Lua | ||
231 | distribution (use the <em>same</em> version your copy of LuaJIT | ||
232 | is based on). This avoids dragging in most of LuaJIT which is not | ||
233 | needed for the pure bytecode compiler. You can also use the bare-bones | ||
234 | Lua to bytecode translator <tt>luac.lua</tt> (look in the <tt>test</tt> | ||
235 | directory of the original Lua distribution). | ||
236 | </p> | ||
237 | |||
238 | <h3>Windows</h3> | ||
239 | <p> | ||
240 | Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt> | ||
241 | to a newly created directory (any location is ok). Add <tt>lua</tt> | ||
242 | and <tt>lua\jit</tt> directories below it and copy all Lua files | ||
243 | from the <tt>jit</tt> directory of the distribution to the latter directory. | ||
244 | </p> | ||
245 | <p> | ||
246 | There are no hardcoded | ||
247 | absolute path names — all modules are loaded relative to the | ||
248 | directory where <tt>luajit.exe</tt> is installed | ||
249 | (see <tt>src/luaconf.h</tt>). | ||
250 | </p> | ||
251 | |||
252 | <h2 id="embedding">Embedding LuaJIT</h2> | ||
253 | <p> | ||
254 | It's strongly recommended that you build the stand-alone executable | ||
255 | with your toolchain and verify that it works <em>before</em> starting | ||
256 | to embed LuaJIT into an application. The stand-alone executable is | ||
257 | also useful later on, when you want to experiment with code snippets | ||
258 | or try out some Lua files. | ||
259 | </p> | ||
260 | <p> | ||
261 | Please consult the Lua docs for general information about how to | ||
262 | embed Lua into your application. The following list only shows | ||
263 | the additional steps needed for embedding LuaJIT: | ||
264 | </p> | ||
265 | <ul> | ||
266 | <li>You need to add the LuaJIT library functions by running | ||
267 | <tt>luaopen_jit()</tt> after all the other standard library functions. | ||
268 | The modified <tt>src/linit.c</tt> used by the stand-alone executable | ||
269 | already does this for you.</li> | ||
270 | <li><em>Caveat:</em> LuaJIT is based on Lua 5.1 which | ||
271 | means the <tt>luaopen_*()</tt> functions <em>must not</em> | ||
272 | be called directly. See <tt>src/linit.c</tt> for the proper way to | ||
273 | run them. You'll get an error initializing the <tt>io</tt> library | ||
274 | if you don't follow these instructions.</li> | ||
275 | <li>To use the optimizer (strongly recommended) you need to: | ||
276 | <ul> | ||
277 | <li>Install the optimizer modules <tt>jit.opt</tt> and | ||
278 | <tt>jit.opt_inline</tt> relative to the Lua module path | ||
279 | (you've probably modified it — see <tt>src/luaconf.h</tt>):<br> | ||
280 | <tt>jit/opt.lua</tt><br> | ||
281 | <tt>jit/opt_inline.lua</tt></li> | ||
282 | <li>If you want to ship a single executable then you may want to | ||
283 | embed the optimizer modules into your application (but don't loose | ||
284 | time with this during the early development phase). This involves: | ||
285 | <ul> | ||
286 | <li>Compile the two modules to bytecode | ||
287 | (using <tt>luac -s</tt> from a plain Lua installation).</li> | ||
288 | <li>Convert them to C include files (search for "Lua bin2c").</li> | ||
289 | <li>On Windows you can also put the compiled bytecode into a resource | ||
290 | (search for "Lua bin2res").</li> | ||
291 | <li>Load the bytecode with <tt>luaL_loadbuffer</tt> (but don't run it).</li> | ||
292 | <li>Put the resulting functions into <tt>package.preload["jit.opt"]</tt> | ||
293 | and <tt>package.preload["jit.opt_inline"]</tt>.</li> | ||
294 | </ul></li> | ||
295 | <li>Activate the LuaJIT optimizer from Lua code to be run at startup: | ||
296 | <tt> require("jit.opt").start()</tt><br> | ||
297 | Or use equivalent C code. See <tt>dojitopt()</tt> in <tt>src/lua.c</tt>.</li> | ||
298 | </ul></li> | ||
299 | <li>All other LuaJIT specific modules (<tt>jit.*</tt>) are for debugging only. | ||
300 | They do not need to be shipped with an application. But they may be quite | ||
301 | useful, anyway (especially <tt>jit.trace</tt>).</li> | ||
302 | <li>DynASM is only needed while <em>building</em> LuaJIT. It's not | ||
303 | needed while running LuaJIT and there is no point in shipping or | ||
304 | installing it together with an application.</li> | ||
305 | <li>In case you want to strip some of the standard libraries from | ||
306 | your application: The optimizer modules need several functions from | ||
307 | the base library and the string library (and of course the LuaJIT | ||
308 | core libraries). The io library is only used to print a fatal error | ||
309 | message (you may want to replace it). The optional modules | ||
310 | for debugging depend on a few more library functions — | ||
311 | please check the source.</li> | ||
312 | </ul> | ||
313 | <p> | ||
314 | Although the very liberal LuaJIT | ||
315 | <a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">»</span> license</a> | ||
316 | does not require any acknowledgment whatsoever, it would be appreciated | ||
317 | if you give some credit in the docs (or the "About" box) of your application. | ||
318 | A simple line like:<br> | ||
319 | <tt> This product includes LuaJIT, http://luajit.org/</tt><br> | ||
320 | would be nice. Please do not include any E-Mail addresses. Thank you! | ||
321 | </p> | ||
322 | <p> | ||
323 | I'm always interested where LuaJIT can be put to good use in applications. | ||
324 | Please <a href="contact.html">tell me</a> | ||
325 | or better yet write a few lines about your project to the | ||
326 | <a href="http://www.lua.org/lua-l.html"><span class="ext">»</span> Lua mailing list</a>. | ||
327 | Thank you! | ||
328 | </p> | ||
329 | <br class="flush"> | ||
330 | </div> | ||
331 | <div id="foot"> | ||
332 | <hr class="hide"> | ||
333 | Copyright © 2005-2011 Mike Pall | ||
334 | <span class="noprint"> | ||
335 | · | ||
336 | <a href="contact.html">Contact</a> | ||
337 | </span> | ||
338 | </div> | ||
339 | </body> | ||
340 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_intro.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_intro.html new file mode 100644 index 0000000..9e1fb23 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_intro.html | |||
@@ -0,0 +1,389 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>Introducing LuaJIT</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>Introducing LuaJIT</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a class="current" href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <p> | ||
63 | This is a little essay that tries to answer the question: | ||
64 | <em>'So, how does LuaJIT really work?'</em>. | ||
65 | </p> | ||
66 | <p> | ||
67 | I tried to avoid going into all the gory details, but at the | ||
68 | same time provide a deep enough explanation, to let you find | ||
69 | your way around LuaJIT's inner workings. | ||
70 | </p> | ||
71 | <p> | ||
72 | The learning curve is maybe a little bit steep for newbies and | ||
73 | compiler gurus will certainly fall asleep after two paragraphs. | ||
74 | It's difficult to strike a balance here. | ||
75 | </p> | ||
76 | |||
77 | <h2>Acronym Soup</h2> | ||
78 | <p> | ||
79 | As the name says LuaJIT is a <em>Just-In-Time</em> (JIT) compiler. | ||
80 | This means that functions are compiled on demand, i.e. when they | ||
81 | are run first. This ensures both a quick application startup | ||
82 | and helps to avoid useless work, too. E.g. unused functions | ||
83 | are not compiled at all. | ||
84 | </p> | ||
85 | <p> | ||
86 | The other alternative is known as <em>Ahead-Of-Time</em> (AOT) | ||
87 | compilation. Here everything is compiled before running any function. | ||
88 | This is the classic way for many languages, such as C or C++. | ||
89 | </p> | ||
90 | <p> | ||
91 | In fact plain Lua allows you to pre-compile Lua source code into | ||
92 | Lua bytecode and store it in a binary file that can be run | ||
93 | later on. This is used only in specific settings (e.g. memory limited | ||
94 | embedded systems), because the Lua bytecode compiler is really fast. | ||
95 | The ability to run source files right away is part of what makes | ||
96 | a dynamic language (aka scripting language) so powerful. | ||
97 | </p> | ||
98 | <p> | ||
99 | JIT compilation has a few other advantages for dynamic languages | ||
100 | that AOT compilation can only provide with a massive amount | ||
101 | of code analysis. More can be found in the literature. | ||
102 | One particular advantage is explained later. | ||
103 | </p> | ||
104 | |||
105 | <h2>Quick, JIT — Run!</h2> | ||
106 | <p> | ||
107 | JIT compilation happens mostly invisible. You'll probably never | ||
108 | notice that a compilation is going on. Part of the secret is | ||
109 | that everything happens in little pieces intermixed with running | ||
110 | the application itself inbetween. The other part of the secret | ||
111 | is that JIT compilation can be made pretty fast. | ||
112 | </p> | ||
113 | <p> | ||
114 | Most applications quickly converge to a stable state where | ||
115 | everything that really needs to be compiled is compiled | ||
116 | right away. Only occasional isolated compiles happen later on. | ||
117 | </p> | ||
118 | <p> | ||
119 | Even though the name doesn't suggest it, LuaJIT <em>can</em> operate | ||
120 | in AOT mode, too. But this is completely under user control | ||
121 | (see <a href="luajit_api.html#jit_compile"><tt>jit.compile()</tt></a>) | ||
122 | and doesn't happen automatically. | ||
123 | </p> | ||
124 | <p> | ||
125 | Unless you have good reason to suspect that AOT compilation | ||
126 | might help for a specific application, I wouldn't bother though. | ||
127 | Compilation speed is usually a non-argument, because LuaJIT | ||
128 | is extremely fast. Compilation times are typically in the | ||
129 | <em>microsecond range</em> for individual Lua functions. | ||
130 | </p> | ||
131 | |||
132 | <h2>Starting Up</h2> | ||
133 | <p> | ||
134 | The next few paragraphs may not be exactly breaking news to you, | ||
135 | if you are familiar with JIT compilers. Still, please read on, | ||
136 | because some terms are introduced that are used later on. | ||
137 | </p> | ||
138 | <p> | ||
139 | When you start LuaJIT everything proceeds like in standard Lua: | ||
140 | the Lua core is initialized, the standard libraries are loaded and | ||
141 | the command line is analyzed. Then usually the first Lua source | ||
142 | code file is loaded and is translated to Lua bytecode. And finally | ||
143 | the function for the initial main chunk is run ... | ||
144 | </p> | ||
145 | |||
146 | <h2>Kicking the Compiler</h2> | ||
147 | <p> | ||
148 | This is where LuaJIT kicks in: | ||
149 | </p> | ||
150 | <p> | ||
151 | All Lua functions carry an additional <em>status code</em> for LuaJIT. | ||
152 | Initially this is set to 'NONE', i.e. the function has not been | ||
153 | looked at (yet). If a function is run with this setting, | ||
154 | the LuaJIT <em>compiler pipeline</em> is started up. | ||
155 | </p> | ||
156 | <p> | ||
157 | If you haven't loaded any special LuaJIT modules and optimization | ||
158 | is not turned on, the compiler pipeline only consists of the | ||
159 | <em>compiler backend</em>. | ||
160 | </p> | ||
161 | <p> | ||
162 | The compiler backend is the low-level encoding engine that translates | ||
163 | bytecode instructions to machine code instructions. Without any | ||
164 | further hints from other modules, the backend more or less does a | ||
165 | 1:1 translation. I.e. a single variant of a bytecode instruction | ||
166 | corresponds to a single piece of machine code. | ||
167 | </p> | ||
168 | <p> | ||
169 | If all goes well, these little code pieces are put together, | ||
170 | a function prologue is slapped on and voila: your Lua function | ||
171 | has been translated to machine code. Of course things are not | ||
172 | that simple when you look closer, but hey — this is | ||
173 | the theory. | ||
174 | </p> | ||
175 | <p> | ||
176 | Anyway, the status code for the function is set to 'OK' and the | ||
177 | machine code is run. If this function runs another Lua function | ||
178 | which has not been compiled, that one is compiled, too. And so on. | ||
179 | </p> | ||
180 | |||
181 | <h2>Call Gates</h2> | ||
182 | <p> | ||
183 | Ok, so what happens when a function is called repeatedly? After all | ||
184 | this is the most common case. | ||
185 | </p> | ||
186 | <p> | ||
187 | Simple: The status code is checked again. This time it's set to 'OK', | ||
188 | so the machine code can be run directly. Well — that's not the | ||
189 | whole truth: for calls that originate in a JIT compiled function | ||
190 | a better mechanism, tentatively named <em>call gates</em> is used. | ||
191 | </p> | ||
192 | <p> | ||
193 | Every function has a call gate field (a function pointer). By default | ||
194 | it's set to a function that does the above checks and runs the | ||
195 | compiler. But as soon as a function is compiled, the call gate | ||
196 | is modified to point to the just compiled machine code. | ||
197 | </p> | ||
198 | <p> | ||
199 | Calling a function is then as easy as calling the code that the | ||
200 | call gate points to. But due to special (faster) calling conventions | ||
201 | this function pointer cannot be used directly from C. So calls from | ||
202 | a non-compiled function or from a C function use an extra entry | ||
203 | call gate which in turn calls the real call gate. But this is | ||
204 | really a non-issue since most calls in typical applications | ||
205 | are intra-JIT calls. | ||
206 | </p> | ||
207 | |||
208 | <h2>The Compiler Pipeline</h2> | ||
209 | <p> | ||
210 | The compiler pipeline has already been mentioned. This sounds | ||
211 | more complicated than it is. Basically this is a coroutine that | ||
212 | runs a <em>frontend</em> function which in turn calls all functions | ||
213 | from the <em>pipeline table</em>. | ||
214 | </p> | ||
215 | <p> | ||
216 | The pipeline table is sorted by <em>priorities</em>. The standard | ||
217 | backend has priority 0. Positive priorities are run before the | ||
218 | backend and negative priorities are run after the backend. Modules | ||
219 | can dynamically attach or detach themselves to the pipeline with | ||
220 | the library function <tt>jit.attach()</tt>. | ||
221 | </p> | ||
222 | <p> | ||
223 | So a typical optimizer pass better have a positive priority, | ||
224 | because it needs to be run before the backend is run. E.g. the | ||
225 | LuaJIT optimizer module registers itself with priority 50. | ||
226 | </p> | ||
227 | <p> | ||
228 | On the other hand a typical helper module for debugging — | ||
229 | a machine code disassembler — needs to be run after the | ||
230 | backend and is attached with a negative priority. | ||
231 | </p> | ||
232 | <p> | ||
233 | One special case occurs when compilation fails. This can be due to | ||
234 | an internal error (ouch) or on purpose. E.g. the optimizer module | ||
235 | checks some characteristics of the function to be compiled and | ||
236 | may decide that it's just not worth it. In this case a status | ||
237 | other than OK is passed back to the pipeline frontend. | ||
238 | </p> | ||
239 | <p> | ||
240 | The easiest thing would be to abort pipeline processing and just | ||
241 | give up. But this would remove the ability to trace the progress | ||
242 | of the compiler (which better include failed compilations, too). | ||
243 | So there is a special rule that odd priorities are still run, | ||
244 | but even priorities are not. That's why e.g. <tt>-j trace</tt> | ||
245 | registers itself with priority -99. | ||
246 | </p> | ||
247 | |||
248 | <h2>The Optimizer</h2> | ||
249 | <p> | ||
250 | Maybe it hasn't become clear from the above description, | ||
251 | but a module can attach any Lua or C function to the compiler | ||
252 | pipeline. In fact all of the loadable modules are Lua modules. | ||
253 | Only the backend itself is written in C. | ||
254 | </p> | ||
255 | <p> | ||
256 | So, yes — the LuaJIT optimizer is written in pure Lua! | ||
257 | </p> | ||
258 | <p> | ||
259 | And no, don't worry, it's quite fast. One reason for this is | ||
260 | that a very simple <em>abstract interpretation</em> algorithm | ||
261 | is used. It mostly ignores control flow and/or basic block | ||
262 | boundaries. | ||
263 | </p> | ||
264 | <p> | ||
265 | Thus the results of the analysis are really only <em>hints</em>. | ||
266 | The backend <em>must</em> check the preconditions (the contracts) | ||
267 | for these hints (e.g. the object type). Still, the generated | ||
268 | hints are pretty accurate and quite useful to speed up the | ||
269 | compiled code (see below). | ||
270 | </p> | ||
271 | <p> | ||
272 | Explaining how abstract interpretation works is not within the | ||
273 | scope for this short essay. You may want to have a look at the | ||
274 | optimizer source code and/or read some articles or books on | ||
275 | this topic. The canonical reference is | ||
276 | <a href="http://www2.imm.dtu.dk/~riis/PPA/ppa.html"><span class="ext">»</span> Principles of Program Analysis</a>. | ||
277 | Ok, so this one is a bit more on the theoretical side (a gross | ||
278 | understatement). Try a search engine with the keywords "abstract | ||
279 | interpretation", too. | ||
280 | </p> | ||
281 | <p> | ||
282 | Suffice to say the optimizer generates hints and passes these | ||
283 | on to the backend. The backend then decides to encode different | ||
284 | forms for the same bytecode instruction, to combine several | ||
285 | instructions or to inline code for C functions. If the hints | ||
286 | from the optimizer are good, the resulting code will perform | ||
287 | better because shorter code paths are used for the typical cases. | ||
288 | </p> | ||
289 | |||
290 | <h2>The JIT Advantage</h2> | ||
291 | <p> | ||
292 | One important feature of the optimizer is that it takes 'live' | ||
293 | function arguments into account. Since the JIT compiler is | ||
294 | called just before the function is run, the arguments for this | ||
295 | first invocation are already present. This can be used to great | ||
296 | advantage in a <em>dynamically typed language</em>, such as Lua. | ||
297 | </p> | ||
298 | <p> | ||
299 | Here's a trivial example: | ||
300 | </p> | ||
301 | <pre> | ||
302 | function foo(t, k) | ||
303 | return t[k] | ||
304 | end | ||
305 | </pre> | ||
306 | <p> | ||
307 | Without knowing the most likely arguments for the function | ||
308 | there's not much to optimize. | ||
309 | </p> | ||
310 | <p> | ||
311 | Ok, so 't' is most likely a table. But it could be userdata, too. | ||
312 | In fact it could be any type since the introduction of generic | ||
313 | metatables for types. | ||
314 | </p> | ||
315 | <p> | ||
316 | And more importantly 'k' can be a number, a string | ||
317 | or any other type. Oh and let's not forget about metamethods ... | ||
318 | </p> | ||
319 | <p> | ||
320 | If you know a bit about Lua internals, it should be clear by now | ||
321 | that the code for this function could potentially branch to half | ||
322 | of the Lua core. And it's of course impossible to inline all | ||
323 | these cases. | ||
324 | </p> | ||
325 | <p> | ||
326 | On the other hand if it's <em>known</em> (or there's a good hint) | ||
327 | that 't' is a table and that 'k' is a positive integer, then there | ||
328 | is a high likeliness that the key 'k' is in the array part | ||
329 | of the table. This lookup can be done with just a few machine code | ||
330 | instructions. | ||
331 | </p> | ||
332 | <p> | ||
333 | Of course the preconditions for this fast path have to be checked | ||
334 | (unless there are definitive hints). But if the hints are right, | ||
335 | the code runs a lot faster (about a factor of 3 in this case | ||
336 | for the pure table lookup). | ||
337 | </p> | ||
338 | |||
339 | <h2>Optimizing the Optimizer</h2> | ||
340 | <p> | ||
341 | A question that surely popped up in your mind while reading | ||
342 | the above section: does the optimizer optimize itself? I.e. | ||
343 | is the optimizer module compiled? | ||
344 | </p> | ||
345 | <p> | ||
346 | The current answer is no. Mainly because the compiler pipeline | ||
347 | is single-threaded only. It's locked during compilation and | ||
348 | any parallel attempt to JIT compile a function results in | ||
349 | a 'DELAYED' status code. In fact all modules that attach to | ||
350 | the compiler pipeline disable compilation for the entire | ||
351 | module (because LuaJIT would do that anyway). The main chunk | ||
352 | of modules loaded with <tt>require()</tt> is never compiled, | ||
353 | so there is no chicken-and-egg problem here. | ||
354 | </p> | ||
355 | <p> | ||
356 | Of course you could do an AOT compilation in the main chunk of | ||
357 | the optimizer module. But then only with the plain backend. | ||
358 | Recompiling it later on with the optimizer attached doesn't work, | ||
359 | because a function cannot be compiled twice (I plan to lift | ||
360 | this restriction). | ||
361 | </p> | ||
362 | <p> | ||
363 | The other question is whether it pays off to compile the optimizer | ||
364 | at all? Honestly, I haven't tried, because the current optimizer | ||
365 | is really simple. It runs very quickly, even under the bytecode | ||
366 | interpreter. | ||
367 | </p> | ||
368 | |||
369 | <h2>That's All Folks</h2> | ||
370 | <p> | ||
371 | Ok, that's all for now. I'll extend this text later on with | ||
372 | new topics that come up in questions. Keep on asking these | ||
373 | on the mailing list if you are interested. | ||
374 | </p> | ||
375 | <p> | ||
376 | Thank you for your attention! | ||
377 | </p> | ||
378 | <br class="flush"> | ||
379 | </div> | ||
380 | <div id="foot"> | ||
381 | <hr class="hide"> | ||
382 | Copyright © 2005-2011 Mike Pall | ||
383 | <span class="noprint"> | ||
384 | · | ||
385 | <a href="contact.html">Contact</a> | ||
386 | </span> | ||
387 | </div> | ||
388 | </body> | ||
389 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_performance.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_performance.html new file mode 100644 index 0000000..7f2307c --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_performance.html | |||
@@ -0,0 +1,394 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>LuaJIT Performance</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | <style type="text/css"> | ||
12 | table.bench { | ||
13 | line-height: 1.2; | ||
14 | } | ||
15 | tr.benchhead td { | ||
16 | font-weight: bold; | ||
17 | } | ||
18 | td img, li img { | ||
19 | vertical-align: middle; | ||
20 | } | ||
21 | td.barhead, td.bar { | ||
22 | font-size: 8pt; | ||
23 | font-family: Courier New, Courier, monospace; | ||
24 | width: 360px; | ||
25 | padding: 0; | ||
26 | } | ||
27 | td.bar { | ||
28 | background: url('img/backbar.png'); | ||
29 | } | ||
30 | td.speedup { | ||
31 | text-align: center; | ||
32 | } | ||
33 | </style> | ||
34 | </head> | ||
35 | <body> | ||
36 | <div id="site"> | ||
37 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
38 | </div> | ||
39 | <div id="head"> | ||
40 | <h1>LuaJIT Performance</h1> | ||
41 | </div> | ||
42 | <div id="nav"> | ||
43 | <ul><li> | ||
44 | <a href="index.html">Index</a> | ||
45 | </li><li> | ||
46 | <a href="luajit.html">LuaJIT</a> | ||
47 | <ul><li> | ||
48 | <a href="luajit_features.html">Features</a> | ||
49 | </li><li> | ||
50 | <a href="luajit_install.html">Installation</a> | ||
51 | </li><li> | ||
52 | <a href="luajit_run.html">Running</a> | ||
53 | </li><li> | ||
54 | <a href="luajit_api.html">API Extensions</a> | ||
55 | </li><li> | ||
56 | <a href="luajit_intro.html">Introduction</a> | ||
57 | </li><li> | ||
58 | <a class="current" href="luajit_performance.html">Performance</a> | ||
59 | </li><li> | ||
60 | <a href="luajit_debug.html">Debugging</a> | ||
61 | </li><li> | ||
62 | <a href="luajit_changes.html">Changes</a> | ||
63 | </li></ul> | ||
64 | </li><li> | ||
65 | <a href="coco.html">Coco</a> | ||
66 | <ul><li> | ||
67 | <a href="coco_portability.html">Portability</a> | ||
68 | </li><li> | ||
69 | <a href="coco_api.html">API Extensions</a> | ||
70 | </li><li> | ||
71 | <a href="coco_changes.html">Changes</a> | ||
72 | </li></ul> | ||
73 | </li><li> | ||
74 | <a href="dynasm.html">DynASM</a> | ||
75 | <ul><li> | ||
76 | <a href="dynasm_features.html">Features</a> | ||
77 | </li><li> | ||
78 | <a href="dynasm_examples.html">Examples</a> | ||
79 | </li></ul> | ||
80 | </li><li> | ||
81 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
82 | </li></ul> | ||
83 | </div> | ||
84 | <div id="main"> | ||
85 | <p> | ||
86 | Here are some performance measurements, based on a few benchmarks. | ||
87 | </p> | ||
88 | <p style="background: #ffd0d0; text-align: center;"> | ||
89 | LuaJIT 2.0 is available with much improved performance!<br> | ||
90 | Please check the new | ||
91 | <a href="http://luajit.org/performance.html"><span class="ext">»</span> interactive performance comparison</a>. | ||
92 | </p> | ||
93 | |||
94 | <h2 id="interpretation">Interpreting the Results</h2> | ||
95 | <p> | ||
96 | As is always the case with benchmarks, care must be taken to | ||
97 | interpret the results: | ||
98 | </p> | ||
99 | <p> | ||
100 | First, the standard Lua interpreter is already <em>very</em> fast. | ||
101 | It's commonly the fastest of it's class (interpreters) in the | ||
102 | <a href="http://shootout.alioth.debian.org/"><span class="ext">»</span> Great Computer Language Shootout</a>. | ||
103 | Only true machine code compilers get a better overall score. | ||
104 | </p> | ||
105 | <p> | ||
106 | Any performance improvements due to LuaJIT can only be incremental. | ||
107 | You can't expect a speedup of 50x if the fastest compiled language | ||
108 | is only 5x faster than interpreted Lua in a particular benchmark. | ||
109 | LuaJIT can't do miracles. | ||
110 | </p> | ||
111 | <p> | ||
112 | Also please note that most of the benchmarks below are <em>not</em> | ||
113 | trivial micro-benchmarks, which are often cited with marvelous numbers. | ||
114 | Micro-benchmarks do not realistically model the performance gains you | ||
115 | can expect in your own programs. | ||
116 | </p> | ||
117 | <p> | ||
118 | It's easy to make up a few one-liners like:<br> | ||
119 | <tt> local function f(...) end; for i=1,1e7 do f() end</tt><br> | ||
120 | This is more than 30x faster with LuaJIT. But you won't find | ||
121 | this in a real-world program. | ||
122 | </p> | ||
123 | |||
124 | <h2 id="methods">Measurement Methods</h2> | ||
125 | <p> | ||
126 | All measurements have been taken on a Pentium III 1.139 GHz | ||
127 | running Linux 2.6. Both Lua and LuaJIT have been compiled with | ||
128 | GCC 3.3.6 with <tt>-O3 -fomit-frame-pointer</tt>. | ||
129 | You'll definitely get different results on different machines or | ||
130 | with different C compiler options. <sup>*</sup> | ||
131 | </p> | ||
132 | <p> | ||
133 | The base for the comparison are the user CPU times as reported by | ||
134 | <tt>/usr/bin/time</tt>. The runtime of each benchmark is parametrized | ||
135 | and has been adjusted to minimize the variation between several runs. | ||
136 | The ratio between the times for LuaJIT and Lua gives the speedup. | ||
137 | Only this number is shown because it's less dependent on a specific system. | ||
138 | </p> | ||
139 | <p> | ||
140 | E.g. a speedup of 6.74 means the same benchmark runs almost 7 times | ||
141 | faster with <tt>luajit -O</tt> than with standard Lua (or with | ||
142 | <tt>-j off</tt>). Your mileage may vary. | ||
143 | </p> | ||
144 | <p style="font-size: 80%;"> | ||
145 | <sup>*</sup> Yes, LuaJIT relies on quite a bit of the Lua core infrastructure | ||
146 | like table and string handling. All of this is written in C and | ||
147 | should be compiled with full optimization turned on, or performance | ||
148 | will suffer. | ||
149 | </p> | ||
150 | |||
151 | <h2 id="lua_luajit" class="pagebreak">Comparing Lua to LuaJIT</h2> | ||
152 | <p> | ||
153 | Here is a comparison using the current benchmark collection of the | ||
154 | <a href="http://shootout.alioth.debian.org/"><span class="ext">»</span> Great Computer Language Shootout</a> (as of 3/2006): | ||
155 | </p> | ||
156 | |||
157 | <div class="tablewrap"> | ||
158 | <table class="bench"> | ||
159 | <tr class="benchhead"> | ||
160 | <td>Benchmark</td> | ||
161 | <td class="speedup">Speedup</td> | ||
162 | <td class="barhead"> | ||
163 | <img src="img/spacer.png" width="360" height="12" alt="-----1x----2x----3x----4x----5x----6x----7x----8x"> | ||
164 | </td> | ||
165 | </tr> | ||
166 | <tr class="odd"> | ||
167 | <td>mandelbrot</td> | ||
168 | <td class="speedup">6.74</td> | ||
169 | <td class="bar"><img src="img/bluebar.png" width="303" height="12" alt="========================================"></td> | ||
170 | </tr> | ||
171 | <tr class="even"> | ||
172 | <td>recursive</td> | ||
173 | <td class="speedup">6.64</td> | ||
174 | <td class="bar"><img src="img/bluebar.png" width="299" height="12" alt="========================================"></td> | ||
175 | </tr> | ||
176 | <tr class="odd"> | ||
177 | <td>fannkuch</td> | ||
178 | <td class="speedup">5.37</td> | ||
179 | <td class="bar"><img src="img/bluebar.png" width="242" height="12" alt="================================"></td> | ||
180 | </tr> | ||
181 | <tr class="even"> | ||
182 | <td>chameneos</td> | ||
183 | <td class="speedup">5.08</td> | ||
184 | <td class="bar"><img src="img/bluebar.png" width="229" height="12" alt="=============================="></td> | ||
185 | </tr> | ||
186 | <tr class="odd"> | ||
187 | <td>nsievebits</td> | ||
188 | <td class="speedup">5.05</td> | ||
189 | <td class="bar"><img src="img/bluebar.png" width="227" height="12" alt="=============================="></td> | ||
190 | </tr> | ||
191 | <tr class="even"> | ||
192 | <td>pidigits</td> | ||
193 | <td class="speedup">4.94</td> | ||
194 | <td class="bar"><img src="img/bluebar.png" width="222" height="12" alt="=============================="></td> | ||
195 | </tr> | ||
196 | <tr class="odd"> | ||
197 | <td>nbody</td> | ||
198 | <td class="speedup">4.63</td> | ||
199 | <td class="bar"><img src="img/bluebar.png" width="208" height="12" alt="============================"></td> | ||
200 | </tr> | ||
201 | <tr class="even"> | ||
202 | <td>spectralnorm</td> | ||
203 | <td class="speedup">4.59</td> | ||
204 | <td class="bar"><img src="img/bluebar.png" width="207" height="12" alt="============================"></td> | ||
205 | </tr> | ||
206 | <tr class="odd"> | ||
207 | <td>cheapconcr</td> | ||
208 | <td class="speedup">4.46</td> | ||
209 | <td class="bar"><img src="img/bluebar.png" width="201" height="12" alt="==========================="></td> | ||
210 | </tr> | ||
211 | <tr class="even"> | ||
212 | <td>partialsums</td> | ||
213 | <td class="speedup">3.73</td> | ||
214 | <td class="bar"><img src="img/bluebar.png" width="168" height="12" alt="======================"></td> | ||
215 | </tr> | ||
216 | <tr class="odd"> | ||
217 | <td>fasta</td> | ||
218 | <td class="speedup">2.68</td> | ||
219 | <td class="bar"><img src="img/bluebar.png" width="121" height="12" alt="================"></td> | ||
220 | </tr> | ||
221 | <tr class="even"> | ||
222 | <td>cheapconcw</td> | ||
223 | <td class="speedup">2.52</td> | ||
224 | <td class="bar"><img src="img/bluebar.png" width="113" height="12" alt="==============="></td> | ||
225 | </tr> | ||
226 | <tr class="odd"> | ||
227 | <td>nsieve</td> | ||
228 | <td class="speedup">1.95</td> | ||
229 | <td class="bar"><img src="img/bluebar.png" width="88" height="12" alt="============"></td> | ||
230 | </tr> | ||
231 | <tr class="even"> | ||
232 | <td>revcomp</td> | ||
233 | <td class="speedup">1.92</td> | ||
234 | <td class="bar"><img src="img/bluebar.png" width="86" height="12" alt="============"></td> | ||
235 | </tr> | ||
236 | <tr class="odd"> | ||
237 | <td>knucleotide</td> | ||
238 | <td class="speedup">1.59</td> | ||
239 | <td class="bar"><img src="img/bluebar.png" width="72" height="12" alt="=========="></td> | ||
240 | </tr> | ||
241 | <tr class="even"> | ||
242 | <td>binarytrees</td> | ||
243 | <td class="speedup">1.52</td> | ||
244 | <td class="bar"><img src="img/bluebar.png" width="68" height="12" alt="========="></td> | ||
245 | </tr> | ||
246 | <tr class="odd"> | ||
247 | <td>sumfile</td> | ||
248 | <td class="speedup">1.27</td> | ||
249 | <td class="bar"><img src="img/bluebar.png" width="57" height="12" alt="========"></td> | ||
250 | </tr> | ||
251 | <tr class="even"> | ||
252 | <td>regexdna</td> | ||
253 | <td class="speedup">1.01</td> | ||
254 | <td class="bar"><img src="img/bluebar.png" width="45" height="12" alt="======"></td> | ||
255 | </tr> | ||
256 | </table> | ||
257 | </div> | ||
258 | <p> | ||
259 | Note that many of these benchmarks have changed over time (both spec | ||
260 | and code). Benchmark results shown in previous versions of LuaJIT | ||
261 | are not directly comparable. The next section compares different | ||
262 | versions with the current set of benchmarks. | ||
263 | </p> | ||
264 | |||
265 | <h2 id="luajit_versions" class="pagebreak">Comparing LuaJIT Versions</h2> | ||
266 | <p> | ||
267 | This shows the improvements between the following versions: | ||
268 | </p> | ||
269 | <ul> | ||
270 | <li>LuaJIT 1.0.x <img src="img/bluebar.png" width="30" height="12" alt="(===)"></li> | ||
271 | <li>LuaJIT 1.1.x <img src="img/bluebar.png" width="30" height="12" alt="(===##)"><img src="img/magentabar.png" width="20" height="12" alt=""></li> | ||
272 | </ul> | ||
273 | |||
274 | <div class="tablewrap"> | ||
275 | <table class="bench"> | ||
276 | <tr class="benchhead"> | ||
277 | <td>Benchmark</td> | ||
278 | <td class="speedup">Speedup</td> | ||
279 | <td class="barhead"> | ||
280 | <img src="img/spacer.png" width="360" height="12" alt="-----1x----2x----3x----4x----5x----6x----7x----8x"> | ||
281 | </td> | ||
282 | </tr> | ||
283 | <tr class="odd"> | ||
284 | <td>fannkuch</td> | ||
285 | <td class="speedup">3.96 → 5.37</td> | ||
286 | <td class="bar"><img src="img/bluebar.png" width="178" height="12" alt="========================"><img src="img/magentabar.png" width="64" height="12" alt="########"></td> | ||
287 | </tr> | ||
288 | <tr class="even"> | ||
289 | <td>chameneos</td> | ||
290 | <td class="speedup">2.25 → 5.08</td> | ||
291 | <td class="bar"><img src="img/bluebar.png" width="101" height="12" alt="=============="><img src="img/magentabar.png" width="128" height="12" alt="################"></td> | ||
292 | </tr> | ||
293 | <tr class="odd"> | ||
294 | <td>nsievebits</td> | ||
295 | <td class="speedup">2.90 → 5.05</td> | ||
296 | <td class="bar"><img src="img/bluebar.png" width="131" height="12" alt="================="><img src="img/magentabar.png" width="96" height="12" alt="#############"></td> | ||
297 | </tr> | ||
298 | <tr class="even"> | ||
299 | <td>pidigits</td> | ||
300 | <td class="speedup">3.58 → 4.94</td> | ||
301 | <td class="bar"><img src="img/bluebar.png" width="161" height="12" alt="====================="><img src="img/magentabar.png" width="61" height="12" alt="#########"></td> | ||
302 | </tr> | ||
303 | <tr class="odd"> | ||
304 | <td>nbody</td> | ||
305 | <td class="speedup">4.16 → 4.63</td> | ||
306 | <td class="bar"><img src="img/bluebar.png" width="187" height="12" alt="========================="><img src="img/magentabar.png" width="21" height="12" alt="###"></td> | ||
307 | </tr> | ||
308 | <tr class="even"> | ||
309 | <td>cheapconcr</td> | ||
310 | <td class="speedup">1.46 → 4.46</td> | ||
311 | <td class="bar"><img src="img/bluebar.png" width="66" height="12" alt="========="><img src="img/magentabar.png" width="135" height="12" alt="##################"></td> | ||
312 | </tr> | ||
313 | <tr class="odd"> | ||
314 | <td>partialsums</td> | ||
315 | <td class="speedup">1.71 → 3.73</td> | ||
316 | <td class="bar"><img src="img/bluebar.png" width="77" height="12" alt="=========="><img src="img/magentabar.png" width="91" height="12" alt="############"></td> | ||
317 | </tr> | ||
318 | <tr class="even"> | ||
319 | <td>fasta</td> | ||
320 | <td class="speedup">2.37 → 2.68</td> | ||
321 | <td class="bar"><img src="img/bluebar.png" width="107" height="12" alt="=============="><img src="img/magentabar.png" width="14" height="12" alt="##"></td> | ||
322 | </tr> | ||
323 | <tr class="odd"> | ||
324 | <td>cheapconcw</td> | ||
325 | <td class="speedup">1.27 → 2.52</td> | ||
326 | <td class="bar"><img src="img/bluebar.png" width="57" height="12" alt="========"><img src="img/magentabar.png" width="56" height="12" alt="#######"></td> | ||
327 | </tr> | ||
328 | <tr class="even"> | ||
329 | <td>revcomp</td> | ||
330 | <td class="speedup">1.45 → 1.92</td> | ||
331 | <td class="bar"><img src="img/bluebar.png" width="65" height="12" alt="========="><img src="img/magentabar.png" width="21" height="12" alt="###"></td> | ||
332 | </tr> | ||
333 | <tr class="odd"> | ||
334 | <td>knucleotide</td> | ||
335 | <td class="speedup">1.32 → 1.59</td> | ||
336 | <td class="bar"><img src="img/bluebar.png" width="59" height="12" alt="========"><img src="img/magentabar.png" width="13" height="12" alt="##"></td> | ||
337 | </tr> | ||
338 | </table> | ||
339 | </div> | ||
340 | <p> | ||
341 | All other benchmarks show only minor performance differences. | ||
342 | </p> | ||
343 | |||
344 | <h2 id="summary">Summary</h2> | ||
345 | <p> | ||
346 | These results should give you an idea about what speedup | ||
347 | you can expect depending on the nature of your Lua code: | ||
348 | </p> | ||
349 | <ul> | ||
350 | <li> | ||
351 | LuaJIT is really good at (floating-point) math and loops | ||
352 | (mandelbrot, pidigits, spectralnorm, partialsums). | ||
353 | </li> | ||
354 | <li> | ||
355 | Function calls (recursive), vararg calls, table lookups (nbody), | ||
356 | table iteration and coroutine switching (chameneos, cheapconc) | ||
357 | are a lot faster than with plain Lua. | ||
358 | </li> | ||
359 | <li> | ||
360 | It's still pretty good for indexed table access (fannkuch, nsieve) | ||
361 | and string processing (fasta, revcomp, knucleotide). | ||
362 | But there is room for improvement in a future version. | ||
363 | </li> | ||
364 | <li> | ||
365 | If your application spends most of the time in C code | ||
366 | you won't see much of a difference (regexdna, sumfile). | ||
367 | Ok, so write more code in pure Lua. :-) | ||
368 | </li> | ||
369 | <li> | ||
370 | The real speedup may be shadowed by other dominant factors in a benchmark: | ||
371 | <ul> | ||
372 | <li>Common parts of the Lua core: e.g. memory allocation | ||
373 | and GC (binarytrees).</li> | ||
374 | <li>Language characteristics: e.g. lack of bit operations (nsievebits).</li> | ||
375 | <li>System characteristics: e.g. CPU cache size and memory speed (nsieve).</li> | ||
376 | </ul> | ||
377 | </li> | ||
378 | </ul> | ||
379 | <p> | ||
380 | The best idea is of course to benchmark your <em>own</em> applications. | ||
381 | Please report any interesting results you may find. Thank you! | ||
382 | </p> | ||
383 | <br class="flush"> | ||
384 | </div> | ||
385 | <div id="foot"> | ||
386 | <hr class="hide"> | ||
387 | Copyright © 2005-2011 Mike Pall | ||
388 | <span class="noprint"> | ||
389 | · | ||
390 | <a href="contact.html">Contact</a> | ||
391 | </span> | ||
392 | </div> | ||
393 | </body> | ||
394 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/luajit_run.html b/libraries/LuaJIT-1.1.7/jitdoc/luajit_run.html new file mode 100644 index 0000000..bc9105b --- /dev/null +++ b/libraries/LuaJIT-1.1.7/jitdoc/luajit_run.html | |||
@@ -0,0 +1,159 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> | ||
2 | <html> | ||
3 | <head> | ||
4 | <title>Running LuaJIT</title> | ||
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
6 | <meta name="Author" content="Mike Pall"> | ||
7 | <meta name="Copyright" content="Copyright (C) 2005-2011, Mike Pall"> | ||
8 | <meta name="Language" content="en"> | ||
9 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
10 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
11 | </head> | ||
12 | <body> | ||
13 | <div id="site"> | ||
14 | <a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a> | ||
15 | </div> | ||
16 | <div id="head"> | ||
17 | <h1>Running LuaJIT</h1> | ||
18 | </div> | ||
19 | <div id="nav"> | ||
20 | <ul><li> | ||
21 | <a href="index.html">Index</a> | ||
22 | </li><li> | ||
23 | <a href="luajit.html">LuaJIT</a> | ||
24 | <ul><li> | ||
25 | <a href="luajit_features.html">Features</a> | ||
26 | </li><li> | ||
27 | <a href="luajit_install.html">Installation</a> | ||
28 | </li><li> | ||
29 | <a class="current" href="luajit_run.html">Running</a> | ||
30 | </li><li> | ||
31 | <a href="luajit_api.html">API Extensions</a> | ||
32 | </li><li> | ||
33 | <a href="luajit_intro.html">Introduction</a> | ||
34 | </li><li> | ||
35 | <a href="luajit_performance.html">Performance</a> | ||
36 | </li><li> | ||
37 | <a href="luajit_debug.html">Debugging</a> | ||
38 | </li><li> | ||
39 | <a href="luajit_changes.html">Changes</a> | ||
40 | </li></ul> | ||
41 | </li><li> | ||
42 | <a href="coco.html">Coco</a> | ||
43 | <ul><li> | ||
44 | <a href="coco_portability.html">Portability</a> | ||
45 | </li><li> | ||
46 | <a href="coco_api.html">API Extensions</a> | ||
47 | </li><li> | ||
48 | <a href="coco_changes.html">Changes</a> | ||
49 | </li></ul> | ||
50 | </li><li> | ||
51 | <a href="dynasm.html">DynASM</a> | ||
52 | <ul><li> | ||
53 | <a href="dynasm_features.html">Features</a> | ||
54 | </li><li> | ||
55 | <a href="dynasm_examples.html">Examples</a> | ||
56 | </li></ul> | ||
57 | </li><li> | ||
58 | <a href="http://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
59 | </li></ul> | ||
60 | </div> | ||
61 | <div id="main"> | ||
62 | <p> | ||
63 | LuaJIT has only a single stand-alone executable, called <tt>luajit</tt>. | ||
64 | It can be used to run simple Lua statements or whole Lua applications | ||
65 | from the command line. It has an interactive mode, too. | ||
66 | </p> | ||
67 | <p> | ||
68 | <em>Note: The optimizer is not activated by default because it resides | ||
69 | in an external module | ||
70 | (see <a href="luajit_install.html">Installing LuaJIT</a>). | ||
71 | It's recommended to always use the optimizer, i.e.:</em> <tt>luajit -O</tt> | ||
72 | </p> | ||
73 | |||
74 | <h2 id="options">Command Line Options</h2> | ||
75 | <p> | ||
76 | The <tt>luajit</tt> stand-alone executable is just a slightly modified | ||
77 | version of the regular <tt>lua</tt> stand-alone executable. | ||
78 | It supports the same basic options, too. Please have a look at the | ||
79 | <a href="../doc/lua.html">Manual Page</a> | ||
80 | for the regular <tt>lua</tt> stand-alone executable. | ||
81 | </p> | ||
82 | <p> | ||
83 | Two additional options control LuaJIT behaviour: | ||
84 | </p> | ||
85 | |||
86 | <h3 id="opt_j"><tt>-j cmd[=value]</tt></h3> | ||
87 | <p> | ||
88 | This option performs a LuaJIT control command. LuaJIT has a small | ||
89 | but extensible set of control commands. It's easy to add your own. | ||
90 | </p> | ||
91 | <p> | ||
92 | The command is first searched for in the <tt>jit.*</tt> library. | ||
93 | If no matching function is found, a module named <tt>jit.<cmd></tt> | ||
94 | is loaded. The module table must provide a <tt>start()</tt> function. | ||
95 | </p> | ||
96 | <p> | ||
97 | For the <tt>-j cmd</tt> form the function is called without an argument. | ||
98 | Otherwise the <tt>value</tt> is passed as the first argument (a string). | ||
99 | </p> | ||
100 | <p> | ||
101 | Here are the built-in LuaJIT control commands: | ||
102 | </p> | ||
103 | <ul> | ||
104 | <li id="j_on"><tt>-j on</tt> — Turns the JIT engine on (default).</li> | ||
105 | <li id="j_off"><tt>-j off</tt> — Turns the JIT engine off.</li> | ||
106 | <li id="j_debug"><tt>-j debug[=level]</tt> — Set debug level. See | ||
107 | <a href="luajit_api.html#jit_debug">jit.debug()</a>.</li> | ||
108 | </ul> | ||
109 | <p> | ||
110 | The following control commands are loaded from add-on modules: | ||
111 | </p> | ||
112 | <ul> | ||
113 | <li id="j_trace"><tt>-j trace[=file]</tt> — Trace the progress of the JIT compiler.</li> | ||
114 | <li id="j_dumphints"><tt>-j dumphints[=file]</tt> — Dump bytecode + hints before compilation.</li> | ||
115 | <li id="j_dump"><tt>-j dump[=file]</tt> — Dump machine code after compilation.</li> | ||
116 | </ul> | ||
117 | |||
118 | <!-- | ||
119 | <h3 id="opt_O"><tt>-O[level|ext]</tt></h3> | ||
120 | --> | ||
121 | <h3 id="opt_O"><tt>-O[level]</tt></h3> | ||
122 | <p> | ||
123 | This option loads and runs the optimizer module <tt>jit.opt</tt>. | ||
124 | The optimizer generates hints for the compiler backend to improve | ||
125 | the performance of the compiled code. The optimizer slows down | ||
126 | compilation slightly, but the end result should make up for it | ||
127 | in almost every case. | ||
128 | </p> | ||
129 | <p> | ||
130 | The <tt>-O</tt> form sets the default optimizer level, which is | ||
131 | currently <tt>2</tt> (this may change in future versions | ||
132 | of LuaJIT). | ||
133 | </p> | ||
134 | <p> | ||
135 | The <tt>-Olevel</tt> form explicitly sets the optimizer level: | ||
136 | </p> | ||
137 | <ul> | ||
138 | <li><tt>-O0</tt> — disable the optimizer but leave it attached.</li> | ||
139 | <li><tt>-O1</tt> — perform standard optimizations (like hints for table lookups).</li> | ||
140 | <li><tt>-O2</tt> — like <tt>-O1</tt> but also loads <tt>jit.opt_inline</tt> to enable result hints and inlining for standard library functions.</li> | ||
141 | </ul> | ||
142 | <!-- | ||
143 | <p> | ||
144 | The <tt>-Oext</tt> form loads optimizer extension modules | ||
145 | from <tt>jit.opt_<ext></tt>. | ||
146 | </p> | ||
147 | --> | ||
148 | <br class="flush"> | ||
149 | </div> | ||
150 | <div id="foot"> | ||
151 | <hr class="hide"> | ||
152 | Copyright © 2005-2011 Mike Pall | ||
153 | <span class="noprint"> | ||
154 | · | ||
155 | <a href="contact.html">Contact</a> | ||
156 | </span> | ||
157 | </div> | ||
158 | </body> | ||
159 | </html> | ||
diff --git a/libraries/LuaJIT-1.1.7/src/Makefile b/libraries/LuaJIT-1.1.7/src/Makefile new file mode 100644 index 0000000..b678fe1 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/Makefile | |||
@@ -0,0 +1,252 @@ | |||
1 | # makefile for building Lua | ||
2 | # see ../INSTALL for installation instructions | ||
3 | # see ../Makefile and luaconf.h for further customization | ||
4 | |||
5 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= | ||
6 | |||
7 | # Your platform. See PLATS for possible values. | ||
8 | PLAT= none | ||
9 | |||
10 | CC= gcc -m32 | ||
11 | CFLAGS= -O2 -fomit-frame-pointer -Wall $(MYCFLAGS) $(COCOCFLAGS) $(JITCFLAGS) | ||
12 | AR= ar rcu | ||
13 | RANLIB= ranlib | ||
14 | RM= rm -f | ||
15 | LIBS= -lm $(MYLIBS) | ||
16 | |||
17 | MYCFLAGS= | ||
18 | MYLDFLAGS= | ||
19 | MYLIBS= | ||
20 | |||
21 | # ++ Coco ========= | ||
22 | # Default: autodetect gccasm/setjmp/ucontext/fibers context switch method. | ||
23 | COCOCFLAGS= | ||
24 | # Force use of setjmp (instead of gccasm). | ||
25 | #COCOCFLAGS= -DCOCO_USE_SETJMP | ||
26 | # Force use of ucontext (instead of gccasm or setjmp). | ||
27 | #COCOCFLAGS= -DCOCO_USE_UCONTEXT | ||
28 | # Uncomment this if you want to compile LuaJIT without Coco. | ||
29 | # This effectively disables yielding from JIT compiled functions. | ||
30 | #COCOCFLAGS= -DCOCO_DISABLE | ||
31 | # -- Coco ========= | ||
32 | |||
33 | # == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= | ||
34 | |||
35 | PLATS= linux bsd macosx solaris mingw cygwin posix generic linux_rl bsd_rl macosx_rl | ||
36 | |||
37 | # ++ Coco ========= | ||
38 | COCO_O= lcoco.o | ||
39 | # -- Coco ========= | ||
40 | |||
41 | # ++ LuaJIT ========= | ||
42 | DASMDIR= ../dynasm | ||
43 | DASMFLAGS= | ||
44 | DASMDISTFLAGS= -LN | ||
45 | |||
46 | # This assumes you already have a copy of (plain) Lua 5.1 installed | ||
47 | # You can use luajit, too (built with the pre-processed headers from the dist) | ||
48 | DASM= lua $(DASMDIR)/dynasm.lua | ||
49 | |||
50 | JITCFLAGS= -I$(DASMDIR) | ||
51 | JIT_O= ljit_core.o ljit_mem.o ljit_dasm.o ljit_backend.o | ||
52 | JITLIB_O= ljitlib.o | ||
53 | |||
54 | ALL_DH = ljit_x86.h | ||
55 | # -- LuaJIT ========= | ||
56 | |||
57 | LUA_A= liblua.a | ||
58 | CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ | ||
59 | lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ | ||
60 | lundump.o lvm.o lzio.o $(COCO_O) $(JIT_O) | ||
61 | LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ | ||
62 | lstrlib.o loadlib.o $(JITLIB_O) linit.o | ||
63 | |||
64 | # Standalone has been renamed to avoid conflicts during installation | ||
65 | LUA_T= luajit | ||
66 | LUA_O= lua.o | ||
67 | |||
68 | LUAC_T= luac | ||
69 | LUAC_O= luac.o print.o | ||
70 | |||
71 | ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O) | ||
72 | # Do not build luac by default | ||
73 | #ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) | ||
74 | ALL_T= $(LUA_A) $(LUA_T) | ||
75 | ALL_A= $(LUA_A) | ||
76 | |||
77 | default: $(PLAT) | ||
78 | |||
79 | all: $(ALL_T) | ||
80 | |||
81 | o: $(ALL_O) | ||
82 | |||
83 | a: $(ALL_A) | ||
84 | |||
85 | $(LUA_A): $(CORE_O) $(LIB_O) | ||
86 | $(AR) $@ $? | ||
87 | $(RANLIB) $@ | ||
88 | |||
89 | $(LUA_T): $(LUA_O) $(LUA_A) | ||
90 | $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) | ||
91 | |||
92 | $(LUAC_T): $(LUAC_O) $(LUA_A) | ||
93 | $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) | ||
94 | |||
95 | # ++ LuaJIT ========= | ||
96 | ljit_x86.h: ljit_x86.dasc ljit_x86_inline.dash ljit_x86.dash | ||
97 | $(DASM) $(DASMFLAGS) -o $@ ljit_x86.dasc | ||
98 | |||
99 | distclean: clean | ||
100 | $(DASM) $(DASMDISTFLAGS) -o ljit_x86.h ljit_x86.dasc | ||
101 | |||
102 | cleaner: clean | ||
103 | $(RM) $(ALL_DH) | ||
104 | # -- LuaJIT ========= | ||
105 | |||
106 | clean: | ||
107 | $(RM) $(ALL_T) $(ALL_O) | ||
108 | |||
109 | depend: | ||
110 | @$(CC) $(CFLAGS) -MM l*.c print.c | ||
111 | |||
112 | echo: | ||
113 | @echo "PLAT = $(PLAT)" | ||
114 | @echo "CC = $(CC)" | ||
115 | @echo "CFLAGS = $(CFLAGS)" | ||
116 | @echo "AR = $(AR)" | ||
117 | @echo "RANLIB = $(RANLIB)" | ||
118 | @echo "RM = $(RM)" | ||
119 | @echo "MYCFLAGS = $(MYCFLAGS)" | ||
120 | @echo "MYLDFLAGS = $(MYLDFLAGS)" | ||
121 | @echo "MYLIBS = $(MYLIBS)" | ||
122 | |||
123 | # convenience targets for popular platforms | ||
124 | |||
125 | none: | ||
126 | @echo "Please choose a platform:" | ||
127 | @echo " $(PLATS)" | ||
128 | |||
129 | bsd: | ||
130 | $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" | ||
131 | |||
132 | bsd_rl: | ||
133 | $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN -DLUA_USE_READLINE" MYLIBS="-Wl,-E -lreadline" | ||
134 | |||
135 | generic: | ||
136 | $(MAKE) all MYCFLAGS= | ||
137 | |||
138 | linux: | ||
139 | $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl" | ||
140 | |||
141 | linux_rl: | ||
142 | $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX -DLUA_USE_READLINE" MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" | ||
143 | |||
144 | # Mac OS X on Intel Macs only! | ||
145 | macosx: | ||
146 | $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX | ||
147 | # use this on Mac OS X 10.3 | ||
148 | # $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX | ||
149 | |||
150 | macosx_rl: | ||
151 | $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX -DLUA_USE_READLINE" MYLIBS="-lreadline" | ||
152 | |||
153 | mingw: | ||
154 | $(MAKE) "LUA_A=lua51.dll" "LUA_T=luajit.exe" \ | ||
155 | "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ | ||
156 | "MYCFLAGS=-DLUA_BUILD_AS_DLL -maccumulate-outgoing-args" \ | ||
157 | "MYLIBS=" "MYLDFLAGS=-s" luajit.exe | ||
158 | |||
159 | cygwin: | ||
160 | $(MAKE) "CC=gcc -mno-cygwin" mingw | ||
161 | |||
162 | posix: | ||
163 | $(MAKE) all MYCFLAGS=-DLUA_USE_POSIX | ||
164 | |||
165 | # Solaris x86 only! | ||
166 | solaris: | ||
167 | $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" | ||
168 | |||
169 | # list targets that do not create files (but not all makes understand .PHONY) | ||
170 | .PHONY: all $(PLATS) default o a clean depend echo none cleaner distclean | ||
171 | |||
172 | # DO NOT DELETE | ||
173 | |||
174 | lapi.o: lapi.c lua.h luaconf.h lapi.h lobject.h llimits.h ldebug.h \ | ||
175 | lstate.h ltm.h lzio.h lmem.h lcoco.h ldo.h lfunc.h lgc.h lstring.h \ | ||
176 | ltable.h lundump.h lvm.h | ||
177 | lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h | ||
178 | lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h lcoco.h | ||
179 | lcoco.o: lcoco.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ | ||
180 | lzio.h lmem.h lcoco.h ldo.h lvm.h lgc.h | ||
181 | lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ | ||
182 | lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h lcoco.h \ | ||
183 | ldo.h lgc.h ltable.h | ||
184 | ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h | ||
185 | ldebug.o: ldebug.c lua.h luaconf.h lapi.h lobject.h llimits.h lcode.h \ | ||
186 | llex.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ | ||
187 | lcoco.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h ljit.h | ||
188 | ldo.o: ldo.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ | ||
189 | lzio.h lmem.h lcoco.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \ | ||
190 | lstring.h ltable.h lundump.h lvm.h ljit.h | ||
191 | ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ | ||
192 | lzio.h lmem.h lcoco.h lundump.h | ||
193 | lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \ | ||
194 | lstate.h ltm.h lzio.h lcoco.h ljit.h | ||
195 | lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ | ||
196 | lzio.h lmem.h lcoco.h ldo.h lfunc.h lgc.h lstring.h ltable.h | ||
197 | linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h | ||
198 | liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h | ||
199 | ljit_backend.o: ljit_backend.c lua.h luaconf.h lobject.h llimits.h \ | ||
200 | lstate.h ltm.h lzio.h lmem.h lcoco.h ldo.h lfunc.h lgc.h lstring.h \ | ||
201 | ltable.h lvm.h lopcodes.h ldebug.h ljit.h ljit_hints.h ljit_dasm.h \ | ||
202 | ../dynasm/dasm_proto.h ljit_x86.h | ||
203 | ljit_core.o: ljit_core.c lua.h luaconf.h lobject.h llimits.h lstate.h \ | ||
204 | ltm.h lzio.h lmem.h lcoco.h ldo.h lstring.h lgc.h ltable.h ldebug.h \ | ||
205 | lopcodes.h ljit.h ljit_hints.h luajit.h | ||
206 | ljit_dasm.o: ljit_dasm.c lua.h luaconf.h ljit.h lobject.h llimits.h \ | ||
207 | ljit_dasm.h ../dynasm/dasm_proto.h lmem.h ../dynasm/dasm_x86.h | ||
208 | ljit_mem.o: ljit_mem.c lua.h luaconf.h lmem.h llimits.h ldo.h lobject.h \ | ||
209 | lstate.h ltm.h lzio.h lcoco.h ljit.h ljit_dasm.h ../dynasm/dasm_proto.h | ||
210 | ljitlib.o: ljitlib.c lua.h luaconf.h lauxlib.h luajit.h lualib.h \ | ||
211 | lobject.h llimits.h lstate.h ltm.h lzio.h lmem.h lcoco.h lstring.h \ | ||
212 | lgc.h ltable.h lfunc.h lopcodes.h ljit.h ljit_hints.h | ||
213 | llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \ | ||
214 | lzio.h lmem.h lcoco.h llex.h lparser.h lstring.h lgc.h ltable.h | ||
215 | lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h | ||
216 | lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ | ||
217 | ltm.h lzio.h lmem.h lcoco.h ldo.h | ||
218 | loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h luajit.h | ||
219 | lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \ | ||
220 | ltm.h lzio.h lmem.h lcoco.h lstring.h lgc.h lvm.h | ||
221 | lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h | ||
222 | loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h | ||
223 | lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ | ||
224 | lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h lcoco.h \ | ||
225 | ldo.h lfunc.h lstring.h lgc.h ltable.h | ||
226 | lstate.o: lstate.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ | ||
227 | ltm.h lzio.h lmem.h lcoco.h ldo.h lfunc.h lgc.h llex.h lstring.h \ | ||
228 | ltable.h ljit.h | ||
229 | lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ | ||
230 | ltm.h lzio.h lcoco.h lstring.h lgc.h | ||
231 | lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h | ||
232 | ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ | ||
233 | ltm.h lzio.h lmem.h lcoco.h ldo.h lgc.h ltable.h | ||
234 | ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h | ||
235 | ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ | ||
236 | lmem.h lcoco.h lstring.h lgc.h ltable.h | ||
237 | lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h luajit.h | ||
238 | luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \ | ||
239 | lstate.h ltm.h lzio.h lmem.h lcoco.h lfunc.h lopcodes.h lstring.h lgc.h \ | ||
240 | lundump.h | ||
241 | lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ | ||
242 | llimits.h ltm.h lzio.h lmem.h lcoco.h ldo.h lfunc.h lstring.h lgc.h \ | ||
243 | lundump.h | ||
244 | lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ | ||
245 | lzio.h lmem.h lcoco.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h \ | ||
246 | lvm.h | ||
247 | lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ | ||
248 | lzio.h lcoco.h | ||
249 | print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ | ||
250 | ltm.h lzio.h lmem.h lcoco.h lopcodes.h lundump.h | ||
251 | |||
252 | # (end of Makefile) | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lapi.c b/libraries/LuaJIT-1.1.7/src/lapi.c new file mode 100644 index 0000000..e8347a2 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lapi.c | |||
@@ -0,0 +1,1082 @@ | |||
1 | /* | ||
2 | ** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $ | ||
3 | ** Lua API | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <assert.h> | ||
9 | #include <math.h> | ||
10 | #include <stdarg.h> | ||
11 | #include <string.h> | ||
12 | |||
13 | #define lapi_c | ||
14 | #define LUA_CORE | ||
15 | |||
16 | #include "lua.h" | ||
17 | |||
18 | #include "lapi.h" | ||
19 | #include "ldebug.h" | ||
20 | #include "ldo.h" | ||
21 | #include "lfunc.h" | ||
22 | #include "lgc.h" | ||
23 | #include "lmem.h" | ||
24 | #include "lobject.h" | ||
25 | #include "lstate.h" | ||
26 | #include "lstring.h" | ||
27 | #include "ltable.h" | ||
28 | #include "ltm.h" | ||
29 | #include "lundump.h" | ||
30 | #include "lvm.h" | ||
31 | |||
32 | |||
33 | |||
34 | const char lua_ident[] = | ||
35 | "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n" | ||
36 | "$Authors: " LUA_AUTHORS " $\n" | ||
37 | "$URL: www.lua.org $\n"; | ||
38 | |||
39 | |||
40 | |||
41 | #define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) | ||
42 | |||
43 | #define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) | ||
44 | |||
45 | #define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} | ||
46 | |||
47 | |||
48 | |||
49 | static TValue *index2adr (lua_State *L, int idx) { | ||
50 | if (idx > 0) { | ||
51 | TValue *o = L->base + (idx - 1); | ||
52 | api_check(L, idx <= L->ci->top - L->base); | ||
53 | if (o >= L->top) return cast(TValue *, luaO_nilobject); | ||
54 | else return o; | ||
55 | } | ||
56 | else if (idx > LUA_REGISTRYINDEX) { | ||
57 | api_check(L, idx != 0 && -idx <= L->top - L->base); | ||
58 | return L->top + idx; | ||
59 | } | ||
60 | else switch (idx) { /* pseudo-indices */ | ||
61 | case LUA_REGISTRYINDEX: return registry(L); | ||
62 | case LUA_ENVIRONINDEX: { | ||
63 | Closure *func = curr_func(L); | ||
64 | sethvalue(L, &L->env, func->c.env); | ||
65 | return &L->env; | ||
66 | } | ||
67 | case LUA_GLOBALSINDEX: return gt(L); | ||
68 | default: { | ||
69 | Closure *func = curr_func(L); | ||
70 | idx = LUA_GLOBALSINDEX - idx; | ||
71 | return (idx <= func->c.nupvalues) | ||
72 | ? &func->c.upvalue[idx-1] | ||
73 | : cast(TValue *, luaO_nilobject); | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | |||
78 | |||
79 | static Table *getcurrenv (lua_State *L) { | ||
80 | if (L->ci == L->base_ci) /* no enclosing function? */ | ||
81 | return hvalue(gt(L)); /* use global table as environment */ | ||
82 | else { | ||
83 | Closure *func = curr_func(L); | ||
84 | return func->c.env; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | |||
89 | void luaA_pushobject (lua_State *L, const TValue *o) { | ||
90 | setobj2s(L, L->top, o); | ||
91 | api_incr_top(L); | ||
92 | } | ||
93 | |||
94 | |||
95 | LUA_API int lua_checkstack (lua_State *L, int size) { | ||
96 | int res = 1; | ||
97 | lua_lock(L); | ||
98 | if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) | ||
99 | res = 0; /* stack overflow */ | ||
100 | else if (size > 0) { | ||
101 | luaD_checkstack(L, size); | ||
102 | if (L->ci->top < L->top + size) | ||
103 | L->ci->top = L->top + size; | ||
104 | } | ||
105 | lua_unlock(L); | ||
106 | return res; | ||
107 | } | ||
108 | |||
109 | |||
110 | LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { | ||
111 | StkId f, t; | ||
112 | if (from == to) return; | ||
113 | lua_lock(to); | ||
114 | api_checknelems(from, n); | ||
115 | api_check(from, G(from) == G(to)); | ||
116 | api_check(from, to->ci->top - to->top >= n); | ||
117 | f = from->top; | ||
118 | t = to->top = to->top + n; | ||
119 | while (--n >= 0) setobj2s(to, --t, --f); | ||
120 | from->top = f; | ||
121 | lua_unlock(to); | ||
122 | } | ||
123 | |||
124 | |||
125 | LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { | ||
126 | lua_CFunction old; | ||
127 | lua_lock(L); | ||
128 | old = G(L)->panic; | ||
129 | G(L)->panic = panicf; | ||
130 | lua_unlock(L); | ||
131 | return old; | ||
132 | } | ||
133 | |||
134 | |||
135 | LUA_API lua_State *lua_newthread (lua_State *L) { | ||
136 | lua_State *L1; | ||
137 | lua_lock(L); | ||
138 | luaC_checkGC(L); | ||
139 | L1 = luaE_newthread(L); | ||
140 | setthvalue(L, L->top, L1); | ||
141 | api_incr_top(L); | ||
142 | lua_unlock(L); | ||
143 | luai_userstatethread(L, L1); | ||
144 | return L1; | ||
145 | } | ||
146 | |||
147 | |||
148 | |||
149 | /* | ||
150 | ** basic stack manipulation | ||
151 | */ | ||
152 | |||
153 | |||
154 | LUA_API int lua_gettop (lua_State *L) { | ||
155 | return cast_int(L->top - L->base); | ||
156 | } | ||
157 | |||
158 | |||
159 | LUA_API void lua_settop (lua_State *L, int idx) { | ||
160 | lua_lock(L); | ||
161 | if (idx >= 0) { | ||
162 | api_check(L, idx <= L->stack_last - L->base); | ||
163 | while (L->top < L->base + idx) | ||
164 | setnilvalue(L->top++); | ||
165 | L->top = L->base + idx; | ||
166 | } | ||
167 | else { | ||
168 | api_check(L, -(idx+1) <= (L->top - L->base)); | ||
169 | L->top += idx+1; /* `subtract' index (index is negative) */ | ||
170 | } | ||
171 | lua_unlock(L); | ||
172 | } | ||
173 | |||
174 | |||
175 | LUA_API void lua_remove (lua_State *L, int idx) { | ||
176 | StkId p; | ||
177 | lua_lock(L); | ||
178 | p = index2adr(L, idx); | ||
179 | api_checkvalidindex(L, p); | ||
180 | while (++p < L->top) setobjs2s(L, p-1, p); | ||
181 | L->top--; | ||
182 | lua_unlock(L); | ||
183 | } | ||
184 | |||
185 | |||
186 | LUA_API void lua_insert (lua_State *L, int idx) { | ||
187 | StkId p; | ||
188 | StkId q; | ||
189 | lua_lock(L); | ||
190 | p = index2adr(L, idx); | ||
191 | api_checkvalidindex(L, p); | ||
192 | for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); | ||
193 | setobjs2s(L, p, L->top); | ||
194 | lua_unlock(L); | ||
195 | } | ||
196 | |||
197 | |||
198 | LUA_API void lua_replace (lua_State *L, int idx) { | ||
199 | StkId o; | ||
200 | lua_lock(L); | ||
201 | /* explicit test for incompatible code */ | ||
202 | if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) | ||
203 | luaG_runerror(L, "no calling environment"); | ||
204 | api_checknelems(L, 1); | ||
205 | o = index2adr(L, idx); | ||
206 | api_checkvalidindex(L, o); | ||
207 | if (idx == LUA_ENVIRONINDEX) { | ||
208 | Closure *func = curr_func(L); | ||
209 | api_check(L, ttistable(L->top - 1)); | ||
210 | func->c.env = hvalue(L->top - 1); | ||
211 | luaC_barrier(L, func, L->top - 1); | ||
212 | } | ||
213 | else { | ||
214 | setobj(L, o, L->top - 1); | ||
215 | if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ | ||
216 | luaC_barrier(L, curr_func(L), L->top - 1); | ||
217 | } | ||
218 | L->top--; | ||
219 | lua_unlock(L); | ||
220 | } | ||
221 | |||
222 | |||
223 | LUA_API void lua_pushvalue (lua_State *L, int idx) { | ||
224 | lua_lock(L); | ||
225 | setobj2s(L, L->top, index2adr(L, idx)); | ||
226 | api_incr_top(L); | ||
227 | lua_unlock(L); | ||
228 | } | ||
229 | |||
230 | |||
231 | |||
232 | /* | ||
233 | ** access functions (stack -> C) | ||
234 | */ | ||
235 | |||
236 | |||
237 | LUA_API int lua_type (lua_State *L, int idx) { | ||
238 | StkId o = index2adr(L, idx); | ||
239 | return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); | ||
240 | } | ||
241 | |||
242 | |||
243 | LUA_API const char *lua_typename (lua_State *L, int t) { | ||
244 | UNUSED(L); | ||
245 | return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; | ||
246 | } | ||
247 | |||
248 | |||
249 | LUA_API int lua_iscfunction (lua_State *L, int idx) { | ||
250 | StkId o = index2adr(L, idx); | ||
251 | return iscfunction(o); | ||
252 | } | ||
253 | |||
254 | |||
255 | LUA_API int lua_isnumber (lua_State *L, int idx) { | ||
256 | TValue n; | ||
257 | const TValue *o = index2adr(L, idx); | ||
258 | return tonumber(o, &n); | ||
259 | } | ||
260 | |||
261 | |||
262 | LUA_API int lua_isstring (lua_State *L, int idx) { | ||
263 | int t = lua_type(L, idx); | ||
264 | return (t == LUA_TSTRING || t == LUA_TNUMBER); | ||
265 | } | ||
266 | |||
267 | |||
268 | LUA_API int lua_isuserdata (lua_State *L, int idx) { | ||
269 | const TValue *o = index2adr(L, idx); | ||
270 | return (ttisuserdata(o) || ttislightuserdata(o)); | ||
271 | } | ||
272 | |||
273 | |||
274 | LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { | ||
275 | StkId o1 = index2adr(L, index1); | ||
276 | StkId o2 = index2adr(L, index2); | ||
277 | return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 | ||
278 | : luaO_rawequalObj(o1, o2); | ||
279 | } | ||
280 | |||
281 | |||
282 | LUA_API int lua_equal (lua_State *L, int index1, int index2) { | ||
283 | StkId o1, o2; | ||
284 | int i; | ||
285 | lua_lock(L); /* may call tag method */ | ||
286 | o1 = index2adr(L, index1); | ||
287 | o2 = index2adr(L, index2); | ||
288 | i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); | ||
289 | lua_unlock(L); | ||
290 | return i; | ||
291 | } | ||
292 | |||
293 | |||
294 | LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { | ||
295 | StkId o1, o2; | ||
296 | int i; | ||
297 | lua_lock(L); /* may call tag method */ | ||
298 | o1 = index2adr(L, index1); | ||
299 | o2 = index2adr(L, index2); | ||
300 | i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 | ||
301 | : luaV_lessthan(L, o1, o2); | ||
302 | lua_unlock(L); | ||
303 | return i; | ||
304 | } | ||
305 | |||
306 | |||
307 | |||
308 | LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { | ||
309 | TValue n; | ||
310 | const TValue *o = index2adr(L, idx); | ||
311 | if (tonumber(o, &n)) | ||
312 | return nvalue(o); | ||
313 | else | ||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | |||
318 | LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { | ||
319 | TValue n; | ||
320 | const TValue *o = index2adr(L, idx); | ||
321 | if (tonumber(o, &n)) { | ||
322 | lua_Integer res; | ||
323 | lua_Number num = nvalue(o); | ||
324 | lua_number2integer(res, num); | ||
325 | return res; | ||
326 | } | ||
327 | else | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | |||
332 | LUA_API int lua_toboolean (lua_State *L, int idx) { | ||
333 | const TValue *o = index2adr(L, idx); | ||
334 | return !l_isfalse(o); | ||
335 | } | ||
336 | |||
337 | |||
338 | LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { | ||
339 | StkId o = index2adr(L, idx); | ||
340 | if (!ttisstring(o)) { | ||
341 | lua_lock(L); /* `luaV_tostring' may create a new string */ | ||
342 | if (!luaV_tostring(L, o)) { /* conversion failed? */ | ||
343 | if (len != NULL) *len = 0; | ||
344 | lua_unlock(L); | ||
345 | return NULL; | ||
346 | } | ||
347 | luaC_checkGC(L); | ||
348 | o = index2adr(L, idx); /* previous call may reallocate the stack */ | ||
349 | lua_unlock(L); | ||
350 | } | ||
351 | if (len != NULL) *len = tsvalue(o)->len; | ||
352 | return svalue(o); | ||
353 | } | ||
354 | |||
355 | |||
356 | LUA_API size_t lua_objlen (lua_State *L, int idx) { | ||
357 | StkId o = index2adr(L, idx); | ||
358 | switch (ttype(o)) { | ||
359 | case LUA_TSTRING: return tsvalue(o)->len; | ||
360 | case LUA_TUSERDATA: return uvalue(o)->len; | ||
361 | case LUA_TTABLE: return luaH_getn(hvalue(o)); | ||
362 | case LUA_TNUMBER: { | ||
363 | size_t l; | ||
364 | lua_lock(L); /* `luaV_tostring' may create a new string */ | ||
365 | l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); | ||
366 | lua_unlock(L); | ||
367 | return l; | ||
368 | } | ||
369 | default: return 0; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | |||
374 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { | ||
375 | StkId o = index2adr(L, idx); | ||
376 | return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; | ||
377 | } | ||
378 | |||
379 | |||
380 | LUA_API void *lua_touserdata (lua_State *L, int idx) { | ||
381 | StkId o = index2adr(L, idx); | ||
382 | switch (ttype(o)) { | ||
383 | case LUA_TUSERDATA: return (rawuvalue(o) + 1); | ||
384 | case LUA_TLIGHTUSERDATA: return pvalue(o); | ||
385 | default: return NULL; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | |||
390 | LUA_API lua_State *lua_tothread (lua_State *L, int idx) { | ||
391 | StkId o = index2adr(L, idx); | ||
392 | return (!ttisthread(o)) ? NULL : thvalue(o); | ||
393 | } | ||
394 | |||
395 | |||
396 | LUA_API const void *lua_topointer (lua_State *L, int idx) { | ||
397 | StkId o = index2adr(L, idx); | ||
398 | switch (ttype(o)) { | ||
399 | case LUA_TTABLE: return hvalue(o); | ||
400 | case LUA_TFUNCTION: return clvalue(o); | ||
401 | case LUA_TTHREAD: return thvalue(o); | ||
402 | case LUA_TUSERDATA: | ||
403 | case LUA_TLIGHTUSERDATA: | ||
404 | return lua_touserdata(L, idx); | ||
405 | default: return NULL; | ||
406 | } | ||
407 | } | ||
408 | |||
409 | |||
410 | |||
411 | /* | ||
412 | ** push functions (C -> stack) | ||
413 | */ | ||
414 | |||
415 | |||
416 | LUA_API void lua_pushnil (lua_State *L) { | ||
417 | lua_lock(L); | ||
418 | setnilvalue(L->top); | ||
419 | api_incr_top(L); | ||
420 | lua_unlock(L); | ||
421 | } | ||
422 | |||
423 | |||
424 | LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { | ||
425 | lua_lock(L); | ||
426 | setnvalue(L->top, n); | ||
427 | api_incr_top(L); | ||
428 | lua_unlock(L); | ||
429 | } | ||
430 | |||
431 | |||
432 | LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { | ||
433 | lua_lock(L); | ||
434 | setnvalue(L->top, cast_num(n)); | ||
435 | api_incr_top(L); | ||
436 | lua_unlock(L); | ||
437 | } | ||
438 | |||
439 | |||
440 | LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { | ||
441 | lua_lock(L); | ||
442 | luaC_checkGC(L); | ||
443 | setsvalue2s(L, L->top, luaS_newlstr(L, s, len)); | ||
444 | api_incr_top(L); | ||
445 | lua_unlock(L); | ||
446 | } | ||
447 | |||
448 | |||
449 | LUA_API void lua_pushstring (lua_State *L, const char *s) { | ||
450 | if (s == NULL) | ||
451 | lua_pushnil(L); | ||
452 | else | ||
453 | lua_pushlstring(L, s, strlen(s)); | ||
454 | } | ||
455 | |||
456 | |||
457 | LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, | ||
458 | va_list argp) { | ||
459 | const char *ret; | ||
460 | lua_lock(L); | ||
461 | luaC_checkGC(L); | ||
462 | ret = luaO_pushvfstring(L, fmt, argp); | ||
463 | lua_unlock(L); | ||
464 | return ret; | ||
465 | } | ||
466 | |||
467 | |||
468 | LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { | ||
469 | const char *ret; | ||
470 | va_list argp; | ||
471 | lua_lock(L); | ||
472 | luaC_checkGC(L); | ||
473 | va_start(argp, fmt); | ||
474 | ret = luaO_pushvfstring(L, fmt, argp); | ||
475 | va_end(argp); | ||
476 | lua_unlock(L); | ||
477 | return ret; | ||
478 | } | ||
479 | |||
480 | |||
481 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | ||
482 | Closure *cl; | ||
483 | lua_lock(L); | ||
484 | luaC_checkGC(L); | ||
485 | api_checknelems(L, n); | ||
486 | cl = luaF_newCclosure(L, n, getcurrenv(L)); | ||
487 | cl->c.f = fn; | ||
488 | L->top -= n; | ||
489 | while (n--) | ||
490 | setobj2n(L, &cl->c.upvalue[n], L->top+n); | ||
491 | setclvalue(L, L->top, cl); | ||
492 | lua_assert(iswhite(obj2gco(cl))); | ||
493 | api_incr_top(L); | ||
494 | lua_unlock(L); | ||
495 | } | ||
496 | |||
497 | |||
498 | LUA_API void lua_pushboolean (lua_State *L, int b) { | ||
499 | lua_lock(L); | ||
500 | setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ | ||
501 | api_incr_top(L); | ||
502 | lua_unlock(L); | ||
503 | } | ||
504 | |||
505 | |||
506 | LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { | ||
507 | lua_lock(L); | ||
508 | setpvalue(L->top, p); | ||
509 | api_incr_top(L); | ||
510 | lua_unlock(L); | ||
511 | } | ||
512 | |||
513 | |||
514 | LUA_API int lua_pushthread (lua_State *L) { | ||
515 | lua_lock(L); | ||
516 | setthvalue(L, L->top, L); | ||
517 | api_incr_top(L); | ||
518 | lua_unlock(L); | ||
519 | return (G(L)->mainthread == L); | ||
520 | } | ||
521 | |||
522 | |||
523 | |||
524 | /* | ||
525 | ** get functions (Lua -> stack) | ||
526 | */ | ||
527 | |||
528 | |||
529 | LUA_API void lua_gettable (lua_State *L, int idx) { | ||
530 | StkId t; | ||
531 | lua_lock(L); | ||
532 | t = index2adr(L, idx); | ||
533 | api_checkvalidindex(L, t); | ||
534 | luaV_gettable(L, t, L->top - 1, L->top - 1); | ||
535 | lua_unlock(L); | ||
536 | } | ||
537 | |||
538 | |||
539 | LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { | ||
540 | StkId t; | ||
541 | TValue key; | ||
542 | lua_lock(L); | ||
543 | t = index2adr(L, idx); | ||
544 | api_checkvalidindex(L, t); | ||
545 | setsvalue(L, &key, luaS_new(L, k)); | ||
546 | luaV_gettable(L, t, &key, L->top); | ||
547 | api_incr_top(L); | ||
548 | lua_unlock(L); | ||
549 | } | ||
550 | |||
551 | |||
552 | LUA_API void lua_rawget (lua_State *L, int idx) { | ||
553 | StkId t; | ||
554 | lua_lock(L); | ||
555 | t = index2adr(L, idx); | ||
556 | api_check(L, ttistable(t)); | ||
557 | setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); | ||
558 | lua_unlock(L); | ||
559 | } | ||
560 | |||
561 | |||
562 | LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { | ||
563 | StkId o; | ||
564 | lua_lock(L); | ||
565 | o = index2adr(L, idx); | ||
566 | api_check(L, ttistable(o)); | ||
567 | setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); | ||
568 | api_incr_top(L); | ||
569 | lua_unlock(L); | ||
570 | } | ||
571 | |||
572 | |||
573 | LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { | ||
574 | lua_lock(L); | ||
575 | luaC_checkGC(L); | ||
576 | sethvalue(L, L->top, luaH_new(L, narray, nrec)); | ||
577 | api_incr_top(L); | ||
578 | lua_unlock(L); | ||
579 | } | ||
580 | |||
581 | |||
582 | LUA_API int lua_getmetatable (lua_State *L, int objindex) { | ||
583 | const TValue *obj; | ||
584 | Table *mt = NULL; | ||
585 | int res; | ||
586 | lua_lock(L); | ||
587 | obj = index2adr(L, objindex); | ||
588 | switch (ttype(obj)) { | ||
589 | case LUA_TTABLE: | ||
590 | mt = hvalue(obj)->metatable; | ||
591 | break; | ||
592 | case LUA_TUSERDATA: | ||
593 | mt = uvalue(obj)->metatable; | ||
594 | break; | ||
595 | default: | ||
596 | mt = G(L)->mt[ttype(obj)]; | ||
597 | break; | ||
598 | } | ||
599 | if (mt == NULL) | ||
600 | res = 0; | ||
601 | else { | ||
602 | sethvalue(L, L->top, mt); | ||
603 | api_incr_top(L); | ||
604 | res = 1; | ||
605 | } | ||
606 | lua_unlock(L); | ||
607 | return res; | ||
608 | } | ||
609 | |||
610 | |||
611 | LUA_API void lua_getfenv (lua_State *L, int idx) { | ||
612 | StkId o; | ||
613 | lua_lock(L); | ||
614 | o = index2adr(L, idx); | ||
615 | api_checkvalidindex(L, o); | ||
616 | switch (ttype(o)) { | ||
617 | case LUA_TFUNCTION: | ||
618 | sethvalue(L, L->top, clvalue(o)->c.env); | ||
619 | break; | ||
620 | case LUA_TUSERDATA: | ||
621 | sethvalue(L, L->top, uvalue(o)->env); | ||
622 | break; | ||
623 | case LUA_TTHREAD: | ||
624 | setobj2s(L, L->top, gt(thvalue(o))); | ||
625 | break; | ||
626 | default: | ||
627 | setnilvalue(L->top); | ||
628 | break; | ||
629 | } | ||
630 | api_incr_top(L); | ||
631 | lua_unlock(L); | ||
632 | } | ||
633 | |||
634 | |||
635 | /* | ||
636 | ** set functions (stack -> Lua) | ||
637 | */ | ||
638 | |||
639 | |||
640 | LUA_API void lua_settable (lua_State *L, int idx) { | ||
641 | StkId t; | ||
642 | lua_lock(L); | ||
643 | api_checknelems(L, 2); | ||
644 | t = index2adr(L, idx); | ||
645 | api_checkvalidindex(L, t); | ||
646 | luaV_settable(L, t, L->top - 2, L->top - 1); | ||
647 | L->top -= 2; /* pop index and value */ | ||
648 | lua_unlock(L); | ||
649 | } | ||
650 | |||
651 | |||
652 | LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { | ||
653 | StkId t; | ||
654 | TValue key; | ||
655 | lua_lock(L); | ||
656 | api_checknelems(L, 1); | ||
657 | t = index2adr(L, idx); | ||
658 | api_checkvalidindex(L, t); | ||
659 | setsvalue(L, &key, luaS_new(L, k)); | ||
660 | luaV_settable(L, t, &key, L->top - 1); | ||
661 | L->top--; /* pop value */ | ||
662 | lua_unlock(L); | ||
663 | } | ||
664 | |||
665 | |||
666 | LUA_API void lua_rawset (lua_State *L, int idx) { | ||
667 | StkId t; | ||
668 | lua_lock(L); | ||
669 | api_checknelems(L, 2); | ||
670 | t = index2adr(L, idx); | ||
671 | api_check(L, ttistable(t)); | ||
672 | setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); | ||
673 | luaC_barriert(L, hvalue(t), L->top-1); | ||
674 | L->top -= 2; | ||
675 | lua_unlock(L); | ||
676 | } | ||
677 | |||
678 | |||
679 | LUA_API void lua_rawseti (lua_State *L, int idx, int n) { | ||
680 | StkId o; | ||
681 | lua_lock(L); | ||
682 | api_checknelems(L, 1); | ||
683 | o = index2adr(L, idx); | ||
684 | api_check(L, ttistable(o)); | ||
685 | setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); | ||
686 | luaC_barriert(L, hvalue(o), L->top-1); | ||
687 | L->top--; | ||
688 | lua_unlock(L); | ||
689 | } | ||
690 | |||
691 | |||
692 | LUA_API int lua_setmetatable (lua_State *L, int objindex) { | ||
693 | TValue *obj; | ||
694 | Table *mt; | ||
695 | lua_lock(L); | ||
696 | api_checknelems(L, 1); | ||
697 | obj = index2adr(L, objindex); | ||
698 | api_checkvalidindex(L, obj); | ||
699 | if (ttisnil(L->top - 1)) | ||
700 | mt = NULL; | ||
701 | else { | ||
702 | api_check(L, ttistable(L->top - 1)); | ||
703 | mt = hvalue(L->top - 1); | ||
704 | } | ||
705 | switch (ttype(obj)) { | ||
706 | case LUA_TTABLE: { | ||
707 | hvalue(obj)->metatable = mt; | ||
708 | if (mt) | ||
709 | luaC_objbarriert(L, hvalue(obj), mt); | ||
710 | break; | ||
711 | } | ||
712 | case LUA_TUSERDATA: { | ||
713 | uvalue(obj)->metatable = mt; | ||
714 | if (mt) | ||
715 | luaC_objbarrier(L, rawuvalue(obj), mt); | ||
716 | break; | ||
717 | } | ||
718 | default: { | ||
719 | G(L)->mt[ttype(obj)] = mt; | ||
720 | break; | ||
721 | } | ||
722 | } | ||
723 | L->top--; | ||
724 | lua_unlock(L); | ||
725 | return 1; | ||
726 | } | ||
727 | |||
728 | |||
729 | LUA_API int lua_setfenv (lua_State *L, int idx) { | ||
730 | StkId o; | ||
731 | int res = 1; | ||
732 | lua_lock(L); | ||
733 | api_checknelems(L, 1); | ||
734 | o = index2adr(L, idx); | ||
735 | api_checkvalidindex(L, o); | ||
736 | api_check(L, ttistable(L->top - 1)); | ||
737 | switch (ttype(o)) { | ||
738 | case LUA_TFUNCTION: | ||
739 | clvalue(o)->c.env = hvalue(L->top - 1); | ||
740 | break; | ||
741 | case LUA_TUSERDATA: | ||
742 | uvalue(o)->env = hvalue(L->top - 1); | ||
743 | break; | ||
744 | case LUA_TTHREAD: | ||
745 | sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1)); | ||
746 | break; | ||
747 | default: | ||
748 | res = 0; | ||
749 | break; | ||
750 | } | ||
751 | if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); | ||
752 | L->top--; | ||
753 | lua_unlock(L); | ||
754 | return res; | ||
755 | } | ||
756 | |||
757 | |||
758 | /* | ||
759 | ** `load' and `call' functions (run Lua code) | ||
760 | */ | ||
761 | |||
762 | |||
763 | #define adjustresults(L,nres) \ | ||
764 | { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; } | ||
765 | |||
766 | |||
767 | #define checkresults(L,na,nr) \ | ||
768 | api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) | ||
769 | |||
770 | |||
771 | LUA_API void lua_call (lua_State *L, int nargs, int nresults) { | ||
772 | StkId func; | ||
773 | lua_lock(L); | ||
774 | api_checknelems(L, nargs+1); | ||
775 | checkresults(L, nargs, nresults); | ||
776 | func = L->top - (nargs+1); | ||
777 | luaD_call(L, func, nresults); | ||
778 | adjustresults(L, nresults); | ||
779 | lua_unlock(L); | ||
780 | } | ||
781 | |||
782 | |||
783 | |||
784 | /* | ||
785 | ** Execute a protected call. | ||
786 | */ | ||
787 | struct CallS { /* data to `f_call' */ | ||
788 | StkId func; | ||
789 | int nresults; | ||
790 | }; | ||
791 | |||
792 | |||
793 | static void f_call (lua_State *L, void *ud) { | ||
794 | struct CallS *c = cast(struct CallS *, ud); | ||
795 | luaD_call(L, c->func, c->nresults); | ||
796 | } | ||
797 | |||
798 | |||
799 | |||
800 | LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { | ||
801 | struct CallS c; | ||
802 | int status; | ||
803 | ptrdiff_t func; | ||
804 | lua_lock(L); | ||
805 | api_checknelems(L, nargs+1); | ||
806 | checkresults(L, nargs, nresults); | ||
807 | if (errfunc == 0) | ||
808 | func = 0; | ||
809 | else { | ||
810 | StkId o = index2adr(L, errfunc); | ||
811 | api_checkvalidindex(L, o); | ||
812 | func = savestack(L, o); | ||
813 | } | ||
814 | c.func = L->top - (nargs+1); /* function to be called */ | ||
815 | c.nresults = nresults; | ||
816 | status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); | ||
817 | adjustresults(L, nresults); | ||
818 | lua_unlock(L); | ||
819 | return status; | ||
820 | } | ||
821 | |||
822 | |||
823 | /* | ||
824 | ** Execute a protected C call. | ||
825 | */ | ||
826 | struct CCallS { /* data to `f_Ccall' */ | ||
827 | lua_CFunction func; | ||
828 | void *ud; | ||
829 | }; | ||
830 | |||
831 | |||
832 | static void f_Ccall (lua_State *L, void *ud) { | ||
833 | struct CCallS *c = cast(struct CCallS *, ud); | ||
834 | Closure *cl; | ||
835 | cl = luaF_newCclosure(L, 0, getcurrenv(L)); | ||
836 | cl->c.f = c->func; | ||
837 | setclvalue(L, L->top, cl); /* push function */ | ||
838 | api_incr_top(L); | ||
839 | setpvalue(L->top, c->ud); /* push only argument */ | ||
840 | api_incr_top(L); | ||
841 | luaD_call(L, L->top - 2, 0); | ||
842 | } | ||
843 | |||
844 | |||
845 | LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { | ||
846 | struct CCallS c; | ||
847 | int status; | ||
848 | lua_lock(L); | ||
849 | c.func = func; | ||
850 | c.ud = ud; | ||
851 | status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); | ||
852 | lua_unlock(L); | ||
853 | return status; | ||
854 | } | ||
855 | |||
856 | |||
857 | LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, | ||
858 | const char *chunkname) { | ||
859 | ZIO z; | ||
860 | int status; | ||
861 | lua_lock(L); | ||
862 | if (!chunkname) chunkname = "?"; | ||
863 | luaZ_init(L, &z, reader, data); | ||
864 | status = luaD_protectedparser(L, &z, chunkname); | ||
865 | lua_unlock(L); | ||
866 | return status; | ||
867 | } | ||
868 | |||
869 | |||
870 | LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { | ||
871 | int status; | ||
872 | TValue *o; | ||
873 | lua_lock(L); | ||
874 | api_checknelems(L, 1); | ||
875 | o = L->top - 1; | ||
876 | if (isLfunction(o)) | ||
877 | status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); | ||
878 | else | ||
879 | status = 1; | ||
880 | lua_unlock(L); | ||
881 | return status; | ||
882 | } | ||
883 | |||
884 | |||
885 | LUA_API int lua_status (lua_State *L) { | ||
886 | return L->status; | ||
887 | } | ||
888 | |||
889 | |||
890 | /* | ||
891 | ** Garbage-collection function | ||
892 | */ | ||
893 | |||
894 | LUA_API int lua_gc (lua_State *L, int what, int data) { | ||
895 | int res = 0; | ||
896 | global_State *g; | ||
897 | lua_lock(L); | ||
898 | g = G(L); | ||
899 | switch (what) { | ||
900 | case LUA_GCSTOP: { | ||
901 | g->GCthreshold = MAX_LUMEM; | ||
902 | break; | ||
903 | } | ||
904 | case LUA_GCRESTART: { | ||
905 | g->GCthreshold = g->totalbytes; | ||
906 | break; | ||
907 | } | ||
908 | case LUA_GCCOLLECT: { | ||
909 | luaC_fullgc(L); | ||
910 | break; | ||
911 | } | ||
912 | case LUA_GCCOUNT: { | ||
913 | /* GC values are expressed in Kbytes: #bytes/2^10 */ | ||
914 | res = cast_int(g->totalbytes >> 10); | ||
915 | break; | ||
916 | } | ||
917 | case LUA_GCCOUNTB: { | ||
918 | res = cast_int(g->totalbytes & 0x3ff); | ||
919 | break; | ||
920 | } | ||
921 | case LUA_GCSTEP: { | ||
922 | lu_mem a = (cast(lu_mem, data) << 10); | ||
923 | if (a <= g->totalbytes) | ||
924 | g->GCthreshold = g->totalbytes - a; | ||
925 | else | ||
926 | g->GCthreshold = 0; | ||
927 | while (g->GCthreshold <= g->totalbytes) { | ||
928 | luaC_step(L); | ||
929 | if (g->gcstate == GCSpause) { /* end of cycle? */ | ||
930 | res = 1; /* signal it */ | ||
931 | break; | ||
932 | } | ||
933 | } | ||
934 | break; | ||
935 | } | ||
936 | case LUA_GCSETPAUSE: { | ||
937 | res = g->gcpause; | ||
938 | g->gcpause = data; | ||
939 | break; | ||
940 | } | ||
941 | case LUA_GCSETSTEPMUL: { | ||
942 | res = g->gcstepmul; | ||
943 | g->gcstepmul = data; | ||
944 | break; | ||
945 | } | ||
946 | default: res = -1; /* invalid option */ | ||
947 | } | ||
948 | lua_unlock(L); | ||
949 | return res; | ||
950 | } | ||
951 | |||
952 | |||
953 | |||
954 | /* | ||
955 | ** miscellaneous functions | ||
956 | */ | ||
957 | |||
958 | |||
959 | LUA_API int lua_error (lua_State *L) { | ||
960 | lua_lock(L); | ||
961 | api_checknelems(L, 1); | ||
962 | luaG_errormsg(L); | ||
963 | lua_unlock(L); | ||
964 | return 0; /* to avoid warnings */ | ||
965 | } | ||
966 | |||
967 | |||
968 | LUA_API int lua_next (lua_State *L, int idx) { | ||
969 | StkId t; | ||
970 | int more; | ||
971 | lua_lock(L); | ||
972 | t = index2adr(L, idx); | ||
973 | api_check(L, ttistable(t)); | ||
974 | more = luaH_next(L, hvalue(t), L->top - 1); | ||
975 | if (more) { | ||
976 | api_incr_top(L); | ||
977 | } | ||
978 | else /* no more elements */ | ||
979 | L->top -= 1; /* remove key */ | ||
980 | lua_unlock(L); | ||
981 | return more; | ||
982 | } | ||
983 | |||
984 | |||
985 | LUA_API void lua_concat (lua_State *L, int n) { | ||
986 | lua_lock(L); | ||
987 | api_checknelems(L, n); | ||
988 | if (n >= 2) { | ||
989 | luaC_checkGC(L); | ||
990 | luaV_concat(L, n, cast_int(L->top - L->base) - 1); | ||
991 | L->top -= (n-1); | ||
992 | } | ||
993 | else if (n == 0) { /* push empty string */ | ||
994 | setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); | ||
995 | api_incr_top(L); | ||
996 | } | ||
997 | /* else n == 1; nothing to do */ | ||
998 | lua_unlock(L); | ||
999 | } | ||
1000 | |||
1001 | |||
1002 | LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { | ||
1003 | lua_Alloc f; | ||
1004 | lua_lock(L); | ||
1005 | if (ud) *ud = G(L)->ud; | ||
1006 | f = G(L)->frealloc; | ||
1007 | lua_unlock(L); | ||
1008 | return f; | ||
1009 | } | ||
1010 | |||
1011 | |||
1012 | LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { | ||
1013 | lua_lock(L); | ||
1014 | G(L)->ud = ud; | ||
1015 | G(L)->frealloc = f; | ||
1016 | lua_unlock(L); | ||
1017 | } | ||
1018 | |||
1019 | |||
1020 | LUA_API void *lua_newuserdata (lua_State *L, size_t size) { | ||
1021 | Udata *u; | ||
1022 | lua_lock(L); | ||
1023 | luaC_checkGC(L); | ||
1024 | u = luaS_newudata(L, size, getcurrenv(L)); | ||
1025 | setuvalue(L, L->top, u); | ||
1026 | api_incr_top(L); | ||
1027 | lua_unlock(L); | ||
1028 | return u + 1; | ||
1029 | } | ||
1030 | |||
1031 | |||
1032 | |||
1033 | |||
1034 | static const char *aux_upvalue (StkId fi, int n, TValue **val) { | ||
1035 | Closure *f; | ||
1036 | if (!ttisfunction(fi)) return NULL; | ||
1037 | f = clvalue(fi); | ||
1038 | if (f->c.isC) { | ||
1039 | if (!(1 <= n && n <= f->c.nupvalues)) return NULL; | ||
1040 | *val = &f->c.upvalue[n-1]; | ||
1041 | return ""; | ||
1042 | } | ||
1043 | else { | ||
1044 | Proto *p = f->l.p; | ||
1045 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; | ||
1046 | *val = f->l.upvals[n-1]->v; | ||
1047 | return getstr(p->upvalues[n-1]); | ||
1048 | } | ||
1049 | } | ||
1050 | |||
1051 | |||
1052 | LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { | ||
1053 | const char *name; | ||
1054 | TValue *val; | ||
1055 | lua_lock(L); | ||
1056 | name = aux_upvalue(index2adr(L, funcindex), n, &val); | ||
1057 | if (name) { | ||
1058 | setobj2s(L, L->top, val); | ||
1059 | api_incr_top(L); | ||
1060 | } | ||
1061 | lua_unlock(L); | ||
1062 | return name; | ||
1063 | } | ||
1064 | |||
1065 | |||
1066 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { | ||
1067 | const char *name; | ||
1068 | TValue *val; | ||
1069 | StkId fi; | ||
1070 | lua_lock(L); | ||
1071 | fi = index2adr(L, funcindex); | ||
1072 | api_checknelems(L, 1); | ||
1073 | name = aux_upvalue(fi, n, &val); | ||
1074 | if (name) { | ||
1075 | L->top--; | ||
1076 | setobj(L, val, L->top); | ||
1077 | luaC_barrier(L, clvalue(fi), L->top); | ||
1078 | } | ||
1079 | lua_unlock(L); | ||
1080 | return name; | ||
1081 | } | ||
1082 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lapi.h b/libraries/LuaJIT-1.1.7/src/lapi.h new file mode 100644 index 0000000..2c3fab2 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lapi.h | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | ** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Auxiliary functions from Lua API | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lapi_h | ||
8 | #define lapi_h | ||
9 | |||
10 | |||
11 | #include "lobject.h" | ||
12 | |||
13 | |||
14 | LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); | ||
15 | |||
16 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lauxlib.c b/libraries/LuaJIT-1.1.7/src/lauxlib.c new file mode 100644 index 0000000..10f14e2 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lauxlib.c | |||
@@ -0,0 +1,652 @@ | |||
1 | /* | ||
2 | ** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $ | ||
3 | ** Auxiliary functions for building Lua libraries | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <ctype.h> | ||
9 | #include <errno.h> | ||
10 | #include <stdarg.h> | ||
11 | #include <stdio.h> | ||
12 | #include <stdlib.h> | ||
13 | #include <string.h> | ||
14 | |||
15 | |||
16 | /* This file uses only the official API of Lua. | ||
17 | ** Any function declared here could be written as an application function. | ||
18 | */ | ||
19 | |||
20 | #define lauxlib_c | ||
21 | #define LUA_LIB | ||
22 | |||
23 | #include "lua.h" | ||
24 | |||
25 | #include "lauxlib.h" | ||
26 | |||
27 | |||
28 | #define FREELIST_REF 0 /* free list of references */ | ||
29 | |||
30 | |||
31 | /* convert a stack index to positive */ | ||
32 | #define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ | ||
33 | lua_gettop(L) + (i) + 1) | ||
34 | |||
35 | |||
36 | /* | ||
37 | ** {====================================================== | ||
38 | ** Error-report functions | ||
39 | ** ======================================================= | ||
40 | */ | ||
41 | |||
42 | |||
43 | LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { | ||
44 | lua_Debug ar; | ||
45 | if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ | ||
46 | return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); | ||
47 | lua_getinfo(L, "n", &ar); | ||
48 | if (strcmp(ar.namewhat, "method") == 0) { | ||
49 | narg--; /* do not count `self' */ | ||
50 | if (narg == 0) /* error is in the self argument itself? */ | ||
51 | return luaL_error(L, "calling " LUA_QS " on bad self (%s)", | ||
52 | ar.name, extramsg); | ||
53 | } | ||
54 | if (ar.name == NULL) | ||
55 | ar.name = "?"; | ||
56 | return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", | ||
57 | narg, ar.name, extramsg); | ||
58 | } | ||
59 | |||
60 | |||
61 | LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { | ||
62 | const char *msg = lua_pushfstring(L, "%s expected, got %s", | ||
63 | tname, luaL_typename(L, narg)); | ||
64 | return luaL_argerror(L, narg, msg); | ||
65 | } | ||
66 | |||
67 | |||
68 | static void tag_error (lua_State *L, int narg, int tag) { | ||
69 | luaL_typerror(L, narg, lua_typename(L, tag)); | ||
70 | } | ||
71 | |||
72 | |||
73 | LUALIB_API void luaL_where (lua_State *L, int level) { | ||
74 | lua_Debug ar; | ||
75 | if (lua_getstack(L, level, &ar)) { /* check function at level */ | ||
76 | lua_getinfo(L, "Sl", &ar); /* get info about it */ | ||
77 | if (ar.currentline > 0) { /* is there info? */ | ||
78 | lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); | ||
79 | return; | ||
80 | } | ||
81 | } | ||
82 | lua_pushliteral(L, ""); /* else, no information available... */ | ||
83 | } | ||
84 | |||
85 | |||
86 | LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { | ||
87 | va_list argp; | ||
88 | va_start(argp, fmt); | ||
89 | luaL_where(L, 1); | ||
90 | lua_pushvfstring(L, fmt, argp); | ||
91 | va_end(argp); | ||
92 | lua_concat(L, 2); | ||
93 | return lua_error(L); | ||
94 | } | ||
95 | |||
96 | /* }====================================================== */ | ||
97 | |||
98 | |||
99 | LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, | ||
100 | const char *const lst[]) { | ||
101 | const char *name = (def) ? luaL_optstring(L, narg, def) : | ||
102 | luaL_checkstring(L, narg); | ||
103 | int i; | ||
104 | for (i=0; lst[i]; i++) | ||
105 | if (strcmp(lst[i], name) == 0) | ||
106 | return i; | ||
107 | return luaL_argerror(L, narg, | ||
108 | lua_pushfstring(L, "invalid option " LUA_QS, name)); | ||
109 | } | ||
110 | |||
111 | |||
112 | LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { | ||
113 | lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ | ||
114 | if (!lua_isnil(L, -1)) /* name already in use? */ | ||
115 | return 0; /* leave previous value on top, but return 0 */ | ||
116 | lua_pop(L, 1); | ||
117 | lua_newtable(L); /* create metatable */ | ||
118 | lua_pushvalue(L, -1); | ||
119 | lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ | ||
120 | return 1; | ||
121 | } | ||
122 | |||
123 | |||
124 | LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { | ||
125 | void *p = lua_touserdata(L, ud); | ||
126 | if (p != NULL) { /* value is a userdata? */ | ||
127 | if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ | ||
128 | lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ | ||
129 | if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ | ||
130 | lua_pop(L, 2); /* remove both metatables */ | ||
131 | return p; | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | luaL_typerror(L, ud, tname); /* else error */ | ||
136 | return NULL; /* to avoid warnings */ | ||
137 | } | ||
138 | |||
139 | |||
140 | LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { | ||
141 | if (!lua_checkstack(L, space)) | ||
142 | luaL_error(L, "stack overflow (%s)", mes); | ||
143 | } | ||
144 | |||
145 | |||
146 | LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { | ||
147 | if (lua_type(L, narg) != t) | ||
148 | tag_error(L, narg, t); | ||
149 | } | ||
150 | |||
151 | |||
152 | LUALIB_API void luaL_checkany (lua_State *L, int narg) { | ||
153 | if (lua_type(L, narg) == LUA_TNONE) | ||
154 | luaL_argerror(L, narg, "value expected"); | ||
155 | } | ||
156 | |||
157 | |||
158 | LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { | ||
159 | const char *s = lua_tolstring(L, narg, len); | ||
160 | if (!s) tag_error(L, narg, LUA_TSTRING); | ||
161 | return s; | ||
162 | } | ||
163 | |||
164 | |||
165 | LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, | ||
166 | const char *def, size_t *len) { | ||
167 | if (lua_isnoneornil(L, narg)) { | ||
168 | if (len) | ||
169 | *len = (def ? strlen(def) : 0); | ||
170 | return def; | ||
171 | } | ||
172 | else return luaL_checklstring(L, narg, len); | ||
173 | } | ||
174 | |||
175 | |||
176 | LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { | ||
177 | lua_Number d = lua_tonumber(L, narg); | ||
178 | if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ | ||
179 | tag_error(L, narg, LUA_TNUMBER); | ||
180 | return d; | ||
181 | } | ||
182 | |||
183 | |||
184 | LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { | ||
185 | return luaL_opt(L, luaL_checknumber, narg, def); | ||
186 | } | ||
187 | |||
188 | |||
189 | LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { | ||
190 | lua_Integer d = lua_tointeger(L, narg); | ||
191 | if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ | ||
192 | tag_error(L, narg, LUA_TNUMBER); | ||
193 | return d; | ||
194 | } | ||
195 | |||
196 | |||
197 | LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, | ||
198 | lua_Integer def) { | ||
199 | return luaL_opt(L, luaL_checkinteger, narg, def); | ||
200 | } | ||
201 | |||
202 | |||
203 | LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { | ||
204 | if (!lua_getmetatable(L, obj)) /* no metatable? */ | ||
205 | return 0; | ||
206 | lua_pushstring(L, event); | ||
207 | lua_rawget(L, -2); | ||
208 | if (lua_isnil(L, -1)) { | ||
209 | lua_pop(L, 2); /* remove metatable and metafield */ | ||
210 | return 0; | ||
211 | } | ||
212 | else { | ||
213 | lua_remove(L, -2); /* remove only metatable */ | ||
214 | return 1; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | |||
219 | LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { | ||
220 | obj = abs_index(L, obj); | ||
221 | if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ | ||
222 | return 0; | ||
223 | lua_pushvalue(L, obj); | ||
224 | lua_call(L, 1, 1); | ||
225 | return 1; | ||
226 | } | ||
227 | |||
228 | |||
229 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, | ||
230 | const luaL_Reg *l) { | ||
231 | luaI_openlib(L, libname, l, 0); | ||
232 | } | ||
233 | |||
234 | |||
235 | static int libsize (const luaL_Reg *l) { | ||
236 | int size = 0; | ||
237 | for (; l->name; l++) size++; | ||
238 | return size; | ||
239 | } | ||
240 | |||
241 | |||
242 | LUALIB_API void luaI_openlib (lua_State *L, const char *libname, | ||
243 | const luaL_Reg *l, int nup) { | ||
244 | if (libname) { | ||
245 | int size = libsize(l); | ||
246 | /* check whether lib already exists */ | ||
247 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); | ||
248 | lua_getfield(L, -1, libname); /* get _LOADED[libname] */ | ||
249 | if (!lua_istable(L, -1)) { /* not found? */ | ||
250 | lua_pop(L, 1); /* remove previous result */ | ||
251 | /* try global variable (and create one if it does not exist) */ | ||
252 | if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) | ||
253 | luaL_error(L, "name conflict for module " LUA_QS, libname); | ||
254 | lua_pushvalue(L, -1); | ||
255 | lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ | ||
256 | } | ||
257 | lua_remove(L, -2); /* remove _LOADED table */ | ||
258 | lua_insert(L, -(nup+1)); /* move library table to below upvalues */ | ||
259 | } | ||
260 | for (; l->name; l++) { | ||
261 | int i; | ||
262 | for (i=0; i<nup; i++) /* copy upvalues to the top */ | ||
263 | lua_pushvalue(L, -nup); | ||
264 | lua_pushcclosure(L, l->func, nup); | ||
265 | lua_setfield(L, -(nup+2), l->name); | ||
266 | } | ||
267 | lua_pop(L, nup); /* remove upvalues */ | ||
268 | } | ||
269 | |||
270 | |||
271 | |||
272 | /* | ||
273 | ** {====================================================== | ||
274 | ** getn-setn: size for arrays | ||
275 | ** ======================================================= | ||
276 | */ | ||
277 | |||
278 | #if defined(LUA_COMPAT_GETN) | ||
279 | |||
280 | static int checkint (lua_State *L, int topop) { | ||
281 | int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; | ||
282 | lua_pop(L, topop); | ||
283 | return n; | ||
284 | } | ||
285 | |||
286 | |||
287 | static void getsizes (lua_State *L) { | ||
288 | lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); | ||
289 | if (lua_isnil(L, -1)) { /* no `size' table? */ | ||
290 | lua_pop(L, 1); /* remove nil */ | ||
291 | lua_newtable(L); /* create it */ | ||
292 | lua_pushvalue(L, -1); /* `size' will be its own metatable */ | ||
293 | lua_setmetatable(L, -2); | ||
294 | lua_pushliteral(L, "kv"); | ||
295 | lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ | ||
296 | lua_pushvalue(L, -1); | ||
297 | lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ | ||
298 | } | ||
299 | } | ||
300 | |||
301 | |||
302 | LUALIB_API void luaL_setn (lua_State *L, int t, int n) { | ||
303 | t = abs_index(L, t); | ||
304 | lua_pushliteral(L, "n"); | ||
305 | lua_rawget(L, t); | ||
306 | if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ | ||
307 | lua_pushliteral(L, "n"); /* use it */ | ||
308 | lua_pushinteger(L, n); | ||
309 | lua_rawset(L, t); | ||
310 | } | ||
311 | else { /* use `sizes' */ | ||
312 | getsizes(L); | ||
313 | lua_pushvalue(L, t); | ||
314 | lua_pushinteger(L, n); | ||
315 | lua_rawset(L, -3); /* sizes[t] = n */ | ||
316 | lua_pop(L, 1); /* remove `sizes' */ | ||
317 | } | ||
318 | } | ||
319 | |||
320 | |||
321 | LUALIB_API int luaL_getn (lua_State *L, int t) { | ||
322 | int n; | ||
323 | t = abs_index(L, t); | ||
324 | lua_pushliteral(L, "n"); /* try t.n */ | ||
325 | lua_rawget(L, t); | ||
326 | if ((n = checkint(L, 1)) >= 0) return n; | ||
327 | getsizes(L); /* else try sizes[t] */ | ||
328 | lua_pushvalue(L, t); | ||
329 | lua_rawget(L, -2); | ||
330 | if ((n = checkint(L, 2)) >= 0) return n; | ||
331 | return (int)lua_objlen(L, t); | ||
332 | } | ||
333 | |||
334 | #endif | ||
335 | |||
336 | /* }====================================================== */ | ||
337 | |||
338 | |||
339 | |||
340 | LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, | ||
341 | const char *r) { | ||
342 | const char *wild; | ||
343 | size_t l = strlen(p); | ||
344 | luaL_Buffer b; | ||
345 | luaL_buffinit(L, &b); | ||
346 | while ((wild = strstr(s, p)) != NULL) { | ||
347 | luaL_addlstring(&b, s, wild - s); /* push prefix */ | ||
348 | luaL_addstring(&b, r); /* push replacement in place of pattern */ | ||
349 | s = wild + l; /* continue after `p' */ | ||
350 | } | ||
351 | luaL_addstring(&b, s); /* push last suffix */ | ||
352 | luaL_pushresult(&b); | ||
353 | return lua_tostring(L, -1); | ||
354 | } | ||
355 | |||
356 | |||
357 | LUALIB_API const char *luaL_findtable (lua_State *L, int idx, | ||
358 | const char *fname, int szhint) { | ||
359 | const char *e; | ||
360 | lua_pushvalue(L, idx); | ||
361 | do { | ||
362 | e = strchr(fname, '.'); | ||
363 | if (e == NULL) e = fname + strlen(fname); | ||
364 | lua_pushlstring(L, fname, e - fname); | ||
365 | lua_rawget(L, -2); | ||
366 | if (lua_isnil(L, -1)) { /* no such field? */ | ||
367 | lua_pop(L, 1); /* remove this nil */ | ||
368 | lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ | ||
369 | lua_pushlstring(L, fname, e - fname); | ||
370 | lua_pushvalue(L, -2); | ||
371 | lua_settable(L, -4); /* set new table into field */ | ||
372 | } | ||
373 | else if (!lua_istable(L, -1)) { /* field has a non-table value? */ | ||
374 | lua_pop(L, 2); /* remove table and value */ | ||
375 | return fname; /* return problematic part of the name */ | ||
376 | } | ||
377 | lua_remove(L, -2); /* remove previous table */ | ||
378 | fname = e + 1; | ||
379 | } while (*e == '.'); | ||
380 | return NULL; | ||
381 | } | ||
382 | |||
383 | |||
384 | |||
385 | /* | ||
386 | ** {====================================================== | ||
387 | ** Generic Buffer manipulation | ||
388 | ** ======================================================= | ||
389 | */ | ||
390 | |||
391 | |||
392 | #define bufflen(B) ((B)->p - (B)->buffer) | ||
393 | #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) | ||
394 | |||
395 | #define LIMIT (LUA_MINSTACK/2) | ||
396 | |||
397 | |||
398 | static int emptybuffer (luaL_Buffer *B) { | ||
399 | size_t l = bufflen(B); | ||
400 | if (l == 0) return 0; /* put nothing on stack */ | ||
401 | else { | ||
402 | lua_pushlstring(B->L, B->buffer, l); | ||
403 | B->p = B->buffer; | ||
404 | B->lvl++; | ||
405 | return 1; | ||
406 | } | ||
407 | } | ||
408 | |||
409 | |||
410 | static void adjuststack (luaL_Buffer *B) { | ||
411 | if (B->lvl > 1) { | ||
412 | lua_State *L = B->L; | ||
413 | int toget = 1; /* number of levels to concat */ | ||
414 | size_t toplen = lua_strlen(L, -1); | ||
415 | do { | ||
416 | size_t l = lua_strlen(L, -(toget+1)); | ||
417 | if (B->lvl - toget + 1 >= LIMIT || toplen > l) { | ||
418 | toplen += l; | ||
419 | toget++; | ||
420 | } | ||
421 | else break; | ||
422 | } while (toget < B->lvl); | ||
423 | lua_concat(L, toget); | ||
424 | B->lvl = B->lvl - toget + 1; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | |||
429 | LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { | ||
430 | if (emptybuffer(B)) | ||
431 | adjuststack(B); | ||
432 | return B->buffer; | ||
433 | } | ||
434 | |||
435 | |||
436 | LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { | ||
437 | while (l--) | ||
438 | luaL_addchar(B, *s++); | ||
439 | } | ||
440 | |||
441 | |||
442 | LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { | ||
443 | luaL_addlstring(B, s, strlen(s)); | ||
444 | } | ||
445 | |||
446 | |||
447 | LUALIB_API void luaL_pushresult (luaL_Buffer *B) { | ||
448 | emptybuffer(B); | ||
449 | lua_concat(B->L, B->lvl); | ||
450 | B->lvl = 1; | ||
451 | } | ||
452 | |||
453 | |||
454 | LUALIB_API void luaL_addvalue (luaL_Buffer *B) { | ||
455 | lua_State *L = B->L; | ||
456 | size_t vl; | ||
457 | const char *s = lua_tolstring(L, -1, &vl); | ||
458 | if (vl <= bufffree(B)) { /* fit into buffer? */ | ||
459 | memcpy(B->p, s, vl); /* put it there */ | ||
460 | B->p += vl; | ||
461 | lua_pop(L, 1); /* remove from stack */ | ||
462 | } | ||
463 | else { | ||
464 | if (emptybuffer(B)) | ||
465 | lua_insert(L, -2); /* put buffer before new value */ | ||
466 | B->lvl++; /* add new value into B stack */ | ||
467 | adjuststack(B); | ||
468 | } | ||
469 | } | ||
470 | |||
471 | |||
472 | LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { | ||
473 | B->L = L; | ||
474 | B->p = B->buffer; | ||
475 | B->lvl = 0; | ||
476 | } | ||
477 | |||
478 | /* }====================================================== */ | ||
479 | |||
480 | |||
481 | LUALIB_API int luaL_ref (lua_State *L, int t) { | ||
482 | int ref; | ||
483 | t = abs_index(L, t); | ||
484 | if (lua_isnil(L, -1)) { | ||
485 | lua_pop(L, 1); /* remove from stack */ | ||
486 | return LUA_REFNIL; /* `nil' has a unique fixed reference */ | ||
487 | } | ||
488 | lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ | ||
489 | ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ | ||
490 | lua_pop(L, 1); /* remove it from stack */ | ||
491 | if (ref != 0) { /* any free element? */ | ||
492 | lua_rawgeti(L, t, ref); /* remove it from list */ | ||
493 | lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ | ||
494 | } | ||
495 | else { /* no free elements */ | ||
496 | ref = (int)lua_objlen(L, t); | ||
497 | ref++; /* create new reference */ | ||
498 | } | ||
499 | lua_rawseti(L, t, ref); | ||
500 | return ref; | ||
501 | } | ||
502 | |||
503 | |||
504 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { | ||
505 | if (ref >= 0) { | ||
506 | t = abs_index(L, t); | ||
507 | lua_rawgeti(L, t, FREELIST_REF); | ||
508 | lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ | ||
509 | lua_pushinteger(L, ref); | ||
510 | lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ | ||
511 | } | ||
512 | } | ||
513 | |||
514 | |||
515 | |||
516 | /* | ||
517 | ** {====================================================== | ||
518 | ** Load functions | ||
519 | ** ======================================================= | ||
520 | */ | ||
521 | |||
522 | typedef struct LoadF { | ||
523 | int extraline; | ||
524 | FILE *f; | ||
525 | char buff[LUAL_BUFFERSIZE]; | ||
526 | } LoadF; | ||
527 | |||
528 | |||
529 | static const char *getF (lua_State *L, void *ud, size_t *size) { | ||
530 | LoadF *lf = (LoadF *)ud; | ||
531 | (void)L; | ||
532 | if (lf->extraline) { | ||
533 | lf->extraline = 0; | ||
534 | *size = 1; | ||
535 | return "\n"; | ||
536 | } | ||
537 | if (feof(lf->f)) return NULL; | ||
538 | *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); | ||
539 | return (*size > 0) ? lf->buff : NULL; | ||
540 | } | ||
541 | |||
542 | |||
543 | static int errfile (lua_State *L, const char *what, int fnameindex) { | ||
544 | const char *serr = strerror(errno); | ||
545 | const char *filename = lua_tostring(L, fnameindex) + 1; | ||
546 | lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); | ||
547 | lua_remove(L, fnameindex); | ||
548 | return LUA_ERRFILE; | ||
549 | } | ||
550 | |||
551 | |||
552 | LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { | ||
553 | LoadF lf; | ||
554 | int status, readstatus; | ||
555 | int c; | ||
556 | int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ | ||
557 | lf.extraline = 0; | ||
558 | if (filename == NULL) { | ||
559 | lua_pushliteral(L, "=stdin"); | ||
560 | lf.f = stdin; | ||
561 | } | ||
562 | else { | ||
563 | lua_pushfstring(L, "@%s", filename); | ||
564 | lf.f = fopen(filename, "r"); | ||
565 | if (lf.f == NULL) return errfile(L, "open", fnameindex); | ||
566 | } | ||
567 | c = getc(lf.f); | ||
568 | if (c == '#') { /* Unix exec. file? */ | ||
569 | lf.extraline = 1; | ||
570 | while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ | ||
571 | if (c == '\n') c = getc(lf.f); | ||
572 | } | ||
573 | if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ | ||
574 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ | ||
575 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); | ||
576 | /* skip eventual `#!...' */ | ||
577 | while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; | ||
578 | lf.extraline = 0; | ||
579 | } | ||
580 | ungetc(c, lf.f); | ||
581 | status = lua_load(L, getF, &lf, lua_tostring(L, -1)); | ||
582 | readstatus = ferror(lf.f); | ||
583 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ | ||
584 | if (readstatus) { | ||
585 | lua_settop(L, fnameindex); /* ignore results from `lua_load' */ | ||
586 | return errfile(L, "read", fnameindex); | ||
587 | } | ||
588 | lua_remove(L, fnameindex); | ||
589 | return status; | ||
590 | } | ||
591 | |||
592 | |||
593 | typedef struct LoadS { | ||
594 | const char *s; | ||
595 | size_t size; | ||
596 | } LoadS; | ||
597 | |||
598 | |||
599 | static const char *getS (lua_State *L, void *ud, size_t *size) { | ||
600 | LoadS *ls = (LoadS *)ud; | ||
601 | (void)L; | ||
602 | if (ls->size == 0) return NULL; | ||
603 | *size = ls->size; | ||
604 | ls->size = 0; | ||
605 | return ls->s; | ||
606 | } | ||
607 | |||
608 | |||
609 | LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, | ||
610 | const char *name) { | ||
611 | LoadS ls; | ||
612 | ls.s = buff; | ||
613 | ls.size = size; | ||
614 | return lua_load(L, getS, &ls, name); | ||
615 | } | ||
616 | |||
617 | |||
618 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) { | ||
619 | return luaL_loadbuffer(L, s, strlen(s), s); | ||
620 | } | ||
621 | |||
622 | |||
623 | |||
624 | /* }====================================================== */ | ||
625 | |||
626 | |||
627 | static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { | ||
628 | (void)ud; | ||
629 | (void)osize; | ||
630 | if (nsize == 0) { | ||
631 | free(ptr); | ||
632 | return NULL; | ||
633 | } | ||
634 | else | ||
635 | return realloc(ptr, nsize); | ||
636 | } | ||
637 | |||
638 | |||
639 | static int panic (lua_State *L) { | ||
640 | (void)L; /* to avoid warnings */ | ||
641 | fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", | ||
642 | lua_tostring(L, -1)); | ||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | |||
647 | LUALIB_API lua_State *luaL_newstate (void) { | ||
648 | lua_State *L = lua_newstate(l_alloc, NULL); | ||
649 | if (L) lua_atpanic(L, &panic); | ||
650 | return L; | ||
651 | } | ||
652 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lauxlib.h b/libraries/LuaJIT-1.1.7/src/lauxlib.h new file mode 100644 index 0000000..3425823 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lauxlib.h | |||
@@ -0,0 +1,174 @@ | |||
1 | /* | ||
2 | ** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Auxiliary functions for building Lua libraries | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #ifndef lauxlib_h | ||
9 | #define lauxlib_h | ||
10 | |||
11 | |||
12 | #include <stddef.h> | ||
13 | #include <stdio.h> | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | |||
18 | #if defined(LUA_COMPAT_GETN) | ||
19 | LUALIB_API int (luaL_getn) (lua_State *L, int t); | ||
20 | LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); | ||
21 | #else | ||
22 | #define luaL_getn(L,i) ((int)lua_objlen(L, i)) | ||
23 | #define luaL_setn(L,i,j) ((void)0) /* no op! */ | ||
24 | #endif | ||
25 | |||
26 | #if defined(LUA_COMPAT_OPENLIB) | ||
27 | #define luaI_openlib luaL_openlib | ||
28 | #endif | ||
29 | |||
30 | |||
31 | /* extra error code for `luaL_load' */ | ||
32 | #define LUA_ERRFILE (LUA_ERRERR+1) | ||
33 | |||
34 | |||
35 | typedef struct luaL_Reg { | ||
36 | const char *name; | ||
37 | lua_CFunction func; | ||
38 | } luaL_Reg; | ||
39 | |||
40 | |||
41 | |||
42 | LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, | ||
43 | const luaL_Reg *l, int nup); | ||
44 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, | ||
45 | const luaL_Reg *l); | ||
46 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); | ||
47 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); | ||
48 | LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); | ||
49 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); | ||
50 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, | ||
51 | size_t *l); | ||
52 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, | ||
53 | const char *def, size_t *l); | ||
54 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); | ||
55 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); | ||
56 | |||
57 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); | ||
58 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, | ||
59 | lua_Integer def); | ||
60 | |||
61 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); | ||
62 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); | ||
63 | LUALIB_API void (luaL_checkany) (lua_State *L, int narg); | ||
64 | |||
65 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); | ||
66 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); | ||
67 | |||
68 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); | ||
69 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); | ||
70 | |||
71 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, | ||
72 | const char *const lst[]); | ||
73 | |||
74 | LUALIB_API int (luaL_ref) (lua_State *L, int t); | ||
75 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); | ||
76 | |||
77 | LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); | ||
78 | LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, | ||
79 | const char *name); | ||
80 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); | ||
81 | |||
82 | LUALIB_API lua_State *(luaL_newstate) (void); | ||
83 | |||
84 | |||
85 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, | ||
86 | const char *r); | ||
87 | |||
88 | LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, | ||
89 | const char *fname, int szhint); | ||
90 | |||
91 | |||
92 | |||
93 | |||
94 | /* | ||
95 | ** =============================================================== | ||
96 | ** some useful macros | ||
97 | ** =============================================================== | ||
98 | */ | ||
99 | |||
100 | #define luaL_argcheck(L, cond,numarg,extramsg) \ | ||
101 | ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) | ||
102 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) | ||
103 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) | ||
104 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) | ||
105 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) | ||
106 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) | ||
107 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) | ||
108 | |||
109 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) | ||
110 | |||
111 | #define luaL_dofile(L, fn) \ | ||
112 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) | ||
113 | |||
114 | #define luaL_dostring(L, s) \ | ||
115 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) | ||
116 | |||
117 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) | ||
118 | |||
119 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) | ||
120 | |||
121 | /* | ||
122 | ** {====================================================== | ||
123 | ** Generic Buffer manipulation | ||
124 | ** ======================================================= | ||
125 | */ | ||
126 | |||
127 | |||
128 | |||
129 | typedef struct luaL_Buffer { | ||
130 | char *p; /* current position in buffer */ | ||
131 | int lvl; /* number of strings in the stack (level) */ | ||
132 | lua_State *L; | ||
133 | char buffer[LUAL_BUFFERSIZE]; | ||
134 | } luaL_Buffer; | ||
135 | |||
136 | #define luaL_addchar(B,c) \ | ||
137 | ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ | ||
138 | (*(B)->p++ = (char)(c))) | ||
139 | |||
140 | /* compatibility only */ | ||
141 | #define luaL_putchar(B,c) luaL_addchar(B,c) | ||
142 | |||
143 | #define luaL_addsize(B,n) ((B)->p += (n)) | ||
144 | |||
145 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); | ||
146 | LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); | ||
147 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); | ||
148 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); | ||
149 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); | ||
150 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); | ||
151 | |||
152 | |||
153 | /* }====================================================== */ | ||
154 | |||
155 | |||
156 | /* compatibility with ref system */ | ||
157 | |||
158 | /* pre-defined references */ | ||
159 | #define LUA_NOREF (-2) | ||
160 | #define LUA_REFNIL (-1) | ||
161 | |||
162 | #define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ | ||
163 | (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) | ||
164 | |||
165 | #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) | ||
166 | |||
167 | #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) | ||
168 | |||
169 | |||
170 | #define luaL_reg luaL_Reg | ||
171 | |||
172 | #endif | ||
173 | |||
174 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lbaselib.c b/libraries/LuaJIT-1.1.7/src/lbaselib.c new file mode 100644 index 0000000..2366a02 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lbaselib.c | |||
@@ -0,0 +1,679 @@ | |||
1 | /* | ||
2 | ** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $ | ||
3 | ** Basic library | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | |||
9 | #include <ctype.h> | ||
10 | #include <stdio.h> | ||
11 | #include <stdlib.h> | ||
12 | #include <string.h> | ||
13 | |||
14 | #define lbaselib_c | ||
15 | #define LUA_LIB | ||
16 | |||
17 | #include "lua.h" | ||
18 | |||
19 | #include "lauxlib.h" | ||
20 | #include "lualib.h" | ||
21 | #ifndef COCO_DISABLE | ||
22 | #include "lcoco.h" | ||
23 | #endif | ||
24 | |||
25 | |||
26 | |||
27 | |||
28 | /* | ||
29 | ** If your system does not support `stdout', you can just remove this function. | ||
30 | ** If you need, you can define your own `print' function, following this | ||
31 | ** model but changing `fputs' to put the strings at a proper place | ||
32 | ** (a console window or a log file, for instance). | ||
33 | */ | ||
34 | static int luaB_print (lua_State *L) { | ||
35 | int n = lua_gettop(L); /* number of arguments */ | ||
36 | int i; | ||
37 | lua_getglobal(L, "tostring"); | ||
38 | for (i=1; i<=n; i++) { | ||
39 | const char *s; | ||
40 | lua_pushvalue(L, -1); /* function to be called */ | ||
41 | lua_pushvalue(L, i); /* value to print */ | ||
42 | lua_call(L, 1, 1); | ||
43 | s = lua_tostring(L, -1); /* get result */ | ||
44 | if (s == NULL) | ||
45 | return luaL_error(L, LUA_QL("tostring") " must return a string to " | ||
46 | LUA_QL("print")); | ||
47 | if (i>1) fputs("\t", stdout); | ||
48 | fputs(s, stdout); | ||
49 | lua_pop(L, 1); /* pop result */ | ||
50 | } | ||
51 | fputs("\n", stdout); | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | |||
56 | static int luaB_tonumber (lua_State *L) { | ||
57 | int base = luaL_optint(L, 2, 10); | ||
58 | if (base == 10) { /* standard conversion */ | ||
59 | luaL_checkany(L, 1); | ||
60 | if (lua_isnumber(L, 1)) { | ||
61 | lua_pushnumber(L, lua_tonumber(L, 1)); | ||
62 | return 1; | ||
63 | } | ||
64 | } | ||
65 | else { | ||
66 | const char *s1 = luaL_checkstring(L, 1); | ||
67 | char *s2; | ||
68 | unsigned long n; | ||
69 | luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); | ||
70 | n = strtoul(s1, &s2, base); | ||
71 | if (s1 != s2) { /* at least one valid digit? */ | ||
72 | while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ | ||
73 | if (*s2 == '\0') { /* no invalid trailing characters? */ | ||
74 | lua_pushnumber(L, (lua_Number)n); | ||
75 | return 1; | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | lua_pushnil(L); /* else not a number */ | ||
80 | return 1; | ||
81 | } | ||
82 | |||
83 | |||
84 | static int luaB_error (lua_State *L) { | ||
85 | int level = luaL_optint(L, 2, 1); | ||
86 | lua_settop(L, 1); | ||
87 | if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ | ||
88 | luaL_where(L, level); | ||
89 | lua_pushvalue(L, 1); | ||
90 | lua_concat(L, 2); | ||
91 | } | ||
92 | return lua_error(L); | ||
93 | } | ||
94 | |||
95 | |||
96 | static int luaB_getmetatable (lua_State *L) { | ||
97 | luaL_checkany(L, 1); | ||
98 | if (!lua_getmetatable(L, 1)) { | ||
99 | lua_pushnil(L); | ||
100 | return 1; /* no metatable */ | ||
101 | } | ||
102 | luaL_getmetafield(L, 1, "__metatable"); | ||
103 | return 1; /* returns either __metatable field (if present) or metatable */ | ||
104 | } | ||
105 | |||
106 | |||
107 | static int luaB_setmetatable (lua_State *L) { | ||
108 | int t = lua_type(L, 2); | ||
109 | luaL_checktype(L, 1, LUA_TTABLE); | ||
110 | luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, | ||
111 | "nil or table expected"); | ||
112 | if (luaL_getmetafield(L, 1, "__metatable")) | ||
113 | luaL_error(L, "cannot change a protected metatable"); | ||
114 | lua_settop(L, 2); | ||
115 | lua_setmetatable(L, 1); | ||
116 | return 1; | ||
117 | } | ||
118 | |||
119 | |||
120 | static void getfunc (lua_State *L, int opt) { | ||
121 | if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); | ||
122 | else { | ||
123 | lua_Debug ar; | ||
124 | int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); | ||
125 | luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); | ||
126 | if (lua_getstack(L, level, &ar) == 0) | ||
127 | luaL_argerror(L, 1, "invalid level"); | ||
128 | lua_getinfo(L, "f", &ar); | ||
129 | if (lua_isnil(L, -1)) | ||
130 | luaL_error(L, "no function environment for tail call at level %d", | ||
131 | level); | ||
132 | } | ||
133 | } | ||
134 | |||
135 | |||
136 | static int luaB_getfenv (lua_State *L) { | ||
137 | getfunc(L, 1); | ||
138 | if (lua_iscfunction(L, -1)) /* is a C function? */ | ||
139 | lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ | ||
140 | else | ||
141 | lua_getfenv(L, -1); | ||
142 | return 1; | ||
143 | } | ||
144 | |||
145 | |||
146 | static int luaB_setfenv (lua_State *L) { | ||
147 | luaL_checktype(L, 2, LUA_TTABLE); | ||
148 | getfunc(L, 0); | ||
149 | lua_pushvalue(L, 2); | ||
150 | if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { | ||
151 | /* change environment of current thread */ | ||
152 | lua_pushthread(L); | ||
153 | lua_insert(L, -2); | ||
154 | lua_setfenv(L, -2); | ||
155 | return 0; | ||
156 | } | ||
157 | else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) | ||
158 | luaL_error(L, | ||
159 | LUA_QL("setfenv") " cannot change environment of given object"); | ||
160 | return 1; | ||
161 | } | ||
162 | |||
163 | |||
164 | static int luaB_rawequal (lua_State *L) { | ||
165 | luaL_checkany(L, 1); | ||
166 | luaL_checkany(L, 2); | ||
167 | lua_pushboolean(L, lua_rawequal(L, 1, 2)); | ||
168 | return 1; | ||
169 | } | ||
170 | |||
171 | |||
172 | static int luaB_rawget (lua_State *L) { | ||
173 | luaL_checktype(L, 1, LUA_TTABLE); | ||
174 | luaL_checkany(L, 2); | ||
175 | lua_settop(L, 2); | ||
176 | lua_rawget(L, 1); | ||
177 | return 1; | ||
178 | } | ||
179 | |||
180 | static int luaB_rawset (lua_State *L) { | ||
181 | luaL_checktype(L, 1, LUA_TTABLE); | ||
182 | luaL_checkany(L, 2); | ||
183 | luaL_checkany(L, 3); | ||
184 | lua_settop(L, 3); | ||
185 | lua_rawset(L, 1); | ||
186 | return 1; | ||
187 | } | ||
188 | |||
189 | |||
190 | static int luaB_gcinfo (lua_State *L) { | ||
191 | lua_pushinteger(L, lua_getgccount(L)); | ||
192 | return 1; | ||
193 | } | ||
194 | |||
195 | |||
196 | static int luaB_collectgarbage (lua_State *L) { | ||
197 | static const char *const opts[] = {"stop", "restart", "collect", | ||
198 | "count", "step", "setpause", "setstepmul", NULL}; | ||
199 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, | ||
200 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL}; | ||
201 | int o = luaL_checkoption(L, 1, "collect", opts); | ||
202 | int ex = luaL_optint(L, 2, 0); | ||
203 | int res = lua_gc(L, optsnum[o], ex); | ||
204 | switch (optsnum[o]) { | ||
205 | case LUA_GCCOUNT: { | ||
206 | int b = lua_gc(L, LUA_GCCOUNTB, 0); | ||
207 | lua_pushnumber(L, res + ((lua_Number)b/1024)); | ||
208 | return 1; | ||
209 | } | ||
210 | case LUA_GCSTEP: { | ||
211 | lua_pushboolean(L, res); | ||
212 | return 1; | ||
213 | } | ||
214 | default: { | ||
215 | lua_pushnumber(L, res); | ||
216 | return 1; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | |||
222 | static int luaB_type (lua_State *L) { | ||
223 | luaL_checkany(L, 1); | ||
224 | lua_pushstring(L, luaL_typename(L, 1)); | ||
225 | return 1; | ||
226 | } | ||
227 | |||
228 | |||
229 | static int luaB_next (lua_State *L) { | ||
230 | luaL_checktype(L, 1, LUA_TTABLE); | ||
231 | lua_settop(L, 2); /* create a 2nd argument if there isn't one */ | ||
232 | if (lua_next(L, 1)) | ||
233 | return 2; | ||
234 | else { | ||
235 | lua_pushnil(L); | ||
236 | return 1; | ||
237 | } | ||
238 | } | ||
239 | |||
240 | |||
241 | static int luaB_pairs (lua_State *L) { | ||
242 | luaL_checktype(L, 1, LUA_TTABLE); | ||
243 | lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ | ||
244 | lua_pushvalue(L, 1); /* state, */ | ||
245 | lua_pushnil(L); /* and initial value */ | ||
246 | return 3; | ||
247 | } | ||
248 | |||
249 | |||
250 | static int ipairsaux (lua_State *L) { | ||
251 | int i = luaL_checkint(L, 2); | ||
252 | luaL_checktype(L, 1, LUA_TTABLE); | ||
253 | i++; /* next value */ | ||
254 | lua_pushinteger(L, i); | ||
255 | lua_rawgeti(L, 1, i); | ||
256 | return (lua_isnil(L, -1)) ? 0 : 2; | ||
257 | } | ||
258 | |||
259 | |||
260 | static int luaB_ipairs (lua_State *L) { | ||
261 | luaL_checktype(L, 1, LUA_TTABLE); | ||
262 | lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ | ||
263 | lua_pushvalue(L, 1); /* state, */ | ||
264 | lua_pushinteger(L, 0); /* and initial value */ | ||
265 | return 3; | ||
266 | } | ||
267 | |||
268 | |||
269 | static int load_aux (lua_State *L, int status) { | ||
270 | if (status == 0) /* OK? */ | ||
271 | return 1; | ||
272 | else { | ||
273 | lua_pushnil(L); | ||
274 | lua_insert(L, -2); /* put before error message */ | ||
275 | return 2; /* return nil plus error message */ | ||
276 | } | ||
277 | } | ||
278 | |||
279 | |||
280 | static int luaB_loadstring (lua_State *L) { | ||
281 | size_t l; | ||
282 | const char *s = luaL_checklstring(L, 1, &l); | ||
283 | const char *chunkname = luaL_optstring(L, 2, s); | ||
284 | return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); | ||
285 | } | ||
286 | |||
287 | |||
288 | static int luaB_loadfile (lua_State *L) { | ||
289 | const char *fname = luaL_optstring(L, 1, NULL); | ||
290 | return load_aux(L, luaL_loadfile(L, fname)); | ||
291 | } | ||
292 | |||
293 | |||
294 | /* | ||
295 | ** Reader for generic `load' function: `lua_load' uses the | ||
296 | ** stack for internal stuff, so the reader cannot change the | ||
297 | ** stack top. Instead, it keeps its resulting string in a | ||
298 | ** reserved slot inside the stack. | ||
299 | */ | ||
300 | static const char *generic_reader (lua_State *L, void *ud, size_t *size) { | ||
301 | (void)ud; /* to avoid warnings */ | ||
302 | luaL_checkstack(L, 2, "too many nested functions"); | ||
303 | lua_pushvalue(L, 1); /* get function */ | ||
304 | lua_call(L, 0, 1); /* call it */ | ||
305 | if (lua_isnil(L, -1)) { | ||
306 | *size = 0; | ||
307 | return NULL; | ||
308 | } | ||
309 | else if (lua_isstring(L, -1)) { | ||
310 | lua_replace(L, 3); /* save string in a reserved stack slot */ | ||
311 | return lua_tolstring(L, 3, size); | ||
312 | } | ||
313 | else luaL_error(L, "reader function must return a string"); | ||
314 | return NULL; /* to avoid warnings */ | ||
315 | } | ||
316 | |||
317 | |||
318 | static int luaB_load (lua_State *L) { | ||
319 | int status; | ||
320 | const char *cname = luaL_optstring(L, 2, "=(load)"); | ||
321 | luaL_checktype(L, 1, LUA_TFUNCTION); | ||
322 | lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ | ||
323 | status = lua_load(L, generic_reader, NULL, cname); | ||
324 | return load_aux(L, status); | ||
325 | } | ||
326 | |||
327 | |||
328 | static int luaB_dofile (lua_State *L) { | ||
329 | const char *fname = luaL_optstring(L, 1, NULL); | ||
330 | int n = lua_gettop(L); | ||
331 | if (luaL_loadfile(L, fname) != 0) lua_error(L); | ||
332 | lua_call(L, 0, LUA_MULTRET); | ||
333 | return lua_gettop(L) - n; | ||
334 | } | ||
335 | |||
336 | |||
337 | static int luaB_assert (lua_State *L) { | ||
338 | luaL_checkany(L, 1); | ||
339 | if (!lua_toboolean(L, 1)) | ||
340 | return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); | ||
341 | return lua_gettop(L); | ||
342 | } | ||
343 | |||
344 | |||
345 | static int luaB_unpack (lua_State *L) { | ||
346 | int i, e, n; | ||
347 | luaL_checktype(L, 1, LUA_TTABLE); | ||
348 | i = luaL_optint(L, 2, 1); | ||
349 | e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); | ||
350 | if (i > e) return 0; /* empty range */ | ||
351 | n = e - i + 1; /* number of elements */ | ||
352 | if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ | ||
353 | return luaL_error(L, "too many results to unpack"); | ||
354 | lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ | ||
355 | while (i++ < e) /* push arg[i + 1...e] */ | ||
356 | lua_rawgeti(L, 1, i); | ||
357 | return n; | ||
358 | } | ||
359 | |||
360 | |||
361 | static int luaB_select (lua_State *L) { | ||
362 | int n = lua_gettop(L); | ||
363 | if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { | ||
364 | lua_pushinteger(L, n-1); | ||
365 | return 1; | ||
366 | } | ||
367 | else { | ||
368 | int i = luaL_checkint(L, 1); | ||
369 | if (i < 0) i = n + i; | ||
370 | else if (i > n) i = n; | ||
371 | luaL_argcheck(L, 1 <= i, 1, "index out of range"); | ||
372 | return n - i; | ||
373 | } | ||
374 | } | ||
375 | |||
376 | |||
377 | static int luaB_pcall (lua_State *L) { | ||
378 | int status; | ||
379 | luaL_checkany(L, 1); | ||
380 | status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); | ||
381 | lua_pushboolean(L, (status == 0)); | ||
382 | lua_insert(L, 1); | ||
383 | return lua_gettop(L); /* return status + all results */ | ||
384 | } | ||
385 | |||
386 | |||
387 | static int luaB_xpcall (lua_State *L) { | ||
388 | int status; | ||
389 | luaL_checkany(L, 2); | ||
390 | lua_settop(L, 2); | ||
391 | lua_insert(L, 1); /* put error function under function to be called */ | ||
392 | status = lua_pcall(L, 0, LUA_MULTRET, 1); | ||
393 | lua_pushboolean(L, (status == 0)); | ||
394 | lua_replace(L, 1); | ||
395 | return lua_gettop(L); /* return status + all results */ | ||
396 | } | ||
397 | |||
398 | |||
399 | static int luaB_tostring (lua_State *L) { | ||
400 | luaL_checkany(L, 1); | ||
401 | if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ | ||
402 | return 1; /* use its value */ | ||
403 | switch (lua_type(L, 1)) { | ||
404 | case LUA_TNUMBER: | ||
405 | lua_pushstring(L, lua_tostring(L, 1)); | ||
406 | break; | ||
407 | case LUA_TSTRING: | ||
408 | lua_pushvalue(L, 1); | ||
409 | break; | ||
410 | case LUA_TBOOLEAN: | ||
411 | lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); | ||
412 | break; | ||
413 | case LUA_TNIL: | ||
414 | lua_pushliteral(L, "nil"); | ||
415 | break; | ||
416 | default: | ||
417 | lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); | ||
418 | break; | ||
419 | } | ||
420 | return 1; | ||
421 | } | ||
422 | |||
423 | |||
424 | static int luaB_newproxy (lua_State *L) { | ||
425 | lua_settop(L, 1); | ||
426 | lua_newuserdata(L, 0); /* create proxy */ | ||
427 | if (lua_toboolean(L, 1) == 0) | ||
428 | return 1; /* no metatable */ | ||
429 | else if (lua_isboolean(L, 1)) { | ||
430 | lua_newtable(L); /* create a new metatable `m' ... */ | ||
431 | lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ | ||
432 | lua_pushboolean(L, 1); | ||
433 | lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ | ||
434 | } | ||
435 | else { | ||
436 | int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ | ||
437 | if (lua_getmetatable(L, 1)) { | ||
438 | lua_rawget(L, lua_upvalueindex(1)); | ||
439 | validproxy = lua_toboolean(L, -1); | ||
440 | lua_pop(L, 1); /* remove value */ | ||
441 | } | ||
442 | luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); | ||
443 | lua_getmetatable(L, 1); /* metatable is valid; get it */ | ||
444 | } | ||
445 | lua_setmetatable(L, 2); | ||
446 | return 1; | ||
447 | } | ||
448 | |||
449 | |||
450 | static const luaL_Reg base_funcs[] = { | ||
451 | {"assert", luaB_assert}, | ||
452 | {"collectgarbage", luaB_collectgarbage}, | ||
453 | {"dofile", luaB_dofile}, | ||
454 | {"error", luaB_error}, | ||
455 | {"gcinfo", luaB_gcinfo}, | ||
456 | {"getfenv", luaB_getfenv}, | ||
457 | {"getmetatable", luaB_getmetatable}, | ||
458 | {"loadfile", luaB_loadfile}, | ||
459 | {"load", luaB_load}, | ||
460 | {"loadstring", luaB_loadstring}, | ||
461 | {"next", luaB_next}, | ||
462 | {"pcall", luaB_pcall}, | ||
463 | {"print", luaB_print}, | ||
464 | {"rawequal", luaB_rawequal}, | ||
465 | {"rawget", luaB_rawget}, | ||
466 | {"rawset", luaB_rawset}, | ||
467 | {"select", luaB_select}, | ||
468 | {"setfenv", luaB_setfenv}, | ||
469 | {"setmetatable", luaB_setmetatable}, | ||
470 | {"tonumber", luaB_tonumber}, | ||
471 | {"tostring", luaB_tostring}, | ||
472 | {"type", luaB_type}, | ||
473 | {"unpack", luaB_unpack}, | ||
474 | {"xpcall", luaB_xpcall}, | ||
475 | {NULL, NULL} | ||
476 | }; | ||
477 | |||
478 | |||
479 | /* | ||
480 | ** {====================================================== | ||
481 | ** Coroutine library | ||
482 | ** ======================================================= | ||
483 | */ | ||
484 | |||
485 | #define CO_RUN 0 /* running */ | ||
486 | #define CO_SUS 1 /* suspended */ | ||
487 | #define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ | ||
488 | #define CO_DEAD 3 | ||
489 | |||
490 | static const char *const statnames[] = | ||
491 | {"running", "suspended", "normal", "dead"}; | ||
492 | |||
493 | static int costatus (lua_State *L, lua_State *co) { | ||
494 | if (L == co) return CO_RUN; | ||
495 | switch (lua_status(co)) { | ||
496 | case LUA_YIELD: | ||
497 | return CO_SUS; | ||
498 | case 0: { | ||
499 | lua_Debug ar; | ||
500 | if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ | ||
501 | return CO_NOR; /* it is running */ | ||
502 | else if (lua_gettop(co) == 0) | ||
503 | return CO_DEAD; | ||
504 | else | ||
505 | return CO_SUS; /* initial state */ | ||
506 | } | ||
507 | default: /* some error occured */ | ||
508 | return CO_DEAD; | ||
509 | } | ||
510 | } | ||
511 | |||
512 | |||
513 | static int luaB_costatus (lua_State *L) { | ||
514 | lua_State *co = lua_tothread(L, 1); | ||
515 | luaL_argcheck(L, co, 1, "coroutine expected"); | ||
516 | lua_pushstring(L, statnames[costatus(L, co)]); | ||
517 | return 1; | ||
518 | } | ||
519 | |||
520 | |||
521 | static int auxresume (lua_State *L, lua_State *co, int narg) { | ||
522 | int status = costatus(L, co); | ||
523 | if (!lua_checkstack(co, narg)) | ||
524 | luaL_error(L, "too many arguments to resume"); | ||
525 | if (status != CO_SUS) { | ||
526 | lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); | ||
527 | return -1; /* error flag */ | ||
528 | } | ||
529 | lua_xmove(L, co, narg); | ||
530 | status = lua_resume(co, narg); | ||
531 | if (status == 0 || status == LUA_YIELD) { | ||
532 | int nres = lua_gettop(co); | ||
533 | if (!lua_checkstack(L, nres + 1)) | ||
534 | luaL_error(L, "too many results to resume"); | ||
535 | lua_xmove(co, L, nres); /* move yielded values */ | ||
536 | return nres; | ||
537 | } | ||
538 | else { | ||
539 | lua_xmove(co, L, 1); /* move error message */ | ||
540 | return -1; /* error flag */ | ||
541 | } | ||
542 | } | ||
543 | |||
544 | |||
545 | static int luaB_coresume (lua_State *L) { | ||
546 | lua_State *co = lua_tothread(L, 1); | ||
547 | int r; | ||
548 | luaL_argcheck(L, co, 1, "coroutine expected"); | ||
549 | r = auxresume(L, co, lua_gettop(L) - 1); | ||
550 | if (r < 0) { | ||
551 | lua_pushboolean(L, 0); | ||
552 | lua_insert(L, -2); | ||
553 | return 2; /* return false + error message */ | ||
554 | } | ||
555 | else { | ||
556 | lua_pushboolean(L, 1); | ||
557 | lua_insert(L, -(r + 1)); | ||
558 | return r + 1; /* return true + `resume' returns */ | ||
559 | } | ||
560 | } | ||
561 | |||
562 | |||
563 | static int luaB_auxwrap (lua_State *L) { | ||
564 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); | ||
565 | int r = auxresume(L, co, lua_gettop(L)); | ||
566 | if (r < 0) { | ||
567 | if (lua_isstring(L, -1)) { /* error object is a string? */ | ||
568 | luaL_where(L, 1); /* add extra info */ | ||
569 | lua_insert(L, -2); | ||
570 | lua_concat(L, 2); | ||
571 | } | ||
572 | lua_error(L); /* propagate error */ | ||
573 | } | ||
574 | return r; | ||
575 | } | ||
576 | |||
577 | |||
578 | #ifndef COCO_DISABLE | ||
579 | static int luaB_cstacksize (lua_State *L) | ||
580 | { | ||
581 | lua_pushinteger(L, luaCOCO_cstacksize(luaL_optint(L, 1, -1))); | ||
582 | return 1; | ||
583 | } | ||
584 | #endif | ||
585 | |||
586 | |||
587 | static int luaB_cocreate (lua_State *L) { | ||
588 | #ifdef COCO_DISABLE | ||
589 | lua_State *NL = lua_newthread(L); | ||
590 | luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, | ||
591 | "Lua function expected"); | ||
592 | #else | ||
593 | int cstacksize = luaL_optint(L, 2, 0); | ||
594 | lua_State *NL = lua_newcthread(L, cstacksize); | ||
595 | luaL_argcheck(L, lua_isfunction(L, 1) && | ||
596 | (cstacksize >= 0 ? 1 : !lua_iscfunction(L, 1)), | ||
597 | 1, "Lua function expected"); | ||
598 | #endif | ||
599 | lua_pushvalue(L, 1); /* move function to top */ | ||
600 | lua_xmove(L, NL, 1); /* move function from L to NL */ | ||
601 | return 1; | ||
602 | } | ||
603 | |||
604 | |||
605 | static int luaB_cowrap (lua_State *L) { | ||
606 | luaB_cocreate(L); | ||
607 | lua_pushcclosure(L, luaB_auxwrap, 1); | ||
608 | return 1; | ||
609 | } | ||
610 | |||
611 | |||
612 | static int luaB_yield (lua_State *L) { | ||
613 | return lua_yield(L, lua_gettop(L)); | ||
614 | } | ||
615 | |||
616 | |||
617 | static int luaB_corunning (lua_State *L) { | ||
618 | if (lua_pushthread(L)) | ||
619 | lua_pushnil(L); /* main thread is not a coroutine */ | ||
620 | return 1; | ||
621 | } | ||
622 | |||
623 | |||
624 | static const luaL_Reg co_funcs[] = { | ||
625 | {"create", luaB_cocreate}, | ||
626 | {"resume", luaB_coresume}, | ||
627 | {"running", luaB_corunning}, | ||
628 | {"status", luaB_costatus}, | ||
629 | {"wrap", luaB_cowrap}, | ||
630 | {"yield", luaB_yield}, | ||
631 | #ifndef COCO_DISABLE | ||
632 | {"cstacksize", luaB_cstacksize}, | ||
633 | #endif | ||
634 | {NULL, NULL} | ||
635 | }; | ||
636 | |||
637 | /* }====================================================== */ | ||
638 | |||
639 | |||
640 | static void auxopen (lua_State *L, const char *name, | ||
641 | lua_CFunction f, lua_CFunction u) { | ||
642 | lua_pushcfunction(L, u); | ||
643 | lua_pushcclosure(L, f, 1); | ||
644 | lua_setfield(L, -2, name); | ||
645 | } | ||
646 | |||
647 | |||
648 | static void base_open (lua_State *L) { | ||
649 | /* set global _G */ | ||
650 | lua_pushvalue(L, LUA_GLOBALSINDEX); | ||
651 | lua_setglobal(L, "_G"); | ||
652 | /* open lib into global table */ | ||
653 | luaL_register(L, "_G", base_funcs); | ||
654 | lua_pushliteral(L, LUA_VERSION); | ||
655 | lua_setglobal(L, "_VERSION"); /* set global _VERSION */ | ||
656 | /* `ipairs' and `pairs' need auxliliary functions as upvalues */ | ||
657 | auxopen(L, "ipairs", luaB_ipairs, ipairsaux); | ||
658 | auxopen(L, "pairs", luaB_pairs, luaB_next); | ||
659 | /* `newproxy' needs a weaktable as upvalue */ | ||
660 | lua_createtable(L, 0, 1); /* new table `w' */ | ||
661 | lua_pushvalue(L, -1); /* `w' will be its own metatable */ | ||
662 | lua_setmetatable(L, -2); | ||
663 | lua_pushliteral(L, "kv"); | ||
664 | lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ | ||
665 | lua_pushcclosure(L, luaB_newproxy, 1); | ||
666 | lua_setglobal(L, "newproxy"); /* set global `newproxy' */ | ||
667 | } | ||
668 | |||
669 | |||
670 | LUALIB_API int luaopen_base (lua_State *L) { | ||
671 | base_open(L); | ||
672 | luaL_register(L, LUA_COLIBNAME, co_funcs); | ||
673 | #ifndef COCO_DISABLE | ||
674 | lua_pushboolean(L, 1); | ||
675 | lua_setfield(L, -2, "coco"); | ||
676 | #endif | ||
677 | return 2; | ||
678 | } | ||
679 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lcoco.c b/libraries/LuaJIT-1.1.7/src/lcoco.c new file mode 100644 index 0000000..c3acc68 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lcoco.c | |||
@@ -0,0 +1,693 @@ | |||
1 | /* | ||
2 | ** Copyright (C) 2004-2011 Mike Pall. All rights reserved. | ||
3 | ** | ||
4 | ** Permission is hereby granted, free of charge, to any person obtaining | ||
5 | ** a copy of this software and associated documentation files (the | ||
6 | ** "Software"), to deal in the Software without restriction, including | ||
7 | ** without limitation the rights to use, copy, modify, merge, publish, | ||
8 | ** distribute, sublicense, and/or sell copies of the Software, and to | ||
9 | ** permit persons to whom the Software is furnished to do so, subject to | ||
10 | ** the following conditions: | ||
11 | ** | ||
12 | ** The above copyright notice and this permission notice shall be | ||
13 | ** included in all copies or substantial portions of the Software. | ||
14 | ** | ||
15 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
16 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
17 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
18 | ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
19 | ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
20 | ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
21 | ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
22 | ** | ||
23 | ** [ MIT license: http://www.opensource.org/licenses/mit-license.php ] | ||
24 | */ | ||
25 | |||
26 | /* Coco -- True C coroutines for Lua. http://luajit.org/coco.html */ | ||
27 | #ifndef COCO_DISABLE | ||
28 | |||
29 | #define lcoco_c | ||
30 | #define LUA_CORE | ||
31 | |||
32 | #include "lua.h" | ||
33 | |||
34 | #include "lobject.h" | ||
35 | #include "lstate.h" | ||
36 | #include "ldo.h" | ||
37 | #include "lvm.h" | ||
38 | #include "lgc.h" | ||
39 | |||
40 | |||
41 | /* | ||
42 | ** Define this if you want to run Coco with valgrind. You will get random | ||
43 | ** errors about accessing memory from newly allocated C stacks if you don't. | ||
44 | ** You need at least valgrind 3.0 for this to work. | ||
45 | ** | ||
46 | ** This macro evaluates to a no-op if not run with valgrind. I.e. you can | ||
47 | ** use the same binary for regular runs, too (without a performance loss). | ||
48 | */ | ||
49 | #ifdef USE_VALGRIND | ||
50 | #include <valgrind/valgrind.h> | ||
51 | #define STACK_REG(coco, p, sz) (coco)->vgid = VALGRIND_STACK_REGISTER(p, p+sz); | ||
52 | #define STACK_DEREG(coco) VALGRIND_STACK_DEREGISTER((coco)->vgid); | ||
53 | #define STACK_VGID unsigned int vgid; | ||
54 | #else | ||
55 | #define STACK_REG(coco, p, sz) | ||
56 | #define STACK_DEREG(id) | ||
57 | #define STACK_VGID | ||
58 | #endif | ||
59 | |||
60 | /* ------------------------------------------------------------------------ */ | ||
61 | |||
62 | /* Use Windows Fibers. */ | ||
63 | #if defined(COCO_USE_FIBERS) | ||
64 | |||
65 | #define _WIN32_WINNT 0x0400 | ||
66 | #include <windows.h> | ||
67 | |||
68 | #define COCO_MAIN_DECL CALLBACK | ||
69 | |||
70 | typedef LPFIBER_START_ROUTINE coco_MainFunc; | ||
71 | |||
72 | #define COCO_NEW(OL, NL, cstacksize, mainfunc) \ | ||
73 | if ((L2COCO(NL)->fib = CreateFiber(cstacksize, mainfunc, NL)) == NULL) \ | ||
74 | luaD_throw(OL, LUA_ERRMEM); | ||
75 | |||
76 | #define COCO_FREE(L) \ | ||
77 | DeleteFiber(L2COCO(L)->fib); \ | ||
78 | L2COCO(L)->fib = NULL; | ||
79 | |||
80 | /* See: http://blogs.msdn.com/oldnewthing/archive/2004/12/31/344799.aspx */ | ||
81 | #define COCO_JUMPIN(coco) \ | ||
82 | { void *cur = GetCurrentFiber(); \ | ||
83 | coco->back = (cur == NULL || cur == (void *)0x1e00) ? \ | ||
84 | ConvertThreadToFiber(NULL) : cur; } \ | ||
85 | SwitchToFiber(coco->fib); | ||
86 | |||
87 | #define COCO_JUMPOUT(coco) \ | ||
88 | SwitchToFiber(coco->back); | ||
89 | |||
90 | /* CreateFiber() defaults to STACKSIZE from the Windows module .def file. */ | ||
91 | #define COCO_DEFAULT_CSTACKSIZE 0 | ||
92 | |||
93 | /* ------------------------------------------------------------------------ */ | ||
94 | |||
95 | #else /* !COCO_USE_FIBERS */ | ||
96 | |||
97 | #ifndef COCO_USE_UCONTEXT | ||
98 | |||
99 | /* Try inline asm first. */ | ||
100 | #if __GNUC__ >= 3 && !defined(COCO_USE_SETJMP) | ||
101 | |||
102 | #if defined(__i386) || defined(__i386__) | ||
103 | |||
104 | #ifdef __PIC__ | ||
105 | typedef void *coco_ctx[4]; /* eip, esp, ebp, ebx */ | ||
106 | static inline void coco_switch(coco_ctx from, coco_ctx to) | ||
107 | { | ||
108 | __asm__ __volatile__ ( | ||
109 | "call 1f\n" "1:\tpopl %%eax\n\t" "addl $(2f-1b),%%eax\n\t" | ||
110 | "movl %%eax, (%0)\n\t" "movl %%esp, 4(%0)\n\t" | ||
111 | "movl %%ebp, 8(%0)\n\t" "movl %%ebx, 12(%0)\n\t" | ||
112 | "movl 12(%1), %%ebx\n\t" "movl 8(%1), %%ebp\n\t" | ||
113 | "movl 4(%1), %%esp\n\t" "jmp *(%1)\n" "2:\n" | ||
114 | : "+S" (from), "+D" (to) : : "eax", "ecx", "edx", "memory", "cc"); | ||
115 | } | ||
116 | #else | ||
117 | typedef void *coco_ctx[3]; /* eip, esp, ebp */ | ||
118 | static inline void coco_switch(coco_ctx from, coco_ctx to) | ||
119 | { | ||
120 | __asm__ __volatile__ ( | ||
121 | "movl $1f, (%0)\n\t" "movl %%esp, 4(%0)\n\t" "movl %%ebp, 8(%0)\n\t" | ||
122 | "movl 8(%1), %%ebp\n\t" "movl 4(%1), %%esp\n\t" "jmp *(%1)\n" "1:\n" | ||
123 | : "+S" (from), "+D" (to) : : "eax", "ebx", "ecx", "edx", "memory", "cc"); | ||
124 | } | ||
125 | #endif | ||
126 | |||
127 | #define COCO_CTX coco_ctx | ||
128 | #define COCO_SWITCH(from, to) coco_switch(from, to); | ||
129 | #define COCO_MAKECTX(coco, buf, func, stack, a0) \ | ||
130 | buf[0] = (void *)(func); \ | ||
131 | buf[1] = (void *)(stack); \ | ||
132 | buf[2] = (void *)0; \ | ||
133 | stack[0] = 0xdeadc0c0; /* Dummy return address. */ \ | ||
134 | coco->arg0 = (size_t)(a0); | ||
135 | #define COCO_STATE_HEAD size_t arg0; | ||
136 | |||
137 | #elif defined(__x86_64__) | ||
138 | |||
139 | static void coco_wrap_main(void) | ||
140 | { | ||
141 | __asm__ __volatile__ ("\tmovq %r13, %rdi\n\tjmpq *%r12\n"); | ||
142 | } | ||
143 | |||
144 | typedef void *coco_ctx[8]; /* rip, rsp, rbp, rbx, r12, r13, r14, r15 */ | ||
145 | static inline void coco_switch(coco_ctx from, coco_ctx to) | ||
146 | { | ||
147 | __asm__ __volatile__ ( | ||
148 | "leaq 1f(%%rip), %%rax\n\t" | ||
149 | "movq %%rax, (%0)\n\t" "movq %%rsp, 8(%0)\n\t" "movq %%rbp, 16(%0)\n\t" | ||
150 | "movq %%rbx, 24(%0)\n\t" "movq %%r12, 32(%0)\n\t" "movq %%r13, 40(%0)\n\t" | ||
151 | "movq %%r14, 48(%0)\n\t" "movq %%r15, 56(%0)\n\t" | ||
152 | "movq 56(%1), %%r15\n\t" "movq 48(%1), %%r14\n\t" "movq 40(%1), %%r13\n\t" | ||
153 | "movq 32(%1), %%r12\n\t" "movq 24(%1), %%rbx\n\t" "movq 16(%1), %%rbp\n\t" | ||
154 | "movq 8(%1), %%rsp\n\t" "jmpq *(%1)\n" "1:\n" | ||
155 | : "+S" (from), "+D" (to) : | ||
156 | : "rax", "rcx", "rdx", "r8", "r9", "r10", "r11", "memory", "cc"); | ||
157 | } | ||
158 | |||
159 | #define COCO_CTX coco_ctx | ||
160 | #define COCO_SWITCH(from, to) coco_switch(from, to); | ||
161 | #define COCO_MAKECTX(coco, buf, func, stack, a0) \ | ||
162 | buf[0] = (void *)(coco_wrap_main); \ | ||
163 | buf[1] = (void *)(stack); \ | ||
164 | buf[2] = (void *)0; \ | ||
165 | buf[3] = (void *)0; \ | ||
166 | buf[4] = (void *)(func); \ | ||
167 | buf[5] = (void *)(a0); \ | ||
168 | buf[6] = (void *)0; \ | ||
169 | buf[7] = (void *)0; \ | ||
170 | stack[0] = 0xdeadc0c0deadc0c0; /* Dummy return address. */ \ | ||
171 | |||
172 | #elif __mips && _MIPS_SIM == _MIPS_SIM_ABI32 && !defined(__mips_eabi) | ||
173 | |||
174 | /* No way to avoid the function prologue with inline assembler. So use this: */ | ||
175 | static const unsigned int coco_switch[] = { | ||
176 | #ifdef __mips_soft_float | ||
177 | #define COCO_STACKSAVE -10 | ||
178 | 0x27bdffd8, /* addiu sp, sp, -(10*4) */ | ||
179 | #else | ||
180 | #define COCO_STACKSAVE -22 | ||
181 | 0x27bdffa8, /* addiu sp, sp, -(10*4+6*8) */ | ||
182 | /* sdc1 {$f20-$f30}, offset(sp) */ | ||
183 | 0xf7be0050, 0xf7bc0048, 0xf7ba0040, 0xf7b80038, 0xf7b60030, 0xf7b40028, | ||
184 | #endif | ||
185 | /* sw {gp,s0-s8}, offset(sp) */ | ||
186 | 0xafbe0024, 0xafb70020, 0xafb6001c, 0xafb50018, 0xafb40014, 0xafb30010, | ||
187 | 0xafb2000c, 0xafb10008, 0xafb00004, 0xafbc0000, | ||
188 | /* sw sp, 4(a0); sw ra, 0(a0); lw ra, 0(a1); lw sp, 4(a1); move t9, ra */ | ||
189 | 0xac9d0004, 0xac9f0000, 0x8cbf0000, 0x8cbd0004, 0x03e0c821, | ||
190 | /* lw caller-saved-reg, offset(sp) */ | ||
191 | 0x8fbe0024, 0x8fb70020, 0x8fb6001c, 0x8fb50018, 0x8fb40014, 0x8fb30010, | ||
192 | 0x8fb2000c, 0x8fb10008, 0x8fb00004, 0x8fbc0000, | ||
193 | #ifdef __mips_soft_float | ||
194 | 0x03e00008, 0x27bd0028 /* jr ra; addiu sp, sp, 10*4 */ | ||
195 | #else | ||
196 | /* ldc1 {$f20-$f30}, offset(sp) */ | ||
197 | 0xd7be0050, 0xd7bc0048, 0xd7ba0040, 0xd7b80038, 0xd7b60030, 0xd7b40028, | ||
198 | 0x03e00008, 0x27bd0058 /* jr ra; addiu sp, sp, 10*4+6*8 */ | ||
199 | #endif | ||
200 | }; | ||
201 | |||
202 | typedef void *coco_ctx[2]; /* ra, sp */ | ||
203 | #define COCO_CTX coco_ctx | ||
204 | #define COCO_SWITCH(from, to) \ | ||
205 | ((void (*)(coco_ctx, coco_ctx))coco_switch)(from, to); | ||
206 | #define COCO_MAKECTX(coco, buf, func, stack, a0) \ | ||
207 | buf[0] = (void *)(func); \ | ||
208 | buf[1] = (void *)&stack[COCO_STACKSAVE]; \ | ||
209 | stack[4] = (size_t)(a0); /* Assumes o32 ABI. */ | ||
210 | #define COCO_STACKADJUST 8 | ||
211 | #define COCO_MAIN_PARAM int _a, int _b, int _c, int _d, lua_State *L | ||
212 | |||
213 | #elif defined(__sparc__) | ||
214 | |||
215 | typedef void *coco_ctx[4]; | ||
216 | #define COCO_CTX coco_ctx | ||
217 | #define COCO_SWITCH(from, to) coco_switch(from, to); | ||
218 | #define COCO_STACKADJUST 24 | ||
219 | |||
220 | #if defined(__LP64__) | ||
221 | #define COCO_STACKBIAS (2047UL) | ||
222 | #define COCO_PTR2SP(stack) (((unsigned long)stack)-COCO_STACKBIAS) | ||
223 | static inline void coco_switch(coco_ctx from, coco_ctx to) | ||
224 | { | ||
225 | void *__stack[16] __attribute__((aligned (16))); | ||
226 | unsigned long __tmp_sp = COCO_PTR2SP(__stack); | ||
227 | __asm__ __volatile__ | ||
228 | (/* Flush register window(s) to stack and save the previous stack | ||
229 | pointer to capture the current registers, %l0-%l7 and %i0-%i7. */ | ||
230 | "ta 3\n\t" | ||
231 | "stx %%sp,[%0+8]\n\t" | ||
232 | /* Move to a temporary stack. If the register window is flushed | ||
233 | for some reason (e.g. context switch), not the next stack | ||
234 | but the temporary stack should be used so as not to break | ||
235 | neither the previous nor next stack */ | ||
236 | "mov %2,%%sp\n\t" | ||
237 | "sethi %%hh(1f),%%g1\n\t" /* i.e. setx 1f,%%g1 */ | ||
238 | "or %%g1,%%hm(1f),%%g1\n\t" | ||
239 | "sethi %%lm(1f),%%g2\n\t" | ||
240 | "or %%g2,%%lo(1f),%%g2\n\t" | ||
241 | "sllx %%g1,32,%%g1\n\t" | ||
242 | "or %%g1,%%g2,%%g1\n\t" | ||
243 | "stx %%g1,[%0]\n\t" | ||
244 | /* Restore registers from stack. DO NOT load the next stack | ||
245 | pointer directly to %sp. The register window can be possibly | ||
246 | flushed and restored asynchronous (e.g. context switch). */ | ||
247 | "mov %1,%%o1\n\t" | ||
248 | "ldx [%%o1+8],%%o2\n\t" | ||
249 | "ldx [%%o2+%3],%%l0\n\t" | ||
250 | "ldx [%%o2+%3+8],%%l1\n\t" | ||
251 | "ldx [%%o2+%3+0x10],%%l2\n\t" | ||
252 | "ldx [%%o2+%3+0x18],%%l3\n\t" | ||
253 | "ldx [%%o2+%3+0x20],%%l4\n\t" | ||
254 | "ldx [%%o2+%3+0x28],%%l5\n\t" | ||
255 | "ldx [%%o2+%3+0x30],%%l6\n\t" | ||
256 | "ldx [%%o2+%3+0x38],%%l7\n\t" | ||
257 | "ldx [%%o2+%3+0x40],%%i0\n\t" | ||
258 | "ldx [%%o2+%3+0x48],%%i1\n\t" | ||
259 | "ldx [%%o2+%3+0x50],%%i2\n\t" | ||
260 | "ldx [%%o2+%3+0x58],%%i3\n\t" | ||
261 | "ldx [%%o2+%3+0x60],%%i4\n\t" | ||
262 | "ldx [%%o2+%3+0x68],%%i5\n\t" | ||
263 | "ldx [%%o2+%3+0x70],%%i6\n\t" | ||
264 | "ldx [%%o2+%3+0x78],%%i7\n\t" | ||
265 | /* Move to the next stack with the consistent registers atomically */ | ||
266 | "mov %%o2,%%sp\n\t" | ||
267 | "ldx [%%o1],%%o2\n\t" | ||
268 | /* Since %o0-%o7 are marked as clobbered, values are safely overwritten | ||
269 | across the inline assembly. %o0-%o7 will have meaningless values | ||
270 | after leaving the inline assembly. The only exception is %o0, which | ||
271 | serves as an argument to coco_main */ | ||
272 | "ldx [%%o1+16],%%o0\n\t" | ||
273 | "jmpl %%o2,%%g0\n\t" | ||
274 | "nop\n\t" | ||
275 | "1:\n" | ||
276 | /* An assumption is made here; no input operand is assigned to %g1 | ||
277 | nor %g2. It's the case for the currently avilable gcc's */ | ||
278 | : : "r"(from),"r"(to),"r"(__tmp_sp),"i"(COCO_STACKBIAS) | ||
279 | : "g1","g2","o0","o1","o2","o3","o4","o5","o7","memory","cc"); | ||
280 | } | ||
281 | |||
282 | #define COCO_MAKECTX(coco, buf, func, stack, a0) \ | ||
283 | buf[0] = (void *)(func); \ | ||
284 | buf[1] = (void *)COCO_PTR2SP(&(stack)[0]); \ | ||
285 | buf[2] = (void *)(a0); \ | ||
286 | stack[0] = 0; \ | ||
287 | stack[1] = 0; \ | ||
288 | stack[2] = 0; \ | ||
289 | stack[3] = 0; \ | ||
290 | stack[4] = 0; \ | ||
291 | stack[5] = 0; \ | ||
292 | stack[6] = 0; \ | ||
293 | stack[7] = 0; \ | ||
294 | stack[8] = 0; \ | ||
295 | stack[9] = 0; \ | ||
296 | stack[10] = 0; \ | ||
297 | stack[11] = 0; \ | ||
298 | stack[12] = 0; \ | ||
299 | stack[13] = 0; \ | ||
300 | stack[14] = COCO_PTR2SP(&(stack)[COCO_STACKADJUST]); \ | ||
301 | stack[15] = 0xdeadc0c0deadc0c0; /* Dummy return address. */ \ | ||
302 | |||
303 | #else | ||
304 | static inline void coco_switch(coco_ctx from, coco_ctx to) | ||
305 | { | ||
306 | void *__tmp_stack[16] __attribute__((aligned (16))); | ||
307 | __asm__ __volatile__ | ||
308 | ("ta 3\n\t" | ||
309 | "st %%sp,[%0+4]\n\t" | ||
310 | "mov %2,%%sp\n\t" | ||
311 | "set 1f,%%g1\n\t" | ||
312 | "st %%g1,[%0]\n\t" | ||
313 | "mov %1,%%o1\n\t" | ||
314 | "ld [%%o1+4],%%o2\n\t" | ||
315 | "ldd [%%o2],%%l0\n\t" | ||
316 | "ldd [%%o2+8],%%l2\n\t" | ||
317 | "ldd [%%o2+0x10],%%l4\n\t" | ||
318 | "ldd [%%o2+0x18],%%l6\n\t" | ||
319 | "ldd [%%o2+0x20],%%i0\n\t" | ||
320 | "ldd [%%o2+0x28],%%i2\n\t" | ||
321 | "ldd [%%o2+0x30],%%i4\n\t" | ||
322 | "ldd [%%o2+0x38],%%i6\n\t" | ||
323 | "mov %%o2,%%sp\n\t" | ||
324 | "ld [%%o1],%%o2\n\t" | ||
325 | "ld [%%o1+8],%%o0\n\t" | ||
326 | "jmpl %%o2,%%g0\n\t" | ||
327 | "nop\n\t" | ||
328 | "1:\n" | ||
329 | : : "r"(from),"r"(to),"r"(__tmp_stack) | ||
330 | : "g1","o0","o1","o2","o3","o4","o5","o7","memory","cc"); | ||
331 | } | ||
332 | |||
333 | #define COCO_MAKECTX(coco, buf, func, stack, a0) \ | ||
334 | buf[0] = (void *)(func); \ | ||
335 | buf[1] = (void *)(stack); \ | ||
336 | buf[2] = (void *)(a0); \ | ||
337 | stack[0] = 0; \ | ||
338 | stack[1] = 0; \ | ||
339 | stack[2] = 0; \ | ||
340 | stack[3] = 0; \ | ||
341 | stack[4] = 0; \ | ||
342 | stack[5] = 0; \ | ||
343 | stack[6] = 0; \ | ||
344 | stack[7] = 0; \ | ||
345 | stack[8] = 0; \ | ||
346 | stack[9] = 0; \ | ||
347 | stack[10] = 0; \ | ||
348 | stack[11] = 0; \ | ||
349 | stack[12] = 0; \ | ||
350 | stack[13] = 0; \ | ||
351 | stack[14] = (size_t)&stack[COCO_STACKADJUST]; \ | ||
352 | stack[15] = 0xdeadc0c0; /* Dummy return address. */ \ | ||
353 | |||
354 | #endif /* !define(__LP64__) */ | ||
355 | |||
356 | #endif /* arch check */ | ||
357 | |||
358 | #endif /* !(__GNUC__ >= 3 && !defined(COCO_USE_SETJMP)) */ | ||
359 | |||
360 | /* Try _setjmp/_longjmp with a patched jump buffer. */ | ||
361 | #ifndef COCO_MAKECTX | ||
362 | #include <setjmp.h> | ||
363 | |||
364 | /* Check for supported CPU+OS combinations. */ | ||
365 | #if defined(__i386) || defined(__i386__) | ||
366 | |||
367 | #define COCO_STATE_HEAD size_t arg0; | ||
368 | #define COCO_SETJMP_X86(coco, stack, a0) \ | ||
369 | stack[COCO_STACKADJUST-1] = 0xdeadc0c0; /* Dummy return address. */ \ | ||
370 | coco->arg0 = (size_t)(a0); | ||
371 | |||
372 | #if __GLIBC__ == 2 && defined(JB_SP) /* x86-linux-glibc2 */ | ||
373 | #define COCO_PATCHCTX(coco, buf, func, stack, a0) \ | ||
374 | buf->__jmpbuf[JB_PC] = (int)(func); \ | ||
375 | buf->__jmpbuf[JB_SP] = (int)(stack); \ | ||
376 | buf->__jmpbuf[JB_BP] = 0; \ | ||
377 | COCO_SETJMP_X86(coco, stack, a0) | ||
378 | #elif defined(__linux__) && defined(_I386_JMP_BUF_H) /* x86-linux-libc5 */ | ||
379 | #define COCO_PATCHCTX(coco, buf, func, stack, a0) \ | ||
380 | buf->__pc = (func); \ | ||
381 | buf->__sp = (stack); \ | ||
382 | buf->__bp = NULL; \ | ||
383 | COCO_SETJMP_X86(coco, stack, a0) | ||
384 | #elif defined(__FreeBSD__) /* x86-FreeBSD */ | ||
385 | #define COCO_PATCHCTX(coco, buf, func, stack, a0) \ | ||
386 | buf->_jb[0] = (long)(func); \ | ||
387 | buf->_jb[2] = (long)(stack); \ | ||
388 | buf->_jb[3] = 0; /* ebp */ \ | ||
389 | COCO_SETJMP_X86(coco, stack, a0) | ||
390 | #define COCO_STACKADJUST 2 | ||
391 | #elif defined(__NetBSD__) || defined(__OpenBSD__) /* x86-NetBSD, x86-OpenBSD */ | ||
392 | #define COCO_PATCHCTX(coco, buf, func, stack, a0) \ | ||
393 | buf[0] = (long)(func); \ | ||
394 | buf[2] = (long)(stack); \ | ||
395 | buf[3] = 0; /* ebp */ \ | ||
396 | COCO_SETJMP_X86(coco, stack, a0) | ||
397 | #define COCO_STACKADJUST 2 | ||
398 | #elif defined(__solaris__) && _JBLEN == 10 /* x86-solaris */ | ||
399 | #define COCO_PATCHCTX(coco, buf, func, stack, a0) \ | ||
400 | buf[5] = (int)(func); \ | ||
401 | buf[4] = (int)(stack); \ | ||
402 | buf[3] = 0; \ | ||
403 | COCO_SETJMP_X86(coco, stack, a0) | ||
404 | #elif defined(__MACH__) && defined(_BSD_I386_SETJMP_H) /* x86-macosx */ | ||
405 | #define COCO_PATCHCTX(coco, buf, func, stack, a0) \ | ||
406 | buf[12] = (int)(func); \ | ||
407 | buf[9] = (int)(stack); \ | ||
408 | buf[8] = 0; /* ebp */ \ | ||
409 | COCO_SETJMP_X86(coco, stack, a0) | ||
410 | #endif | ||
411 | |||
412 | #elif defined(__x86_64__) || defined(__x86_64) | ||
413 | |||
414 | #define COCO_STATE_HEAD size_t arg0; | ||
415 | |||
416 | #define COCO_MAIN_PARAM \ | ||
417 | int _a, int _b, int _c, int _d, int _e, int _f, lua_State *L | ||
418 | |||
419 | #if defined(__solaris__) && _JBLEN == 8 /* x64-solaris */ | ||
420 | #define COCO_PATCHCTX(coco, buf, func, stack, a0) \ | ||
421 | buf[7] = (long)(func); \ | ||
422 | buf[6] = (long)(stack); \ | ||
423 | buf[5] = 0; \ | ||
424 | stack[0] = 0xdeadc0c0; /* Dummy return address. */ \ | ||
425 | coco->arg0 = (size_t)(a0); | ||
426 | #endif | ||
427 | |||
428 | #elif defined(PPC) || defined(__ppc__) || defined(__PPC__) || \ | ||
429 | defined(__powerpc__) || defined(__POWERPC__) || defined(_ARCH_PPC) | ||
430 | |||
431 | #define COCO_STACKADJUST 16 | ||
432 | #define COCO_MAIN_PARAM \ | ||
433 | int _a, int _b, int _c, int _d, int _e, int _f, int _g, int _h, lua_State *L | ||
434 | |||
435 | #if defined(__MACH__) && defined(_BSD_PPC_SETJMP_H_) /* ppc32-macosx */ | ||
436 | #define COCO_PATCHCTX(coco, buf, func, stack, a0) \ | ||
437 | buf[21] = (int)(func); \ | ||
438 | buf[0] = (int)(stack); \ | ||
439 | stack[6+8] = (size_t)(a0); | ||
440 | #endif | ||
441 | |||
442 | #elif (defined(MIPS) || defined(MIPSEL) || defined(__mips)) && \ | ||
443 | _MIPS_SIM == _MIPS_SIM_ABI32 && !defined(__mips_eabi) | ||
444 | |||
445 | /* Stack layout for o32 ABI. */ | ||
446 | #define COCO_STACKADJUST 8 | ||
447 | #define COCO_MAIN_PARAM int _a, int _b, int _c, int _d, lua_State *L | ||
448 | |||
449 | #if __GLIBC__ == 2 || defined(__UCLIBC__) /* mips32-linux-glibc2 */ | ||
450 | #define COCO_PATCHCTX(coco, buf, func, stack, a0) \ | ||
451 | buf->__jmpbuf->__pc = (func); /* = t9 in _longjmp. Reqd. for -mabicalls. */ \ | ||
452 | buf->__jmpbuf->__sp = (stack); \ | ||
453 | buf->__jmpbuf->__fp = (void *)0; \ | ||
454 | stack[4] = (size_t)(a0); | ||
455 | #endif | ||
456 | |||
457 | #elif defined(__arm__) || defined(__ARM__) | ||
458 | |||
459 | #if __GLIBC__ == 2 || defined(__UCLIBC__) /* arm-linux-glibc2 */ | ||
460 | #ifndef __JMP_BUF_SP | ||
461 | #define __JMP_BUF_SP ((sizeof(__jmp_buf)/sizeof(int))-2) | ||
462 | #endif | ||
463 | #define COCO_PATCHCTX(coco, buf, func, stack, a0) \ | ||
464 | buf->__jmpbuf[__JMP_BUF_SP+1] = (int)(func); /* pc */ \ | ||
465 | buf->__jmpbuf[__JMP_BUF_SP] = (int)(stack); /* sp */ \ | ||
466 | buf->__jmpbuf[__JMP_BUF_SP-1] = 0; /* fp */ \ | ||
467 | stack[0] = (size_t)(a0); | ||
468 | #define COCO_STACKADJUST 2 | ||
469 | #define COCO_MAIN_PARAM int _a, int _b, int _c, int _d, lua_State *L | ||
470 | #endif | ||
471 | |||
472 | #endif /* arch check */ | ||
473 | |||
474 | #ifdef COCO_PATCHCTX | ||
475 | #define COCO_CTX jmp_buf | ||
476 | #define COCO_MAKECTX(coco, buf, func, stack, a0) \ | ||
477 | _setjmp(buf); COCO_PATCHCTX(coco, buf, func, stack, a0) | ||
478 | #define COCO_SWITCH(from, to) if (!_setjmp(from)) _longjmp(to, 1); | ||
479 | #endif | ||
480 | |||
481 | #endif /* !defined(COCO_MAKECTX) */ | ||
482 | |||
483 | #endif /* !defined(COCO_USE_UCONTEXT) */ | ||
484 | |||
485 | /* ------------------------------------------------------------------------ */ | ||
486 | |||
487 | /* Use inline asm or _setjmp/_longjmp if available. */ | ||
488 | #ifdef COCO_MAKECTX | ||
489 | |||
490 | #ifndef COCO_STACKADJUST | ||
491 | #define COCO_STACKADJUST 1 | ||
492 | #endif | ||
493 | |||
494 | #define COCO_FILL(coco, NL, mainfunc) \ | ||
495 | { /* Include the return address to get proper stack alignment. */ \ | ||
496 | size_t *stackptr = &((size_t *)coco)[-COCO_STACKADJUST]; \ | ||
497 | COCO_MAKECTX(coco, coco->ctx, mainfunc, stackptr, NL) \ | ||
498 | } | ||
499 | |||
500 | /* ------------------------------------------------------------------------ */ | ||
501 | |||
502 | /* Else fallback to ucontext. Slower, because it saves/restores signals. */ | ||
503 | #else /* !defined(COCO_MAKECTX) */ | ||
504 | |||
505 | #include <ucontext.h> | ||
506 | |||
507 | #define COCO_CTX ucontext_t | ||
508 | |||
509 | /* Ugly workaround for makecontext() deficiencies on 64 bit CPUs. */ | ||
510 | /* Note that WIN64 (which is LLP64) never comes here. See above. */ | ||
511 | #if defined(__LP64__) || defined(_LP64) || INT_MAX != LONG_MAX | ||
512 | /* 64 bit CPU: split the pointer into two 32 bit ints. */ | ||
513 | #define COCO_MAIN_PARAM unsigned int lo, unsigned int hi | ||
514 | #define COCO_MAIN_GETL \ | ||
515 | lua_State *L = (lua_State *)((((unsigned long)hi)<<32)+(unsigned long)lo); | ||
516 | #define COCO_MAKECTX(coco, NL, mainfunc) \ | ||
517 | makecontext(&coco->ctx, mainfunc, 2, \ | ||
518 | (int)(ptrdiff_t)NL, (int)((ptrdiff_t)NL>>32)); | ||
519 | #else | ||
520 | /* 32 bit CPU: a pointer fits into an int. */ | ||
521 | #define COCO_MAKECTX(coco, NL, mainfunc) \ | ||
522 | makecontext(&coco->ctx, mainfunc, 1, (int)NL); | ||
523 | #endif | ||
524 | |||
525 | #define COCO_FILL(coco, NL, mainfunc) \ | ||
526 | getcontext(&coco->ctx); \ | ||
527 | coco->ctx.uc_link = NULL; /* We never exit from coco_main. */ \ | ||
528 | coco->ctx.uc_stack.ss_sp = coco->allocptr; \ | ||
529 | coco->ctx.uc_stack.ss_size = (char *)coco - (char *)(coco->allocptr); \ | ||
530 | COCO_MAKECTX(coco, NL, mainfunc) | ||
531 | |||
532 | #define COCO_SWITCH(from, to) swapcontext(&(from), &(to)); | ||
533 | |||
534 | #endif /* !defined(COCO_MAKECTX) */ | ||
535 | |||
536 | |||
537 | /* Common code for inline asm/setjmp/ucontext to allocate/free the stack. */ | ||
538 | |||
539 | struct coco_State { | ||
540 | #ifdef COCO_STATE_HEAD | ||
541 | COCO_STATE_HEAD | ||
542 | #endif | ||
543 | COCO_CTX ctx; /* Own context. */ | ||
544 | COCO_CTX back; /* Context to switch back to. */ | ||
545 | void *allocptr; /* Pointer to allocated memory. */ | ||
546 | int allocsize; /* Size of allocated memory. */ | ||
547 | int nargs; /* Number of arguments to pass. */ | ||
548 | STACK_VGID /* Optional valgrind stack id. See above. */ | ||
549 | }; | ||
550 | |||
551 | typedef void (*coco_MainFunc)(void); | ||
552 | |||
553 | /* Put the Coco state at the end and align it downwards. */ | ||
554 | #define ALIGNED_END(p, s, t) \ | ||
555 | ((t *)(((char *)0) + ((((char *)(p)-(char *)0)+(s)-sizeof(t)) & -16))) | ||
556 | |||
557 | /* TODO: use mmap. */ | ||
558 | #define COCO_NEW(OL, NL, cstacksize, mainfunc) \ | ||
559 | { \ | ||
560 | void *ptr = luaM_malloc(OL, cstacksize); \ | ||
561 | coco_State *coco = ALIGNED_END(ptr, cstacksize, coco_State); \ | ||
562 | STACK_REG(coco, ptr, cstacksize) \ | ||
563 | coco->allocptr = ptr; \ | ||
564 | coco->allocsize = cstacksize; \ | ||
565 | COCO_FILL(coco, NL, mainfunc) \ | ||
566 | L2COCO(NL) = coco; \ | ||
567 | } | ||
568 | |||
569 | #define COCO_FREE(L) \ | ||
570 | STACK_DEREG(L2COCO(L)) \ | ||
571 | luaM_freemem(L, L2COCO(L)->allocptr, L2COCO(L)->allocsize); \ | ||
572 | L2COCO(L) = NULL; | ||
573 | |||
574 | #define COCO_JUMPIN(coco) COCO_SWITCH(coco->back, coco->ctx) | ||
575 | #define COCO_JUMPOUT(coco) COCO_SWITCH(coco->ctx, coco->back) | ||
576 | |||
577 | #endif /* !COCO_USE_FIBERS */ | ||
578 | |||
579 | /* ------------------------------------------------------------------------ */ | ||
580 | |||
581 | #ifndef COCO_MIN_CSTACKSIZE | ||
582 | #define COCO_MIN_CSTACKSIZE (32768+4096) | ||
583 | #endif | ||
584 | |||
585 | /* Don't use multiples of 64K to avoid D-cache aliasing conflicts. */ | ||
586 | #ifndef COCO_DEFAULT_CSTACKSIZE | ||
587 | #define COCO_DEFAULT_CSTACKSIZE (65536-4096) | ||
588 | #endif | ||
589 | |||
590 | static int defaultcstacksize = COCO_DEFAULT_CSTACKSIZE; | ||
591 | |||
592 | /* Start the Lua or C function. */ | ||
593 | static void coco_start(lua_State *L, void *ud) | ||
594 | { | ||
595 | if (luaD_precall(L, (StkId)ud, LUA_MULTRET) == PCRLUA) | ||
596 | luaV_execute(L, L->ci - L->base_ci); | ||
597 | } | ||
598 | |||
599 | #ifndef COCO_MAIN_PARAM | ||
600 | #define COCO_MAIN_PARAM lua_State *L | ||
601 | #endif | ||
602 | |||
603 | #ifndef COCO_MAIN_DECL | ||
604 | #define COCO_MAIN_DECL | ||
605 | #endif | ||
606 | |||
607 | /* Toplevel function for the new coroutine stack. Never exits. */ | ||
608 | static void COCO_MAIN_DECL coco_main(COCO_MAIN_PARAM) | ||
609 | { | ||
610 | #ifdef COCO_MAIN_GETL | ||
611 | COCO_MAIN_GETL | ||
612 | #endif | ||
613 | coco_State *coco = L2COCO(L); | ||
614 | for (;;) { | ||
615 | L->status = luaD_rawrunprotected(L, coco_start, L->top - (coco->nargs+1)); | ||
616 | if (L->status != 0) luaD_seterrorobj(L, L->status, L->top); | ||
617 | COCO_JUMPOUT(coco) | ||
618 | } | ||
619 | } | ||
620 | |||
621 | /* Add a C stack to a coroutine. */ | ||
622 | lua_State *lua_newcthread(lua_State *OL, int cstacksize) | ||
623 | { | ||
624 | lua_State *NL = lua_newthread(OL); | ||
625 | |||
626 | if (cstacksize < 0) | ||
627 | return NL; | ||
628 | if (cstacksize == 0) | ||
629 | cstacksize = defaultcstacksize; | ||
630 | else if (cstacksize < COCO_MIN_CSTACKSIZE) | ||
631 | cstacksize = COCO_MIN_CSTACKSIZE; | ||
632 | cstacksize &= -16; | ||
633 | |||
634 | COCO_NEW(OL, NL, cstacksize, ((coco_MainFunc)(coco_main))) | ||
635 | |||
636 | return NL; | ||
637 | } | ||
638 | |||
639 | /* Free the C stack of a coroutine. Called from lstate.c. */ | ||
640 | void luaCOCO_free(lua_State *L) | ||
641 | { | ||
642 | COCO_FREE(L) | ||
643 | } | ||
644 | |||
645 | /* Resume a coroutine with a C stack. Called from ldo.c. */ | ||
646 | int luaCOCO_resume(lua_State *L, int nargs) | ||
647 | { | ||
648 | coco_State *coco = L2COCO(L); | ||
649 | coco->nargs = nargs; | ||
650 | COCO_JUMPIN(coco) | ||
651 | #ifndef COCO_DISABLE_EARLY_FREE | ||
652 | if (L->status != LUA_YIELD) { | ||
653 | COCO_FREE(L) | ||
654 | } | ||
655 | #endif | ||
656 | return L->status; | ||
657 | } | ||
658 | |||
659 | /* Yield from a coroutine with a C stack. Called from ldo.c. */ | ||
660 | int luaCOCO_yield(lua_State *L) | ||
661 | { | ||
662 | coco_State *coco = L2COCO(L); | ||
663 | L->status = LUA_YIELD; | ||
664 | COCO_JUMPOUT(coco) | ||
665 | L->status = 0; | ||
666 | { | ||
667 | StkId base = L->top - coco->nargs; | ||
668 | StkId rbase = L->base; | ||
669 | if (rbase < base) { /* Need to move args down? */ | ||
670 | while (base < L->top) | ||
671 | setobjs2s(L, rbase++, base++); | ||
672 | L->top = rbase; | ||
673 | } | ||
674 | } | ||
675 | L->base = L->ci->base; /* Restore invariant. */ | ||
676 | return coco->nargs; | ||
677 | } | ||
678 | |||
679 | /* Get/set the default C stack size. */ | ||
680 | int luaCOCO_cstacksize(int cstacksize) | ||
681 | { | ||
682 | int oldsz = defaultcstacksize; | ||
683 | if (cstacksize >= 0) { | ||
684 | if (cstacksize == 0) | ||
685 | cstacksize = COCO_DEFAULT_CSTACKSIZE; | ||
686 | else if (cstacksize < COCO_MIN_CSTACKSIZE) | ||
687 | cstacksize = COCO_MIN_CSTACKSIZE; | ||
688 | defaultcstacksize = cstacksize; | ||
689 | } | ||
690 | return oldsz; | ||
691 | } | ||
692 | |||
693 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lcoco.h b/libraries/LuaJIT-1.1.7/src/lcoco.h new file mode 100644 index 0000000..9fb6207 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lcoco.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | ** Lua/Coco glue. | ||
3 | ** Copyright (C) 2004-2011 Mike Pall. See copyright notice in lcoco.c | ||
4 | */ | ||
5 | |||
6 | #ifndef lcoco_h | ||
7 | #define lcoco_h | ||
8 | |||
9 | #define LUACOCO_VERSION "Coco 1.1.6" | ||
10 | #define LUACOCO_VERSION_NUM 10106 | ||
11 | |||
12 | /* Exported C API to add a C stack to a coroutine. */ | ||
13 | LUA_API lua_State *lua_newcthread(lua_State *L, int cstacksize); | ||
14 | |||
15 | /* Internal support routines. */ | ||
16 | LUAI_FUNC void luaCOCO_free(lua_State *L); | ||
17 | LUAI_FUNC int luaCOCO_resume(lua_State *L, int nargs); | ||
18 | LUAI_FUNC int luaCOCO_yield(lua_State *L); | ||
19 | LUAI_FUNC int luaCOCO_cstacksize(int cstacksize); | ||
20 | |||
21 | /* Forward declaration. */ | ||
22 | typedef struct coco_State coco_State; | ||
23 | |||
24 | /* These are redefined below. */ | ||
25 | #undef LUAI_EXTRASPACE | ||
26 | #undef luai_userstateopen | ||
27 | /* luai_userstateclose unused */ | ||
28 | #undef luai_userstatethread | ||
29 | #undef luai_userstatefree | ||
30 | #undef luai_userstateresume | ||
31 | #undef luai_userstateyield | ||
32 | |||
33 | /* Use Windows Fibers (Win98+). */ | ||
34 | #if defined(_WIN32) | ||
35 | |||
36 | /* Fibers allocate their own stack. The whole Coco state is in front of L. */ | ||
37 | struct coco_State { | ||
38 | void *fib; /* Own fiber (if any). */ | ||
39 | void *back; /* Fiber to switch back to. */ | ||
40 | int nargs; /* Number of arguments to pass. */ | ||
41 | int dummy_align; | ||
42 | }; | ||
43 | |||
44 | #define L2COCO(L) (&((coco_State *)(L))[-1]) | ||
45 | #define LHASCOCO(L) (L2COCO(L)->fib) | ||
46 | #define LUAI_EXTRASPACE sizeof(coco_State) | ||
47 | #define luai_userstateopen(L) L2COCO(L)->fib = NULL | ||
48 | #define luai_userstatethread(L,L1) L2COCO(L1)->fib = NULL | ||
49 | #define COCO_USE_FIBERS | ||
50 | |||
51 | #else /* !defined(_WIN32) */ | ||
52 | |||
53 | /* The Coco state depends on the context switch method used. See lcoco.c. */ | ||
54 | /* It's stored at the end of the stack. Only need a pointer in front of L. */ | ||
55 | #define L2COCO(L) (((coco_State **)(L))[-1]) | ||
56 | #define LHASCOCO(L) (L2COCO(L)) | ||
57 | /* This wastes some space on 32 bit systems, but gets better alignment. */ | ||
58 | #define LUAI_EXTRASPACE sizeof(LUAI_USER_ALIGNMENT_T) | ||
59 | #define luai_userstateopen(L) L2COCO(L) = NULL | ||
60 | #define luai_userstatethread(L,L1) L2COCO(L1) = NULL | ||
61 | |||
62 | #endif /* !defined(_WIN32) */ | ||
63 | |||
64 | #define luai_userstatefree(L) if (LHASCOCO(L)) luaCOCO_free(L) | ||
65 | #define luai_userstateresume(L, nargs) \ | ||
66 | if (LHASCOCO(L)) return luaCOCO_resume(L, nargs) | ||
67 | #define luai_userstateyield(L, nresults) \ | ||
68 | do { if (LHASCOCO(L)) { \ | ||
69 | L->base = L->top - (nresults); /* Protect stack slots below. */ \ | ||
70 | return luaCOCO_yield(L); } } while (0) | ||
71 | |||
72 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lcode.c b/libraries/LuaJIT-1.1.7/src/lcode.c new file mode 100644 index 0000000..c13066e --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lcode.c | |||
@@ -0,0 +1,831 @@ | |||
1 | /* | ||
2 | ** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $ | ||
3 | ** Code generator for Lua | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <stdlib.h> | ||
9 | |||
10 | #define lcode_c | ||
11 | #define LUA_CORE | ||
12 | |||
13 | #include "lua.h" | ||
14 | |||
15 | #include "lcode.h" | ||
16 | #include "ldebug.h" | ||
17 | #include "ldo.h" | ||
18 | #include "lgc.h" | ||
19 | #include "llex.h" | ||
20 | #include "lmem.h" | ||
21 | #include "lobject.h" | ||
22 | #include "lopcodes.h" | ||
23 | #include "lparser.h" | ||
24 | #include "ltable.h" | ||
25 | |||
26 | |||
27 | #define hasjumps(e) ((e)->t != (e)->f) | ||
28 | |||
29 | |||
30 | static int isnumeral(expdesc *e) { | ||
31 | return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); | ||
32 | } | ||
33 | |||
34 | |||
35 | void luaK_nil (FuncState *fs, int from, int n) { | ||
36 | Instruction *previous; | ||
37 | if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ | ||
38 | if (fs->pc == 0) { /* function start? */ | ||
39 | if (from >= fs->nactvar) | ||
40 | return; /* positions are already clean */ | ||
41 | } | ||
42 | else { | ||
43 | previous = &fs->f->code[fs->pc-1]; | ||
44 | if (GET_OPCODE(*previous) == OP_LOADNIL) { | ||
45 | int pfrom = GETARG_A(*previous); | ||
46 | int pto = GETARG_B(*previous); | ||
47 | if (pfrom <= from && from <= pto+1) { /* can connect both? */ | ||
48 | if (from+n-1 > pto) | ||
49 | SETARG_B(*previous, from+n-1); | ||
50 | return; | ||
51 | } | ||
52 | } | ||
53 | } | ||
54 | } | ||
55 | luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ | ||
56 | } | ||
57 | |||
58 | |||
59 | int luaK_jump (FuncState *fs) { | ||
60 | int jpc = fs->jpc; /* save list of jumps to here */ | ||
61 | int j; | ||
62 | fs->jpc = NO_JUMP; | ||
63 | j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); | ||
64 | luaK_concat(fs, &j, jpc); /* keep them on hold */ | ||
65 | return j; | ||
66 | } | ||
67 | |||
68 | |||
69 | void luaK_ret (FuncState *fs, int first, int nret) { | ||
70 | luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); | ||
71 | } | ||
72 | |||
73 | |||
74 | static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { | ||
75 | luaK_codeABC(fs, op, A, B, C); | ||
76 | return luaK_jump(fs); | ||
77 | } | ||
78 | |||
79 | |||
80 | static void fixjump (FuncState *fs, int pc, int dest) { | ||
81 | Instruction *jmp = &fs->f->code[pc]; | ||
82 | int offset = dest-(pc+1); | ||
83 | lua_assert(dest != NO_JUMP); | ||
84 | if (abs(offset) > MAXARG_sBx) | ||
85 | luaX_syntaxerror(fs->ls, "control structure too long"); | ||
86 | SETARG_sBx(*jmp, offset); | ||
87 | } | ||
88 | |||
89 | |||
90 | /* | ||
91 | ** returns current `pc' and marks it as a jump target (to avoid wrong | ||
92 | ** optimizations with consecutive instructions not in the same basic block). | ||
93 | */ | ||
94 | int luaK_getlabel (FuncState *fs) { | ||
95 | fs->lasttarget = fs->pc; | ||
96 | return fs->pc; | ||
97 | } | ||
98 | |||
99 | |||
100 | static int getjump (FuncState *fs, int pc) { | ||
101 | int offset = GETARG_sBx(fs->f->code[pc]); | ||
102 | if (offset == NO_JUMP) /* point to itself represents end of list */ | ||
103 | return NO_JUMP; /* end of list */ | ||
104 | else | ||
105 | return (pc+1)+offset; /* turn offset into absolute position */ | ||
106 | } | ||
107 | |||
108 | |||
109 | static Instruction *getjumpcontrol (FuncState *fs, int pc) { | ||
110 | Instruction *pi = &fs->f->code[pc]; | ||
111 | if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) | ||
112 | return pi-1; | ||
113 | else | ||
114 | return pi; | ||
115 | } | ||
116 | |||
117 | |||
118 | /* | ||
119 | ** check whether list has any jump that do not produce a value | ||
120 | ** (or produce an inverted value) | ||
121 | */ | ||
122 | static int need_value (FuncState *fs, int list) { | ||
123 | for (; list != NO_JUMP; list = getjump(fs, list)) { | ||
124 | Instruction i = *getjumpcontrol(fs, list); | ||
125 | if (GET_OPCODE(i) != OP_TESTSET) return 1; | ||
126 | } | ||
127 | return 0; /* not found */ | ||
128 | } | ||
129 | |||
130 | |||
131 | static int patchtestreg (FuncState *fs, int node, int reg) { | ||
132 | Instruction *i = getjumpcontrol(fs, node); | ||
133 | if (GET_OPCODE(*i) != OP_TESTSET) | ||
134 | return 0; /* cannot patch other instructions */ | ||
135 | if (reg != NO_REG && reg != GETARG_B(*i)) | ||
136 | SETARG_A(*i, reg); | ||
137 | else /* no register to put value or register already has the value */ | ||
138 | *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); | ||
139 | |||
140 | return 1; | ||
141 | } | ||
142 | |||
143 | |||
144 | static void removevalues (FuncState *fs, int list) { | ||
145 | for (; list != NO_JUMP; list = getjump(fs, list)) | ||
146 | patchtestreg(fs, list, NO_REG); | ||
147 | } | ||
148 | |||
149 | |||
150 | static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, | ||
151 | int dtarget) { | ||
152 | while (list != NO_JUMP) { | ||
153 | int next = getjump(fs, list); | ||
154 | if (patchtestreg(fs, list, reg)) | ||
155 | fixjump(fs, list, vtarget); | ||
156 | else | ||
157 | fixjump(fs, list, dtarget); /* jump to default target */ | ||
158 | list = next; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | |||
163 | static void dischargejpc (FuncState *fs) { | ||
164 | patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); | ||
165 | fs->jpc = NO_JUMP; | ||
166 | } | ||
167 | |||
168 | |||
169 | void luaK_patchlist (FuncState *fs, int list, int target) { | ||
170 | if (target == fs->pc) | ||
171 | luaK_patchtohere(fs, list); | ||
172 | else { | ||
173 | lua_assert(target < fs->pc); | ||
174 | patchlistaux(fs, list, target, NO_REG, target); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | |||
179 | void luaK_patchtohere (FuncState *fs, int list) { | ||
180 | luaK_getlabel(fs); | ||
181 | luaK_concat(fs, &fs->jpc, list); | ||
182 | } | ||
183 | |||
184 | |||
185 | void luaK_concat (FuncState *fs, int *l1, int l2) { | ||
186 | if (l2 == NO_JUMP) return; | ||
187 | else if (*l1 == NO_JUMP) | ||
188 | *l1 = l2; | ||
189 | else { | ||
190 | int list = *l1; | ||
191 | int next; | ||
192 | while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ | ||
193 | list = next; | ||
194 | fixjump(fs, list, l2); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | |||
199 | void luaK_checkstack (FuncState *fs, int n) { | ||
200 | int newstack = fs->freereg + n; | ||
201 | if (newstack > fs->f->maxstacksize) { | ||
202 | if (newstack >= MAXSTACK) | ||
203 | luaX_syntaxerror(fs->ls, "function or expression too complex"); | ||
204 | fs->f->maxstacksize = cast_byte(newstack); | ||
205 | } | ||
206 | } | ||
207 | |||
208 | |||
209 | void luaK_reserveregs (FuncState *fs, int n) { | ||
210 | luaK_checkstack(fs, n); | ||
211 | fs->freereg += n; | ||
212 | } | ||
213 | |||
214 | |||
215 | static void freereg (FuncState *fs, int reg) { | ||
216 | if (!ISK(reg) && reg >= fs->nactvar) { | ||
217 | fs->freereg--; | ||
218 | lua_assert(reg == fs->freereg); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | |||
223 | static void freeexp (FuncState *fs, expdesc *e) { | ||
224 | if (e->k == VNONRELOC) | ||
225 | freereg(fs, e->u.s.info); | ||
226 | } | ||
227 | |||
228 | |||
229 | static int addk (FuncState *fs, TValue *k, TValue *v) { | ||
230 | lua_State *L = fs->L; | ||
231 | TValue *idx = luaH_set(L, fs->h, k); | ||
232 | Proto *f = fs->f; | ||
233 | int oldsize = f->sizek; | ||
234 | if (ttisnumber(idx)) { | ||
235 | lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); | ||
236 | return cast_int(nvalue(idx)); | ||
237 | } | ||
238 | else { /* constant not found; create a new entry */ | ||
239 | setnvalue(idx, cast_num(fs->nk)); | ||
240 | luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, | ||
241 | MAXARG_Bx, "constant table overflow"); | ||
242 | while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); | ||
243 | setobj(L, &f->k[fs->nk], v); | ||
244 | luaC_barrier(L, f, v); | ||
245 | return fs->nk++; | ||
246 | } | ||
247 | } | ||
248 | |||
249 | |||
250 | int luaK_stringK (FuncState *fs, TString *s) { | ||
251 | TValue o; | ||
252 | setsvalue(fs->L, &o, s); | ||
253 | return addk(fs, &o, &o); | ||
254 | } | ||
255 | |||
256 | |||
257 | int luaK_numberK (FuncState *fs, lua_Number r) { | ||
258 | TValue o; | ||
259 | setnvalue(&o, r); | ||
260 | return addk(fs, &o, &o); | ||
261 | } | ||
262 | |||
263 | |||
264 | static int boolK (FuncState *fs, int b) { | ||
265 | TValue o; | ||
266 | setbvalue(&o, b); | ||
267 | return addk(fs, &o, &o); | ||
268 | } | ||
269 | |||
270 | |||
271 | static int nilK (FuncState *fs) { | ||
272 | TValue k, v; | ||
273 | setnilvalue(&v); | ||
274 | /* cannot use nil as key; instead use table itself to represent nil */ | ||
275 | sethvalue(fs->L, &k, fs->h); | ||
276 | return addk(fs, &k, &v); | ||
277 | } | ||
278 | |||
279 | |||
280 | void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { | ||
281 | if (e->k == VCALL) { /* expression is an open function call? */ | ||
282 | SETARG_C(getcode(fs, e), nresults+1); | ||
283 | } | ||
284 | else if (e->k == VVARARG) { | ||
285 | SETARG_B(getcode(fs, e), nresults+1); | ||
286 | SETARG_A(getcode(fs, e), fs->freereg); | ||
287 | luaK_reserveregs(fs, 1); | ||
288 | } | ||
289 | } | ||
290 | |||
291 | |||
292 | void luaK_setoneret (FuncState *fs, expdesc *e) { | ||
293 | if (e->k == VCALL) { /* expression is an open function call? */ | ||
294 | e->k = VNONRELOC; | ||
295 | e->u.s.info = GETARG_A(getcode(fs, e)); | ||
296 | } | ||
297 | else if (e->k == VVARARG) { | ||
298 | SETARG_B(getcode(fs, e), 2); | ||
299 | e->k = VRELOCABLE; /* can relocate its simple result */ | ||
300 | } | ||
301 | } | ||
302 | |||
303 | |||
304 | void luaK_dischargevars (FuncState *fs, expdesc *e) { | ||
305 | switch (e->k) { | ||
306 | case VLOCAL: { | ||
307 | e->k = VNONRELOC; | ||
308 | break; | ||
309 | } | ||
310 | case VUPVAL: { | ||
311 | e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); | ||
312 | e->k = VRELOCABLE; | ||
313 | break; | ||
314 | } | ||
315 | case VGLOBAL: { | ||
316 | e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); | ||
317 | e->k = VRELOCABLE; | ||
318 | break; | ||
319 | } | ||
320 | case VINDEXED: { | ||
321 | freereg(fs, e->u.s.aux); | ||
322 | freereg(fs, e->u.s.info); | ||
323 | e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); | ||
324 | e->k = VRELOCABLE; | ||
325 | break; | ||
326 | } | ||
327 | case VVARARG: | ||
328 | case VCALL: { | ||
329 | luaK_setoneret(fs, e); | ||
330 | break; | ||
331 | } | ||
332 | default: break; /* there is one value available (somewhere) */ | ||
333 | } | ||
334 | } | ||
335 | |||
336 | |||
337 | static int code_label (FuncState *fs, int A, int b, int jump) { | ||
338 | luaK_getlabel(fs); /* those instructions may be jump targets */ | ||
339 | return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); | ||
340 | } | ||
341 | |||
342 | |||
343 | static void discharge2reg (FuncState *fs, expdesc *e, int reg) { | ||
344 | luaK_dischargevars(fs, e); | ||
345 | switch (e->k) { | ||
346 | case VNIL: { | ||
347 | luaK_nil(fs, reg, 1); | ||
348 | break; | ||
349 | } | ||
350 | case VFALSE: case VTRUE: { | ||
351 | luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); | ||
352 | break; | ||
353 | } | ||
354 | case VK: { | ||
355 | luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); | ||
356 | break; | ||
357 | } | ||
358 | case VKNUM: { | ||
359 | luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); | ||
360 | break; | ||
361 | } | ||
362 | case VRELOCABLE: { | ||
363 | Instruction *pc = &getcode(fs, e); | ||
364 | SETARG_A(*pc, reg); | ||
365 | break; | ||
366 | } | ||
367 | case VNONRELOC: { | ||
368 | if (reg != e->u.s.info) | ||
369 | luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); | ||
370 | break; | ||
371 | } | ||
372 | default: { | ||
373 | lua_assert(e->k == VVOID || e->k == VJMP); | ||
374 | return; /* nothing to do... */ | ||
375 | } | ||
376 | } | ||
377 | e->u.s.info = reg; | ||
378 | e->k = VNONRELOC; | ||
379 | } | ||
380 | |||
381 | |||
382 | static void discharge2anyreg (FuncState *fs, expdesc *e) { | ||
383 | if (e->k != VNONRELOC) { | ||
384 | luaK_reserveregs(fs, 1); | ||
385 | discharge2reg(fs, e, fs->freereg-1); | ||
386 | } | ||
387 | } | ||
388 | |||
389 | |||
390 | static void exp2reg (FuncState *fs, expdesc *e, int reg) { | ||
391 | discharge2reg(fs, e, reg); | ||
392 | if (e->k == VJMP) | ||
393 | luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ | ||
394 | if (hasjumps(e)) { | ||
395 | int final; /* position after whole expression */ | ||
396 | int p_f = NO_JUMP; /* position of an eventual LOAD false */ | ||
397 | int p_t = NO_JUMP; /* position of an eventual LOAD true */ | ||
398 | if (need_value(fs, e->t) || need_value(fs, e->f)) { | ||
399 | int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); | ||
400 | p_f = code_label(fs, reg, 0, 1); | ||
401 | p_t = code_label(fs, reg, 1, 0); | ||
402 | luaK_patchtohere(fs, fj); | ||
403 | } | ||
404 | final = luaK_getlabel(fs); | ||
405 | patchlistaux(fs, e->f, final, reg, p_f); | ||
406 | patchlistaux(fs, e->t, final, reg, p_t); | ||
407 | } | ||
408 | e->f = e->t = NO_JUMP; | ||
409 | e->u.s.info = reg; | ||
410 | e->k = VNONRELOC; | ||
411 | } | ||
412 | |||
413 | |||
414 | void luaK_exp2nextreg (FuncState *fs, expdesc *e) { | ||
415 | luaK_dischargevars(fs, e); | ||
416 | freeexp(fs, e); | ||
417 | luaK_reserveregs(fs, 1); | ||
418 | exp2reg(fs, e, fs->freereg - 1); | ||
419 | } | ||
420 | |||
421 | |||
422 | int luaK_exp2anyreg (FuncState *fs, expdesc *e) { | ||
423 | luaK_dischargevars(fs, e); | ||
424 | if (e->k == VNONRELOC) { | ||
425 | if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ | ||
426 | if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ | ||
427 | exp2reg(fs, e, e->u.s.info); /* put value on it */ | ||
428 | return e->u.s.info; | ||
429 | } | ||
430 | } | ||
431 | luaK_exp2nextreg(fs, e); /* default */ | ||
432 | return e->u.s.info; | ||
433 | } | ||
434 | |||
435 | |||
436 | void luaK_exp2val (FuncState *fs, expdesc *e) { | ||
437 | if (hasjumps(e)) | ||
438 | luaK_exp2anyreg(fs, e); | ||
439 | else | ||
440 | luaK_dischargevars(fs, e); | ||
441 | } | ||
442 | |||
443 | |||
444 | int luaK_exp2RK (FuncState *fs, expdesc *e) { | ||
445 | luaK_exp2val(fs, e); | ||
446 | switch (e->k) { | ||
447 | case VKNUM: | ||
448 | case VTRUE: | ||
449 | case VFALSE: | ||
450 | case VNIL: { | ||
451 | if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ | ||
452 | e->u.s.info = (e->k == VNIL) ? nilK(fs) : | ||
453 | (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) : | ||
454 | boolK(fs, (e->k == VTRUE)); | ||
455 | e->k = VK; | ||
456 | return RKASK(e->u.s.info); | ||
457 | } | ||
458 | else break; | ||
459 | } | ||
460 | case VK: { | ||
461 | if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */ | ||
462 | return RKASK(e->u.s.info); | ||
463 | else break; | ||
464 | } | ||
465 | default: break; | ||
466 | } | ||
467 | /* not a constant in the right range: put it in a register */ | ||
468 | return luaK_exp2anyreg(fs, e); | ||
469 | } | ||
470 | |||
471 | |||
472 | void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { | ||
473 | switch (var->k) { | ||
474 | case VLOCAL: { | ||
475 | freeexp(fs, ex); | ||
476 | exp2reg(fs, ex, var->u.s.info); | ||
477 | return; | ||
478 | } | ||
479 | case VUPVAL: { | ||
480 | int e = luaK_exp2anyreg(fs, ex); | ||
481 | luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); | ||
482 | break; | ||
483 | } | ||
484 | case VGLOBAL: { | ||
485 | int e = luaK_exp2anyreg(fs, ex); | ||
486 | luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info); | ||
487 | break; | ||
488 | } | ||
489 | case VINDEXED: { | ||
490 | int e = luaK_exp2RK(fs, ex); | ||
491 | luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); | ||
492 | break; | ||
493 | } | ||
494 | default: { | ||
495 | lua_assert(0); /* invalid var kind to store */ | ||
496 | break; | ||
497 | } | ||
498 | } | ||
499 | freeexp(fs, ex); | ||
500 | } | ||
501 | |||
502 | |||
503 | void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { | ||
504 | int func; | ||
505 | luaK_exp2anyreg(fs, e); | ||
506 | freeexp(fs, e); | ||
507 | func = fs->freereg; | ||
508 | luaK_reserveregs(fs, 2); | ||
509 | luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); | ||
510 | freeexp(fs, key); | ||
511 | e->u.s.info = func; | ||
512 | e->k = VNONRELOC; | ||
513 | } | ||
514 | |||
515 | |||
516 | static void invertjump (FuncState *fs, expdesc *e) { | ||
517 | Instruction *pc = getjumpcontrol(fs, e->u.s.info); | ||
518 | lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && | ||
519 | GET_OPCODE(*pc) != OP_TEST); | ||
520 | SETARG_A(*pc, !(GETARG_A(*pc))); | ||
521 | } | ||
522 | |||
523 | |||
524 | static int jumponcond (FuncState *fs, expdesc *e, int cond) { | ||
525 | if (e->k == VRELOCABLE) { | ||
526 | Instruction ie = getcode(fs, e); | ||
527 | if (GET_OPCODE(ie) == OP_NOT) { | ||
528 | fs->pc--; /* remove previous OP_NOT */ | ||
529 | return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); | ||
530 | } | ||
531 | /* else go through */ | ||
532 | } | ||
533 | discharge2anyreg(fs, e); | ||
534 | freeexp(fs, e); | ||
535 | return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); | ||
536 | } | ||
537 | |||
538 | |||
539 | void luaK_goiftrue (FuncState *fs, expdesc *e) { | ||
540 | int pc; /* pc of last jump */ | ||
541 | luaK_dischargevars(fs, e); | ||
542 | switch (e->k) { | ||
543 | case VK: case VKNUM: case VTRUE: { | ||
544 | pc = NO_JUMP; /* always true; do nothing */ | ||
545 | break; | ||
546 | } | ||
547 | case VJMP: { | ||
548 | invertjump(fs, e); | ||
549 | pc = e->u.s.info; | ||
550 | break; | ||
551 | } | ||
552 | default: { | ||
553 | pc = jumponcond(fs, e, 0); | ||
554 | break; | ||
555 | } | ||
556 | } | ||
557 | luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ | ||
558 | luaK_patchtohere(fs, e->t); | ||
559 | e->t = NO_JUMP; | ||
560 | } | ||
561 | |||
562 | |||
563 | static void luaK_goiffalse (FuncState *fs, expdesc *e) { | ||
564 | int pc; /* pc of last jump */ | ||
565 | luaK_dischargevars(fs, e); | ||
566 | switch (e->k) { | ||
567 | case VNIL: case VFALSE: { | ||
568 | pc = NO_JUMP; /* always false; do nothing */ | ||
569 | break; | ||
570 | } | ||
571 | case VJMP: { | ||
572 | pc = e->u.s.info; | ||
573 | break; | ||
574 | } | ||
575 | default: { | ||
576 | pc = jumponcond(fs, e, 1); | ||
577 | break; | ||
578 | } | ||
579 | } | ||
580 | luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ | ||
581 | luaK_patchtohere(fs, e->f); | ||
582 | e->f = NO_JUMP; | ||
583 | } | ||
584 | |||
585 | |||
586 | static void codenot (FuncState *fs, expdesc *e) { | ||
587 | luaK_dischargevars(fs, e); | ||
588 | switch (e->k) { | ||
589 | case VNIL: case VFALSE: { | ||
590 | e->k = VTRUE; | ||
591 | break; | ||
592 | } | ||
593 | case VK: case VKNUM: case VTRUE: { | ||
594 | e->k = VFALSE; | ||
595 | break; | ||
596 | } | ||
597 | case VJMP: { | ||
598 | invertjump(fs, e); | ||
599 | break; | ||
600 | } | ||
601 | case VRELOCABLE: | ||
602 | case VNONRELOC: { | ||
603 | discharge2anyreg(fs, e); | ||
604 | freeexp(fs, e); | ||
605 | e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); | ||
606 | e->k = VRELOCABLE; | ||
607 | break; | ||
608 | } | ||
609 | default: { | ||
610 | lua_assert(0); /* cannot happen */ | ||
611 | break; | ||
612 | } | ||
613 | } | ||
614 | /* interchange true and false lists */ | ||
615 | { int temp = e->f; e->f = e->t; e->t = temp; } | ||
616 | removevalues(fs, e->f); | ||
617 | removevalues(fs, e->t); | ||
618 | } | ||
619 | |||
620 | |||
621 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | ||
622 | t->u.s.aux = luaK_exp2RK(fs, k); | ||
623 | t->k = VINDEXED; | ||
624 | } | ||
625 | |||
626 | |||
627 | static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { | ||
628 | lua_Number v1, v2, r; | ||
629 | if (!isnumeral(e1) || !isnumeral(e2)) return 0; | ||
630 | v1 = e1->u.nval; | ||
631 | v2 = e2->u.nval; | ||
632 | switch (op) { | ||
633 | case OP_ADD: r = luai_numadd(v1, v2); break; | ||
634 | case OP_SUB: r = luai_numsub(v1, v2); break; | ||
635 | case OP_MUL: r = luai_nummul(v1, v2); break; | ||
636 | case OP_DIV: | ||
637 | if (v2 == 0) return 0; /* do not attempt to divide by 0 */ | ||
638 | r = luai_numdiv(v1, v2); break; | ||
639 | case OP_MOD: | ||
640 | if (v2 == 0) return 0; /* do not attempt to divide by 0 */ | ||
641 | r = luai_nummod(v1, v2); break; | ||
642 | case OP_POW: r = luai_numpow(v1, v2); break; | ||
643 | case OP_UNM: r = luai_numunm(v1); break; | ||
644 | case OP_LEN: return 0; /* no constant folding for 'len' */ | ||
645 | default: lua_assert(0); r = 0; break; | ||
646 | } | ||
647 | if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */ | ||
648 | e1->u.nval = r; | ||
649 | return 1; | ||
650 | } | ||
651 | |||
652 | |||
653 | static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { | ||
654 | if (constfolding(op, e1, e2)) | ||
655 | return; | ||
656 | else { | ||
657 | int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; | ||
658 | int o1 = luaK_exp2RK(fs, e1); | ||
659 | if (o1 > o2) { | ||
660 | freeexp(fs, e1); | ||
661 | freeexp(fs, e2); | ||
662 | } | ||
663 | else { | ||
664 | freeexp(fs, e2); | ||
665 | freeexp(fs, e1); | ||
666 | } | ||
667 | e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); | ||
668 | e1->k = VRELOCABLE; | ||
669 | } | ||
670 | } | ||
671 | |||
672 | |||
673 | static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, | ||
674 | expdesc *e2) { | ||
675 | int o1 = luaK_exp2RK(fs, e1); | ||
676 | int o2 = luaK_exp2RK(fs, e2); | ||
677 | freeexp(fs, e2); | ||
678 | freeexp(fs, e1); | ||
679 | if (cond == 0 && op != OP_EQ) { | ||
680 | int temp; /* exchange args to replace by `<' or `<=' */ | ||
681 | temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ | ||
682 | cond = 1; | ||
683 | } | ||
684 | e1->u.s.info = condjump(fs, op, cond, o1, o2); | ||
685 | e1->k = VJMP; | ||
686 | } | ||
687 | |||
688 | |||
689 | void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { | ||
690 | expdesc e2; | ||
691 | e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; | ||
692 | switch (op) { | ||
693 | case OPR_MINUS: { | ||
694 | if (!isnumeral(e)) | ||
695 | luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ | ||
696 | codearith(fs, OP_UNM, e, &e2); | ||
697 | break; | ||
698 | } | ||
699 | case OPR_NOT: codenot(fs, e); break; | ||
700 | case OPR_LEN: { | ||
701 | luaK_exp2anyreg(fs, e); /* cannot operate on constants */ | ||
702 | codearith(fs, OP_LEN, e, &e2); | ||
703 | break; | ||
704 | } | ||
705 | default: lua_assert(0); | ||
706 | } | ||
707 | } | ||
708 | |||
709 | |||
710 | void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | ||
711 | switch (op) { | ||
712 | case OPR_AND: { | ||
713 | luaK_goiftrue(fs, v); | ||
714 | break; | ||
715 | } | ||
716 | case OPR_OR: { | ||
717 | luaK_goiffalse(fs, v); | ||
718 | break; | ||
719 | } | ||
720 | case OPR_CONCAT: { | ||
721 | luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ | ||
722 | break; | ||
723 | } | ||
724 | case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: | ||
725 | case OPR_MOD: case OPR_POW: { | ||
726 | if (!isnumeral(v)) luaK_exp2RK(fs, v); | ||
727 | break; | ||
728 | } | ||
729 | default: { | ||
730 | luaK_exp2RK(fs, v); | ||
731 | break; | ||
732 | } | ||
733 | } | ||
734 | } | ||
735 | |||
736 | |||
737 | void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { | ||
738 | switch (op) { | ||
739 | case OPR_AND: { | ||
740 | lua_assert(e1->t == NO_JUMP); /* list must be closed */ | ||
741 | luaK_dischargevars(fs, e2); | ||
742 | luaK_concat(fs, &e2->f, e1->f); | ||
743 | *e1 = *e2; | ||
744 | break; | ||
745 | } | ||
746 | case OPR_OR: { | ||
747 | lua_assert(e1->f == NO_JUMP); /* list must be closed */ | ||
748 | luaK_dischargevars(fs, e2); | ||
749 | luaK_concat(fs, &e2->t, e1->t); | ||
750 | *e1 = *e2; | ||
751 | break; | ||
752 | } | ||
753 | case OPR_CONCAT: { | ||
754 | luaK_exp2val(fs, e2); | ||
755 | if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { | ||
756 | lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); | ||
757 | freeexp(fs, e1); | ||
758 | SETARG_B(getcode(fs, e2), e1->u.s.info); | ||
759 | e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info; | ||
760 | } | ||
761 | else { | ||
762 | luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ | ||
763 | codearith(fs, OP_CONCAT, e1, e2); | ||
764 | } | ||
765 | break; | ||
766 | } | ||
767 | case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break; | ||
768 | case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break; | ||
769 | case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break; | ||
770 | case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break; | ||
771 | case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break; | ||
772 | case OPR_POW: codearith(fs, OP_POW, e1, e2); break; | ||
773 | case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break; | ||
774 | case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break; | ||
775 | case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break; | ||
776 | case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break; | ||
777 | case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break; | ||
778 | case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break; | ||
779 | default: lua_assert(0); | ||
780 | } | ||
781 | } | ||
782 | |||
783 | |||
784 | void luaK_fixline (FuncState *fs, int line) { | ||
785 | fs->f->lineinfo[fs->pc - 1] = line; | ||
786 | } | ||
787 | |||
788 | |||
789 | static int luaK_code (FuncState *fs, Instruction i, int line) { | ||
790 | Proto *f = fs->f; | ||
791 | dischargejpc(fs); /* `pc' will change */ | ||
792 | /* put new instruction in code array */ | ||
793 | luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, | ||
794 | MAX_INT, "code size overflow"); | ||
795 | f->code[fs->pc] = i; | ||
796 | /* save corresponding line information */ | ||
797 | luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, | ||
798 | MAX_INT, "code size overflow"); | ||
799 | f->lineinfo[fs->pc] = line; | ||
800 | return fs->pc++; | ||
801 | } | ||
802 | |||
803 | |||
804 | int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { | ||
805 | lua_assert(getOpMode(o) == iABC); | ||
806 | lua_assert(getBMode(o) != OpArgN || b == 0); | ||
807 | lua_assert(getCMode(o) != OpArgN || c == 0); | ||
808 | return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); | ||
809 | } | ||
810 | |||
811 | |||
812 | int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { | ||
813 | lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); | ||
814 | lua_assert(getCMode(o) == OpArgN); | ||
815 | return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); | ||
816 | } | ||
817 | |||
818 | |||
819 | void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { | ||
820 | int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; | ||
821 | int b = (tostore == LUA_MULTRET) ? 0 : tostore; | ||
822 | lua_assert(tostore != 0); | ||
823 | if (c <= MAXARG_C) | ||
824 | luaK_codeABC(fs, OP_SETLIST, base, b, c); | ||
825 | else { | ||
826 | luaK_codeABC(fs, OP_SETLIST, base, b, 0); | ||
827 | luaK_code(fs, cast(Instruction, c), fs->ls->lastline); | ||
828 | } | ||
829 | fs->freereg = base + 1; /* free registers with list values */ | ||
830 | } | ||
831 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lcode.h b/libraries/LuaJIT-1.1.7/src/lcode.h new file mode 100644 index 0000000..b941c60 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lcode.h | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | ** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Code generator for Lua | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lcode_h | ||
8 | #define lcode_h | ||
9 | |||
10 | #include "llex.h" | ||
11 | #include "lobject.h" | ||
12 | #include "lopcodes.h" | ||
13 | #include "lparser.h" | ||
14 | |||
15 | |||
16 | /* | ||
17 | ** Marks the end of a patch list. It is an invalid value both as an absolute | ||
18 | ** address, and as a list link (would link an element to itself). | ||
19 | */ | ||
20 | #define NO_JUMP (-1) | ||
21 | |||
22 | |||
23 | /* | ||
24 | ** grep "ORDER OPR" if you change these enums | ||
25 | */ | ||
26 | typedef enum BinOpr { | ||
27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, | ||
28 | OPR_CONCAT, | ||
29 | OPR_NE, OPR_EQ, | ||
30 | OPR_LT, OPR_LE, OPR_GT, OPR_GE, | ||
31 | OPR_AND, OPR_OR, | ||
32 | OPR_NOBINOPR | ||
33 | } BinOpr; | ||
34 | |||
35 | |||
36 | typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; | ||
37 | |||
38 | |||
39 | #define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) | ||
40 | |||
41 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) | ||
42 | |||
43 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) | ||
44 | |||
45 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); | ||
46 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); | ||
47 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); | ||
48 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); | ||
49 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); | ||
50 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); | ||
51 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); | ||
52 | LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); | ||
53 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); | ||
54 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); | ||
55 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); | ||
56 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); | ||
57 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); | ||
58 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); | ||
59 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); | ||
60 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); | ||
61 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); | ||
62 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); | ||
63 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); | ||
64 | LUAI_FUNC int luaK_jump (FuncState *fs); | ||
65 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); | ||
66 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); | ||
67 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); | ||
68 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); | ||
69 | LUAI_FUNC int luaK_getlabel (FuncState *fs); | ||
70 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); | ||
71 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); | ||
72 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); | ||
73 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); | ||
74 | |||
75 | |||
76 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/ldblib.c b/libraries/LuaJIT-1.1.7/src/ldblib.c new file mode 100644 index 0000000..21116ac --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ldblib.c | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | ** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $ | ||
3 | ** Interface from Lua to its debug API | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <stdio.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <string.h> | ||
11 | |||
12 | #define ldblib_c | ||
13 | #define LUA_LIB | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "lauxlib.h" | ||
18 | #include "lualib.h" | ||
19 | |||
20 | |||
21 | |||
22 | static int db_getregistry (lua_State *L) { | ||
23 | lua_pushvalue(L, LUA_REGISTRYINDEX); | ||
24 | return 1; | ||
25 | } | ||
26 | |||
27 | |||
28 | static int db_getmetatable (lua_State *L) { | ||
29 | luaL_checkany(L, 1); | ||
30 | if (!lua_getmetatable(L, 1)) { | ||
31 | lua_pushnil(L); /* no metatable */ | ||
32 | } | ||
33 | return 1; | ||
34 | } | ||
35 | |||
36 | |||
37 | static int db_setmetatable (lua_State *L) { | ||
38 | int t = lua_type(L, 2); | ||
39 | luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, | ||
40 | "nil or table expected"); | ||
41 | lua_settop(L, 2); | ||
42 | lua_pushboolean(L, lua_setmetatable(L, 1)); | ||
43 | return 1; | ||
44 | } | ||
45 | |||
46 | |||
47 | static int db_getfenv (lua_State *L) { | ||
48 | luaL_checkany(L, 1); | ||
49 | lua_getfenv(L, 1); | ||
50 | return 1; | ||
51 | } | ||
52 | |||
53 | |||
54 | static int db_setfenv (lua_State *L) { | ||
55 | luaL_checktype(L, 2, LUA_TTABLE); | ||
56 | lua_settop(L, 2); | ||
57 | if (lua_setfenv(L, 1) == 0) | ||
58 | luaL_error(L, LUA_QL("setfenv") | ||
59 | " cannot change environment of given object"); | ||
60 | return 1; | ||
61 | } | ||
62 | |||
63 | |||
64 | static void settabss (lua_State *L, const char *i, const char *v) { | ||
65 | lua_pushstring(L, v); | ||
66 | lua_setfield(L, -2, i); | ||
67 | } | ||
68 | |||
69 | |||
70 | static void settabsi (lua_State *L, const char *i, int v) { | ||
71 | lua_pushinteger(L, v); | ||
72 | lua_setfield(L, -2, i); | ||
73 | } | ||
74 | |||
75 | |||
76 | static lua_State *getthread (lua_State *L, int *arg) { | ||
77 | if (lua_isthread(L, 1)) { | ||
78 | *arg = 1; | ||
79 | return lua_tothread(L, 1); | ||
80 | } | ||
81 | else { | ||
82 | *arg = 0; | ||
83 | return L; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | |||
88 | static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { | ||
89 | if (L == L1) { | ||
90 | lua_pushvalue(L, -2); | ||
91 | lua_remove(L, -3); | ||
92 | } | ||
93 | else | ||
94 | lua_xmove(L1, L, 1); | ||
95 | lua_setfield(L, -2, fname); | ||
96 | } | ||
97 | |||
98 | |||
99 | static int db_getinfo (lua_State *L) { | ||
100 | lua_Debug ar; | ||
101 | int arg; | ||
102 | lua_State *L1 = getthread(L, &arg); | ||
103 | const char *options = luaL_optstring(L, arg+2, "flnSu"); | ||
104 | if (lua_isnumber(L, arg+1)) { | ||
105 | if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { | ||
106 | lua_pushnil(L); /* level out of range */ | ||
107 | return 1; | ||
108 | } | ||
109 | } | ||
110 | else if (lua_isfunction(L, arg+1)) { | ||
111 | lua_pushfstring(L, ">%s", options); | ||
112 | options = lua_tostring(L, -1); | ||
113 | lua_pushvalue(L, arg+1); | ||
114 | lua_xmove(L, L1, 1); | ||
115 | } | ||
116 | else | ||
117 | return luaL_argerror(L, arg+1, "function or level expected"); | ||
118 | if (!lua_getinfo(L1, options, &ar)) | ||
119 | return luaL_argerror(L, arg+2, "invalid option"); | ||
120 | lua_createtable(L, 0, 2); | ||
121 | if (strchr(options, 'S')) { | ||
122 | settabss(L, "source", ar.source); | ||
123 | settabss(L, "short_src", ar.short_src); | ||
124 | settabsi(L, "linedefined", ar.linedefined); | ||
125 | settabsi(L, "lastlinedefined", ar.lastlinedefined); | ||
126 | settabss(L, "what", ar.what); | ||
127 | } | ||
128 | if (strchr(options, 'l')) | ||
129 | settabsi(L, "currentline", ar.currentline); | ||
130 | if (strchr(options, 'u')) | ||
131 | settabsi(L, "nups", ar.nups); | ||
132 | if (strchr(options, 'n')) { | ||
133 | settabss(L, "name", ar.name); | ||
134 | settabss(L, "namewhat", ar.namewhat); | ||
135 | } | ||
136 | if (strchr(options, 'L')) | ||
137 | treatstackoption(L, L1, "activelines"); | ||
138 | if (strchr(options, 'f')) | ||
139 | treatstackoption(L, L1, "func"); | ||
140 | return 1; /* return table */ | ||
141 | } | ||
142 | |||
143 | |||
144 | static int db_getlocal (lua_State *L) { | ||
145 | int arg; | ||
146 | lua_State *L1 = getthread(L, &arg); | ||
147 | lua_Debug ar; | ||
148 | const char *name; | ||
149 | if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ | ||
150 | return luaL_argerror(L, arg+1, "level out of range"); | ||
151 | name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2)); | ||
152 | if (name) { | ||
153 | lua_xmove(L1, L, 1); | ||
154 | lua_pushstring(L, name); | ||
155 | lua_pushvalue(L, -2); | ||
156 | return 2; | ||
157 | } | ||
158 | else { | ||
159 | lua_pushnil(L); | ||
160 | return 1; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | |||
165 | static int db_setlocal (lua_State *L) { | ||
166 | int arg; | ||
167 | lua_State *L1 = getthread(L, &arg); | ||
168 | lua_Debug ar; | ||
169 | if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ | ||
170 | return luaL_argerror(L, arg+1, "level out of range"); | ||
171 | luaL_checkany(L, arg+3); | ||
172 | lua_settop(L, arg+3); | ||
173 | lua_xmove(L, L1, 1); | ||
174 | lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); | ||
175 | return 1; | ||
176 | } | ||
177 | |||
178 | |||
179 | static int auxupvalue (lua_State *L, int get) { | ||
180 | const char *name; | ||
181 | int n = luaL_checkint(L, 2); | ||
182 | luaL_checktype(L, 1, LUA_TFUNCTION); | ||
183 | if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ | ||
184 | name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); | ||
185 | if (name == NULL) return 0; | ||
186 | lua_pushstring(L, name); | ||
187 | lua_insert(L, -(get+1)); | ||
188 | return get + 1; | ||
189 | } | ||
190 | |||
191 | |||
192 | static int db_getupvalue (lua_State *L) { | ||
193 | return auxupvalue(L, 1); | ||
194 | } | ||
195 | |||
196 | |||
197 | static int db_setupvalue (lua_State *L) { | ||
198 | luaL_checkany(L, 3); | ||
199 | return auxupvalue(L, 0); | ||
200 | } | ||
201 | |||
202 | |||
203 | |||
204 | static const char KEY_HOOK = 'h'; | ||
205 | |||
206 | |||
207 | static void hookf (lua_State *L, lua_Debug *ar) { | ||
208 | static const char *const hooknames[] = | ||
209 | {"call", "return", "line", "count", "tail return"}; | ||
210 | lua_pushlightuserdata(L, (void *)&KEY_HOOK); | ||
211 | lua_rawget(L, LUA_REGISTRYINDEX); | ||
212 | lua_pushlightuserdata(L, L); | ||
213 | lua_rawget(L, -2); | ||
214 | if (lua_isfunction(L, -1)) { | ||
215 | lua_pushstring(L, hooknames[(int)ar->event]); | ||
216 | if (ar->currentline >= 0) | ||
217 | lua_pushinteger(L, ar->currentline); | ||
218 | else lua_pushnil(L); | ||
219 | lua_assert(lua_getinfo(L, "lS", ar)); | ||
220 | lua_call(L, 2, 0); | ||
221 | } | ||
222 | } | ||
223 | |||
224 | |||
225 | static int makemask (const char *smask, int count) { | ||
226 | int mask = 0; | ||
227 | if (strchr(smask, 'c')) mask |= LUA_MASKCALL; | ||
228 | if (strchr(smask, 'r')) mask |= LUA_MASKRET; | ||
229 | if (strchr(smask, 'l')) mask |= LUA_MASKLINE; | ||
230 | if (count > 0) mask |= LUA_MASKCOUNT; | ||
231 | return mask; | ||
232 | } | ||
233 | |||
234 | |||
235 | static char *unmakemask (int mask, char *smask) { | ||
236 | int i = 0; | ||
237 | if (mask & LUA_MASKCALL) smask[i++] = 'c'; | ||
238 | if (mask & LUA_MASKRET) smask[i++] = 'r'; | ||
239 | if (mask & LUA_MASKLINE) smask[i++] = 'l'; | ||
240 | smask[i] = '\0'; | ||
241 | return smask; | ||
242 | } | ||
243 | |||
244 | |||
245 | static void gethooktable (lua_State *L) { | ||
246 | lua_pushlightuserdata(L, (void *)&KEY_HOOK); | ||
247 | lua_rawget(L, LUA_REGISTRYINDEX); | ||
248 | if (!lua_istable(L, -1)) { | ||
249 | lua_pop(L, 1); | ||
250 | lua_createtable(L, 0, 1); | ||
251 | lua_pushlightuserdata(L, (void *)&KEY_HOOK); | ||
252 | lua_pushvalue(L, -2); | ||
253 | lua_rawset(L, LUA_REGISTRYINDEX); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | |||
258 | static int db_sethook (lua_State *L) { | ||
259 | int arg, mask, count; | ||
260 | lua_Hook func; | ||
261 | lua_State *L1 = getthread(L, &arg); | ||
262 | if (lua_isnoneornil(L, arg+1)) { | ||
263 | lua_settop(L, arg+1); | ||
264 | func = NULL; mask = 0; count = 0; /* turn off hooks */ | ||
265 | } | ||
266 | else { | ||
267 | const char *smask = luaL_checkstring(L, arg+2); | ||
268 | luaL_checktype(L, arg+1, LUA_TFUNCTION); | ||
269 | count = luaL_optint(L, arg+3, 0); | ||
270 | func = hookf; mask = makemask(smask, count); | ||
271 | } | ||
272 | gethooktable(L); | ||
273 | lua_pushlightuserdata(L, L1); | ||
274 | lua_pushvalue(L, arg+1); | ||
275 | lua_rawset(L, -3); /* set new hook */ | ||
276 | lua_pop(L, 1); /* remove hook table */ | ||
277 | lua_sethook(L1, func, mask, count); /* set hooks */ | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | |||
282 | static int db_gethook (lua_State *L) { | ||
283 | int arg; | ||
284 | lua_State *L1 = getthread(L, &arg); | ||
285 | char buff[5]; | ||
286 | int mask = lua_gethookmask(L1); | ||
287 | lua_Hook hook = lua_gethook(L1); | ||
288 | if (hook != NULL && hook != hookf) /* external hook? */ | ||
289 | lua_pushliteral(L, "external hook"); | ||
290 | else { | ||
291 | gethooktable(L); | ||
292 | lua_pushlightuserdata(L, L1); | ||
293 | lua_rawget(L, -2); /* get hook */ | ||
294 | lua_remove(L, -2); /* remove hook table */ | ||
295 | } | ||
296 | lua_pushstring(L, unmakemask(mask, buff)); | ||
297 | lua_pushinteger(L, lua_gethookcount(L1)); | ||
298 | return 3; | ||
299 | } | ||
300 | |||
301 | |||
302 | static int db_debug (lua_State *L) { | ||
303 | for (;;) { | ||
304 | char buffer[250]; | ||
305 | fputs("lua_debug> ", stderr); | ||
306 | if (fgets(buffer, sizeof(buffer), stdin) == 0 || | ||
307 | strcmp(buffer, "cont\n") == 0) | ||
308 | return 0; | ||
309 | if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || | ||
310 | lua_pcall(L, 0, 0, 0)) { | ||
311 | fputs(lua_tostring(L, -1), stderr); | ||
312 | fputs("\n", stderr); | ||
313 | } | ||
314 | lua_settop(L, 0); /* remove eventual returns */ | ||
315 | } | ||
316 | } | ||
317 | |||
318 | |||
319 | #define LEVELS1 12 /* size of the first part of the stack */ | ||
320 | #define LEVELS2 10 /* size of the second part of the stack */ | ||
321 | |||
322 | static int db_errorfb (lua_State *L) { | ||
323 | int level; | ||
324 | int firstpart = 1; /* still before eventual `...' */ | ||
325 | int arg; | ||
326 | lua_State *L1 = getthread(L, &arg); | ||
327 | lua_Debug ar; | ||
328 | if (lua_isnumber(L, arg+2)) { | ||
329 | level = (int)lua_tointeger(L, arg+2); | ||
330 | lua_pop(L, 1); | ||
331 | } | ||
332 | else | ||
333 | level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ | ||
334 | if (lua_gettop(L) == arg) | ||
335 | lua_pushliteral(L, ""); | ||
336 | else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ | ||
337 | else lua_pushliteral(L, "\n"); | ||
338 | lua_pushliteral(L, "stack traceback:"); | ||
339 | while (lua_getstack(L1, level++, &ar)) { | ||
340 | if (level > LEVELS1 && firstpart) { | ||
341 | /* no more than `LEVELS2' more levels? */ | ||
342 | if (!lua_getstack(L1, level+LEVELS2, &ar)) | ||
343 | level--; /* keep going */ | ||
344 | else { | ||
345 | lua_pushliteral(L, "\n\t..."); /* too many levels */ | ||
346 | while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */ | ||
347 | level++; | ||
348 | } | ||
349 | firstpart = 0; | ||
350 | continue; | ||
351 | } | ||
352 | lua_pushliteral(L, "\n\t"); | ||
353 | lua_getinfo(L1, "Snl", &ar); | ||
354 | lua_pushfstring(L, "%s:", ar.short_src); | ||
355 | if (ar.currentline > 0) | ||
356 | lua_pushfstring(L, "%d:", ar.currentline); | ||
357 | if (*ar.namewhat != '\0') /* is there a name? */ | ||
358 | lua_pushfstring(L, " in function " LUA_QS, ar.name); | ||
359 | else { | ||
360 | if (*ar.what == 'm') /* main? */ | ||
361 | lua_pushfstring(L, " in main chunk"); | ||
362 | else if (*ar.what == 'C' || *ar.what == 't') | ||
363 | lua_pushliteral(L, " ?"); /* C function or tail call */ | ||
364 | else | ||
365 | lua_pushfstring(L, " in function <%s:%d>", | ||
366 | ar.short_src, ar.linedefined); | ||
367 | } | ||
368 | lua_concat(L, lua_gettop(L) - arg); | ||
369 | } | ||
370 | lua_concat(L, lua_gettop(L) - arg); | ||
371 | return 1; | ||
372 | } | ||
373 | |||
374 | |||
375 | static const luaL_Reg dblib[] = { | ||
376 | {"debug", db_debug}, | ||
377 | {"getfenv", db_getfenv}, | ||
378 | {"gethook", db_gethook}, | ||
379 | {"getinfo", db_getinfo}, | ||
380 | {"getlocal", db_getlocal}, | ||
381 | {"getregistry", db_getregistry}, | ||
382 | {"getmetatable", db_getmetatable}, | ||
383 | {"getupvalue", db_getupvalue}, | ||
384 | {"setfenv", db_setfenv}, | ||
385 | {"sethook", db_sethook}, | ||
386 | {"setlocal", db_setlocal}, | ||
387 | {"setmetatable", db_setmetatable}, | ||
388 | {"setupvalue", db_setupvalue}, | ||
389 | {"traceback", db_errorfb}, | ||
390 | {NULL, NULL} | ||
391 | }; | ||
392 | |||
393 | |||
394 | LUALIB_API int luaopen_debug (lua_State *L) { | ||
395 | luaL_register(L, LUA_DBLIBNAME, dblib); | ||
396 | return 1; | ||
397 | } | ||
398 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ldebug.c b/libraries/LuaJIT-1.1.7/src/ldebug.c new file mode 100644 index 0000000..89891fd --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ldebug.c | |||
@@ -0,0 +1,640 @@ | |||
1 | /* | ||
2 | ** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $ | ||
3 | ** Debug Interface | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <stdarg.h> | ||
9 | #include <stddef.h> | ||
10 | #include <string.h> | ||
11 | |||
12 | |||
13 | #define ldebug_c | ||
14 | #define LUA_CORE | ||
15 | |||
16 | #include "lua.h" | ||
17 | |||
18 | #include "lapi.h" | ||
19 | #include "lcode.h" | ||
20 | #include "ldebug.h" | ||
21 | #include "ldo.h" | ||
22 | #include "lfunc.h" | ||
23 | #include "lobject.h" | ||
24 | #include "lopcodes.h" | ||
25 | #include "lstate.h" | ||
26 | #include "lstring.h" | ||
27 | #include "ltable.h" | ||
28 | #include "ltm.h" | ||
29 | #include "lvm.h" | ||
30 | #include "ljit.h" | ||
31 | |||
32 | |||
33 | |||
34 | static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); | ||
35 | |||
36 | |||
37 | static int currentpc (lua_State *L, CallInfo *ci) { | ||
38 | if (isLua(ci)) /* must be a Lua function to get current PC */ | ||
39 | return luaJIT_findpc(ci_func(ci)->l.p, | ||
40 | ci==L->ci ? L->savedpc : ci->savedpc); | ||
41 | else | ||
42 | return -1; | ||
43 | } | ||
44 | |||
45 | |||
46 | static int currentline (lua_State *L, CallInfo *ci) { | ||
47 | int pc = currentpc(L, ci); | ||
48 | if (pc < 0) | ||
49 | return -1; /* only active lua functions have current-line information */ | ||
50 | else | ||
51 | return getline(ci_func(ci)->l.p, pc); | ||
52 | } | ||
53 | |||
54 | |||
55 | /* | ||
56 | ** this function can be called asynchronous (e.g. during a signal) | ||
57 | */ | ||
58 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { | ||
59 | if (func == NULL || mask == 0) { /* turn off hooks? */ | ||
60 | mask = 0; | ||
61 | func = NULL; | ||
62 | } | ||
63 | L->hook = func; | ||
64 | L->basehookcount = count; | ||
65 | resethookcount(L); | ||
66 | L->hookmask = cast_byte(mask); | ||
67 | return 1; | ||
68 | } | ||
69 | |||
70 | |||
71 | LUA_API lua_Hook lua_gethook (lua_State *L) { | ||
72 | return L->hook; | ||
73 | } | ||
74 | |||
75 | |||
76 | LUA_API int lua_gethookmask (lua_State *L) { | ||
77 | return L->hookmask; | ||
78 | } | ||
79 | |||
80 | |||
81 | LUA_API int lua_gethookcount (lua_State *L) { | ||
82 | return L->basehookcount; | ||
83 | } | ||
84 | |||
85 | |||
86 | LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { | ||
87 | int status; | ||
88 | CallInfo *ci; | ||
89 | lua_lock(L); | ||
90 | for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { | ||
91 | level--; | ||
92 | if (f_isLua(ci)) /* Lua function? */ | ||
93 | level -= ci->tailcalls; /* skip lost tail calls */ | ||
94 | } | ||
95 | if (level == 0 && ci > L->base_ci) { /* level found? */ | ||
96 | status = 1; | ||
97 | ar->i_ci = cast_int(ci - L->base_ci); | ||
98 | } | ||
99 | else if (level < 0) { /* level is of a lost tail call? */ | ||
100 | status = 1; | ||
101 | ar->i_ci = 0; | ||
102 | } | ||
103 | else status = 0; /* no such level */ | ||
104 | lua_unlock(L); | ||
105 | return status; | ||
106 | } | ||
107 | |||
108 | |||
109 | static Proto *getluaproto (CallInfo *ci) { | ||
110 | return (isLua(ci) ? ci_func(ci)->l.p : NULL); | ||
111 | } | ||
112 | |||
113 | |||
114 | static const char *findlocal (lua_State *L, CallInfo *ci, int n) { | ||
115 | const char *name; | ||
116 | Proto *fp = getluaproto(ci); | ||
117 | if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) | ||
118 | return name; /* is a local variable in a Lua function */ | ||
119 | else { | ||
120 | StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; | ||
121 | if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ | ||
122 | return "(*temporary)"; | ||
123 | else | ||
124 | return NULL; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | |||
129 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | ||
130 | CallInfo *ci = L->base_ci + ar->i_ci; | ||
131 | const char *name = findlocal(L, ci, n); | ||
132 | lua_lock(L); | ||
133 | if (name) | ||
134 | luaA_pushobject(L, ci->base + (n - 1)); | ||
135 | lua_unlock(L); | ||
136 | return name; | ||
137 | } | ||
138 | |||
139 | |||
140 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | ||
141 | CallInfo *ci = L->base_ci + ar->i_ci; | ||
142 | const char *name = findlocal(L, ci, n); | ||
143 | lua_lock(L); | ||
144 | if (name) | ||
145 | setobjs2s(L, ci->base + (n - 1), L->top - 1); | ||
146 | L->top--; /* pop value */ | ||
147 | lua_unlock(L); | ||
148 | return name; | ||
149 | } | ||
150 | |||
151 | |||
152 | static void funcinfo (lua_Debug *ar, Closure *cl) { | ||
153 | if (cl->c.isC) { | ||
154 | ar->source = "=[C]"; | ||
155 | ar->linedefined = -1; | ||
156 | ar->lastlinedefined = -1; | ||
157 | ar->what = "C"; | ||
158 | } | ||
159 | else { | ||
160 | ar->source = getstr(cl->l.p->source); | ||
161 | ar->linedefined = cl->l.p->linedefined; | ||
162 | ar->lastlinedefined = cl->l.p->lastlinedefined; | ||
163 | ar->what = (ar->linedefined == 0) ? "main" : "Lua"; | ||
164 | } | ||
165 | luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); | ||
166 | } | ||
167 | |||
168 | |||
169 | static void info_tailcall (lua_Debug *ar) { | ||
170 | ar->name = ar->namewhat = ""; | ||
171 | ar->what = "tail"; | ||
172 | ar->lastlinedefined = ar->linedefined = ar->currentline = -1; | ||
173 | ar->source = "=(tail call)"; | ||
174 | luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); | ||
175 | ar->nups = 0; | ||
176 | } | ||
177 | |||
178 | |||
179 | static void collectvalidlines (lua_State *L, Closure *f) { | ||
180 | if (f == NULL || f->c.isC) { | ||
181 | setnilvalue(L->top); | ||
182 | } | ||
183 | else { | ||
184 | Table *t = luaH_new(L, 0, 0); | ||
185 | int *lineinfo = f->l.p->lineinfo; | ||
186 | int i; | ||
187 | for (i=0; i<f->l.p->sizelineinfo; i++) | ||
188 | setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); | ||
189 | sethvalue(L, L->top, t); | ||
190 | } | ||
191 | incr_top(L); | ||
192 | } | ||
193 | |||
194 | |||
195 | static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | ||
196 | Closure *f, CallInfo *ci) { | ||
197 | int status = 1; | ||
198 | if (f == NULL) { | ||
199 | info_tailcall(ar); | ||
200 | return status; | ||
201 | } | ||
202 | for (; *what; what++) { | ||
203 | switch (*what) { | ||
204 | case 'S': { | ||
205 | funcinfo(ar, f); | ||
206 | break; | ||
207 | } | ||
208 | case 'l': { | ||
209 | ar->currentline = (ci) ? currentline(L, ci) : -1; | ||
210 | break; | ||
211 | } | ||
212 | case 'u': { | ||
213 | ar->nups = f->c.nupvalues; | ||
214 | break; | ||
215 | } | ||
216 | case 'n': { | ||
217 | ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; | ||
218 | if (ar->namewhat == NULL) { | ||
219 | ar->namewhat = ""; /* not found */ | ||
220 | ar->name = NULL; | ||
221 | } | ||
222 | break; | ||
223 | } | ||
224 | case 'L': | ||
225 | case 'f': /* handled by lua_getinfo */ | ||
226 | break; | ||
227 | default: status = 0; /* invalid option */ | ||
228 | } | ||
229 | } | ||
230 | return status; | ||
231 | } | ||
232 | |||
233 | |||
234 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | ||
235 | int status; | ||
236 | Closure *f = NULL; | ||
237 | CallInfo *ci = NULL; | ||
238 | lua_lock(L); | ||
239 | if (*what == '>') { | ||
240 | StkId func = L->top - 1; | ||
241 | luai_apicheck(L, ttisfunction(func)); | ||
242 | what++; /* skip the '>' */ | ||
243 | f = clvalue(func); | ||
244 | L->top--; /* pop function */ | ||
245 | } | ||
246 | else if (ar->i_ci != 0) { /* no tail call? */ | ||
247 | ci = L->base_ci + ar->i_ci; | ||
248 | lua_assert(ttisfunction(ci->func)); | ||
249 | f = clvalue(ci->func); | ||
250 | } | ||
251 | status = auxgetinfo(L, what, ar, f, ci); | ||
252 | if (strchr(what, 'f')) { | ||
253 | if (f == NULL) setnilvalue(L->top); | ||
254 | else setclvalue(L, L->top, f); | ||
255 | incr_top(L); | ||
256 | } | ||
257 | if (strchr(what, 'L')) | ||
258 | collectvalidlines(L, f); | ||
259 | lua_unlock(L); | ||
260 | return status; | ||
261 | } | ||
262 | |||
263 | |||
264 | /* | ||
265 | ** {====================================================== | ||
266 | ** Symbolic Execution and code checker | ||
267 | ** ======================================================= | ||
268 | */ | ||
269 | |||
270 | #define check(x) if (!(x)) return 0; | ||
271 | |||
272 | #define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) | ||
273 | |||
274 | #define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) | ||
275 | |||
276 | |||
277 | |||
278 | static int precheck (const Proto *pt) { | ||
279 | check(pt->maxstacksize <= MAXSTACK); | ||
280 | check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); | ||
281 | check(!(pt->is_vararg & VARARG_NEEDSARG) || | ||
282 | (pt->is_vararg & VARARG_HASARG)); | ||
283 | check(pt->sizeupvalues <= pt->nups); | ||
284 | check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); | ||
285 | check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); | ||
286 | return 1; | ||
287 | } | ||
288 | |||
289 | |||
290 | #define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) | ||
291 | |||
292 | int luaG_checkopenop (Instruction i) { | ||
293 | switch (GET_OPCODE(i)) { | ||
294 | case OP_CALL: | ||
295 | case OP_TAILCALL: | ||
296 | case OP_RETURN: | ||
297 | case OP_SETLIST: { | ||
298 | check(GETARG_B(i) == 0); | ||
299 | return 1; | ||
300 | } | ||
301 | default: return 0; /* invalid instruction after an open call */ | ||
302 | } | ||
303 | } | ||
304 | |||
305 | |||
306 | static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { | ||
307 | switch (mode) { | ||
308 | case OpArgN: check(r == 0); break; | ||
309 | case OpArgU: break; | ||
310 | case OpArgR: checkreg(pt, r); break; | ||
311 | case OpArgK: | ||
312 | check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); | ||
313 | break; | ||
314 | } | ||
315 | return 1; | ||
316 | } | ||
317 | |||
318 | |||
319 | static Instruction symbexec (const Proto *pt, int lastpc, int reg) { | ||
320 | int pc; | ||
321 | int last; /* stores position of last instruction that changed `reg' */ | ||
322 | last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ | ||
323 | check(precheck(pt)); | ||
324 | for (pc = 0; pc < lastpc; pc++) { | ||
325 | Instruction i = pt->code[pc]; | ||
326 | OpCode op = GET_OPCODE(i); | ||
327 | int a = GETARG_A(i); | ||
328 | int b = 0; | ||
329 | int c = 0; | ||
330 | check(op < NUM_OPCODES); | ||
331 | checkreg(pt, a); | ||
332 | switch (getOpMode(op)) { | ||
333 | case iABC: { | ||
334 | b = GETARG_B(i); | ||
335 | c = GETARG_C(i); | ||
336 | check(checkArgMode(pt, b, getBMode(op))); | ||
337 | check(checkArgMode(pt, c, getCMode(op))); | ||
338 | break; | ||
339 | } | ||
340 | case iABx: { | ||
341 | b = GETARG_Bx(i); | ||
342 | if (getBMode(op) == OpArgK) check(b < pt->sizek); | ||
343 | break; | ||
344 | } | ||
345 | case iAsBx: { | ||
346 | b = GETARG_sBx(i); | ||
347 | if (getBMode(op) == OpArgR) { | ||
348 | int dest = pc+1+b; | ||
349 | check(0 <= dest && dest < pt->sizecode); | ||
350 | if (dest > 0) { | ||
351 | int j; | ||
352 | /* check that it does not jump to a setlist count; this | ||
353 | is tricky, because the count from a previous setlist may | ||
354 | have the same value of an invalid setlist; so, we must | ||
355 | go all the way back to the first of them (if any) */ | ||
356 | for (j = 0; j < dest; j++) { | ||
357 | Instruction d = pt->code[dest-1-j]; | ||
358 | if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break; | ||
359 | } | ||
360 | /* if 'j' is even, previous value is not a setlist (even if | ||
361 | it looks like one) */ | ||
362 | check((j&1) == 0); | ||
363 | } | ||
364 | } | ||
365 | break; | ||
366 | } | ||
367 | } | ||
368 | if (testAMode(op)) { | ||
369 | if (a == reg) last = pc; /* change register `a' */ | ||
370 | } | ||
371 | if (testTMode(op)) { | ||
372 | check(pc+2 < pt->sizecode); /* check skip */ | ||
373 | check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); | ||
374 | } | ||
375 | switch (op) { | ||
376 | case OP_LOADBOOL: { | ||
377 | if (c == 1) { /* does it jump? */ | ||
378 | check(pc+2 < pt->sizecode); /* check its jump */ | ||
379 | check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST || | ||
380 | GETARG_C(pt->code[pc+1]) != 0); | ||
381 | } | ||
382 | break; | ||
383 | } | ||
384 | case OP_LOADNIL: { | ||
385 | if (a <= reg && reg <= b) | ||
386 | last = pc; /* set registers from `a' to `b' */ | ||
387 | break; | ||
388 | } | ||
389 | case OP_GETUPVAL: | ||
390 | case OP_SETUPVAL: { | ||
391 | check(b < pt->nups); | ||
392 | break; | ||
393 | } | ||
394 | case OP_GETGLOBAL: | ||
395 | case OP_SETGLOBAL: { | ||
396 | check(ttisstring(&pt->k[b])); | ||
397 | break; | ||
398 | } | ||
399 | case OP_SELF: { | ||
400 | checkreg(pt, a+1); | ||
401 | if (reg == a+1) last = pc; | ||
402 | break; | ||
403 | } | ||
404 | case OP_CONCAT: { | ||
405 | check(b < c); /* at least two operands */ | ||
406 | break; | ||
407 | } | ||
408 | case OP_TFORLOOP: { | ||
409 | check(c >= 1); /* at least one result (control variable) */ | ||
410 | checkreg(pt, a+2+c); /* space for results */ | ||
411 | if (reg >= a+2) last = pc; /* affect all regs above its base */ | ||
412 | break; | ||
413 | } | ||
414 | case OP_FORLOOP: | ||
415 | case OP_FORPREP: | ||
416 | checkreg(pt, a+3); | ||
417 | /* go through */ | ||
418 | case OP_JMP: { | ||
419 | int dest = pc+1+b; | ||
420 | /* not full check and jump is forward and do not skip `lastpc'? */ | ||
421 | if (reg != NO_REG && pc < dest && dest <= lastpc) | ||
422 | pc += b; /* do the jump */ | ||
423 | break; | ||
424 | } | ||
425 | case OP_CALL: | ||
426 | case OP_TAILCALL: { | ||
427 | if (b != 0) { | ||
428 | checkreg(pt, a+b-1); | ||
429 | } | ||
430 | c--; /* c = num. returns */ | ||
431 | if (c == LUA_MULTRET) { | ||
432 | check(checkopenop(pt, pc)); | ||
433 | } | ||
434 | else if (c != 0) | ||
435 | checkreg(pt, a+c-1); | ||
436 | if (reg >= a) last = pc; /* affect all registers above base */ | ||
437 | break; | ||
438 | } | ||
439 | case OP_RETURN: { | ||
440 | b--; /* b = num. returns */ | ||
441 | if (b > 0) checkreg(pt, a+b-1); | ||
442 | break; | ||
443 | } | ||
444 | case OP_SETLIST: { | ||
445 | if (b > 0) checkreg(pt, a + b); | ||
446 | if (c == 0) { | ||
447 | pc++; | ||
448 | check(pc < pt->sizecode - 1); | ||
449 | } | ||
450 | break; | ||
451 | } | ||
452 | case OP_CLOSURE: { | ||
453 | int nup, j; | ||
454 | check(b < pt->sizep); | ||
455 | nup = pt->p[b]->nups; | ||
456 | check(pc + nup < pt->sizecode); | ||
457 | for (j = 1; j <= nup; j++) { | ||
458 | OpCode op1 = GET_OPCODE(pt->code[pc + j]); | ||
459 | check(op1 == OP_GETUPVAL || op1 == OP_MOVE); | ||
460 | } | ||
461 | if (reg != NO_REG) /* tracing? */ | ||
462 | pc += nup; /* do not 'execute' these pseudo-instructions */ | ||
463 | break; | ||
464 | } | ||
465 | case OP_VARARG: { | ||
466 | check((pt->is_vararg & VARARG_ISVARARG) && | ||
467 | !(pt->is_vararg & VARARG_NEEDSARG)); | ||
468 | b--; | ||
469 | if (b == LUA_MULTRET) check(checkopenop(pt, pc)); | ||
470 | checkreg(pt, a+b-1); | ||
471 | break; | ||
472 | } | ||
473 | default: break; | ||
474 | } | ||
475 | } | ||
476 | return pt->code[last]; | ||
477 | } | ||
478 | |||
479 | #undef check | ||
480 | #undef checkjump | ||
481 | #undef checkreg | ||
482 | |||
483 | /* }====================================================== */ | ||
484 | |||
485 | |||
486 | int luaG_checkcode (const Proto *pt) { | ||
487 | return (symbexec(pt, pt->sizecode, NO_REG) != 0); | ||
488 | } | ||
489 | |||
490 | |||
491 | static const char *kname (Proto *p, int c) { | ||
492 | if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) | ||
493 | return svalue(&p->k[INDEXK(c)]); | ||
494 | else | ||
495 | return "?"; | ||
496 | } | ||
497 | |||
498 | |||
499 | static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, | ||
500 | const char **name) { | ||
501 | if (isLua(ci)) { /* a Lua function? */ | ||
502 | Proto *p = ci_func(ci)->l.p; | ||
503 | int pc = currentpc(L, ci); | ||
504 | Instruction i; | ||
505 | *name = luaF_getlocalname(p, stackpos+1, pc); | ||
506 | if (*name) /* is a local? */ | ||
507 | return "local"; | ||
508 | i = symbexec(p, pc, stackpos); /* try symbolic execution */ | ||
509 | lua_assert(pc != -1); | ||
510 | switch (GET_OPCODE(i)) { | ||
511 | case OP_GETGLOBAL: { | ||
512 | int g = GETARG_Bx(i); /* global index */ | ||
513 | lua_assert(ttisstring(&p->k[g])); | ||
514 | *name = svalue(&p->k[g]); | ||
515 | return "global"; | ||
516 | } | ||
517 | case OP_MOVE: { | ||
518 | int a = GETARG_A(i); | ||
519 | int b = GETARG_B(i); /* move from `b' to `a' */ | ||
520 | if (b < a) | ||
521 | return getobjname(L, ci, b, name); /* get name for `b' */ | ||
522 | break; | ||
523 | } | ||
524 | case OP_GETTABLE: { | ||
525 | int k = GETARG_C(i); /* key index */ | ||
526 | *name = kname(p, k); | ||
527 | return "field"; | ||
528 | } | ||
529 | case OP_GETUPVAL: { | ||
530 | int u = GETARG_B(i); /* upvalue index */ | ||
531 | *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; | ||
532 | return "upvalue"; | ||
533 | } | ||
534 | case OP_SELF: { | ||
535 | int k = GETARG_C(i); /* key index */ | ||
536 | *name = kname(p, k); | ||
537 | return "method"; | ||
538 | } | ||
539 | default: break; | ||
540 | } | ||
541 | } | ||
542 | return NULL; /* no useful name found */ | ||
543 | } | ||
544 | |||
545 | |||
546 | static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { | ||
547 | Instruction i; | ||
548 | if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) | ||
549 | return NULL; /* calling function is not Lua (or is unknown) */ | ||
550 | ci--; /* calling function */ | ||
551 | i = ci_func(ci)->l.p->code[currentpc(L, ci)]; | ||
552 | if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || | ||
553 | GET_OPCODE(i) == OP_TFORLOOP) | ||
554 | return getobjname(L, ci, GETARG_A(i), name); | ||
555 | else | ||
556 | return NULL; /* no useful name can be found */ | ||
557 | } | ||
558 | |||
559 | |||
560 | /* only ANSI way to check whether a pointer points to an array */ | ||
561 | static int isinstack (CallInfo *ci, const TValue *o) { | ||
562 | StkId p; | ||
563 | for (p = ci->base; p < ci->top; p++) | ||
564 | if (o == p) return 1; | ||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | |||
569 | void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { | ||
570 | const char *name = NULL; | ||
571 | const char *t = luaT_typenames[ttype(o)]; | ||
572 | const char *kind = (isinstack(L->ci, o)) ? | ||
573 | getobjname(L, L->ci, cast_int(o - L->base), &name) : | ||
574 | NULL; | ||
575 | if (kind) | ||
576 | luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", | ||
577 | op, kind, name, t); | ||
578 | else | ||
579 | luaG_runerror(L, "attempt to %s a %s value", op, t); | ||
580 | } | ||
581 | |||
582 | |||
583 | void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { | ||
584 | if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; | ||
585 | lua_assert(!ttisstring(p1) && !ttisnumber(p1)); | ||
586 | luaG_typeerror(L, p1, "concatenate"); | ||
587 | } | ||
588 | |||
589 | |||
590 | void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { | ||
591 | TValue temp; | ||
592 | if (luaV_tonumber(p1, &temp) == NULL) | ||
593 | p2 = p1; /* first operand is wrong */ | ||
594 | luaG_typeerror(L, p2, "perform arithmetic on"); | ||
595 | } | ||
596 | |||
597 | |||
598 | int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { | ||
599 | const char *t1 = luaT_typenames[ttype(p1)]; | ||
600 | const char *t2 = luaT_typenames[ttype(p2)]; | ||
601 | if (t1[2] == t2[2]) | ||
602 | luaG_runerror(L, "attempt to compare two %s values", t1); | ||
603 | else | ||
604 | luaG_runerror(L, "attempt to compare %s with %s", t1, t2); | ||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | |||
609 | static void addinfo (lua_State *L, const char *msg) { | ||
610 | CallInfo *ci = L->ci; | ||
611 | if (isLua(ci)) { /* is Lua code? */ | ||
612 | char buff[LUA_IDSIZE]; /* add file:line information */ | ||
613 | int line = currentline(L, ci); | ||
614 | luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); | ||
615 | luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); | ||
616 | } | ||
617 | } | ||
618 | |||
619 | |||
620 | void luaG_errormsg (lua_State *L) { | ||
621 | if (L->errfunc != 0) { /* is there an error handling function? */ | ||
622 | StkId errfunc = restorestack(L, L->errfunc); | ||
623 | if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); | ||
624 | setobjs2s(L, L->top, L->top - 1); /* move argument */ | ||
625 | setobjs2s(L, L->top - 1, errfunc); /* push function */ | ||
626 | incr_top(L); | ||
627 | luaD_call(L, L->top - 2, 1); /* call it */ | ||
628 | } | ||
629 | luaD_throw(L, LUA_ERRRUN); | ||
630 | } | ||
631 | |||
632 | |||
633 | void luaG_runerror (lua_State *L, const char *fmt, ...) { | ||
634 | va_list argp; | ||
635 | va_start(argp, fmt); | ||
636 | addinfo(L, luaO_pushvfstring(L, fmt, argp)); | ||
637 | va_end(argp); | ||
638 | luaG_errormsg(L); | ||
639 | } | ||
640 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ldebug.h b/libraries/LuaJIT-1.1.7/src/ldebug.h new file mode 100644 index 0000000..ba28a97 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ldebug.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | ** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Auxiliary functions from Debug Interface module | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef ldebug_h | ||
8 | #define ldebug_h | ||
9 | |||
10 | |||
11 | #include "lstate.h" | ||
12 | |||
13 | |||
14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) | ||
15 | |||
16 | #define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) | ||
17 | |||
18 | #define resethookcount(L) (L->hookcount = L->basehookcount) | ||
19 | |||
20 | |||
21 | LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, | ||
22 | const char *opname); | ||
23 | LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); | ||
24 | LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, | ||
25 | const TValue *p2); | ||
26 | LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, | ||
27 | const TValue *p2); | ||
28 | LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); | ||
29 | LUAI_FUNC void luaG_errormsg (lua_State *L); | ||
30 | LUAI_FUNC int luaG_checkcode (const Proto *pt); | ||
31 | LUAI_FUNC int luaG_checkopenop (Instruction i); | ||
32 | |||
33 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/ldo.c b/libraries/LuaJIT-1.1.7/src/ldo.c new file mode 100644 index 0000000..1d9393d --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ldo.c | |||
@@ -0,0 +1,519 @@ | |||
1 | /* | ||
2 | ** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $ | ||
3 | ** Stack and Call structure of Lua | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <setjmp.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <string.h> | ||
11 | |||
12 | #define ldo_c | ||
13 | #define LUA_CORE | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "ldebug.h" | ||
18 | #include "ldo.h" | ||
19 | #include "lfunc.h" | ||
20 | #include "lgc.h" | ||
21 | #include "lmem.h" | ||
22 | #include "lobject.h" | ||
23 | #include "lopcodes.h" | ||
24 | #include "lparser.h" | ||
25 | #include "lstate.h" | ||
26 | #include "lstring.h" | ||
27 | #include "ltable.h" | ||
28 | #include "ltm.h" | ||
29 | #include "lundump.h" | ||
30 | #include "lvm.h" | ||
31 | #include "lzio.h" | ||
32 | #include "ljit.h" | ||
33 | |||
34 | |||
35 | |||
36 | |||
37 | /* | ||
38 | ** {====================================================== | ||
39 | ** Error-recovery functions | ||
40 | ** ======================================================= | ||
41 | */ | ||
42 | |||
43 | |||
44 | /* chain list of long jump buffers */ | ||
45 | struct lua_longjmp { | ||
46 | struct lua_longjmp *previous; | ||
47 | luai_jmpbuf b; | ||
48 | volatile int status; /* error code */ | ||
49 | }; | ||
50 | |||
51 | |||
52 | void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { | ||
53 | switch (errcode) { | ||
54 | case LUA_ERRMEM: { | ||
55 | setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); | ||
56 | break; | ||
57 | } | ||
58 | case LUA_ERRERR: { | ||
59 | setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); | ||
60 | break; | ||
61 | } | ||
62 | case LUA_ERRSYNTAX: | ||
63 | case LUA_ERRRUN: { | ||
64 | setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ | ||
65 | break; | ||
66 | } | ||
67 | } | ||
68 | L->top = oldtop + 1; | ||
69 | } | ||
70 | |||
71 | |||
72 | static void restore_stack_limit (lua_State *L) { | ||
73 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); | ||
74 | if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ | ||
75 | int inuse = cast_int(L->ci - L->base_ci); | ||
76 | if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ | ||
77 | luaD_reallocCI(L, LUAI_MAXCALLS); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | |||
82 | static void resetstack (lua_State *L, int status) { | ||
83 | L->ci = L->base_ci; | ||
84 | L->base = L->ci->base; | ||
85 | luaF_close(L, L->base); /* close eventual pending closures */ | ||
86 | luaD_seterrorobj(L, status, L->base); | ||
87 | L->nCcalls = 0; | ||
88 | L->allowhook = 1; | ||
89 | restore_stack_limit(L); | ||
90 | L->errfunc = 0; | ||
91 | L->errorJmp = NULL; | ||
92 | } | ||
93 | |||
94 | |||
95 | void luaD_throw (lua_State *L, int errcode) { | ||
96 | if (L->errorJmp) { | ||
97 | L->errorJmp->status = errcode; | ||
98 | LUAI_THROW(L, L->errorJmp); | ||
99 | } | ||
100 | else { | ||
101 | L->status = cast_byte(errcode); | ||
102 | if (G(L)->panic) { | ||
103 | resetstack(L, errcode); | ||
104 | lua_unlock(L); | ||
105 | G(L)->panic(L); | ||
106 | } | ||
107 | exit(EXIT_FAILURE); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | |||
112 | int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | ||
113 | struct lua_longjmp lj; | ||
114 | lj.status = 0; | ||
115 | lj.previous = L->errorJmp; /* chain new error handler */ | ||
116 | L->errorJmp = &lj; | ||
117 | LUAI_TRY(L, &lj, | ||
118 | (*f)(L, ud); | ||
119 | ); | ||
120 | L->errorJmp = lj.previous; /* restore old error handler */ | ||
121 | return lj.status; | ||
122 | } | ||
123 | |||
124 | /* }====================================================== */ | ||
125 | |||
126 | |||
127 | static void correctstack (lua_State *L, TValue *oldstack) { | ||
128 | CallInfo *ci; | ||
129 | GCObject *up; | ||
130 | L->top = (L->top - oldstack) + L->stack; | ||
131 | for (up = L->openupval; up != NULL; up = up->gch.next) | ||
132 | gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; | ||
133 | for (ci = L->base_ci; ci <= L->ci; ci++) { | ||
134 | ci->top = (ci->top - oldstack) + L->stack; | ||
135 | ci->base = (ci->base - oldstack) + L->stack; | ||
136 | ci->func = (ci->func - oldstack) + L->stack; | ||
137 | } | ||
138 | L->base = (L->base - oldstack) + L->stack; | ||
139 | } | ||
140 | |||
141 | |||
142 | void luaD_reallocstack (lua_State *L, int newsize) { | ||
143 | TValue *oldstack = L->stack; | ||
144 | int realsize = newsize + 1 + EXTRA_STACK; | ||
145 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); | ||
146 | luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); | ||
147 | L->stacksize = realsize; | ||
148 | L->stack_last = L->stack+newsize; | ||
149 | correctstack(L, oldstack); | ||
150 | } | ||
151 | |||
152 | |||
153 | void luaD_reallocCI (lua_State *L, int newsize) { | ||
154 | CallInfo *oldci = L->base_ci; | ||
155 | luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); | ||
156 | L->size_ci = newsize; | ||
157 | L->ci = (L->ci - oldci) + L->base_ci; | ||
158 | L->end_ci = L->base_ci + L->size_ci - 1; | ||
159 | } | ||
160 | |||
161 | |||
162 | void luaD_growstack (lua_State *L, int n) { | ||
163 | if (n <= L->stacksize) /* double size is enough? */ | ||
164 | luaD_reallocstack(L, 2*L->stacksize); | ||
165 | else | ||
166 | luaD_reallocstack(L, L->stacksize + n); | ||
167 | } | ||
168 | |||
169 | |||
170 | CallInfo *luaD_growCI (lua_State *L) { | ||
171 | if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ | ||
172 | luaD_throw(L, LUA_ERRERR); | ||
173 | else { | ||
174 | luaD_reallocCI(L, 2*L->size_ci); | ||
175 | if (L->size_ci > LUAI_MAXCALLS) | ||
176 | luaG_runerror(L, "stack overflow"); | ||
177 | } | ||
178 | return ++L->ci; | ||
179 | } | ||
180 | |||
181 | |||
182 | void luaD_callhook (lua_State *L, int event, int line) { | ||
183 | lua_Hook hook = L->hook; | ||
184 | if (hook && L->allowhook) { | ||
185 | ptrdiff_t top = savestack(L, L->top); | ||
186 | ptrdiff_t ci_top = savestack(L, L->ci->top); | ||
187 | lua_Debug ar; | ||
188 | ar.event = event; | ||
189 | ar.currentline = line; | ||
190 | if (event == LUA_HOOKTAILRET) | ||
191 | ar.i_ci = 0; /* tail call; no debug information about it */ | ||
192 | else | ||
193 | ar.i_ci = cast_int(L->ci - L->base_ci); | ||
194 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | ||
195 | L->ci->top = L->top + LUA_MINSTACK; | ||
196 | lua_assert(L->ci->top <= L->stack_last); | ||
197 | L->allowhook = 0; /* cannot call hooks inside a hook */ | ||
198 | lua_unlock(L); | ||
199 | (*hook)(L, &ar); | ||
200 | lua_lock(L); | ||
201 | lua_assert(!L->allowhook); | ||
202 | L->allowhook = 1; | ||
203 | L->ci->top = restorestack(L, ci_top); | ||
204 | L->top = restorestack(L, top); | ||
205 | } | ||
206 | } | ||
207 | |||
208 | |||
209 | static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { | ||
210 | int i; | ||
211 | int nfixargs = p->numparams; | ||
212 | Table *htab = NULL; | ||
213 | StkId base, fixed; | ||
214 | for (; actual < nfixargs; ++actual) | ||
215 | setnilvalue(L->top++); | ||
216 | #if defined(LUA_COMPAT_VARARG) | ||
217 | if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */ | ||
218 | int nvar = actual - nfixargs; /* number of extra arguments */ | ||
219 | lua_assert(p->is_vararg & VARARG_HASARG); | ||
220 | luaC_checkGC(L); | ||
221 | htab = luaH_new(L, nvar, 1); /* create `arg' table */ | ||
222 | for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */ | ||
223 | setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i); | ||
224 | /* store counter in field `n' */ | ||
225 | setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); | ||
226 | } | ||
227 | #endif | ||
228 | /* move fixed parameters to final position */ | ||
229 | fixed = L->top - actual; /* first fixed argument */ | ||
230 | base = L->top; /* final position of first argument */ | ||
231 | for (i=0; i<nfixargs; i++) { | ||
232 | setobjs2s(L, L->top++, fixed+i); | ||
233 | setnilvalue(fixed+i); | ||
234 | } | ||
235 | /* add `arg' parameter */ | ||
236 | if (htab) { | ||
237 | sethvalue(L, L->top++, htab); | ||
238 | lua_assert(iswhite(obj2gco(htab))); | ||
239 | } | ||
240 | return base; | ||
241 | } | ||
242 | |||
243 | |||
244 | StkId luaD_tryfuncTM (lua_State *L, StkId func) { | ||
245 | const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); | ||
246 | StkId p; | ||
247 | ptrdiff_t funcr = savestack(L, func); | ||
248 | if (!ttisfunction(tm)) | ||
249 | luaG_typeerror(L, func, "call"); | ||
250 | /* Open a hole inside the stack at `func' */ | ||
251 | for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); | ||
252 | incr_top(L); | ||
253 | func = restorestack(L, funcr); /* previous call may change stack */ | ||
254 | setobj2s(L, func, tm); /* tag method is the new function to be called */ | ||
255 | return func; | ||
256 | } | ||
257 | |||
258 | |||
259 | |||
260 | #define inc_ci(L) \ | ||
261 | ((L->ci == L->end_ci) ? luaD_growCI(L) : \ | ||
262 | (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) | ||
263 | |||
264 | |||
265 | int luaD_precall (lua_State *L, StkId func, int nresults) { | ||
266 | LClosure *cl; | ||
267 | ptrdiff_t funcr; | ||
268 | if (!ttisfunction(func)) /* `func' is not a function? */ | ||
269 | func = luaD_tryfuncTM(L, func); /* check the `function' tag method */ | ||
270 | funcr = savestack(L, func); | ||
271 | cl = &clvalue(func)->l; | ||
272 | L->ci->savedpc = L->savedpc; | ||
273 | if (!cl->isC) { /* Lua function? prepare its call */ | ||
274 | CallInfo *ci; | ||
275 | StkId st, base; | ||
276 | Proto *p = cl->p; | ||
277 | if (p->jit_status <= JIT_S_NONE) { /* JIT compiler enabled? */ | ||
278 | if (p->jit_status == JIT_S_OK) | ||
279 | return G(L)->jit_gateLJ(L, func, nresults); /* Run compiled code. */ | ||
280 | else | ||
281 | return luaJIT_run(L, func, nresults); /* Compile and run code. */ | ||
282 | } | ||
283 | luaD_checkstack(L, p->maxstacksize); | ||
284 | func = restorestack(L, funcr); | ||
285 | if (!p->is_vararg) { /* no varargs? */ | ||
286 | base = func + 1; | ||
287 | if (L->top > base + p->numparams) | ||
288 | L->top = base + p->numparams; | ||
289 | } | ||
290 | else { /* vararg function */ | ||
291 | int nargs = cast_int(L->top - func) - 1; | ||
292 | base = adjust_varargs(L, p, nargs); | ||
293 | func = restorestack(L, funcr); /* previous call may change the stack */ | ||
294 | } | ||
295 | ci = inc_ci(L); /* now `enter' new function */ | ||
296 | ci->func = func; | ||
297 | L->base = ci->base = base; | ||
298 | ci->top = L->base + p->maxstacksize; | ||
299 | lua_assert(ci->top <= L->stack_last); | ||
300 | L->savedpc = p->code; /* starting point */ | ||
301 | ci->tailcalls = 0; | ||
302 | ci->nresults = nresults; | ||
303 | for (st = L->top; st < ci->top; st++) | ||
304 | setnilvalue(st); | ||
305 | L->top = ci->top; | ||
306 | if (L->hookmask & LUA_MASKCALL) { | ||
307 | L->savedpc++; /* hooks assume 'pc' is already incremented */ | ||
308 | luaD_callhook(L, LUA_HOOKCALL, -1); | ||
309 | L->savedpc--; /* correct 'pc' */ | ||
310 | } | ||
311 | return PCRLUA; | ||
312 | } | ||
313 | else { /* if is a C function, call it */ | ||
314 | CallInfo *ci; | ||
315 | int n; | ||
316 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | ||
317 | ci = inc_ci(L); /* now `enter' new function */ | ||
318 | ci->func = restorestack(L, funcr); | ||
319 | L->base = ci->base = ci->func + 1; | ||
320 | ci->top = L->top + LUA_MINSTACK; | ||
321 | lua_assert(ci->top <= L->stack_last); | ||
322 | ci->nresults = nresults; | ||
323 | if (L->hookmask & LUA_MASKCALL) | ||
324 | luaD_callhook(L, LUA_HOOKCALL, -1); | ||
325 | lua_unlock(L); | ||
326 | n = (*curr_func(L)->c.f)(L); /* do the actual call */ | ||
327 | lua_lock(L); | ||
328 | if (n < 0) /* yielding? */ | ||
329 | return PCRYIELD; | ||
330 | else { | ||
331 | luaD_poscall(L, L->top - n); | ||
332 | return PCRC; | ||
333 | } | ||
334 | } | ||
335 | } | ||
336 | |||
337 | |||
338 | static StkId callrethooks (lua_State *L, StkId firstResult) { | ||
339 | ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ | ||
340 | luaD_callhook(L, LUA_HOOKRET, -1); | ||
341 | if (f_isLua(L->ci)) { /* Lua function? */ | ||
342 | while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ | ||
343 | luaD_callhook(L, LUA_HOOKTAILRET, -1); | ||
344 | } | ||
345 | return restorestack(L, fr); | ||
346 | } | ||
347 | |||
348 | |||
349 | int luaD_poscall (lua_State *L, StkId firstResult) { | ||
350 | StkId res; | ||
351 | int wanted, i; | ||
352 | CallInfo *ci; | ||
353 | if (L->hookmask & LUA_MASKRET) | ||
354 | firstResult = callrethooks(L, firstResult); | ||
355 | ci = L->ci--; | ||
356 | res = ci->func; /* res == final position of 1st result */ | ||
357 | wanted = ci->nresults; | ||
358 | L->base = (ci - 1)->base; /* restore base */ | ||
359 | L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ | ||
360 | /* move results to correct place */ | ||
361 | for (i = wanted; i != 0 && firstResult < L->top; i--) | ||
362 | setobjs2s(L, res++, firstResult++); | ||
363 | while (i-- > 0) | ||
364 | setnilvalue(res++); | ||
365 | L->top = res; | ||
366 | return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ | ||
367 | } | ||
368 | |||
369 | |||
370 | /* | ||
371 | ** Call a function (C or Lua). The function to be called is at *func. | ||
372 | ** The arguments are on the stack, right after the function. | ||
373 | ** When returns, all the results are on the stack, starting at the original | ||
374 | ** function position. | ||
375 | */ | ||
376 | void luaD_call (lua_State *L, StkId func, int nResults) { | ||
377 | if (++L->nCcalls >= LUAI_MAXCCALLS) { | ||
378 | if (L->nCcalls == LUAI_MAXCCALLS) | ||
379 | luaG_runerror(L, "C stack overflow"); | ||
380 | else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) | ||
381 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ | ||
382 | } | ||
383 | if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ | ||
384 | luaV_execute(L, 1); /* call it */ | ||
385 | L->nCcalls--; | ||
386 | luaC_checkGC(L); | ||
387 | } | ||
388 | |||
389 | |||
390 | static void resume (lua_State *L, void *ud) { | ||
391 | StkId firstArg = cast(StkId, ud); | ||
392 | CallInfo *ci = L->ci; | ||
393 | if (L->status == 0) { /* start coroutine? */ | ||
394 | lua_assert(ci == L->base_ci && firstArg > L->base); | ||
395 | if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) | ||
396 | return; | ||
397 | } | ||
398 | else { /* resuming from previous yield */ | ||
399 | lua_assert(L->status == LUA_YIELD); | ||
400 | L->status = 0; | ||
401 | if (!f_isLua(ci)) { /* `common' yield? */ | ||
402 | /* finish interrupted execution of `OP_CALL' */ | ||
403 | lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || | ||
404 | GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); | ||
405 | if (luaD_poscall(L, firstArg)) /* complete it... */ | ||
406 | L->top = L->ci->top; /* and correct top if not multiple results */ | ||
407 | } | ||
408 | else /* yielded inside a hook: just continue its execution */ | ||
409 | L->base = L->ci->base; | ||
410 | } | ||
411 | luaV_execute(L, cast_int(L->ci - L->base_ci)); | ||
412 | } | ||
413 | |||
414 | |||
415 | static int resume_error (lua_State *L, const char *msg) { | ||
416 | L->top = L->ci->base; | ||
417 | setsvalue2s(L, L->top, luaS_new(L, msg)); | ||
418 | incr_top(L); | ||
419 | lua_unlock(L); | ||
420 | return LUA_ERRRUN; | ||
421 | } | ||
422 | |||
423 | |||
424 | LUA_API int lua_resume (lua_State *L, int nargs) { | ||
425 | int status; | ||
426 | lua_lock(L); | ||
427 | if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) | ||
428 | return resume_error(L, "cannot resume non-suspended coroutine"); | ||
429 | luai_userstateresume(L, nargs); | ||
430 | lua_assert(L->errfunc == 0 && L->nCcalls == 0); | ||
431 | status = luaD_rawrunprotected(L, resume, L->top - nargs); | ||
432 | if (status != 0) { /* error? */ | ||
433 | L->status = cast_byte(status); /* mark thread as `dead' */ | ||
434 | luaD_seterrorobj(L, status, L->top); | ||
435 | L->ci->top = L->top; | ||
436 | } | ||
437 | else | ||
438 | status = L->status; | ||
439 | lua_unlock(L); | ||
440 | return status; | ||
441 | } | ||
442 | |||
443 | |||
444 | LUA_API int lua_yield (lua_State *L, int nresults) { | ||
445 | luai_userstateyield(L, nresults); | ||
446 | lua_lock(L); | ||
447 | if (L->nCcalls > 0) | ||
448 | luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); | ||
449 | L->base = L->top - nresults; /* protect stack slots below */ | ||
450 | L->status = LUA_YIELD; | ||
451 | lua_unlock(L); | ||
452 | return -1; | ||
453 | } | ||
454 | |||
455 | |||
456 | int luaD_pcall (lua_State *L, Pfunc func, void *u, | ||
457 | ptrdiff_t old_top, ptrdiff_t ef) { | ||
458 | int status; | ||
459 | unsigned short oldnCcalls = L->nCcalls; | ||
460 | ptrdiff_t old_ci = saveci(L, L->ci); | ||
461 | lu_byte old_allowhooks = L->allowhook; | ||
462 | ptrdiff_t old_errfunc = L->errfunc; | ||
463 | L->errfunc = ef; | ||
464 | status = luaD_rawrunprotected(L, func, u); | ||
465 | if (status != 0) { /* an error occurred? */ | ||
466 | StkId oldtop = restorestack(L, old_top); | ||
467 | luaF_close(L, oldtop); /* close eventual pending closures */ | ||
468 | luaD_seterrorobj(L, status, oldtop); | ||
469 | L->nCcalls = oldnCcalls; | ||
470 | L->ci = restoreci(L, old_ci); | ||
471 | L->base = L->ci->base; | ||
472 | L->savedpc = L->ci->savedpc; | ||
473 | L->allowhook = old_allowhooks; | ||
474 | restore_stack_limit(L); | ||
475 | } | ||
476 | L->errfunc = old_errfunc; | ||
477 | return status; | ||
478 | } | ||
479 | |||
480 | |||
481 | |||
482 | /* | ||
483 | ** Execute a protected parser. | ||
484 | */ | ||
485 | struct SParser { /* data to `f_parser' */ | ||
486 | ZIO *z; | ||
487 | Mbuffer buff; /* buffer to be used by the scanner */ | ||
488 | const char *name; | ||
489 | }; | ||
490 | |||
491 | static void f_parser (lua_State *L, void *ud) { | ||
492 | int i; | ||
493 | Proto *tf; | ||
494 | Closure *cl; | ||
495 | struct SParser *p = cast(struct SParser *, ud); | ||
496 | int c = luaZ_lookahead(p->z); | ||
497 | luaC_checkGC(L); | ||
498 | tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, | ||
499 | &p->buff, p->name); | ||
500 | cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); | ||
501 | cl->l.p = tf; | ||
502 | for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ | ||
503 | cl->l.upvals[i] = luaF_newupval(L); | ||
504 | setclvalue(L, L->top, cl); | ||
505 | incr_top(L); | ||
506 | } | ||
507 | |||
508 | |||
509 | int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { | ||
510 | struct SParser p; | ||
511 | int status; | ||
512 | p.z = z; p.name = name; | ||
513 | luaZ_initbuffer(L, &p.buff); | ||
514 | status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); | ||
515 | luaZ_freebuffer(L, &p.buff); | ||
516 | return status; | ||
517 | } | ||
518 | |||
519 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ldo.h b/libraries/LuaJIT-1.1.7/src/ldo.h new file mode 100644 index 0000000..63760f9 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ldo.h | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | ** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Stack and Call structure of Lua | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef ldo_h | ||
8 | #define ldo_h | ||
9 | |||
10 | |||
11 | #include "lobject.h" | ||
12 | #include "lstate.h" | ||
13 | #include "lzio.h" | ||
14 | |||
15 | |||
16 | #define luaD_checkstack(L,n) \ | ||
17 | if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ | ||
18 | luaD_growstack(L, n); \ | ||
19 | else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); | ||
20 | |||
21 | |||
22 | #define incr_top(L) {luaD_checkstack(L,1); L->top++;} | ||
23 | |||
24 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) | ||
25 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) | ||
26 | |||
27 | #define saveci(L,p) ((char *)(p) - (char *)L->base_ci) | ||
28 | #define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) | ||
29 | |||
30 | |||
31 | /* results from luaD_precall */ | ||
32 | #define PCRLUA 0 /* initiated a call to a Lua function */ | ||
33 | #define PCRC 1 /* did a call to a C function */ | ||
34 | #define PCRYIELD 2 /* C function yielded */ | ||
35 | |||
36 | |||
37 | /* type of protected functions, to be ran by `runprotected' */ | ||
38 | typedef void (*Pfunc) (lua_State *L, void *ud); | ||
39 | |||
40 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); | ||
41 | LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); | ||
42 | LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func); | ||
43 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); | ||
44 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); | ||
45 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, | ||
46 | ptrdiff_t oldtop, ptrdiff_t ef); | ||
47 | LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); | ||
48 | LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize); | ||
49 | LUAI_FUNC CallInfo *luaD_growCI (lua_State *L); | ||
50 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); | ||
51 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); | ||
52 | |||
53 | LUAI_FUNC void luaD_throw (lua_State *L, int errcode); | ||
54 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); | ||
55 | |||
56 | LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); | ||
57 | |||
58 | #endif | ||
59 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ldump.c b/libraries/LuaJIT-1.1.7/src/ldump.c new file mode 100644 index 0000000..c9d3d48 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ldump.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | ** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** save precompiled Lua chunks | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #include <stddef.h> | ||
8 | |||
9 | #define ldump_c | ||
10 | #define LUA_CORE | ||
11 | |||
12 | #include "lua.h" | ||
13 | |||
14 | #include "lobject.h" | ||
15 | #include "lstate.h" | ||
16 | #include "lundump.h" | ||
17 | |||
18 | typedef struct { | ||
19 | lua_State* L; | ||
20 | lua_Writer writer; | ||
21 | void* data; | ||
22 | int strip; | ||
23 | int status; | ||
24 | } DumpState; | ||
25 | |||
26 | #define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) | ||
27 | #define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) | ||
28 | |||
29 | static void DumpBlock(const void* b, size_t size, DumpState* D) | ||
30 | { | ||
31 | if (D->status==0) | ||
32 | { | ||
33 | lua_unlock(D->L); | ||
34 | D->status=(*D->writer)(D->L,b,size,D->data); | ||
35 | lua_lock(D->L); | ||
36 | } | ||
37 | } | ||
38 | |||
39 | static void DumpChar(int y, DumpState* D) | ||
40 | { | ||
41 | char x=(char)y; | ||
42 | DumpVar(x,D); | ||
43 | } | ||
44 | |||
45 | static void DumpInt(int x, DumpState* D) | ||
46 | { | ||
47 | DumpVar(x,D); | ||
48 | } | ||
49 | |||
50 | static void DumpNumber(lua_Number x, DumpState* D) | ||
51 | { | ||
52 | DumpVar(x,D); | ||
53 | } | ||
54 | |||
55 | static void DumpVector(const void* b, int n, size_t size, DumpState* D) | ||
56 | { | ||
57 | DumpInt(n,D); | ||
58 | DumpMem(b,n,size,D); | ||
59 | } | ||
60 | |||
61 | static void DumpString(const TString* s, DumpState* D) | ||
62 | { | ||
63 | if (s==NULL || getstr(s)==NULL) | ||
64 | { | ||
65 | size_t size=0; | ||
66 | DumpVar(size,D); | ||
67 | } | ||
68 | else | ||
69 | { | ||
70 | size_t size=s->tsv.len+1; /* include trailing '\0' */ | ||
71 | DumpVar(size,D); | ||
72 | DumpBlock(getstr(s),size,D); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | #define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) | ||
77 | |||
78 | static void DumpFunction(const Proto* f, const TString* p, DumpState* D); | ||
79 | |||
80 | static void DumpConstants(const Proto* f, DumpState* D) | ||
81 | { | ||
82 | int i,n=f->sizek; | ||
83 | DumpInt(n,D); | ||
84 | for (i=0; i<n; i++) | ||
85 | { | ||
86 | const TValue* o=&f->k[i]; | ||
87 | DumpChar(ttype(o),D); | ||
88 | switch (ttype(o)) | ||
89 | { | ||
90 | case LUA_TNIL: | ||
91 | break; | ||
92 | case LUA_TBOOLEAN: | ||
93 | DumpChar(bvalue(o),D); | ||
94 | break; | ||
95 | case LUA_TNUMBER: | ||
96 | DumpNumber(nvalue(o),D); | ||
97 | break; | ||
98 | case LUA_TSTRING: | ||
99 | DumpString(rawtsvalue(o),D); | ||
100 | break; | ||
101 | default: | ||
102 | lua_assert(0); /* cannot happen */ | ||
103 | break; | ||
104 | } | ||
105 | } | ||
106 | n=f->sizep; | ||
107 | DumpInt(n,D); | ||
108 | for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D); | ||
109 | } | ||
110 | |||
111 | static void DumpDebug(const Proto* f, DumpState* D) | ||
112 | { | ||
113 | int i,n; | ||
114 | n= (D->strip) ? 0 : f->sizelineinfo; | ||
115 | DumpVector(f->lineinfo,n,sizeof(int),D); | ||
116 | n= (D->strip) ? 0 : f->sizelocvars; | ||
117 | DumpInt(n,D); | ||
118 | for (i=0; i<n; i++) | ||
119 | { | ||
120 | DumpString(f->locvars[i].varname,D); | ||
121 | DumpInt(f->locvars[i].startpc,D); | ||
122 | DumpInt(f->locvars[i].endpc,D); | ||
123 | } | ||
124 | n= (D->strip) ? 0 : f->sizeupvalues; | ||
125 | DumpInt(n,D); | ||
126 | for (i=0; i<n; i++) DumpString(f->upvalues[i],D); | ||
127 | } | ||
128 | |||
129 | static void DumpFunction(const Proto* f, const TString* p, DumpState* D) | ||
130 | { | ||
131 | DumpString((f->source==p || D->strip) ? NULL : f->source,D); | ||
132 | DumpInt(f->linedefined,D); | ||
133 | DumpInt(f->lastlinedefined,D); | ||
134 | DumpChar(f->nups,D); | ||
135 | DumpChar(f->numparams,D); | ||
136 | DumpChar(f->is_vararg,D); | ||
137 | DumpChar(f->maxstacksize,D); | ||
138 | DumpCode(f,D); | ||
139 | DumpConstants(f,D); | ||
140 | DumpDebug(f,D); | ||
141 | } | ||
142 | |||
143 | static void DumpHeader(DumpState* D) | ||
144 | { | ||
145 | char h[LUAC_HEADERSIZE]; | ||
146 | luaU_header(h); | ||
147 | DumpBlock(h,LUAC_HEADERSIZE,D); | ||
148 | } | ||
149 | |||
150 | /* | ||
151 | ** dump Lua function as precompiled chunk | ||
152 | */ | ||
153 | int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) | ||
154 | { | ||
155 | DumpState D; | ||
156 | D.L=L; | ||
157 | D.writer=w; | ||
158 | D.data=data; | ||
159 | D.strip=strip; | ||
160 | D.status=0; | ||
161 | DumpHeader(&D); | ||
162 | DumpFunction(f,NULL,&D); | ||
163 | return D.status; | ||
164 | } | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lfunc.c b/libraries/LuaJIT-1.1.7/src/lfunc.c new file mode 100644 index 0000000..334e305 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lfunc.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* | ||
2 | ** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ | ||
3 | ** Auxiliary functions to manipulate prototypes and closures | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <stddef.h> | ||
9 | |||
10 | #define lfunc_c | ||
11 | #define LUA_CORE | ||
12 | |||
13 | #include "lua.h" | ||
14 | |||
15 | #include "lfunc.h" | ||
16 | #include "lgc.h" | ||
17 | #include "lmem.h" | ||
18 | #include "lobject.h" | ||
19 | #include "lstate.h" | ||
20 | #include "ljit.h" | ||
21 | |||
22 | |||
23 | |||
24 | Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { | ||
25 | Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); | ||
26 | luaC_link(L, obj2gco(c), LUA_TFUNCTION); | ||
27 | c->c.isC = 1; | ||
28 | c->c.env = e; | ||
29 | c->c.nupvalues = cast_byte(nelems); | ||
30 | c->c.jit_gate = G(L)->jit_gateJC; | ||
31 | return c; | ||
32 | } | ||
33 | |||
34 | |||
35 | Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { | ||
36 | Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); | ||
37 | luaC_link(L, obj2gco(c), LUA_TFUNCTION); | ||
38 | c->l.isC = 0; | ||
39 | c->l.env = e; | ||
40 | c->l.jit_gate = G(L)->jit_gateJL; | ||
41 | c->l.nupvalues = cast_byte(nelems); | ||
42 | while (nelems--) c->l.upvals[nelems] = NULL; | ||
43 | return c; | ||
44 | } | ||
45 | |||
46 | |||
47 | UpVal *luaF_newupval (lua_State *L) { | ||
48 | UpVal *uv = luaM_new(L, UpVal); | ||
49 | luaC_link(L, obj2gco(uv), LUA_TUPVAL); | ||
50 | uv->v = &uv->u.value; | ||
51 | setnilvalue(uv->v); | ||
52 | return uv; | ||
53 | } | ||
54 | |||
55 | |||
56 | UpVal *luaF_findupval (lua_State *L, StkId level) { | ||
57 | global_State *g = G(L); | ||
58 | GCObject **pp = &L->openupval; | ||
59 | UpVal *p; | ||
60 | UpVal *uv; | ||
61 | while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { | ||
62 | lua_assert(p->v != &p->u.value); | ||
63 | if (p->v == level) { /* found a corresponding upvalue? */ | ||
64 | if (isdead(g, obj2gco(p))) /* is it dead? */ | ||
65 | changewhite(obj2gco(p)); /* ressurect it */ | ||
66 | return p; | ||
67 | } | ||
68 | pp = &p->next; | ||
69 | } | ||
70 | uv = luaM_new(L, UpVal); /* not found: create a new one */ | ||
71 | uv->tt = LUA_TUPVAL; | ||
72 | uv->marked = luaC_white(g); | ||
73 | uv->v = level; /* current value lives in the stack */ | ||
74 | uv->next = *pp; /* chain it in the proper position */ | ||
75 | *pp = obj2gco(uv); | ||
76 | uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ | ||
77 | uv->u.l.next = g->uvhead.u.l.next; | ||
78 | uv->u.l.next->u.l.prev = uv; | ||
79 | g->uvhead.u.l.next = uv; | ||
80 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | ||
81 | return uv; | ||
82 | } | ||
83 | |||
84 | |||
85 | static void unlinkupval (UpVal *uv) { | ||
86 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | ||
87 | uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ | ||
88 | uv->u.l.prev->u.l.next = uv->u.l.next; | ||
89 | } | ||
90 | |||
91 | |||
92 | void luaF_freeupval (lua_State *L, UpVal *uv) { | ||
93 | if (uv->v != &uv->u.value) /* is it open? */ | ||
94 | unlinkupval(uv); /* remove from open list */ | ||
95 | luaM_free(L, uv); /* free upvalue */ | ||
96 | } | ||
97 | |||
98 | |||
99 | void luaF_close (lua_State *L, StkId level) { | ||
100 | UpVal *uv; | ||
101 | global_State *g = G(L); | ||
102 | while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { | ||
103 | GCObject *o = obj2gco(uv); | ||
104 | lua_assert(!isblack(o) && uv->v != &uv->u.value); | ||
105 | L->openupval = uv->next; /* remove from `open' list */ | ||
106 | if (isdead(g, o)) | ||
107 | luaF_freeupval(L, uv); /* free upvalue */ | ||
108 | else { | ||
109 | unlinkupval(uv); | ||
110 | setobj(L, &uv->u.value, uv->v); | ||
111 | uv->v = &uv->u.value; /* now current value lives here */ | ||
112 | luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | |||
117 | |||
118 | Proto *luaF_newproto (lua_State *L) { | ||
119 | Proto *f = luaM_new(L, Proto); | ||
120 | luaC_link(L, obj2gco(f), LUA_TPROTO); | ||
121 | f->k = NULL; | ||
122 | f->sizek = 0; | ||
123 | f->p = NULL; | ||
124 | f->sizep = 0; | ||
125 | f->code = NULL; | ||
126 | f->sizecode = 0; | ||
127 | f->sizelineinfo = 0; | ||
128 | f->sizeupvalues = 0; | ||
129 | f->nups = 0; | ||
130 | f->upvalues = NULL; | ||
131 | f->numparams = 0; | ||
132 | f->is_vararg = 0; | ||
133 | f->maxstacksize = 0; | ||
134 | f->lineinfo = NULL; | ||
135 | f->sizelocvars = 0; | ||
136 | f->locvars = NULL; | ||
137 | f->linedefined = 0; | ||
138 | f->lastlinedefined = 0; | ||
139 | f->source = NULL; | ||
140 | /* LuaJIT extensions */ | ||
141 | f->jit_mcode = NULL; | ||
142 | f->jit_szmcode = 0; | ||
143 | f->jit_status = JIT_S_NONE; | ||
144 | return f; | ||
145 | } | ||
146 | |||
147 | |||
148 | void luaF_freeproto (lua_State *L, Proto *f) { | ||
149 | luaJIT_freeproto(L, f); | ||
150 | luaM_freearray(L, f->code, f->sizecode, Instruction); | ||
151 | luaM_freearray(L, f->p, f->sizep, Proto *); | ||
152 | luaM_freearray(L, f->k, f->sizek, TValue); | ||
153 | luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); | ||
154 | luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); | ||
155 | luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); | ||
156 | luaM_free(L, f); | ||
157 | } | ||
158 | |||
159 | |||
160 | void luaF_freeclosure (lua_State *L, Closure *c) { | ||
161 | int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : | ||
162 | sizeLclosure(c->l.nupvalues); | ||
163 | luaM_freemem(L, c, size); | ||
164 | } | ||
165 | |||
166 | |||
167 | /* | ||
168 | ** Look for n-th local variable at line `line' in function `func'. | ||
169 | ** Returns NULL if not found. | ||
170 | */ | ||
171 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { | ||
172 | int i; | ||
173 | for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) { | ||
174 | if (pc < f->locvars[i].endpc) { /* is variable active? */ | ||
175 | local_number--; | ||
176 | if (local_number == 0) | ||
177 | return getstr(f->locvars[i].varname); | ||
178 | } | ||
179 | } | ||
180 | return NULL; /* not found */ | ||
181 | } | ||
182 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lfunc.h b/libraries/LuaJIT-1.1.7/src/lfunc.h new file mode 100644 index 0000000..a68cf51 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lfunc.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | ** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Auxiliary functions to manipulate prototypes and closures | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lfunc_h | ||
8 | #define lfunc_h | ||
9 | |||
10 | |||
11 | #include "lobject.h" | ||
12 | |||
13 | |||
14 | #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ | ||
15 | cast(int, sizeof(TValue)*((n)-1))) | ||
16 | |||
17 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ | ||
18 | cast(int, sizeof(TValue *)*((n)-1))) | ||
19 | |||
20 | |||
21 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); | ||
22 | LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); | ||
23 | LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); | ||
24 | LUAI_FUNC UpVal *luaF_newupval (lua_State *L); | ||
25 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); | ||
26 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); | ||
27 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); | ||
28 | LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c); | ||
29 | LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); | ||
30 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, | ||
31 | int pc); | ||
32 | |||
33 | |||
34 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lgc.c b/libraries/LuaJIT-1.1.7/src/lgc.c new file mode 100644 index 0000000..d9e0b78 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lgc.c | |||
@@ -0,0 +1,711 @@ | |||
1 | /* | ||
2 | ** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Garbage Collector | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #include <string.h> | ||
8 | |||
9 | #define lgc_c | ||
10 | #define LUA_CORE | ||
11 | |||
12 | #include "lua.h" | ||
13 | |||
14 | #include "ldebug.h" | ||
15 | #include "ldo.h" | ||
16 | #include "lfunc.h" | ||
17 | #include "lgc.h" | ||
18 | #include "lmem.h" | ||
19 | #include "lobject.h" | ||
20 | #include "lstate.h" | ||
21 | #include "lstring.h" | ||
22 | #include "ltable.h" | ||
23 | #include "ltm.h" | ||
24 | |||
25 | |||
26 | #define GCSTEPSIZE 1024u | ||
27 | #define GCSWEEPMAX 40 | ||
28 | #define GCSWEEPCOST 10 | ||
29 | #define GCFINALIZECOST 100 | ||
30 | |||
31 | |||
32 | #define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) | ||
33 | |||
34 | #define makewhite(g,x) \ | ||
35 | ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) | ||
36 | |||
37 | #define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) | ||
38 | #define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) | ||
39 | |||
40 | #define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) | ||
41 | |||
42 | |||
43 | #define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) | ||
44 | #define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) | ||
45 | |||
46 | |||
47 | #define KEYWEAK bitmask(KEYWEAKBIT) | ||
48 | #define VALUEWEAK bitmask(VALUEWEAKBIT) | ||
49 | |||
50 | |||
51 | |||
52 | #define markvalue(g,o) { checkconsistency(o); \ | ||
53 | if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } | ||
54 | |||
55 | #define markobject(g,t) { if (iswhite(obj2gco(t))) \ | ||
56 | reallymarkobject(g, obj2gco(t)); } | ||
57 | |||
58 | |||
59 | #define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) | ||
60 | |||
61 | |||
62 | static void removeentry (Node *n) { | ||
63 | lua_assert(ttisnil(gval(n))); | ||
64 | if (iscollectable(gkey(n))) | ||
65 | setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ | ||
66 | } | ||
67 | |||
68 | |||
69 | static void reallymarkobject (global_State *g, GCObject *o) { | ||
70 | lua_assert(iswhite(o) && !isdead(g, o)); | ||
71 | white2gray(o); | ||
72 | switch (o->gch.tt) { | ||
73 | case LUA_TSTRING: { | ||
74 | return; | ||
75 | } | ||
76 | case LUA_TUSERDATA: { | ||
77 | Table *mt = gco2u(o)->metatable; | ||
78 | gray2black(o); /* udata are never gray */ | ||
79 | if (mt) markobject(g, mt); | ||
80 | markobject(g, gco2u(o)->env); | ||
81 | return; | ||
82 | } | ||
83 | case LUA_TUPVAL: { | ||
84 | UpVal *uv = gco2uv(o); | ||
85 | markvalue(g, uv->v); | ||
86 | if (uv->v == &uv->u.value) /* closed? */ | ||
87 | gray2black(o); /* open upvalues are never black */ | ||
88 | return; | ||
89 | } | ||
90 | case LUA_TFUNCTION: { | ||
91 | gco2cl(o)->c.gclist = g->gray; | ||
92 | g->gray = o; | ||
93 | break; | ||
94 | } | ||
95 | case LUA_TTABLE: { | ||
96 | gco2h(o)->gclist = g->gray; | ||
97 | g->gray = o; | ||
98 | break; | ||
99 | } | ||
100 | case LUA_TTHREAD: { | ||
101 | gco2th(o)->gclist = g->gray; | ||
102 | g->gray = o; | ||
103 | break; | ||
104 | } | ||
105 | case LUA_TPROTO: { | ||
106 | gco2p(o)->gclist = g->gray; | ||
107 | g->gray = o; | ||
108 | break; | ||
109 | } | ||
110 | default: lua_assert(0); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | |||
115 | static void marktmu (global_State *g) { | ||
116 | GCObject *u = g->tmudata; | ||
117 | if (u) { | ||
118 | do { | ||
119 | u = u->gch.next; | ||
120 | makewhite(g, u); /* may be marked, if left from previous GC */ | ||
121 | reallymarkobject(g, u); | ||
122 | } while (u != g->tmudata); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | |||
127 | /* move `dead' udata that need finalization to list `tmudata' */ | ||
128 | size_t luaC_separateudata (lua_State *L, int all) { | ||
129 | global_State *g = G(L); | ||
130 | size_t deadmem = 0; | ||
131 | GCObject **p = &g->mainthread->next; | ||
132 | GCObject *curr; | ||
133 | while ((curr = *p) != NULL) { | ||
134 | if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) | ||
135 | p = &curr->gch.next; /* don't bother with them */ | ||
136 | else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) { | ||
137 | markfinalized(gco2u(curr)); /* don't need finalization */ | ||
138 | p = &curr->gch.next; | ||
139 | } | ||
140 | else { /* must call its gc method */ | ||
141 | deadmem += sizeudata(gco2u(curr)); | ||
142 | markfinalized(gco2u(curr)); | ||
143 | *p = curr->gch.next; | ||
144 | /* link `curr' at the end of `tmudata' list */ | ||
145 | if (g->tmudata == NULL) /* list is empty? */ | ||
146 | g->tmudata = curr->gch.next = curr; /* creates a circular list */ | ||
147 | else { | ||
148 | curr->gch.next = g->tmudata->gch.next; | ||
149 | g->tmudata->gch.next = curr; | ||
150 | g->tmudata = curr; | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | return deadmem; | ||
155 | } | ||
156 | |||
157 | |||
158 | static int traversetable (global_State *g, Table *h) { | ||
159 | int i; | ||
160 | int weakkey = 0; | ||
161 | int weakvalue = 0; | ||
162 | const TValue *mode; | ||
163 | if (h->metatable) | ||
164 | markobject(g, h->metatable); | ||
165 | mode = gfasttm(g, h->metatable, TM_MODE); | ||
166 | if (mode && ttisstring(mode)) { /* is there a weak mode? */ | ||
167 | weakkey = (strchr(svalue(mode), 'k') != NULL); | ||
168 | weakvalue = (strchr(svalue(mode), 'v') != NULL); | ||
169 | if (weakkey || weakvalue) { /* is really weak? */ | ||
170 | h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ | ||
171 | h->marked |= cast_byte((weakkey << KEYWEAKBIT) | | ||
172 | (weakvalue << VALUEWEAKBIT)); | ||
173 | h->gclist = g->weak; /* must be cleared after GC, ... */ | ||
174 | g->weak = obj2gco(h); /* ... so put in the appropriate list */ | ||
175 | } | ||
176 | } | ||
177 | if (weakkey && weakvalue) return 1; | ||
178 | if (!weakvalue) { | ||
179 | i = h->sizearray; | ||
180 | while (i--) | ||
181 | markvalue(g, &h->array[i]); | ||
182 | } | ||
183 | i = sizenode(h); | ||
184 | while (i--) { | ||
185 | Node *n = gnode(h, i); | ||
186 | lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); | ||
187 | if (ttisnil(gval(n))) | ||
188 | removeentry(n); /* remove empty entries */ | ||
189 | else { | ||
190 | lua_assert(!ttisnil(gkey(n))); | ||
191 | if (!weakkey) markvalue(g, gkey(n)); | ||
192 | if (!weakvalue) markvalue(g, gval(n)); | ||
193 | } | ||
194 | } | ||
195 | return weakkey || weakvalue; | ||
196 | } | ||
197 | |||
198 | |||
199 | /* | ||
200 | ** All marks are conditional because a GC may happen while the | ||
201 | ** prototype is still being created | ||
202 | */ | ||
203 | static void traverseproto (global_State *g, Proto *f) { | ||
204 | int i; | ||
205 | if (f->source) stringmark(f->source); | ||
206 | for (i=0; i<f->sizek; i++) /* mark literals */ | ||
207 | markvalue(g, &f->k[i]); | ||
208 | for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */ | ||
209 | if (f->upvalues[i]) | ||
210 | stringmark(f->upvalues[i]); | ||
211 | } | ||
212 | for (i=0; i<f->sizep; i++) { /* mark nested protos */ | ||
213 | if (f->p[i]) | ||
214 | markobject(g, f->p[i]); | ||
215 | } | ||
216 | for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */ | ||
217 | if (f->locvars[i].varname) | ||
218 | stringmark(f->locvars[i].varname); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | |||
223 | |||
224 | static void traverseclosure (global_State *g, Closure *cl) { | ||
225 | markobject(g, cl->c.env); | ||
226 | if (cl->c.isC) { | ||
227 | int i; | ||
228 | for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */ | ||
229 | markvalue(g, &cl->c.upvalue[i]); | ||
230 | } | ||
231 | else { | ||
232 | int i; | ||
233 | lua_assert(cl->l.nupvalues == cl->l.p->nups); | ||
234 | markobject(g, cl->l.p); | ||
235 | for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ | ||
236 | markobject(g, cl->l.upvals[i]); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | |||
241 | static void checkstacksizes (lua_State *L, StkId max) { | ||
242 | int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ | ||
243 | int s_used = cast_int(max - L->stack); /* part of stack in use */ | ||
244 | if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ | ||
245 | return; /* do not touch the stacks */ | ||
246 | if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) | ||
247 | luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ | ||
248 | condhardstacktests(luaD_reallocCI(L, ci_used + 1)); | ||
249 | if (4*s_used < L->stacksize && | ||
250 | 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) | ||
251 | luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ | ||
252 | condhardstacktests(luaD_reallocstack(L, s_used)); | ||
253 | } | ||
254 | |||
255 | |||
256 | static void traversestack (global_State *g, lua_State *l) { | ||
257 | StkId o, lim; | ||
258 | CallInfo *ci; | ||
259 | markvalue(g, gt(l)); | ||
260 | lim = l->top; | ||
261 | for (ci = l->base_ci; ci <= l->ci; ci++) { | ||
262 | lua_assert(ci->top <= l->stack_last); | ||
263 | if (lim < ci->top) lim = ci->top; | ||
264 | } | ||
265 | for (o = l->stack; o < l->top; o++) | ||
266 | markvalue(g, o); | ||
267 | for (; o <= lim; o++) | ||
268 | setnilvalue(o); | ||
269 | checkstacksizes(l, lim); | ||
270 | } | ||
271 | |||
272 | |||
273 | /* | ||
274 | ** traverse one gray object, turning it to black. | ||
275 | ** Returns `quantity' traversed. | ||
276 | */ | ||
277 | static l_mem propagatemark (global_State *g) { | ||
278 | GCObject *o = g->gray; | ||
279 | lua_assert(isgray(o)); | ||
280 | gray2black(o); | ||
281 | switch (o->gch.tt) { | ||
282 | case LUA_TTABLE: { | ||
283 | Table *h = gco2h(o); | ||
284 | g->gray = h->gclist; | ||
285 | if (traversetable(g, h)) /* table is weak? */ | ||
286 | black2gray(o); /* keep it gray */ | ||
287 | return sizeof(Table) + sizeof(TValue) * h->sizearray + | ||
288 | sizeof(Node) * sizenode(h); | ||
289 | } | ||
290 | case LUA_TFUNCTION: { | ||
291 | Closure *cl = gco2cl(o); | ||
292 | g->gray = cl->c.gclist; | ||
293 | traverseclosure(g, cl); | ||
294 | return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : | ||
295 | sizeLclosure(cl->l.nupvalues); | ||
296 | } | ||
297 | case LUA_TTHREAD: { | ||
298 | lua_State *th = gco2th(o); | ||
299 | g->gray = th->gclist; | ||
300 | th->gclist = g->grayagain; | ||
301 | g->grayagain = o; | ||
302 | black2gray(o); | ||
303 | traversestack(g, th); | ||
304 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize + | ||
305 | sizeof(CallInfo) * th->size_ci; | ||
306 | } | ||
307 | case LUA_TPROTO: { | ||
308 | Proto *p = gco2p(o); | ||
309 | g->gray = p->gclist; | ||
310 | traverseproto(g, p); | ||
311 | return sizeof(Proto) + sizeof(Instruction) * p->sizecode + | ||
312 | sizeof(Proto *) * p->sizep + | ||
313 | sizeof(TValue) * p->sizek + | ||
314 | sizeof(int) * p->sizelineinfo + | ||
315 | sizeof(LocVar) * p->sizelocvars + | ||
316 | sizeof(TString *) * p->sizeupvalues; | ||
317 | } | ||
318 | default: lua_assert(0); return 0; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | |||
323 | static size_t propagateall (global_State *g) { | ||
324 | size_t m = 0; | ||
325 | while (g->gray) m += propagatemark(g); | ||
326 | return m; | ||
327 | } | ||
328 | |||
329 | |||
330 | /* | ||
331 | ** The next function tells whether a key or value can be cleared from | ||
332 | ** a weak table. Non-collectable objects are never removed from weak | ||
333 | ** tables. Strings behave as `values', so are never removed too. for | ||
334 | ** other objects: if really collected, cannot keep them; for userdata | ||
335 | ** being finalized, keep them in keys, but not in values | ||
336 | */ | ||
337 | static int iscleared (const TValue *o, int iskey) { | ||
338 | if (!iscollectable(o)) return 0; | ||
339 | if (ttisstring(o)) { | ||
340 | stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ | ||
341 | return 0; | ||
342 | } | ||
343 | return iswhite(gcvalue(o)) || | ||
344 | (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); | ||
345 | } | ||
346 | |||
347 | |||
348 | /* | ||
349 | ** clear collected entries from weaktables | ||
350 | */ | ||
351 | static void cleartable (GCObject *l) { | ||
352 | while (l) { | ||
353 | Table *h = gco2h(l); | ||
354 | int i = h->sizearray; | ||
355 | lua_assert(testbit(h->marked, VALUEWEAKBIT) || | ||
356 | testbit(h->marked, KEYWEAKBIT)); | ||
357 | if (testbit(h->marked, VALUEWEAKBIT)) { | ||
358 | while (i--) { | ||
359 | TValue *o = &h->array[i]; | ||
360 | if (iscleared(o, 0)) /* value was collected? */ | ||
361 | setnilvalue(o); /* remove value */ | ||
362 | } | ||
363 | } | ||
364 | i = sizenode(h); | ||
365 | while (i--) { | ||
366 | Node *n = gnode(h, i); | ||
367 | if (!ttisnil(gval(n)) && /* non-empty entry? */ | ||
368 | (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { | ||
369 | setnilvalue(gval(n)); /* remove value ... */ | ||
370 | removeentry(n); /* remove entry from table */ | ||
371 | } | ||
372 | } | ||
373 | l = h->gclist; | ||
374 | } | ||
375 | } | ||
376 | |||
377 | |||
378 | static void freeobj (lua_State *L, GCObject *o) { | ||
379 | switch (o->gch.tt) { | ||
380 | case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; | ||
381 | case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; | ||
382 | case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; | ||
383 | case LUA_TTABLE: luaH_free(L, gco2h(o)); break; | ||
384 | case LUA_TTHREAD: { | ||
385 | lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); | ||
386 | luaE_freethread(L, gco2th(o)); | ||
387 | break; | ||
388 | } | ||
389 | case LUA_TSTRING: { | ||
390 | G(L)->strt.nuse--; | ||
391 | luaM_freemem(L, o, sizestring(gco2ts(o))); | ||
392 | break; | ||
393 | } | ||
394 | case LUA_TUSERDATA: { | ||
395 | luaM_freemem(L, o, sizeudata(gco2u(o))); | ||
396 | break; | ||
397 | } | ||
398 | default: lua_assert(0); | ||
399 | } | ||
400 | } | ||
401 | |||
402 | |||
403 | |||
404 | #define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) | ||
405 | |||
406 | |||
407 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { | ||
408 | GCObject *curr; | ||
409 | global_State *g = G(L); | ||
410 | int deadmask = otherwhite(g); | ||
411 | while ((curr = *p) != NULL && count-- > 0) { | ||
412 | if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ | ||
413 | sweepwholelist(L, &gco2th(curr)->openupval); | ||
414 | if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ | ||
415 | lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); | ||
416 | makewhite(g, curr); /* make it white (for next cycle) */ | ||
417 | p = &curr->gch.next; | ||
418 | } | ||
419 | else { /* must erase `curr' */ | ||
420 | lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); | ||
421 | *p = curr->gch.next; | ||
422 | if (curr == g->rootgc) /* is the first element of the list? */ | ||
423 | g->rootgc = curr->gch.next; /* adjust first */ | ||
424 | freeobj(L, curr); | ||
425 | } | ||
426 | } | ||
427 | return p; | ||
428 | } | ||
429 | |||
430 | |||
431 | static void checkSizes (lua_State *L) { | ||
432 | global_State *g = G(L); | ||
433 | /* check size of string hash */ | ||
434 | if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && | ||
435 | g->strt.size > MINSTRTABSIZE*2) | ||
436 | luaS_resize(L, g->strt.size/2); /* table is too big */ | ||
437 | /* check size of buffer */ | ||
438 | if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ | ||
439 | size_t newsize = luaZ_sizebuffer(&g->buff) / 2; | ||
440 | luaZ_resizebuffer(L, &g->buff, newsize); | ||
441 | } | ||
442 | } | ||
443 | |||
444 | |||
445 | static void GCTM (lua_State *L) { | ||
446 | global_State *g = G(L); | ||
447 | GCObject *o = g->tmudata->gch.next; /* get first element */ | ||
448 | Udata *udata = rawgco2u(o); | ||
449 | const TValue *tm; | ||
450 | /* remove udata from `tmudata' */ | ||
451 | if (o == g->tmudata) /* last element? */ | ||
452 | g->tmudata = NULL; | ||
453 | else | ||
454 | g->tmudata->gch.next = udata->uv.next; | ||
455 | udata->uv.next = g->mainthread->next; /* return it to `root' list */ | ||
456 | g->mainthread->next = o; | ||
457 | makewhite(g, o); | ||
458 | tm = fasttm(L, udata->uv.metatable, TM_GC); | ||
459 | if (tm != NULL) { | ||
460 | lu_byte oldah = L->allowhook; | ||
461 | lu_mem oldt = g->GCthreshold; | ||
462 | L->allowhook = 0; /* stop debug hooks during GC tag method */ | ||
463 | g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ | ||
464 | setobj2s(L, L->top, tm); | ||
465 | setuvalue(L, L->top+1, udata); | ||
466 | L->top += 2; | ||
467 | luaD_call(L, L->top - 2, 0); | ||
468 | L->allowhook = oldah; /* restore hooks */ | ||
469 | g->GCthreshold = oldt; /* restore threshold */ | ||
470 | } | ||
471 | } | ||
472 | |||
473 | |||
474 | /* | ||
475 | ** Call all GC tag methods | ||
476 | */ | ||
477 | void luaC_callGCTM (lua_State *L) { | ||
478 | while (G(L)->tmudata) | ||
479 | GCTM(L); | ||
480 | } | ||
481 | |||
482 | |||
483 | void luaC_freeall (lua_State *L) { | ||
484 | global_State *g = G(L); | ||
485 | int i; | ||
486 | g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */ | ||
487 | sweepwholelist(L, &g->rootgc); | ||
488 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ | ||
489 | sweepwholelist(L, &g->strt.hash[i]); | ||
490 | } | ||
491 | |||
492 | |||
493 | static void markmt (global_State *g) { | ||
494 | int i; | ||
495 | for (i=0; i<NUM_TAGS; i++) | ||
496 | if (g->mt[i]) markobject(g, g->mt[i]); | ||
497 | } | ||
498 | |||
499 | |||
500 | /* mark root set */ | ||
501 | static void markroot (lua_State *L) { | ||
502 | global_State *g = G(L); | ||
503 | g->gray = NULL; | ||
504 | g->grayagain = NULL; | ||
505 | g->weak = NULL; | ||
506 | markobject(g, g->mainthread); | ||
507 | /* make global table be traversed before main stack */ | ||
508 | markvalue(g, gt(g->mainthread)); | ||
509 | markvalue(g, registry(L)); | ||
510 | markmt(g); | ||
511 | g->gcstate = GCSpropagate; | ||
512 | } | ||
513 | |||
514 | |||
515 | static void remarkupvals (global_State *g) { | ||
516 | UpVal *uv; | ||
517 | for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { | ||
518 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | ||
519 | if (isgray(obj2gco(uv))) | ||
520 | markvalue(g, uv->v); | ||
521 | } | ||
522 | } | ||
523 | |||
524 | |||
525 | static void atomic (lua_State *L) { | ||
526 | global_State *g = G(L); | ||
527 | size_t udsize; /* total size of userdata to be finalized */ | ||
528 | /* remark occasional upvalues of (maybe) dead threads */ | ||
529 | remarkupvals(g); | ||
530 | /* traverse objects cautch by write barrier and by 'remarkupvals' */ | ||
531 | propagateall(g); | ||
532 | /* remark weak tables */ | ||
533 | g->gray = g->weak; | ||
534 | g->weak = NULL; | ||
535 | lua_assert(!iswhite(obj2gco(g->mainthread))); | ||
536 | markobject(g, L); /* mark running thread */ | ||
537 | markmt(g); /* mark basic metatables (again) */ | ||
538 | propagateall(g); | ||
539 | /* remark gray again */ | ||
540 | g->gray = g->grayagain; | ||
541 | g->grayagain = NULL; | ||
542 | propagateall(g); | ||
543 | udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ | ||
544 | marktmu(g); /* mark `preserved' userdata */ | ||
545 | udsize += propagateall(g); /* remark, to propagate `preserveness' */ | ||
546 | cleartable(g->weak); /* remove collected objects from weak tables */ | ||
547 | /* flip current white */ | ||
548 | g->currentwhite = cast_byte(otherwhite(g)); | ||
549 | g->sweepstrgc = 0; | ||
550 | g->sweepgc = &g->rootgc; | ||
551 | g->gcstate = GCSsweepstring; | ||
552 | g->estimate = g->totalbytes - udsize; /* first estimate */ | ||
553 | } | ||
554 | |||
555 | |||
556 | static l_mem singlestep (lua_State *L) { | ||
557 | global_State *g = G(L); | ||
558 | /*lua_checkmemory(L);*/ | ||
559 | switch (g->gcstate) { | ||
560 | case GCSpause: { | ||
561 | markroot(L); /* start a new collection */ | ||
562 | return 0; | ||
563 | } | ||
564 | case GCSpropagate: { | ||
565 | if (g->gray) | ||
566 | return propagatemark(g); | ||
567 | else { /* no more `gray' objects */ | ||
568 | atomic(L); /* finish mark phase */ | ||
569 | return 0; | ||
570 | } | ||
571 | } | ||
572 | case GCSsweepstring: { | ||
573 | lu_mem old = g->totalbytes; | ||
574 | sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); | ||
575 | if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ | ||
576 | g->gcstate = GCSsweep; /* end sweep-string phase */ | ||
577 | lua_assert(old >= g->totalbytes); | ||
578 | g->estimate -= old - g->totalbytes; | ||
579 | return GCSWEEPCOST; | ||
580 | } | ||
581 | case GCSsweep: { | ||
582 | lu_mem old = g->totalbytes; | ||
583 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); | ||
584 | if (*g->sweepgc == NULL) { /* nothing more to sweep? */ | ||
585 | checkSizes(L); | ||
586 | g->gcstate = GCSfinalize; /* end sweep phase */ | ||
587 | } | ||
588 | lua_assert(old >= g->totalbytes); | ||
589 | g->estimate -= old - g->totalbytes; | ||
590 | return GCSWEEPMAX*GCSWEEPCOST; | ||
591 | } | ||
592 | case GCSfinalize: { | ||
593 | if (g->tmudata) { | ||
594 | GCTM(L); | ||
595 | if (g->estimate > GCFINALIZECOST) | ||
596 | g->estimate -= GCFINALIZECOST; | ||
597 | return GCFINALIZECOST; | ||
598 | } | ||
599 | else { | ||
600 | g->gcstate = GCSpause; /* end collection */ | ||
601 | g->gcdept = 0; | ||
602 | return 0; | ||
603 | } | ||
604 | } | ||
605 | default: lua_assert(0); return 0; | ||
606 | } | ||
607 | } | ||
608 | |||
609 | |||
610 | void luaC_step (lua_State *L) { | ||
611 | global_State *g = G(L); | ||
612 | l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; | ||
613 | if (lim == 0) | ||
614 | lim = (MAX_LUMEM-1)/2; /* no limit */ | ||
615 | g->gcdept += g->totalbytes - g->GCthreshold; | ||
616 | do { | ||
617 | lim -= singlestep(L); | ||
618 | if (g->gcstate == GCSpause) | ||
619 | break; | ||
620 | } while (lim > 0); | ||
621 | if (g->gcstate != GCSpause) { | ||
622 | if (g->gcdept < GCSTEPSIZE) | ||
623 | g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ | ||
624 | else { | ||
625 | g->gcdept -= GCSTEPSIZE; | ||
626 | g->GCthreshold = g->totalbytes; | ||
627 | } | ||
628 | } | ||
629 | else { | ||
630 | lua_assert(g->totalbytes >= g->estimate); | ||
631 | setthreshold(g); | ||
632 | } | ||
633 | } | ||
634 | |||
635 | |||
636 | void luaC_fullgc (lua_State *L) { | ||
637 | global_State *g = G(L); | ||
638 | if (g->gcstate <= GCSpropagate) { | ||
639 | /* reset sweep marks to sweep all elements (returning them to white) */ | ||
640 | g->sweepstrgc = 0; | ||
641 | g->sweepgc = &g->rootgc; | ||
642 | /* reset other collector lists */ | ||
643 | g->gray = NULL; | ||
644 | g->grayagain = NULL; | ||
645 | g->weak = NULL; | ||
646 | g->gcstate = GCSsweepstring; | ||
647 | } | ||
648 | lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate); | ||
649 | /* finish any pending sweep phase */ | ||
650 | while (g->gcstate != GCSfinalize) { | ||
651 | lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); | ||
652 | singlestep(L); | ||
653 | } | ||
654 | markroot(L); | ||
655 | while (g->gcstate != GCSpause) { | ||
656 | singlestep(L); | ||
657 | } | ||
658 | setthreshold(g); | ||
659 | } | ||
660 | |||
661 | |||
662 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { | ||
663 | global_State *g = G(L); | ||
664 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); | ||
665 | lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); | ||
666 | lua_assert(ttype(&o->gch) != LUA_TTABLE); | ||
667 | /* must keep invariant? */ | ||
668 | if (g->gcstate == GCSpropagate) | ||
669 | reallymarkobject(g, v); /* restore invariant */ | ||
670 | else /* don't mind */ | ||
671 | makewhite(g, o); /* mark as white just to avoid other barriers */ | ||
672 | } | ||
673 | |||
674 | |||
675 | void luaC_barrierback (lua_State *L, Table *t) { | ||
676 | global_State *g = G(L); | ||
677 | GCObject *o = obj2gco(t); | ||
678 | lua_assert(isblack(o) && !isdead(g, o)); | ||
679 | lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); | ||
680 | black2gray(o); /* make table gray (again) */ | ||
681 | t->gclist = g->grayagain; | ||
682 | g->grayagain = o; | ||
683 | } | ||
684 | |||
685 | |||
686 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { | ||
687 | global_State *g = G(L); | ||
688 | o->gch.next = g->rootgc; | ||
689 | g->rootgc = o; | ||
690 | o->gch.marked = luaC_white(g); | ||
691 | o->gch.tt = tt; | ||
692 | } | ||
693 | |||
694 | |||
695 | void luaC_linkupval (lua_State *L, UpVal *uv) { | ||
696 | global_State *g = G(L); | ||
697 | GCObject *o = obj2gco(uv); | ||
698 | o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ | ||
699 | g->rootgc = o; | ||
700 | if (isgray(o)) { | ||
701 | if (g->gcstate == GCSpropagate) { | ||
702 | gray2black(o); /* closed upvalues need barrier */ | ||
703 | luaC_barrier(L, uv, uv->v); | ||
704 | } | ||
705 | else { /* sweep phase: sweep it (turning it into white) */ | ||
706 | makewhite(g, o); | ||
707 | lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); | ||
708 | } | ||
709 | } | ||
710 | } | ||
711 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lgc.h b/libraries/LuaJIT-1.1.7/src/lgc.h new file mode 100644 index 0000000..5a8dc60 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lgc.h | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | ** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Garbage Collector | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lgc_h | ||
8 | #define lgc_h | ||
9 | |||
10 | |||
11 | #include "lobject.h" | ||
12 | |||
13 | |||
14 | /* | ||
15 | ** Possible states of the Garbage Collector | ||
16 | */ | ||
17 | #define GCSpause 0 | ||
18 | #define GCSpropagate 1 | ||
19 | #define GCSsweepstring 2 | ||
20 | #define GCSsweep 3 | ||
21 | #define GCSfinalize 4 | ||
22 | |||
23 | |||
24 | /* | ||
25 | ** some userful bit tricks | ||
26 | */ | ||
27 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) | ||
28 | #define setbits(x,m) ((x) |= (m)) | ||
29 | #define testbits(x,m) ((x) & (m)) | ||
30 | #define bitmask(b) (1<<(b)) | ||
31 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) | ||
32 | #define l_setbit(x,b) setbits(x, bitmask(b)) | ||
33 | #define resetbit(x,b) resetbits(x, bitmask(b)) | ||
34 | #define testbit(x,b) testbits(x, bitmask(b)) | ||
35 | #define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) | ||
36 | #define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) | ||
37 | #define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) | ||
38 | |||
39 | |||
40 | |||
41 | /* | ||
42 | ** Layout for bit use in `marked' field: | ||
43 | ** bit 0 - object is white (type 0) | ||
44 | ** bit 1 - object is white (type 1) | ||
45 | ** bit 2 - object is black | ||
46 | ** bit 3 - for userdata: has been finalized | ||
47 | ** bit 3 - for tables: has weak keys | ||
48 | ** bit 4 - for tables: has weak values | ||
49 | ** bit 5 - object is fixed (should not be collected) | ||
50 | ** bit 6 - object is "super" fixed (only the main thread) | ||
51 | */ | ||
52 | |||
53 | |||
54 | #define WHITE0BIT 0 | ||
55 | #define WHITE1BIT 1 | ||
56 | #define BLACKBIT 2 | ||
57 | #define FINALIZEDBIT 3 | ||
58 | #define KEYWEAKBIT 3 | ||
59 | #define VALUEWEAKBIT 4 | ||
60 | #define FIXEDBIT 5 | ||
61 | #define SFIXEDBIT 6 | ||
62 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) | ||
63 | |||
64 | |||
65 | #define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) | ||
66 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) | ||
67 | #define isgray(x) (!isblack(x) && !iswhite(x)) | ||
68 | |||
69 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) | ||
70 | #define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) | ||
71 | |||
72 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) | ||
73 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) | ||
74 | |||
75 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) | ||
76 | |||
77 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) | ||
78 | |||
79 | |||
80 | #define luaC_checkGC(L) { \ | ||
81 | condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ | ||
82 | if (G(L)->totalbytes >= G(L)->GCthreshold) \ | ||
83 | luaC_step(L); } | ||
84 | |||
85 | |||
86 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ | ||
87 | luaC_barrierf(L,obj2gco(p),gcvalue(v)); } | ||
88 | |||
89 | #define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ | ||
90 | luaC_barrierback(L,t); } | ||
91 | |||
92 | #define luaC_objbarrier(L,p,o) \ | ||
93 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ | ||
94 | luaC_barrierf(L,obj2gco(p),obj2gco(o)); } | ||
95 | |||
96 | #define luaC_objbarriert(L,t,o) \ | ||
97 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } | ||
98 | |||
99 | LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); | ||
100 | LUAI_FUNC void luaC_callGCTM (lua_State *L); | ||
101 | LUAI_FUNC void luaC_freeall (lua_State *L); | ||
102 | LUAI_FUNC void luaC_step (lua_State *L); | ||
103 | LUAI_FUNC void luaC_fullgc (lua_State *L); | ||
104 | LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); | ||
105 | LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); | ||
106 | LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); | ||
107 | LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); | ||
108 | |||
109 | |||
110 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/linit.c b/libraries/LuaJIT-1.1.7/src/linit.c new file mode 100644 index 0000000..db24ccd --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/linit.c | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | ** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Initialization of libraries for lua.c | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #define linit_c | ||
9 | #define LUA_LIB | ||
10 | |||
11 | #include "lua.h" | ||
12 | |||
13 | #include "lualib.h" | ||
14 | #include "lauxlib.h" | ||
15 | |||
16 | |||
17 | static const luaL_Reg lualibs[] = { | ||
18 | {"", luaopen_base}, | ||
19 | {LUA_LOADLIBNAME, luaopen_package}, | ||
20 | {LUA_TABLIBNAME, luaopen_table}, | ||
21 | {LUA_IOLIBNAME, luaopen_io}, | ||
22 | {LUA_OSLIBNAME, luaopen_os}, | ||
23 | {LUA_STRLIBNAME, luaopen_string}, | ||
24 | {LUA_MATHLIBNAME, luaopen_math}, | ||
25 | {LUA_DBLIBNAME, luaopen_debug}, | ||
26 | {LUA_JITLIBNAME, luaopen_jit}, | ||
27 | {NULL, NULL} | ||
28 | }; | ||
29 | |||
30 | |||
31 | LUALIB_API void luaL_openlibs (lua_State *L) { | ||
32 | const luaL_Reg *lib = lualibs; | ||
33 | for (; lib->func; lib++) { | ||
34 | lua_pushcfunction(L, lib->func); | ||
35 | lua_pushstring(L, lib->name); | ||
36 | lua_call(L, 1, 0); | ||
37 | } | ||
38 | } | ||
39 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/liolib.c b/libraries/LuaJIT-1.1.7/src/liolib.c new file mode 100644 index 0000000..8de2547 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/liolib.c | |||
@@ -0,0 +1,556 @@ | |||
1 | /* | ||
2 | ** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $ | ||
3 | ** Standard I/O (and system) library | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <errno.h> | ||
9 | #include <stdio.h> | ||
10 | #include <stdlib.h> | ||
11 | #include <string.h> | ||
12 | |||
13 | #define liolib_c | ||
14 | #define LUA_LIB | ||
15 | |||
16 | #include "lua.h" | ||
17 | |||
18 | #include "lauxlib.h" | ||
19 | #include "lualib.h" | ||
20 | |||
21 | |||
22 | |||
23 | #define IO_INPUT 1 | ||
24 | #define IO_OUTPUT 2 | ||
25 | |||
26 | |||
27 | static const char *const fnames[] = {"input", "output"}; | ||
28 | |||
29 | |||
30 | static int pushresult (lua_State *L, int i, const char *filename) { | ||
31 | int en = errno; /* calls to Lua API may change this value */ | ||
32 | if (i) { | ||
33 | lua_pushboolean(L, 1); | ||
34 | return 1; | ||
35 | } | ||
36 | else { | ||
37 | lua_pushnil(L); | ||
38 | if (filename) | ||
39 | lua_pushfstring(L, "%s: %s", filename, strerror(en)); | ||
40 | else | ||
41 | lua_pushfstring(L, "%s", strerror(en)); | ||
42 | lua_pushinteger(L, en); | ||
43 | return 3; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | |||
48 | static void fileerror (lua_State *L, int arg, const char *filename) { | ||
49 | lua_pushfstring(L, "%s: %s", filename, strerror(errno)); | ||
50 | luaL_argerror(L, arg, lua_tostring(L, -1)); | ||
51 | } | ||
52 | |||
53 | |||
54 | #define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) | ||
55 | |||
56 | |||
57 | static int io_type (lua_State *L) { | ||
58 | void *ud; | ||
59 | luaL_checkany(L, 1); | ||
60 | ud = lua_touserdata(L, 1); | ||
61 | lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); | ||
62 | if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) | ||
63 | lua_pushnil(L); /* not a file */ | ||
64 | else if (*((FILE **)ud) == NULL) | ||
65 | lua_pushliteral(L, "closed file"); | ||
66 | else | ||
67 | lua_pushliteral(L, "file"); | ||
68 | return 1; | ||
69 | } | ||
70 | |||
71 | |||
72 | static FILE *tofile (lua_State *L) { | ||
73 | FILE **f = tofilep(L); | ||
74 | if (*f == NULL) | ||
75 | luaL_error(L, "attempt to use a closed file"); | ||
76 | return *f; | ||
77 | } | ||
78 | |||
79 | |||
80 | |||
81 | /* | ||
82 | ** When creating file handles, always creates a `closed' file handle | ||
83 | ** before opening the actual file; so, if there is a memory error, the | ||
84 | ** file is not left opened. | ||
85 | */ | ||
86 | static FILE **newfile (lua_State *L) { | ||
87 | FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); | ||
88 | *pf = NULL; /* file handle is currently `closed' */ | ||
89 | luaL_getmetatable(L, LUA_FILEHANDLE); | ||
90 | lua_setmetatable(L, -2); | ||
91 | return pf; | ||
92 | } | ||
93 | |||
94 | |||
95 | /* | ||
96 | ** function to (not) close the standard files stdin, stdout, and stderr | ||
97 | */ | ||
98 | static int io_noclose (lua_State *L) { | ||
99 | lua_pushnil(L); | ||
100 | lua_pushliteral(L, "cannot close standard file"); | ||
101 | return 2; | ||
102 | } | ||
103 | |||
104 | |||
105 | /* | ||
106 | ** function to close 'popen' files | ||
107 | */ | ||
108 | static int io_pclose (lua_State *L) { | ||
109 | FILE **p = tofilep(L); | ||
110 | int ok = lua_pclose(L, *p); | ||
111 | *p = NULL; | ||
112 | return pushresult(L, ok, NULL); | ||
113 | } | ||
114 | |||
115 | |||
116 | /* | ||
117 | ** function to close regular files | ||
118 | */ | ||
119 | static int io_fclose (lua_State *L) { | ||
120 | FILE **p = tofilep(L); | ||
121 | int ok = (fclose(*p) == 0); | ||
122 | *p = NULL; | ||
123 | return pushresult(L, ok, NULL); | ||
124 | } | ||
125 | |||
126 | |||
127 | static int aux_close (lua_State *L) { | ||
128 | lua_getfenv(L, 1); | ||
129 | lua_getfield(L, -1, "__close"); | ||
130 | return (lua_tocfunction(L, -1))(L); | ||
131 | } | ||
132 | |||
133 | |||
134 | static int io_close (lua_State *L) { | ||
135 | if (lua_isnone(L, 1)) | ||
136 | lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); | ||
137 | tofile(L); /* make sure argument is a file */ | ||
138 | return aux_close(L); | ||
139 | } | ||
140 | |||
141 | |||
142 | static int io_gc (lua_State *L) { | ||
143 | FILE *f = *tofilep(L); | ||
144 | /* ignore closed files */ | ||
145 | if (f != NULL) | ||
146 | aux_close(L); | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | |||
151 | static int io_tostring (lua_State *L) { | ||
152 | FILE *f = *tofilep(L); | ||
153 | if (f == NULL) | ||
154 | lua_pushliteral(L, "file (closed)"); | ||
155 | else | ||
156 | lua_pushfstring(L, "file (%p)", f); | ||
157 | return 1; | ||
158 | } | ||
159 | |||
160 | |||
161 | static int io_open (lua_State *L) { | ||
162 | const char *filename = luaL_checkstring(L, 1); | ||
163 | const char *mode = luaL_optstring(L, 2, "r"); | ||
164 | FILE **pf = newfile(L); | ||
165 | *pf = fopen(filename, mode); | ||
166 | return (*pf == NULL) ? pushresult(L, 0, filename) : 1; | ||
167 | } | ||
168 | |||
169 | |||
170 | /* | ||
171 | ** this function has a separated environment, which defines the | ||
172 | ** correct __close for 'popen' files | ||
173 | */ | ||
174 | static int io_popen (lua_State *L) { | ||
175 | const char *filename = luaL_checkstring(L, 1); | ||
176 | const char *mode = luaL_optstring(L, 2, "r"); | ||
177 | FILE **pf = newfile(L); | ||
178 | *pf = lua_popen(L, filename, mode); | ||
179 | return (*pf == NULL) ? pushresult(L, 0, filename) : 1; | ||
180 | } | ||
181 | |||
182 | |||
183 | static int io_tmpfile (lua_State *L) { | ||
184 | FILE **pf = newfile(L); | ||
185 | *pf = tmpfile(); | ||
186 | return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; | ||
187 | } | ||
188 | |||
189 | |||
190 | static FILE *getiofile (lua_State *L, int findex) { | ||
191 | FILE *f; | ||
192 | lua_rawgeti(L, LUA_ENVIRONINDEX, findex); | ||
193 | f = *(FILE **)lua_touserdata(L, -1); | ||
194 | if (f == NULL) | ||
195 | luaL_error(L, "standard %s file is closed", fnames[findex - 1]); | ||
196 | return f; | ||
197 | } | ||
198 | |||
199 | |||
200 | static int g_iofile (lua_State *L, int f, const char *mode) { | ||
201 | if (!lua_isnoneornil(L, 1)) { | ||
202 | const char *filename = lua_tostring(L, 1); | ||
203 | if (filename) { | ||
204 | FILE **pf = newfile(L); | ||
205 | *pf = fopen(filename, mode); | ||
206 | if (*pf == NULL) | ||
207 | fileerror(L, 1, filename); | ||
208 | } | ||
209 | else { | ||
210 | tofile(L); /* check that it's a valid file handle */ | ||
211 | lua_pushvalue(L, 1); | ||
212 | } | ||
213 | lua_rawseti(L, LUA_ENVIRONINDEX, f); | ||
214 | } | ||
215 | /* return current value */ | ||
216 | lua_rawgeti(L, LUA_ENVIRONINDEX, f); | ||
217 | return 1; | ||
218 | } | ||
219 | |||
220 | |||
221 | static int io_input (lua_State *L) { | ||
222 | return g_iofile(L, IO_INPUT, "r"); | ||
223 | } | ||
224 | |||
225 | |||
226 | static int io_output (lua_State *L) { | ||
227 | return g_iofile(L, IO_OUTPUT, "w"); | ||
228 | } | ||
229 | |||
230 | |||
231 | static int io_readline (lua_State *L); | ||
232 | |||
233 | |||
234 | static void aux_lines (lua_State *L, int idx, int toclose) { | ||
235 | lua_pushvalue(L, idx); | ||
236 | lua_pushboolean(L, toclose); /* close/not close file when finished */ | ||
237 | lua_pushcclosure(L, io_readline, 2); | ||
238 | } | ||
239 | |||
240 | |||
241 | static int f_lines (lua_State *L) { | ||
242 | tofile(L); /* check that it's a valid file handle */ | ||
243 | aux_lines(L, 1, 0); | ||
244 | return 1; | ||
245 | } | ||
246 | |||
247 | |||
248 | static int io_lines (lua_State *L) { | ||
249 | if (lua_isnoneornil(L, 1)) { /* no arguments? */ | ||
250 | /* will iterate over default input */ | ||
251 | lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); | ||
252 | return f_lines(L); | ||
253 | } | ||
254 | else { | ||
255 | const char *filename = luaL_checkstring(L, 1); | ||
256 | FILE **pf = newfile(L); | ||
257 | *pf = fopen(filename, "r"); | ||
258 | if (*pf == NULL) | ||
259 | fileerror(L, 1, filename); | ||
260 | aux_lines(L, lua_gettop(L), 1); | ||
261 | return 1; | ||
262 | } | ||
263 | } | ||
264 | |||
265 | |||
266 | /* | ||
267 | ** {====================================================== | ||
268 | ** READ | ||
269 | ** ======================================================= | ||
270 | */ | ||
271 | |||
272 | |||
273 | static int read_number (lua_State *L, FILE *f) { | ||
274 | lua_Number d; | ||
275 | if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { | ||
276 | lua_pushnumber(L, d); | ||
277 | return 1; | ||
278 | } | ||
279 | else { | ||
280 | lua_pushnil(L); /* "result" to be removed */ | ||
281 | return 0; /* read fails */ | ||
282 | } | ||
283 | } | ||
284 | |||
285 | |||
286 | static int test_eof (lua_State *L, FILE *f) { | ||
287 | int c = getc(f); | ||
288 | ungetc(c, f); | ||
289 | lua_pushlstring(L, NULL, 0); | ||
290 | return (c != EOF); | ||
291 | } | ||
292 | |||
293 | |||
294 | static int read_line (lua_State *L, FILE *f) { | ||
295 | luaL_Buffer b; | ||
296 | luaL_buffinit(L, &b); | ||
297 | for (;;) { | ||
298 | size_t l; | ||
299 | char *p = luaL_prepbuffer(&b); | ||
300 | if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ | ||
301 | luaL_pushresult(&b); /* close buffer */ | ||
302 | return (lua_objlen(L, -1) > 0); /* check whether read something */ | ||
303 | } | ||
304 | l = strlen(p); | ||
305 | if (l == 0 || p[l-1] != '\n') | ||
306 | luaL_addsize(&b, l); | ||
307 | else { | ||
308 | luaL_addsize(&b, l - 1); /* do not include `eol' */ | ||
309 | luaL_pushresult(&b); /* close buffer */ | ||
310 | return 1; /* read at least an `eol' */ | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | |||
315 | |||
316 | static int read_chars (lua_State *L, FILE *f, size_t n) { | ||
317 | size_t rlen; /* how much to read */ | ||
318 | size_t nr; /* number of chars actually read */ | ||
319 | luaL_Buffer b; | ||
320 | luaL_buffinit(L, &b); | ||
321 | rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ | ||
322 | do { | ||
323 | char *p = luaL_prepbuffer(&b); | ||
324 | if (rlen > n) rlen = n; /* cannot read more than asked */ | ||
325 | nr = fread(p, sizeof(char), rlen, f); | ||
326 | luaL_addsize(&b, nr); | ||
327 | n -= nr; /* still have to read `n' chars */ | ||
328 | } while (n > 0 && nr == rlen); /* until end of count or eof */ | ||
329 | luaL_pushresult(&b); /* close buffer */ | ||
330 | return (n == 0 || lua_objlen(L, -1) > 0); | ||
331 | } | ||
332 | |||
333 | |||
334 | static int g_read (lua_State *L, FILE *f, int first) { | ||
335 | int nargs = lua_gettop(L) - 1; | ||
336 | int success; | ||
337 | int n; | ||
338 | clearerr(f); | ||
339 | if (nargs == 0) { /* no arguments? */ | ||
340 | success = read_line(L, f); | ||
341 | n = first+1; /* to return 1 result */ | ||
342 | } | ||
343 | else { /* ensure stack space for all results and for auxlib's buffer */ | ||
344 | luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); | ||
345 | success = 1; | ||
346 | for (n = first; nargs-- && success; n++) { | ||
347 | if (lua_type(L, n) == LUA_TNUMBER) { | ||
348 | size_t l = (size_t)lua_tointeger(L, n); | ||
349 | success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); | ||
350 | } | ||
351 | else { | ||
352 | const char *p = lua_tostring(L, n); | ||
353 | luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); | ||
354 | switch (p[1]) { | ||
355 | case 'n': /* number */ | ||
356 | success = read_number(L, f); | ||
357 | break; | ||
358 | case 'l': /* line */ | ||
359 | success = read_line(L, f); | ||
360 | break; | ||
361 | case 'a': /* file */ | ||
362 | read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ | ||
363 | success = 1; /* always success */ | ||
364 | break; | ||
365 | default: | ||
366 | return luaL_argerror(L, n, "invalid format"); | ||
367 | } | ||
368 | } | ||
369 | } | ||
370 | } | ||
371 | if (ferror(f)) | ||
372 | return pushresult(L, 0, NULL); | ||
373 | if (!success) { | ||
374 | lua_pop(L, 1); /* remove last result */ | ||
375 | lua_pushnil(L); /* push nil instead */ | ||
376 | } | ||
377 | return n - first; | ||
378 | } | ||
379 | |||
380 | |||
381 | static int io_read (lua_State *L) { | ||
382 | return g_read(L, getiofile(L, IO_INPUT), 1); | ||
383 | } | ||
384 | |||
385 | |||
386 | static int f_read (lua_State *L) { | ||
387 | return g_read(L, tofile(L), 2); | ||
388 | } | ||
389 | |||
390 | |||
391 | static int io_readline (lua_State *L) { | ||
392 | FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); | ||
393 | int sucess; | ||
394 | if (f == NULL) /* file is already closed? */ | ||
395 | luaL_error(L, "file is already closed"); | ||
396 | sucess = read_line(L, f); | ||
397 | if (ferror(f)) | ||
398 | return luaL_error(L, "%s", strerror(errno)); | ||
399 | if (sucess) return 1; | ||
400 | else { /* EOF */ | ||
401 | if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ | ||
402 | lua_settop(L, 0); | ||
403 | lua_pushvalue(L, lua_upvalueindex(1)); | ||
404 | aux_close(L); /* close it */ | ||
405 | } | ||
406 | return 0; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | /* }====================================================== */ | ||
411 | |||
412 | |||
413 | static int g_write (lua_State *L, FILE *f, int arg) { | ||
414 | int nargs = lua_gettop(L) - 1; | ||
415 | int status = 1; | ||
416 | for (; nargs--; arg++) { | ||
417 | if (lua_type(L, arg) == LUA_TNUMBER) { | ||
418 | /* optimization: could be done exactly as for strings */ | ||
419 | status = status && | ||
420 | fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; | ||
421 | } | ||
422 | else { | ||
423 | size_t l; | ||
424 | const char *s = luaL_checklstring(L, arg, &l); | ||
425 | status = status && (fwrite(s, sizeof(char), l, f) == l); | ||
426 | } | ||
427 | } | ||
428 | return pushresult(L, status, NULL); | ||
429 | } | ||
430 | |||
431 | |||
432 | static int io_write (lua_State *L) { | ||
433 | return g_write(L, getiofile(L, IO_OUTPUT), 1); | ||
434 | } | ||
435 | |||
436 | |||
437 | static int f_write (lua_State *L) { | ||
438 | return g_write(L, tofile(L), 2); | ||
439 | } | ||
440 | |||
441 | |||
442 | static int f_seek (lua_State *L) { | ||
443 | static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; | ||
444 | static const char *const modenames[] = {"set", "cur", "end", NULL}; | ||
445 | FILE *f = tofile(L); | ||
446 | int op = luaL_checkoption(L, 2, "cur", modenames); | ||
447 | long offset = luaL_optlong(L, 3, 0); | ||
448 | op = fseek(f, offset, mode[op]); | ||
449 | if (op) | ||
450 | return pushresult(L, 0, NULL); /* error */ | ||
451 | else { | ||
452 | lua_pushinteger(L, ftell(f)); | ||
453 | return 1; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | |||
458 | static int f_setvbuf (lua_State *L) { | ||
459 | static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; | ||
460 | static const char *const modenames[] = {"no", "full", "line", NULL}; | ||
461 | FILE *f = tofile(L); | ||
462 | int op = luaL_checkoption(L, 2, NULL, modenames); | ||
463 | lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); | ||
464 | int res = setvbuf(f, NULL, mode[op], sz); | ||
465 | return pushresult(L, res == 0, NULL); | ||
466 | } | ||
467 | |||
468 | |||
469 | |||
470 | static int io_flush (lua_State *L) { | ||
471 | return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); | ||
472 | } | ||
473 | |||
474 | |||
475 | static int f_flush (lua_State *L) { | ||
476 | return pushresult(L, fflush(tofile(L)) == 0, NULL); | ||
477 | } | ||
478 | |||
479 | |||
480 | static const luaL_Reg iolib[] = { | ||
481 | {"close", io_close}, | ||
482 | {"flush", io_flush}, | ||
483 | {"input", io_input}, | ||
484 | {"lines", io_lines}, | ||
485 | {"open", io_open}, | ||
486 | {"output", io_output}, | ||
487 | {"popen", io_popen}, | ||
488 | {"read", io_read}, | ||
489 | {"tmpfile", io_tmpfile}, | ||
490 | {"type", io_type}, | ||
491 | {"write", io_write}, | ||
492 | {NULL, NULL} | ||
493 | }; | ||
494 | |||
495 | |||
496 | static const luaL_Reg flib[] = { | ||
497 | {"close", io_close}, | ||
498 | {"flush", f_flush}, | ||
499 | {"lines", f_lines}, | ||
500 | {"read", f_read}, | ||
501 | {"seek", f_seek}, | ||
502 | {"setvbuf", f_setvbuf}, | ||
503 | {"write", f_write}, | ||
504 | {"__gc", io_gc}, | ||
505 | {"__tostring", io_tostring}, | ||
506 | {NULL, NULL} | ||
507 | }; | ||
508 | |||
509 | |||
510 | static void createmeta (lua_State *L) { | ||
511 | luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ | ||
512 | lua_pushvalue(L, -1); /* push metatable */ | ||
513 | lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ | ||
514 | luaL_register(L, NULL, flib); /* file methods */ | ||
515 | } | ||
516 | |||
517 | |||
518 | static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { | ||
519 | *newfile(L) = f; | ||
520 | if (k > 0) { | ||
521 | lua_pushvalue(L, -1); | ||
522 | lua_rawseti(L, LUA_ENVIRONINDEX, k); | ||
523 | } | ||
524 | lua_pushvalue(L, -2); /* copy environment */ | ||
525 | lua_setfenv(L, -2); /* set it */ | ||
526 | lua_setfield(L, -3, fname); | ||
527 | } | ||
528 | |||
529 | |||
530 | static void newfenv (lua_State *L, lua_CFunction cls) { | ||
531 | lua_createtable(L, 0, 1); | ||
532 | lua_pushcfunction(L, cls); | ||
533 | lua_setfield(L, -2, "__close"); | ||
534 | } | ||
535 | |||
536 | |||
537 | LUALIB_API int luaopen_io (lua_State *L) { | ||
538 | createmeta(L); | ||
539 | /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ | ||
540 | newfenv(L, io_fclose); | ||
541 | lua_replace(L, LUA_ENVIRONINDEX); | ||
542 | /* open library */ | ||
543 | luaL_register(L, LUA_IOLIBNAME, iolib); | ||
544 | /* create (and set) default files */ | ||
545 | newfenv(L, io_noclose); /* close function for default files */ | ||
546 | createstdfile(L, stdin, IO_INPUT, "stdin"); | ||
547 | createstdfile(L, stdout, IO_OUTPUT, "stdout"); | ||
548 | createstdfile(L, stderr, 0, "stderr"); | ||
549 | lua_pop(L, 1); /* pop environment for default files */ | ||
550 | lua_getfield(L, -1, "popen"); | ||
551 | newfenv(L, io_pclose); /* create environment for 'popen' */ | ||
552 | lua_setfenv(L, -2); /* set fenv for 'popen' */ | ||
553 | lua_pop(L, 1); /* pop 'popen' */ | ||
554 | return 1; | ||
555 | } | ||
556 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ljit.h b/libraries/LuaJIT-1.1.7/src/ljit.h new file mode 100644 index 0000000..347de3b --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit.h | |||
@@ -0,0 +1,167 @@ | |||
1 | /* | ||
2 | ** Interface to JIT engine. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #ifndef ljit_h | ||
7 | #define ljit_h | ||
8 | |||
9 | #include "lobject.h" | ||
10 | |||
11 | |||
12 | /* Define this to enable assertions when debugging LuaJIT. */ | ||
13 | #ifdef LUAJIT_ASSERT | ||
14 | #include <assert.h> | ||
15 | #define jit_assert(x) assert(x) | ||
16 | #define DASM_CHECKS | ||
17 | #else | ||
18 | /* A better idea is to define lua_assert() in luaconf.h. */ | ||
19 | #define jit_assert(x) lua_assert(x) | ||
20 | #endif | ||
21 | |||
22 | /* Define this to set the C stack size for the compiler thread. */ | ||
23 | /* The compiler runs on the callers C stack otherwise. */ | ||
24 | #undef LUAJIT_COMPILER_CSTACK | ||
25 | |||
26 | /* Hardcoded limits for the backend to avoid useless work. */ | ||
27 | /* Note: mind you, these are very generous limits. Check jit.opt, too. */ | ||
28 | #define LUAJIT_LIM_BYTECODE 3000 /* Max. # of bytecodes. */ | ||
29 | #define LUAJIT_LIM_MCODE 128000 /* Max. mcode size of a function. */ | ||
30 | |||
31 | /* Global JIT engine flags. */ | ||
32 | #define JIT_F_ON 0x0001 /* JIT engine is on. */ | ||
33 | #define JIT_F_COMPILING 0x0002 /* Currently compiling. */ | ||
34 | #define JIT_F_INIT_FAILED 0x0004 /* Initialization failed. */ | ||
35 | |||
36 | #define JIT_F_CPU_CMOV 0x0010 /* CPU has conditional move support. */ | ||
37 | #define JIT_F_CPU_SSE2 0x0020 /* CPU has SSE2 support. */ | ||
38 | |||
39 | #define JIT_F_DEBUG_CALL 0x0100 /* Compile with call hooks. */ | ||
40 | #define JIT_F_DEBUG_INS 0x0200 /* Compile with instruction hooks. */ | ||
41 | #define JIT_F_DEBUG 0x0f00 /* Union of all debug flags. */ | ||
42 | |||
43 | /* Temporary backend flags. */ | ||
44 | #define JIT_TF_USED_DEOPT 0x0001 /* Used .deopt segment. */ | ||
45 | |||
46 | /* JIT engine status codes for prototypes (grep "ORDER JIT_S"). */ | ||
47 | enum { | ||
48 | JIT_S_OK, /* OK, code has been compiled. */ | ||
49 | JIT_S_NONE, /* Nothing compiled yet (default). */ | ||
50 | |||
51 | JIT_S_OFF, /* Compilation for this prototype disabled. */ | ||
52 | JIT_S_ENGINE_OFF, /* JIT engine is turned off. */ | ||
53 | JIT_S_DELAYED, /* Compilation delayed (recursive invocation). */ | ||
54 | |||
55 | JIT_S_TOOLARGE, /* Bytecode or machine code is too large. */ | ||
56 | JIT_S_COMPILER_ERROR, /* Error from compiler frontend. */ | ||
57 | JIT_S_DASM_ERROR, /* Error from DynASM engine. */ | ||
58 | |||
59 | JIT_S_MAX | ||
60 | }; | ||
61 | |||
62 | /* Machine code trailer and mcode fragment map. */ | ||
63 | typedef struct jit_MCTrailer { | ||
64 | char *mcode; /* Pointer to next machine code block. */ | ||
65 | size_t sz; /* Size of next machine code block. */ | ||
66 | } jit_MCTrailer; | ||
67 | |||
68 | typedef unsigned short jit_Mfm; | ||
69 | |||
70 | /* Deliberately return a void * because the trailer is not fully aligned. */ | ||
71 | #define JIT_MCTRAILER(mcode, sz) \ | ||
72 | ((void *)(((char *)(mcode))+(sz)-sizeof(jit_MCTrailer))) | ||
73 | #define JIT_MCMFM(mcode, sz) \ | ||
74 | ((jit_Mfm *)(((char *)(mcode))+(sz)-sizeof(jit_MCTrailer)-sizeof(jit_Mfm))) | ||
75 | |||
76 | #define JIT_MFM_MAX 0x7ff0 /* Max. mcode fragment length. */ | ||
77 | #define JIT_MFM_MASK 0x7fff /* Tag mask. */ | ||
78 | #define JIT_MFM_MARK 0x8000 /* Deoptimized (main mfm), seek (deopt mfm). */ | ||
79 | #define JIT_MFM_COMBINE 0xfffd /* Combined with prev. instruction(s). */ | ||
80 | #define JIT_MFM_DEAD 0xfffe /* Dead instruction. */ | ||
81 | #define JIT_MFM_STOP 0xffff /* End of map. */ | ||
82 | |||
83 | #define jit_mfm_ismain(mfm) (!(*(mfm) & JIT_MFM_MARK)) | ||
84 | #define jit_mfm_isdeoptpc(mfm, pc) ((mfm)[-(pc)] & JIT_MFM_MARK) | ||
85 | |||
86 | /* Deoptimization hints at end of mfm. */ | ||
87 | #define JIT_MFM_DEOPT_PAIRS 0xfffc /* CALL+TFORLOOP inlined (i)pairs. */ | ||
88 | |||
89 | /* Preallocation for the hash part of the compiler state table. */ | ||
90 | #define COMSTATE_PREALLOC 128 | ||
91 | |||
92 | /* Forward declaration for DynASM state. */ | ||
93 | struct dasm_State; | ||
94 | |||
95 | /* Frontend wrapper. */ | ||
96 | typedef int (*jit_FrontWrap)(lua_State *L, Table *st); | ||
97 | |||
98 | /* Global JIT state. */ | ||
99 | typedef struct jit_State { | ||
100 | /* Permanent backend environment: */ | ||
101 | struct dasm_State *D; /* DynASM state. Keep this as the first field. */ | ||
102 | void *mcodeheap; /* Private heap to allocate executable memory from. */ | ||
103 | void **jsub; /* Addresses of JIT subroutines. */ | ||
104 | void *jsubmcode; /* Base address of JSUB mcode. */ | ||
105 | size_t szjsubmcode; /* Size of JSUB mcode. */ | ||
106 | int numjsub; /* Number of JSUBs. */ | ||
107 | |||
108 | /* Temporary backend environment (valid only while running): */ | ||
109 | lua_State *L; /* Compiler thread. */ | ||
110 | Table *comstate; /* Compiler state table. */ | ||
111 | Proto *pt; /* Currently compiled prototype. */ | ||
112 | const Instruction *nextins; /* Pointer to next instruction. */ | ||
113 | jit_Mfm *mfm; /* Position in temporary mcode fragment map. */ | ||
114 | int nextpc; /* Next PC. */ | ||
115 | int combine; /* Number of following instructions to combine. */ | ||
116 | unsigned int tflags; /* Temporary flags. */ | ||
117 | int dasmstatus; /* DynASM status code. */ | ||
118 | |||
119 | /* JIT engine fields: */ | ||
120 | jit_FrontWrap frontwrap; /* Compiler frontend wrapper. */ | ||
121 | unsigned int flags; /* Global JIT engine flags. */ | ||
122 | } jit_State; | ||
123 | |||
124 | |||
125 | /* --- ljit_core.c */ | ||
126 | |||
127 | /* Initialize and free JIT engine state. */ | ||
128 | LUAI_FUNC void luaJIT_initstate(lua_State *L); | ||
129 | LUAI_FUNC void luaJIT_freestate(lua_State *L); | ||
130 | |||
131 | /* Compile and run a function. */ | ||
132 | LUAI_FUNC int luaJIT_run(lua_State *L, StkId func, int nresults); | ||
133 | /* Deoptimize the current instruction. Return new mcode addr to continue. */ | ||
134 | LUAI_FUNC void *luaJIT_deoptimize(lua_State *L); | ||
135 | |||
136 | /* Find relative PC (0 based) for a bytecode pointer or a JIT mcode address. */ | ||
137 | LUAI_FUNC int luaJIT_findpc(Proto *pt, const Instruction *savedpc); | ||
138 | /* Find mcode address for PC (1 based). */ | ||
139 | LUAI_FUNC void *luaJIT_findmcode(Proto *pt, int pc); | ||
140 | |||
141 | |||
142 | /* --- ljit_backend.c */ | ||
143 | |||
144 | /* Arch string. */ | ||
145 | LUAI_DATA const char luaJIT_arch[]; | ||
146 | /* Initialize and free compiler backend. */ | ||
147 | LUAI_FUNC int luaJIT_initbackend(lua_State *L); | ||
148 | LUAI_FUNC void luaJIT_freebackend(lua_State *L); | ||
149 | /* Compiler backend. */ | ||
150 | LUAI_FUNC int luaJIT_backend(lua_State *L); | ||
151 | /* Notify backend that the debug mode may have changed. */ | ||
152 | LUAI_FUNC void luaJIT_debugnotify(jit_State *J); | ||
153 | |||
154 | |||
155 | /* ---- ljit_mem.c */ | ||
156 | |||
157 | /* Free the mcode heap. */ | ||
158 | LUAI_FUNC void luaJIT_freemcodeheap(jit_State *J); | ||
159 | /* Free mcode. */ | ||
160 | LUAI_FUNC void luaJIT_freemcode(jit_State *J, void *mcode, size_t sz); | ||
161 | /* Free JIT structures in function prototype. */ | ||
162 | LUAI_FUNC void luaJIT_freeproto(lua_State *L, Proto *pt); | ||
163 | /* Link generated code. */ | ||
164 | LUAI_FUNC int luaJIT_link(jit_State *J, void **mcodep, size_t *szp); | ||
165 | |||
166 | |||
167 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_backend.c b/libraries/LuaJIT-1.1.7/src/ljit_backend.c new file mode 100644 index 0000000..698342f --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit_backend.c | |||
@@ -0,0 +1,342 @@ | |||
1 | /* | ||
2 | ** LuaJIT wrapper for architecture-specific compiler backend. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #include <math.h> | ||
7 | #include <string.h> | ||
8 | |||
9 | #define ljit_backend_c | ||
10 | #define LUA_CORE | ||
11 | |||
12 | #include "lua.h" | ||
13 | |||
14 | #include "lobject.h" | ||
15 | #include "lstate.h" | ||
16 | #include "ldo.h" | ||
17 | #include "lfunc.h" | ||
18 | #include "lgc.h" | ||
19 | #include "lstring.h" | ||
20 | #include "ltable.h" | ||
21 | #include "ltm.h" | ||
22 | #include "lvm.h" | ||
23 | #include "lopcodes.h" | ||
24 | #include "ldebug.h" | ||
25 | #include "lzio.h" | ||
26 | |||
27 | #include "ljit.h" | ||
28 | #include "ljit_hints.h" | ||
29 | #include "ljit_dasm.h" | ||
30 | |||
31 | /* ------------------------------------------------------------------------ */ | ||
32 | |||
33 | /* Get target of combined JMP op. */ | ||
34 | static int jit_jmp_target(jit_State *J) | ||
35 | { | ||
36 | J->combine++; | ||
37 | jit_assert(GET_OPCODE(*J->nextins)==OP_JMP); | ||
38 | return J->nextpc + 1 + GETARG_sBx(*J->nextins); | ||
39 | } | ||
40 | |||
41 | /* ------------------------------------------------------------------------ */ | ||
42 | |||
43 | /* Include pre-processed architecture-specific backend. */ | ||
44 | #if defined(__i386) || defined(__i386__) || defined(_M_IX86) | ||
45 | #ifndef LUA_NUMBER_DOUBLE | ||
46 | #error "No support for other number types on x86 (yet)" | ||
47 | #endif | ||
48 | #include "ljit_x86.h" | ||
49 | #else | ||
50 | #error "No support for this architecture (yet)" | ||
51 | #endif | ||
52 | |||
53 | /* ------------------------------------------------------------------------ */ | ||
54 | |||
55 | /* Compile instruction range. */ | ||
56 | static void jit_compile_irange(jit_State *J, int firstpc, int lastpc) | ||
57 | { | ||
58 | J->combine = 0; | ||
59 | J->nextpc = firstpc; | ||
60 | J->nextins = J->pt->code + (firstpc-1); | ||
61 | while (J->nextpc <= lastpc) { | ||
62 | Instruction ins = *J->nextins++; | ||
63 | OpCode op = GET_OPCODE(ins); | ||
64 | int ra = GETARG_A(ins); | ||
65 | int rb = GETARG_B(ins); | ||
66 | int rc = GETARG_C(ins); | ||
67 | int rbx = GETARG_Bx(ins); | ||
68 | const TValue *combinehint; | ||
69 | |||
70 | jit_ins_start(J); | ||
71 | J->nextpc++; | ||
72 | |||
73 | combinehint = hint_get(J, COMBINE); | ||
74 | if (ttisboolean(combinehint)) { | ||
75 | if (bvalue(combinehint)) { /* COMBINE = true: combine with next ins. */ | ||
76 | if (!(J->flags & JIT_F_DEBUG)) /* But not when debugging. */ | ||
77 | J->combine = 1; | ||
78 | } else { /* COMBINE = false: dead instruction. */ | ||
79 | *J->mfm++ = JIT_MFM_DEAD; | ||
80 | continue; | ||
81 | } | ||
82 | } /* Other COMBINE hint value types are not defined (yet). */ | ||
83 | |||
84 | if (J->flags & JIT_F_DEBUG_INS) | ||
85 | jit_ins_debug(J, luaG_checkopenop(ins)); | ||
86 | |||
87 | switch (op) { | ||
88 | case OP_MOVE: jit_op_move(J, ra, rb); break; | ||
89 | case OP_LOADK: jit_op_loadk(J, ra, rbx); break; | ||
90 | case OP_LOADBOOL: jit_op_loadbool(J, ra, rb, rc); break; | ||
91 | case OP_LOADNIL: jit_op_loadnil(J, ra, rb); break; | ||
92 | |||
93 | case OP_GETUPVAL: jit_op_getupval(J, ra, rb); break; | ||
94 | case OP_SETUPVAL: jit_op_setupval(J, ra, rb); break; | ||
95 | |||
96 | case OP_GETGLOBAL: jit_op_getglobal(J, ra, rbx); break; | ||
97 | case OP_SETGLOBAL: jit_op_setglobal(J, ra, rbx); break; | ||
98 | |||
99 | case OP_NEWTABLE: jit_op_newtable(J, ra, rb, rc); break; | ||
100 | case OP_GETTABLE: jit_op_gettable(J, ra, rb, rc); break; | ||
101 | case OP_SETTABLE: jit_op_settable(J, ra, rb, rc); break; | ||
102 | case OP_SELF: jit_op_self(J, ra, rb, rc); break; | ||
103 | case OP_SETLIST: jit_op_setlist(J, ra, rb, rc); break; | ||
104 | |||
105 | case OP_ADD: jit_op_arith(J, ra, rb, rc, TM_ADD); break; | ||
106 | case OP_SUB: jit_op_arith(J, ra, rb, rc, TM_SUB); break; | ||
107 | case OP_MUL: jit_op_arith(J, ra, rb, rc, TM_MUL); break; | ||
108 | case OP_DIV: jit_op_arith(J, ra, rb, rc, TM_DIV); break; | ||
109 | case OP_MOD: jit_op_arith(J, ra, rb, rc, TM_MOD); break; | ||
110 | case OP_POW: jit_op_arith(J, ra, rb, rc, TM_POW); break; | ||
111 | case OP_UNM: jit_op_arith(J, ra, rb, rb, TM_UNM); break; /* rc unused. */ | ||
112 | |||
113 | case OP_LEN: jit_op_len(J, ra, rb); break; | ||
114 | case OP_NOT: jit_op_not(J, ra, rb); break; | ||
115 | |||
116 | case OP_CONCAT: jit_op_concat(J, ra, rb, rc); break; | ||
117 | |||
118 | case OP_EQ: jit_op_eq(J, ra, rb, rc); break; | ||
119 | case OP_LT: jit_op_arith(J, ra, rb, rc, TM_LT); break; | ||
120 | case OP_LE: jit_op_arith(J, ra, rb, rc, TM_LE); break; | ||
121 | |||
122 | case OP_TEST: jit_op_test(J, rc, ra, ra); break; | ||
123 | case OP_TESTSET: jit_op_test(J, rc, ra, rb); break; | ||
124 | |||
125 | case OP_JMP: jit_op_jmp(J, J->nextpc + rbx-MAXARG_sBx); break; | ||
126 | |||
127 | case OP_CALL: jit_op_call(J, ra, rb-1, rc-1); break; | ||
128 | case OP_TAILCALL: jit_op_tailcall(J, ra, rb-1); break; | ||
129 | case OP_RETURN: jit_op_return(J, ra, rb-1); break; | ||
130 | |||
131 | case OP_FORLOOP: jit_op_forloop(J, ra, J->nextpc + rbx-MAXARG_sBx); break; | ||
132 | case OP_FORPREP: jit_op_forprep(J, ra, J->nextpc + rbx-MAXARG_sBx); break; | ||
133 | |||
134 | case OP_TFORLOOP: jit_op_tforloop(J, ra, rc); break; | ||
135 | |||
136 | case OP_CLOSE: jit_op_close(J, ra); break; | ||
137 | case OP_CLOSURE: jit_op_closure(J, ra, rbx); break; | ||
138 | |||
139 | case OP_VARARG: jit_op_vararg(J, ra, rb-1); break; | ||
140 | |||
141 | default: jit_assert(0); break; | ||
142 | } | ||
143 | |||
144 | /* Convention: all opcodes start and end with the .code section. */ | ||
145 | if (dasm_checkstep(Dst, DASM_SECTION_CODE)) { J->nextpc--; return; } | ||
146 | |||
147 | *J->mfm++ = 0; /* Placeholder mfm entry. Replaced later. */ | ||
148 | if (J->combine > 0) { /* Combine next J->combine ins with prev ins. */ | ||
149 | J->nextpc += J->combine; | ||
150 | J->nextins += J->combine; | ||
151 | do { *J->mfm++ = JIT_MFM_COMBINE; } while (--J->combine); | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | |||
156 | /* Merge temporary mfm (forward) with PC labels to inverse mfm in mcode. */ | ||
157 | static void jit_mfm_merge(jit_State *J, jit_Mfm *from, jit_Mfm *to, int maxpc) | ||
158 | { | ||
159 | int pc = 1, ofs = 0; | ||
160 | for (;;) { | ||
161 | int m = *from++; | ||
162 | if (m & JIT_MFM_MARK) { | ||
163 | switch (m) { | ||
164 | default: pc = m ^ JIT_MFM_MARK; break; | ||
165 | case JIT_MFM_COMBINE: case JIT_MFM_DEAD: break; | ||
166 | case JIT_MFM_STOP: return; | ||
167 | } | ||
168 | } else { | ||
169 | int idx, nofs; | ||
170 | for (idx = 0; from[idx] == JIT_MFM_COMBINE; idx++) ; | ||
171 | idx += pc; | ||
172 | if (idx == J->nextpc) idx = maxpc + 1; | ||
173 | nofs = dasm_getpclabel(Dst, idx); | ||
174 | m = nofs - ofs; | ||
175 | ofs = nofs; | ||
176 | jit_assert(nofs >= 0 && m >= 0 && m < JIT_MFM_MAX); | ||
177 | } | ||
178 | pc++; | ||
179 | *to-- = m; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | /* Compile function prototype. */ | ||
184 | static int jit_compile_proto(jit_State *J, Table *deopt) | ||
185 | { | ||
186 | jit_Mfm *tempmfm; | ||
187 | void *mcode; | ||
188 | size_t sz; | ||
189 | int firstpc = 0, maxpc = J->pt->sizecode; | ||
190 | int deoptidx = 1; | ||
191 | int status; | ||
192 | /* (Ab)use the global string concatenation buffer for the temporary mfm. */ | ||
193 | /* Caveat: the GC must not be run while the backend is active. */ | ||
194 | tempmfm = (jit_Mfm *)luaZ_openspace(J->L, &G(J->L)->buff, | ||
195 | (1+maxpc+1+1+1)*sizeof(jit_Mfm)); | ||
196 | nextdeopt: | ||
197 | J->mfm = tempmfm; | ||
198 | J->tflags = 0; | ||
199 | /* Setup DynASM. */ | ||
200 | dasm_growpc(Dst, 1+maxpc+2); /* See jit_ins_last(). */ | ||
201 | dasm_setup(Dst, jit_actionlist); | ||
202 | if (deopt) { /* Partial deoptimization. */ | ||
203 | /* TODO: check deopt chain length? problem: pairs TFOR_CTL migration. */ | ||
204 | int pc, lastpc; | ||
205 | lua_Number n; | ||
206 | const TValue *obj = luaH_getnum(deopt, deoptidx++); | ||
207 | if (ttisnil(obj) && deoptidx != 2) return JIT_S_OK; | ||
208 | if (!ttisnumber(obj)) return JIT_S_COMPILER_ERROR; | ||
209 | n = nvalue(obj); | ||
210 | lua_number2int(pc, n); | ||
211 | firstpc = JIT_IH_IDX(pc); | ||
212 | lastpc = firstpc + JIT_IH_LIB(pc); | ||
213 | if (firstpc < 1 || firstpc > maxpc || lastpc > maxpc || | ||
214 | J->pt->jit_szmcode == 0) | ||
215 | return JIT_S_COMPILER_ERROR; | ||
216 | *J->mfm++ = JIT_MFM_MARK+firstpc; /* Seek to firstpc. */ | ||
217 | jit_compile_irange(J, firstpc, lastpc); | ||
218 | jit_assert(J->nextpc == lastpc+1); /* Problem with combined ins? */ | ||
219 | if (J->nextpc <= maxpc) jit_ins_chainto(J, J->nextpc); | ||
220 | *J->mfm++ = JIT_MFM_MARK+maxpc+1; /* Seek to .deopt/.tail. */ | ||
221 | for (pc = 1; pc <= maxpc; pc++) | ||
222 | if (dasm_getpclabel(Dst, pc) == -1) { /* Undefind label referenced? */ | ||
223 | jit_ins_setpc(J, pc, luaJIT_findmcode(J->pt, pc)); /* => Old mcode. */ | ||
224 | } | ||
225 | } else { /* Full compile. */ | ||
226 | *J->mfm++ = 0; /* Placeholder mfm entry for prologue. */ | ||
227 | jit_prologue(J); | ||
228 | jit_compile_irange(J, 1, maxpc); | ||
229 | } | ||
230 | *J->mfm++ = 0; /* Placeholder mfm entry for .deopt/.tail. */ | ||
231 | *J->mfm = JIT_MFM_STOP; | ||
232 | jit_ins_last(J, maxpc, (char *)J->mfm - (char *)tempmfm); | ||
233 | |||
234 | status = luaJIT_link(J, &mcode, &sz); | ||
235 | if (status != JIT_S_OK) | ||
236 | return status; | ||
237 | |||
238 | jit_mfm_merge(J, tempmfm, JIT_MCMFM(mcode, sz), maxpc); | ||
239 | |||
240 | if (deopt) { | ||
241 | jit_MCTrailer tr; | ||
242 | /* Patch first instruction to jump to the deoptimized code. */ | ||
243 | jit_patch_jmp(J, luaJIT_findmcode(J->pt, firstpc), mcode); | ||
244 | /* Mark instruction as deoptimized in main mfm. */ | ||
245 | JIT_MCMFM(J->pt->jit_mcode, J->pt->jit_szmcode)[-firstpc] |= JIT_MFM_MARK; | ||
246 | /* Chain deopt mcode block between main mfm and existing mfms. */ | ||
247 | memcpy(JIT_MCTRAILER(mcode, sz), | ||
248 | JIT_MCTRAILER(J->pt->jit_mcode, J->pt->jit_szmcode), | ||
249 | sizeof(jit_MCTrailer)); | ||
250 | tr.mcode = (char *)mcode; | ||
251 | tr.sz = sz; | ||
252 | memcpy(JIT_MCTRAILER(J->pt->jit_mcode, J->pt->jit_szmcode), (void *)&tr, | ||
253 | sizeof(jit_MCTrailer)); | ||
254 | goto nextdeopt; | ||
255 | } | ||
256 | |||
257 | if (J->pt->jit_szmcode != 0) { /* Full recompile? */ | ||
258 | jit_MCTrailer tr; | ||
259 | /* Patch old mcode entry so other closures get the new callgate. */ | ||
260 | jit_patch_jmp(J, J->pt->jit_mcode, J->jsub[JSUB_GATE_JL]); | ||
261 | /* Chain old main mfm after new main mfm. */ | ||
262 | tr.mcode = (char *)J->pt->jit_mcode; | ||
263 | tr.sz = J->pt->jit_szmcode; | ||
264 | memcpy(JIT_MCTRAILER(mcode, sz), (void *)&tr, sizeof(jit_MCTrailer)); | ||
265 | } | ||
266 | /* Set new main mcode block. */ | ||
267 | J->pt->jit_mcode = mcode; | ||
268 | J->pt->jit_szmcode = sz; | ||
269 | return JIT_S_OK; | ||
270 | } | ||
271 | |||
272 | /* ------------------------------------------------------------------------ */ | ||
273 | |||
274 | /* Compiler backend. */ | ||
275 | int luaJIT_backend(lua_State *L) | ||
276 | { | ||
277 | jit_State *J = G(L)->jit_state; | ||
278 | const TValue *cl; | ||
279 | int status = JIT_S_COMPILER_ERROR; | ||
280 | lua_lock(L); | ||
281 | /* Remember compiler state table. */ | ||
282 | jit_assert(L->top > L->base && ttistable(L->top-1)); | ||
283 | J->comstate = hvalue(L->top-1); | ||
284 | /* Fetch prototoype. Better check this in case some handler screwed up. */ | ||
285 | cl = luaH_getstr(J->comstate, luaS_newliteral(L, "func")); | ||
286 | if (isLfunction(cl)) { | ||
287 | J->pt = clvalue(cl)->l.p; | ||
288 | if (J->pt->sizecode > LUAJIT_LIM_BYTECODE) { /* Hard backend limit. */ | ||
289 | status = JIT_S_TOOLARGE; | ||
290 | } else { | ||
291 | const TValue *obj = luaH_getstr(J->comstate, | ||
292 | luaS_newliteral(J->L, "deopt")); | ||
293 | status = jit_compile_proto(J, ttistable(obj) ? hvalue(obj) : (Table *)0); | ||
294 | } | ||
295 | } | ||
296 | lua_unlock(L); | ||
297 | J->comstate = NULL; /* Just in case. */ | ||
298 | J->pt = NULL; | ||
299 | if (status == JIT_S_OK) { | ||
300 | return 0; | ||
301 | } else { | ||
302 | if (status == JIT_S_DASM_ERROR) { | ||
303 | lua_pushinteger(L, J->nextpc); | ||
304 | lua_setfield(L, 1, "dasm_pc"); | ||
305 | lua_pushinteger(L, J->dasmstatus); | ||
306 | lua_setfield(L, 1, "dasm_err"); | ||
307 | } | ||
308 | lua_pushinteger(L, status); | ||
309 | return 1; | ||
310 | } | ||
311 | } | ||
312 | |||
313 | /* Initialize compiler backend. */ | ||
314 | int luaJIT_initbackend(lua_State *L) | ||
315 | { | ||
316 | jit_State *J = G(L)->jit_state; | ||
317 | J->L = L; | ||
318 | J->pt = NULL; /* Not in use. */ | ||
319 | J->D = NULL; | ||
320 | J->mcodeheap = NULL; | ||
321 | J->jsubmcode = NULL; | ||
322 | J->szjsubmcode = 0; | ||
323 | J->numjsub = JSUB__MAX; | ||
324 | J->jsub = luaM_newvector(J->L, JSUB__MAX, void *); | ||
325 | memset((void *)J->jsub, 0, JSUB__MAX*sizeof(void *)); /* Just in case. */ | ||
326 | dasm_init(Dst, DASM_MAXSECTION); | ||
327 | dasm_setupglobal(Dst, J->jsub, JSUB__MAX); | ||
328 | return jit_compile_jsub(J); | ||
329 | } | ||
330 | |||
331 | /* Free compiler backend. */ | ||
332 | void luaJIT_freebackend(lua_State *L) | ||
333 | { | ||
334 | jit_State *J = G(L)->jit_state; | ||
335 | J->L = L; | ||
336 | if (J->jsub) luaM_freearray(L, J->jsub, JSUB__MAX, void *); | ||
337 | luaJIT_freemcodeheap(J); /* Frees JSUB mcode, too. */ | ||
338 | dasm_free(Dst); | ||
339 | } | ||
340 | |||
341 | /* ------------------------------------------------------------------------ */ | ||
342 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_core.c b/libraries/LuaJIT-1.1.7/src/ljit_core.c new file mode 100644 index 0000000..f7385f2 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit_core.c | |||
@@ -0,0 +1,385 @@ | |||
1 | /* | ||
2 | ** Interface to JIT engine. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #define ljit_core_c | ||
7 | #define LUA_CORE | ||
8 | |||
9 | #include <string.h> | ||
10 | |||
11 | #include "lua.h" | ||
12 | |||
13 | #include "lobject.h" | ||
14 | #include "lstate.h" | ||
15 | #include "ldo.h" | ||
16 | #include "lstring.h" | ||
17 | #include "ltable.h" | ||
18 | #include "ldebug.h" | ||
19 | #include "lopcodes.h" | ||
20 | |||
21 | #include "ljit.h" | ||
22 | #include "ljit_hints.h" | ||
23 | #include "luajit.h" | ||
24 | |||
25 | const char luajit_ident[] = | ||
26 | "$LuaJIT: " LUAJIT_VERSION " " LUAJIT_COPYRIGHT " " LUAJIT_URL " $\n"; | ||
27 | |||
28 | /* ------------------------------------------------------------------------ */ | ||
29 | |||
30 | /* Initialize JIT engine state. */ | ||
31 | void luaJIT_initstate(lua_State *L) | ||
32 | { | ||
33 | jit_State *J = luaM_new(L, jit_State); | ||
34 | G(L)->jit_state = J; | ||
35 | /* Clear JIT engine fields. */ | ||
36 | J->frontwrap = NULL; /* Filled in by ljitlib before enabling the engine. */ | ||
37 | J->flags = 0; /* Disable the JIT engine by default. */ | ||
38 | /* Try to initialize the backend. */ | ||
39 | if (luaJIT_initbackend(L) != JIT_S_OK) | ||
40 | J->flags = JIT_F_INIT_FAILED; | ||
41 | J->L = NULL; /* No compiler thread allocated, yet. */ | ||
42 | } | ||
43 | |||
44 | /* Free JIT engine state. */ | ||
45 | void luaJIT_freestate(lua_State *L) | ||
46 | { | ||
47 | jit_State *J = G(L)->jit_state; | ||
48 | if (J == NULL) return; | ||
49 | luaJIT_freebackend(L); | ||
50 | luaM_free(L, J); | ||
51 | G(L)->jit_state = NULL; | ||
52 | } | ||
53 | |||
54 | /* ------------------------------------------------------------------------ */ | ||
55 | |||
56 | /* Find relative PC (0 based) for a bytecode pointer or a JIT mcode address. */ | ||
57 | int luaJIT_findpc(Proto *pt, const Instruction *savedpc) | ||
58 | { | ||
59 | ptrdiff_t pcdiff = savedpc - pt->code; | ||
60 | if (pcdiff >= 0 && pcdiff <= pt->sizecode) { /* Bytecode pointer? */ | ||
61 | return (int)pcdiff-1; | ||
62 | } else { /* Else translate JIT mcode address to PC. */ | ||
63 | char *addr = (char *)savedpc; | ||
64 | jit_MCTrailer tr; | ||
65 | tr.mcode = (char *)pt->jit_mcode; | ||
66 | tr.sz = pt->jit_szmcode; | ||
67 | /* Follow trailer chain until addr is part of an mcode block. */ | ||
68 | while (!((size_t)(addr - tr.mcode) < tr.sz)) { | ||
69 | memcpy((void *)&tr, JIT_MCTRAILER(tr.mcode, tr.sz), | ||
70 | sizeof(jit_MCTrailer)); | ||
71 | if (tr.mcode == NULL) return -1; /* Not in chain. */ | ||
72 | } | ||
73 | { | ||
74 | jit_Mfm *mfm = JIT_MCMFM(tr.mcode, tr.sz); | ||
75 | int ofs = (int)(addr - tr.mcode); | ||
76 | int isdeopt = !jit_mfm_ismain(mfm); | ||
77 | int pc = 0; /* Prologue fragment is at start of main mfm. */ | ||
78 | while (pc <= pt->sizecode) { | ||
79 | int m = *mfm--; | ||
80 | switch (m) { | ||
81 | default: | ||
82 | if (m & JIT_MFM_MARK) { | ||
83 | m ^= JIT_MFM_MARK; | ||
84 | if (isdeopt) { pc = m; continue; } /* Seek. */ | ||
85 | } | ||
86 | ofs -= m; | ||
87 | if (ofs <= 0) return pc-1; /* Found! */ | ||
88 | case JIT_MFM_COMBINE: | ||
89 | case JIT_MFM_DEAD: | ||
90 | pc++; | ||
91 | break; | ||
92 | case JIT_MFM_STOP: | ||
93 | jit_assert(0); /* Premature STOP found. */ | ||
94 | return -1; | ||
95 | } | ||
96 | } | ||
97 | jit_assert(0); /* Address is in .tail. */ | ||
98 | return -1; | ||
99 | } | ||
100 | } | ||
101 | } | ||
102 | |||
103 | /* Lookup mcode address for PC (1 based) in mfm. */ | ||
104 | static void *jit_mfmlookup(jit_Mfm *mfm, char *addr, int mpc) | ||
105 | { | ||
106 | int isdeopt = !jit_mfm_ismain(mfm); | ||
107 | int pc = 0; /* Prologue fragment is at start of main mfm. */ | ||
108 | while (pc != mpc) { | ||
109 | int m = *mfm--; | ||
110 | switch (m) { | ||
111 | default: | ||
112 | if (m & JIT_MFM_MARK) { | ||
113 | m ^= JIT_MFM_MARK; | ||
114 | if (isdeopt) { pc = m; continue; } /* Seek. */ | ||
115 | } | ||
116 | addr += m; | ||
117 | case JIT_MFM_COMBINE: | ||
118 | case JIT_MFM_DEAD: | ||
119 | pc++; | ||
120 | break; | ||
121 | case JIT_MFM_STOP: | ||
122 | return NULL; | ||
123 | } | ||
124 | } | ||
125 | return (void *)addr; | ||
126 | } | ||
127 | |||
128 | /* Find mcode address for PC (1 based). */ | ||
129 | void *luaJIT_findmcode(Proto *pt, int pc) | ||
130 | { | ||
131 | void *addr = NULL; | ||
132 | jit_Mfm *mfm; | ||
133 | jit_MCTrailer tr; | ||
134 | tr.mcode = (char *)pt->jit_mcode; | ||
135 | tr.sz = pt->jit_szmcode; | ||
136 | mfm = JIT_MCMFM(tr.mcode, tr.sz); | ||
137 | jit_assert(pc >= 1 && pc <= pt->sizecode); | ||
138 | while (mfm[-pc] == JIT_MFM_COMBINE) pc--; | ||
139 | while (mfm[-pc] == JIT_MFM_DEAD) pc++; | ||
140 | jit_assert(pc >= 1 && mfm[-pc] < (JIT_MFM_MARK|JIT_MFM_MAX)); /* Valid? */ | ||
141 | if (jit_mfm_isdeoptpc(mfm, pc)) { /* Deoptimized instruction. */ | ||
142 | do { /* Search through deopt mfm chain. */ | ||
143 | memcpy((void *)&tr, JIT_MCTRAILER(tr.mcode, tr.sz), | ||
144 | sizeof(jit_MCTrailer)); | ||
145 | if (tr.mcode == NULL) break; /* Deopt ins missing in chain. */ | ||
146 | mfm = JIT_MCMFM(tr.mcode, tr.sz); | ||
147 | if (jit_mfm_ismain(mfm)) break; /* Old main mfm stops search, too. */ | ||
148 | addr = jit_mfmlookup(mfm, tr.mcode, pc); | ||
149 | } while (addr == NULL); | ||
150 | } else { /* Not deoptimized. Lookup in main mfm. */ | ||
151 | addr = jit_mfmlookup(mfm, tr.mcode, pc); | ||
152 | } | ||
153 | jit_assert(addr != NULL); /* Corrupt mfm chain. */ | ||
154 | return addr; | ||
155 | } | ||
156 | |||
157 | /* ------------------------------------------------------------------------ */ | ||
158 | |||
159 | /* Compile a prototype. */ | ||
160 | /* Note: func pointer may be invalidated because of stack reallocation. */ | ||
161 | static int jit_compile(lua_State *L, StkId func, Table *st, int force) | ||
162 | { | ||
163 | jit_State *J = G(L)->jit_state; | ||
164 | Closure *cl = clvalue(func); | ||
165 | Proto *pt = cl->l.p; | ||
166 | int status; | ||
167 | |||
168 | /* Check if JIT engine is enabled and prevent recursive invocation. */ | ||
169 | if ((J->flags & JIT_F_INIT_FAILED) || | ||
170 | (!force && !(J->flags & JIT_F_ON)) || | ||
171 | !J->frontwrap) { | ||
172 | status = JIT_S_ENGINE_OFF; | ||
173 | } else if (J->flags & JIT_F_COMPILING) { | ||
174 | status = JIT_S_DELAYED; | ||
175 | } else if (pt->jit_szmcode != 0 && force < 2) { /* Prevent recompile. */ | ||
176 | /* TODO: Allow recompiles? Use case? Extra flag for jit.compile()? */ | ||
177 | status = JIT_S_OK; | ||
178 | } else { | ||
179 | setclvalue(L, luaH_setstr(L, st, luaS_newliteral(L, "func")), cl); | ||
180 | /* Call frontend wrapper. */ | ||
181 | J->flags |= JIT_F_COMPILING; | ||
182 | lua_unlock(L); | ||
183 | status = J->frontwrap(L, st); | ||
184 | lua_lock(L); | ||
185 | J->flags &= ~JIT_F_COMPILING; | ||
186 | } | ||
187 | |||
188 | /* Better sanity check what the frontend returns. */ | ||
189 | if ((status == JIT_S_OK && pt->jit_szmcode == 0) || status == JIT_S_NONE) | ||
190 | status = JIT_S_COMPILER_ERROR; | ||
191 | |||
192 | /* Update closure callgate and prototype status. */ | ||
193 | cl->l.jit_gate = (status == JIT_S_OK) ? (lua_CFunction)pt->jit_mcode : | ||
194 | G(L)->jit_gateJL; | ||
195 | pt->jit_status = status; | ||
196 | return status; | ||
197 | } | ||
198 | |||
199 | /* Create the state table and copy the arguments. */ | ||
200 | static Table *jit_createstate(lua_State *L, StkId arg, int nargs) | ||
201 | { | ||
202 | Table *st = luaH_new(L, nargs, COMSTATE_PREALLOC); | ||
203 | int i; | ||
204 | for (i = 0; i < nargs; i++) | ||
205 | setobj2t(L, luaH_setnum(L, st, i+1), arg+i); | ||
206 | return st; | ||
207 | } | ||
208 | |||
209 | /* ------------------------------------------------------------------------ */ | ||
210 | |||
211 | /* Compile and run a function. To be used by luaD_precall() only. */ | ||
212 | int luaJIT_run(lua_State *L, StkId func, int nresults) | ||
213 | { | ||
214 | ptrdiff_t funcr = savestack(L, func); | ||
215 | Table *st = jit_createstate(L, func+1, L->top-(func+1)); | ||
216 | int status = jit_compile(L, func, st, 0); /* Compile function. */ | ||
217 | func = restorestack(L, funcr); | ||
218 | |||
219 | /* Run the compiled function on success. Fallback to bytecode on failure. */ | ||
220 | if (status == JIT_S_OK) | ||
221 | return G(L)->jit_gateLJ(L, func, nresults); | ||
222 | else | ||
223 | return luaD_precall(L, func, nresults); | ||
224 | /* Note: We are called from luaD_precall and we call it again. */ | ||
225 | /* So jit_compile makes sure pt->jit_status != JIT_S_NONE. */ | ||
226 | } | ||
227 | |||
228 | /* ------------------------------------------------------------------------ */ | ||
229 | |||
230 | /* No more than two ranges for a single deoptimization right now. */ | ||
231 | #define DEOPTRANGE_ALLOC 2 | ||
232 | |||
233 | /* Find PC range of combined instructions and return a range hint. */ | ||
234 | static int combinedrange(jit_Mfm *mfm, int pc) | ||
235 | { | ||
236 | int lastpc = pc; | ||
237 | while (mfm[-pc] == JIT_MFM_COMBINE) pc--; /* 1st comb. ins. */ | ||
238 | while (mfm[-(lastpc+1)] == JIT_MFM_COMBINE) lastpc++; /* Last comb. ins. */ | ||
239 | return JIT_IH_MKIDX(lastpc-pc, pc); /* (#ins-1, pc) in hint format. */ | ||
240 | } | ||
241 | |||
242 | /* Process deoptimization hints for the given PC range. */ | ||
243 | static int deopthints(Proto *pt, jit_Mfm *dh, TValue *dhint, int pcrange) | ||
244 | { | ||
245 | int m; | ||
246 | setnvalue(dhint++, (lua_Number)pcrange); | ||
247 | while ((m = *dh--) != JIT_MFM_STOP) { | ||
248 | if ((unsigned int)(m - JIT_IH_IDX(pcrange)) <= | ||
249 | (unsigned int)JIT_IH_LIB(pcrange)) { | ||
250 | switch (*dh--) { | ||
251 | case JIT_MFM_DEOPT_PAIRS: /* CALL [i]pairs(): deopt TFORLOOP+JMP. */ | ||
252 | if (GET_OPCODE(pt->code[m+1-1]) == OP_JMP) { | ||
253 | int tfpc = m+2 + GETARG_sBx(pt->code[m+1-1]); | ||
254 | if ((unsigned)tfpc < (unsigned)pt->sizecode && | ||
255 | GET_OPCODE(pt->code[tfpc-1]) == OP_TFORLOOP) { | ||
256 | setnvalue(dhint++, (lua_Number)JIT_IH_MKIDX(1, tfpc)); | ||
257 | break; | ||
258 | } | ||
259 | } | ||
260 | return 1; /* Bad hint. */ | ||
261 | default: | ||
262 | return 1; /* Cannot tolerate unknown deoptimization hints. */ | ||
263 | } | ||
264 | } | ||
265 | } | ||
266 | return 0; /* Ok. */ | ||
267 | } | ||
268 | |||
269 | /* Deoptimize the current instruction. Return new mcode addr to continue. */ | ||
270 | void *luaJIT_deoptimize(lua_State *L) | ||
271 | { | ||
272 | StkId func = L->ci->func; | ||
273 | Proto *pt = clvalue(func)->l.p; | ||
274 | int pc = luaJIT_findpc(pt, L->savedpc)+1; /* Get prev. PC (1 based). */ | ||
275 | jit_Mfm *mfm = JIT_MCMFM(pt->jit_mcode, pt->jit_szmcode); | ||
276 | int pcrange = combinedrange(mfm, pc); | ||
277 | if (!jit_mfm_isdeoptpc(mfm, JIT_IH_IDX(pcrange))) { /* Not deopt. yet? */ | ||
278 | Table *st = jit_createstate(L, NULL, 0); /* Don't know original args. */ | ||
279 | Table *deopt = luaH_new(L, DEOPTRANGE_ALLOC, 0); | ||
280 | sethvalue(L, luaH_setstr(L, st, luaS_newliteral(L, "deopt")), deopt); | ||
281 | if (deopthints(pt, mfm-(pt->sizecode+2), deopt->array, pcrange) || | ||
282 | jit_compile(L, func, st, 2) != JIT_S_OK) | ||
283 | luaG_runerror(L, "deoptimization failed"); | ||
284 | } | ||
285 | return luaJIT_findmcode(pt, pc); | ||
286 | } | ||
287 | |||
288 | /* ------------------------------------------------------------------------ */ | ||
289 | |||
290 | /* API function: Compile a Lua function. Pass arguments as hints. */ | ||
291 | LUA_API int luaJIT_compile(lua_State *L, int nargs) | ||
292 | { | ||
293 | StkId func; | ||
294 | Table *st; | ||
295 | int status; | ||
296 | lua_lock(L); | ||
297 | api_check(L, (nargs+1) <= (L->top - L->base)); | ||
298 | func = L->top - (nargs+1); | ||
299 | st = jit_createstate(L, func+1, nargs); | ||
300 | status = isLfunction(func) ? jit_compile(L, func, st, 1) : -1; | ||
301 | lua_unlock(L); | ||
302 | return status; | ||
303 | } | ||
304 | |||
305 | /* Recursively set the mode for all subroutines. */ | ||
306 | static void rec_setmode(Proto *pt, int on) | ||
307 | { | ||
308 | int i; | ||
309 | for (i = 0; i < pt->sizep; i++) { | ||
310 | Proto *pti = pt->p[i]; | ||
311 | pti->jit_status = on ? (pti->jit_szmcode?JIT_S_OK:JIT_S_NONE) : JIT_S_OFF; | ||
312 | rec_setmode(pti, on); /* Recurse into proto. */ | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /* API function: Set the JIT mode for the whole engine or a function+subs. */ | ||
317 | LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode) | ||
318 | { | ||
319 | jit_State *J = G(L)->jit_state; | ||
320 | int mm = mode & LUAJIT_MODE_MASK; | ||
321 | if (J->flags & JIT_F_INIT_FAILED) return -1; /* Init failed. */ | ||
322 | switch (mm) { | ||
323 | case LUAJIT_MODE_ENGINE: /* Set mode for JIT engine. */ | ||
324 | if (mode & LUAJIT_MODE_ON) | ||
325 | J->flags |= JIT_F_ON; | ||
326 | else | ||
327 | J->flags &= ~JIT_F_ON; | ||
328 | break; | ||
329 | case LUAJIT_MODE_DEBUG: { /* Set debug mode. */ | ||
330 | int dbg; | ||
331 | switch (idx) { | ||
332 | case 0: dbg = 0; break; | ||
333 | case 1: dbg = JIT_F_DEBUG_CALL; break; | ||
334 | case 2: default: dbg = JIT_F_DEBUG_CALL | JIT_F_DEBUG_INS; break; | ||
335 | } | ||
336 | J->flags = (J->flags & ~JIT_F_DEBUG) | dbg; | ||
337 | luaJIT_debugnotify(J); | ||
338 | break; | ||
339 | } | ||
340 | case LUAJIT_MODE_FUNC: /* Set mode for function. */ | ||
341 | case LUAJIT_MODE_ALLFUNC: /* Set mode for function + subfuncs. */ | ||
342 | case LUAJIT_MODE_ALLSUBFUNC: { /* Set mode for subfunctions. */ | ||
343 | StkId func; | ||
344 | lua_lock(L); | ||
345 | func = idx == 0 ? (L->ci-1)->func : | ||
346 | (idx > 0 ? L->base + (idx-1) : L->top + idx); | ||
347 | if (isLfunction(func)) { | ||
348 | Closure *cl = clvalue(func); | ||
349 | Proto *pt = cl->l.p; | ||
350 | if (mm != LUAJIT_MODE_ALLSUBFUNC) { | ||
351 | if (mode & LUAJIT_MODE_ON) { | ||
352 | if (pt->jit_szmcode) { /* Already compiled? */ | ||
353 | cl->l.jit_gate = (lua_CFunction)pt->jit_mcode; /* Reenable. */ | ||
354 | pt->jit_status = JIT_S_OK; | ||
355 | } else { | ||
356 | pt->jit_status = JIT_S_NONE; /* (Re-)enable proto compilation */ | ||
357 | } | ||
358 | } else { | ||
359 | cl->l.jit_gate = G(L)->jit_gateJL; /* Default callgate. */ | ||
360 | pt->jit_status = JIT_S_OFF; /* Disable proto compilation. */ | ||
361 | /* Note: compiled code must be retained for suspended threads. */ | ||
362 | } | ||
363 | } | ||
364 | if (mm != LUAJIT_MODE_FUNC) | ||
365 | rec_setmode(pt, mode & LUAJIT_MODE_ON); | ||
366 | lua_unlock(L); | ||
367 | } else { | ||
368 | lua_unlock(L); | ||
369 | return 0; /* Failed. */ | ||
370 | } | ||
371 | break; | ||
372 | } | ||
373 | default: | ||
374 | return 0; /* Failed. */ | ||
375 | } | ||
376 | return 1; /* OK. */ | ||
377 | } | ||
378 | |||
379 | /* Enforce (dynamic) linker error for version mismatches. See lua.c. */ | ||
380 | LUA_API void LUAJIT_VERSION_SYM(void) | ||
381 | { | ||
382 | } | ||
383 | |||
384 | /* ------------------------------------------------------------------------ */ | ||
385 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_dasm.c b/libraries/LuaJIT-1.1.7/src/ljit_dasm.c new file mode 100644 index 0000000..c2d44ee --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit_dasm.c | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | ** Wrapper for architecture-specific DynASM encoder. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #define ljit_dasm_c | ||
7 | #define LUA_CORE | ||
8 | |||
9 | |||
10 | #include "lua.h" | ||
11 | |||
12 | #include "ljit.h" | ||
13 | #include "ljit_dasm.h" | ||
14 | #include "lmem.h" | ||
15 | |||
16 | |||
17 | /* Glue macros for DynASM memory allocation. */ | ||
18 | #define DASM_M_GROW(J, t, p, sz, need) \ | ||
19 | do { \ | ||
20 | size_t _sz = (sz), _need = (need); \ | ||
21 | if (_sz < _need) { \ | ||
22 | if (_sz < 16) _sz = 16; \ | ||
23 | while (_sz < _need) _sz += _sz; \ | ||
24 | (p) = (t *)luaM_realloc_(J->L, (p), (sz), _sz); \ | ||
25 | (sz) = _sz; \ | ||
26 | } \ | ||
27 | } while(0) | ||
28 | |||
29 | #define DASM_M_FREE(J, p, sz) luaM_freemem(J->L, p, sz) | ||
30 | |||
31 | /* Embed architecture-specific DynASM encoder. */ | ||
32 | #if defined(__i386) || defined(__i386__) || defined(_M_IX86) | ||
33 | #include "dasm_x86.h" | ||
34 | #else | ||
35 | #error "No support for this architecture (yet)" | ||
36 | #endif | ||
37 | |||
38 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_dasm.h b/libraries/LuaJIT-1.1.7/src/ljit_dasm.h new file mode 100644 index 0000000..0a9dd5d --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit_dasm.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | ** Interface to DynASM engine. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #ifndef ljit_dasm_h | ||
7 | #define ljit_dasm_h | ||
8 | |||
9 | #include "ljit.h" | ||
10 | |||
11 | /* DynASM glue definitions. */ | ||
12 | #define Dst J | ||
13 | #define Dst_DECL jit_State *J | ||
14 | #define Dst_REF (J->D) | ||
15 | #define DASM_FDEF LUAI_FUNC | ||
16 | |||
17 | #include "dasm_proto.h" | ||
18 | |||
19 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_hints.h b/libraries/LuaJIT-1.1.7/src/ljit_hints.h new file mode 100644 index 0000000..23743bc --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit_hints.h | |||
@@ -0,0 +1,137 @@ | |||
1 | /* | ||
2 | ** Hints for the JIT compiler backend. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #ifdef STRING_HINTS | ||
7 | #define HH(x, name) #name | ||
8 | #define HH_START(x) static const char *const hints_##x [] = { | ||
9 | #define HH_END(x) NULL } | ||
10 | #else | ||
11 | #define HH(x, name) JIT_##x##_##name | ||
12 | #define HH_START(x) enum { JIT_##x##_NONE, | ||
13 | #define HH_END(x) JIT_##x##_MAX } | ||
14 | |||
15 | /* Macros to access hints. */ | ||
16 | #define JIT_H2NUM(x) ((x) << 16) | ||
17 | |||
18 | #define fhint_get(J, hh) \ | ||
19 | (luaH_getnum(J->comstate, JIT_H2NUM(JIT_FH_##hh))) | ||
20 | #define fhint_isset(J, hh) (!ttisnil(fhint_get(J, hh))) | ||
21 | |||
22 | #define hint_getpc(J, hh, pc) \ | ||
23 | (luaH_getnum(J->comstate, (pc)+JIT_H2NUM(JIT_H_##hh))) | ||
24 | #define hint_get(J, hh) hint_getpc(J, hh, J->nextpc-1) | ||
25 | #define hint_issetpc(J, hh, pc) (!ttisnil(hint_getpc(J, hh, pc))) | ||
26 | #define hint_isset(J, hh) hint_issetpc(J, hh, J->nextpc-1) | ||
27 | |||
28 | #endif | ||
29 | |||
30 | /* Hints for functions. */ | ||
31 | HH_START(FH) | ||
32 | HH(FH, NOCLOSE), /* No luaF_close() needed. */ | ||
33 | HH_END(FH); | ||
34 | |||
35 | /* Hints for individual bytecode instruction. */ | ||
36 | HH_START(H) | ||
37 | HH(H, COMBINE), /* Combine/dead instruction: true/false. */ | ||
38 | HH(H, FOR_STEP_K), /* FORPREP/FORLOOP step is const: step. */ | ||
39 | HH(H, TYPE), /* Type hint: typed object. */ | ||
40 | HH(H, TYPEKEY), /* Type hint for keys: typed object. */ | ||
41 | HH(H, INLINE), /* Inline function call: internal index. */ | ||
42 | HH_END(H); | ||
43 | |||
44 | #undef HH | ||
45 | #undef HH_START | ||
46 | #undef HH_END | ||
47 | |||
48 | |||
49 | /* Avoid multiple inclusion for the following. */ | ||
50 | #ifndef ljit_hints_h | ||
51 | #define ljit_hints_h | ||
52 | |||
53 | /* Index numbers for inlining C functions. */ | ||
54 | /* CHECK: the index numbers must match with jit.opt_lib. */ | ||
55 | |||
56 | #define JIT_IH_LIB(x) ((x) >> 16) | ||
57 | #define JIT_IH_IDX(x) ((x) & 0xffff) | ||
58 | #define JIT_IH_MKIDX(l, f) (((l) << 16) | (f)) | ||
59 | |||
60 | /* Library index numbers. */ | ||
61 | enum { | ||
62 | JIT_IHLIB_INTERNAL, | ||
63 | JIT_IHLIB_BASE, | ||
64 | JIT_IHLIB_COROUTINE, | ||
65 | JIT_IHLIB_STRING, | ||
66 | JIT_IHLIB_TABLE, | ||
67 | JIT_IHLIB_MATH, | ||
68 | JIT_IHLIB__LAST | ||
69 | }; | ||
70 | |||
71 | /* Internal functions. */ | ||
72 | enum { | ||
73 | JIT_IH_INTERNAL_RECURSIVE, /* Recursive call. */ | ||
74 | JIT_IH_INTERNAL__LAST | ||
75 | }; | ||
76 | |||
77 | /* Base library functions. */ | ||
78 | enum { | ||
79 | JIT_IH_BASE_PAIRS, | ||
80 | JIT_IH_BASE_IPAIRS, | ||
81 | JIT_IH_BASE__LAST | ||
82 | }; | ||
83 | |||
84 | /* Coroutine library functions. */ | ||
85 | enum { | ||
86 | JIT_IH_COROUTINE_YIELD, | ||
87 | JIT_IH_COROUTINE_RESUME, | ||
88 | JIT_IH_COROUTINE__LAST | ||
89 | }; | ||
90 | |||
91 | /* String library functions. */ | ||
92 | enum { | ||
93 | JIT_IH_STRING_LEN, | ||
94 | JIT_IH_STRING_SUB, | ||
95 | JIT_IH_STRING_CHAR, | ||
96 | JIT_IH_STRING__LAST | ||
97 | }; | ||
98 | |||
99 | /* Table library functions. */ | ||
100 | enum { | ||
101 | JIT_IH_TABLE_INSERT, | ||
102 | JIT_IH_TABLE_REMOVE, | ||
103 | JIT_IH_TABLE_GETN, | ||
104 | JIT_IH_TABLE__LAST | ||
105 | }; | ||
106 | |||
107 | /* Math library functions. */ | ||
108 | /* CHECK: order must match with function table for jit_inline_math(). */ | ||
109 | enum { | ||
110 | /* 1 arg, 1 result. */ | ||
111 | /* Partially inlined. Call C function from libm: */ | ||
112 | JIT_IH_MATH_LOG, | ||
113 | JIT_IH_MATH_LOG10, | ||
114 | JIT_IH_MATH_EXP, | ||
115 | JIT_IH_MATH_SINH, | ||
116 | JIT_IH_MATH_COSH, | ||
117 | JIT_IH_MATH_TANH, | ||
118 | JIT_IH_MATH_ASIN, | ||
119 | JIT_IH_MATH_ACOS, | ||
120 | JIT_IH_MATH_ATAN, | ||
121 | /* Fully inlined: */ | ||
122 | JIT_IH_MATH_SIN, | ||
123 | JIT_IH_MATH_COS, | ||
124 | JIT_IH_MATH_TAN, | ||
125 | JIT_IH_MATH_CEIL, | ||
126 | JIT_IH_MATH_FLOOR, | ||
127 | JIT_IH_MATH_ABS, | ||
128 | JIT_IH_MATH_SQRT, | ||
129 | /* 2 args, 1 result. */ | ||
130 | JIT_IH_MATH_FMOD, | ||
131 | JIT_IH_MATH_ATAN2, | ||
132 | JIT_IH_MATH__LAST | ||
133 | }; | ||
134 | |||
135 | #define JIT_IH_MATH__21 JIT_IH_MATH_FMOD | ||
136 | |||
137 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_mem.c b/libraries/LuaJIT-1.1.7/src/ljit_mem.c new file mode 100644 index 0000000..73ade7f --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit_mem.c | |||
@@ -0,0 +1,405 @@ | |||
1 | /* | ||
2 | ** Memory management for machine code. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #define ljit_mem_c | ||
7 | #define LUA_CORE | ||
8 | |||
9 | #include <string.h> | ||
10 | |||
11 | #include "lua.h" | ||
12 | |||
13 | #include "lmem.h" | ||
14 | #include "ldo.h" | ||
15 | #include "ljit.h" | ||
16 | #include "ljit_dasm.h" | ||
17 | |||
18 | |||
19 | /* | ||
20 | ** Define this if you want to run LuaJIT with valgrind. You will get random | ||
21 | ** errors if you don't. And these errors are usually not caught by valgrind! | ||
22 | ** | ||
23 | ** This macro evaluates to a no-op if not run with valgrind. I.e. you can | ||
24 | ** use the same binary for regular runs, too (without a performance loss). | ||
25 | */ | ||
26 | #ifdef USE_VALGRIND | ||
27 | #include <valgrind/valgrind.h> | ||
28 | #define MCH_INVALIDATE(ptr, addr) VALGRIND_DISCARD_TRANSLATIONS(ptr, addr) | ||
29 | #else | ||
30 | #define MCH_INVALIDATE(ptr, addr) ((void)0) | ||
31 | #endif | ||
32 | |||
33 | |||
34 | /* ------------------------------------------------------------------------ */ | ||
35 | |||
36 | #if defined(_WIN32) && !defined(LUAJIT_MCH_USE_MALLOC) | ||
37 | |||
38 | /* Use a private heap with executable memory for Windows. */ | ||
39 | #include <windows.h> | ||
40 | |||
41 | /* No need for serialization. There's already a lock per Lua universe. */ | ||
42 | #ifdef HEAP_CREATE_ENABLE_EXECUTE | ||
43 | #define MCH_HCFLAGS (HEAP_NO_SERIALIZE|HEAP_CREATE_ENABLE_EXECUTE) | ||
44 | #else | ||
45 | #define MCH_HCFLAGS (HEAP_NO_SERIALIZE|0x00040000) | ||
46 | #endif | ||
47 | |||
48 | /* Free the whole mcode heap. */ | ||
49 | void luaJIT_freemcodeheap(jit_State *J) | ||
50 | { | ||
51 | if (J->mcodeheap) HeapDestroy((HANDLE)J->mcodeheap); | ||
52 | } | ||
53 | |||
54 | /* Allocate a code block from the mcode heap. */ | ||
55 | static void *mcode_alloc(jit_State *J, size_t sz) | ||
56 | { | ||
57 | void *ptr; | ||
58 | if (J->mcodeheap == NULL) { | ||
59 | J->mcodeheap = (void *)HeapCreate(MCH_HCFLAGS, 0, 0); | ||
60 | if (J->mcodeheap == NULL) luaD_throw(J->L, LUA_ERRMEM); | ||
61 | } | ||
62 | ptr = HeapAlloc(J->mcodeheap, 0, (sz)); | ||
63 | if (ptr == NULL) luaD_throw(J->L, LUA_ERRMEM); | ||
64 | return ptr; | ||
65 | } | ||
66 | |||
67 | #define mcode_free(L, J, p, sz) HeapFree(J->mcodeheap, 0, (p)) | ||
68 | |||
69 | /* ------------------------------------------------------------------------ */ | ||
70 | |||
71 | #elif defined(LUA_USE_POSIX) && !defined(LUAJIT_MCH_USE_MALLOC) | ||
72 | |||
73 | /* | ||
74 | ** Allocate EXECUTABLE memory with mmap() on POSIX systems. | ||
75 | ** | ||
76 | ** There is no standard way to reuse malloc(). So this is a very small, | ||
77 | ** but also very naive memory allocator. This should be ok, because: | ||
78 | ** | ||
79 | ** 1. Most apps only allocate mcode while running and free all on exit. | ||
80 | ** | ||
81 | ** 2. Some apps regularly load/unload a bunch of modules ("stages"). | ||
82 | ** Allocs/frees come in groups, so coalescing should work fine. | ||
83 | ** | ||
84 | ** If your app differs, then please elaborate and/or supply code. | ||
85 | ** And no -- including a full blown malloc is NOT an option. | ||
86 | ** | ||
87 | ** Caveat: the mmap()'ed heaps are not freed until exit. | ||
88 | ** This shouldn't be too difficult to add, but I didn't bother. | ||
89 | */ | ||
90 | |||
91 | #include <sys/types.h> | ||
92 | #include <sys/mman.h> | ||
93 | |||
94 | /* TODO: move this to luaconf.h */ | ||
95 | #define LUAJIT_MCH_CHUNKSIZE (1<<17) /* 128K */ | ||
96 | |||
97 | #if defined(MAP_ANONYMOUS) | ||
98 | #define MCH_MMFLAGS (MAP_PRIVATE|MAP_ANONYMOUS) | ||
99 | #elif defined(MAP_ANON) | ||
100 | #define MCH_MMFLAGS (MAP_PRIVATE|MAP_ANON) | ||
101 | #else | ||
102 | /* I'm too lazy to add /dev/zero support for ancient systems. */ | ||
103 | #error "Your OS has no (easy) support for anonymous mmap(). Please upgrade." | ||
104 | #endif | ||
105 | |||
106 | /* Chunk header. Used for the free chunk list / heap headers. */ | ||
107 | typedef struct MCodeHead { | ||
108 | struct MCodeHead *next; /* Next free chunk / 1st head: first free. */ | ||
109 | struct MCodeHead *prev; /* Prev free chunk / 1st head: next head. */ | ||
110 | size_t size; /* Size of free chunk / Size of heap. */ | ||
111 | size_t dummy; /* May or may not overlap with trailer. */ | ||
112 | } MCodeHead; | ||
113 | |||
114 | /* Allocation granularity. Assumes sizeof(void *) >= sizeof(size_t). */ | ||
115 | #define MCH_GRANULARITY (4*sizeof(void *)) | ||
116 | #define MCH_ROUNDSIZE(x) (((x) + MCH_GRANULARITY-1) & -MCH_GRANULARITY) | ||
117 | #define MCH_ROUNDHEAP(x) (((x) + 4095) & -4096) | ||
118 | #define MCH_HEADERSIZE MCH_ROUNDSIZE(sizeof(MCodeHead)) | ||
119 | |||
120 | /* Trailer flags. */ | ||
121 | #define MCH_USED 1 /* Next chunk is in use. */ | ||
122 | #define MCH_LAST 2 /* Next chunk is the last one. */ | ||
123 | #define MCH_FIRST 4 /* Next chunk is the first one. */ | ||
124 | /* Note: the last chunk of each heap doesn't have a trailer. */ | ||
125 | |||
126 | /* Trailer macros. */ | ||
127 | #define MCH_PREVTRAILER(mh) ((size_t *)(mh) - 1) | ||
128 | #define MCH_TRAILER(mh, sz) ((size_t *)((char *)(mh) + (sz)) - 1) | ||
129 | #define MCH_TRFLAGS(tr) ((tr) & (MCH_USED|MCH_LAST)) | ||
130 | #define MCH_TRSIZE(tr) ((tr) & ~(MCH_USED|MCH_LAST)) | ||
131 | |||
132 | /* Debugging memory allocators is ... oh well. */ | ||
133 | #ifdef MCH_DEBUG | ||
134 | #include <stdio.h> | ||
135 | #define MCH_DBGF stderr | ||
136 | #define MCH_DBG(x) fprintf x | ||
137 | #else | ||
138 | #define MCH_DBG(x) ((void)0) | ||
139 | #endif | ||
140 | |||
141 | /* Free the whole list of mcode heaps. */ | ||
142 | void luaJIT_freemcodeheap(jit_State *J) | ||
143 | { | ||
144 | MCodeHead *mh = (MCodeHead *)J->mcodeheap; | ||
145 | while (mh) { | ||
146 | MCodeHead *prev = mh->prev; /* Heaps are in the prev chain. */ | ||
147 | #ifdef MCH_DEBUG | ||
148 | munmap((void *)mh, mh->size+4096); | ||
149 | #else | ||
150 | munmap((void *)mh, mh->size); | ||
151 | #endif | ||
152 | mh = prev; | ||
153 | } | ||
154 | J->mcodeheap = NULL; | ||
155 | } | ||
156 | |||
157 | /* Allocate a new heap of at least the given size. */ | ||
158 | static void mcode_newheap(jit_State *J, size_t sz) | ||
159 | { | ||
160 | MCodeHead *mh, *mhn, *fh; | ||
161 | void *ptr; | ||
162 | |||
163 | /* Ensure minimum size or round up. */ | ||
164 | if (sz + MCH_HEADERSIZE <= LUAJIT_MCH_CHUNKSIZE) | ||
165 | sz = LUAJIT_MCH_CHUNKSIZE; | ||
166 | else | ||
167 | sz = MCH_ROUNDHEAP(sz + MCH_HEADERSIZE); | ||
168 | |||
169 | #ifdef MCH_DEBUG | ||
170 | /* Allocate a new heap plus a guard page. */ | ||
171 | ptr = mmap(NULL, sz+4096, PROT_READ|PROT_WRITE|PROT_EXEC, MCH_MMFLAGS, -1, 0); | ||
172 | if (ptr == MAP_FAILED) luaD_throw(J->L, LUA_ERRMEM); | ||
173 | mprotect((char *)ptr+sz, 4096, PROT_NONE); | ||
174 | #else | ||
175 | /* Allocate a new heap. */ | ||
176 | ptr = mmap(NULL, sz, PROT_READ|PROT_WRITE|PROT_EXEC, MCH_MMFLAGS, -1, 0); | ||
177 | if (ptr == MAP_FAILED) luaD_throw(J->L, LUA_ERRMEM); | ||
178 | #endif | ||
179 | |||
180 | /* Initialize free chunk. */ | ||
181 | fh = (MCodeHead *)((char *)ptr + MCH_HEADERSIZE); | ||
182 | fh->size = sz - MCH_HEADERSIZE; | ||
183 | *MCH_PREVTRAILER(fh) = MCH_LAST | MCH_FIRST; /* Zero size, no coalesce. */ | ||
184 | |||
185 | /* Initialize new heap and make it the first heap. */ | ||
186 | mh = (MCodeHead *)J->mcodeheap; | ||
187 | J->mcodeheap = ptr; | ||
188 | mhn = (MCodeHead *)ptr; | ||
189 | mhn->prev = mh; /* Heaps are in the prev. chain. */ | ||
190 | mhn->size = sz; | ||
191 | mhn->next = fh; /* Start of free list is always in the first heap. */ | ||
192 | fh->prev = mhn; | ||
193 | if (mh) { | ||
194 | fh->next = mh->next; /* Old start of free list. */ | ||
195 | mh->next = NULL; /* Just in case. */ | ||
196 | } else { | ||
197 | fh->next = NULL; /* No other free chunks yet. */ | ||
198 | } | ||
199 | MCH_DBG((MCH_DBGF, "HEAP %p %5x\n", mhn, sz)); | ||
200 | } | ||
201 | |||
202 | /* Allocate a code block. */ | ||
203 | static void *mcode_alloc(jit_State *J, size_t sz) | ||
204 | { | ||
205 | sz = MCH_ROUNDSIZE(sz + sizeof(size_t)); | ||
206 | for ( ; ; ) { | ||
207 | MCodeHead *mh = (MCodeHead *)J->mcodeheap; | ||
208 | if (mh) { /* Got at least one heap so search free list. */ | ||
209 | #ifdef MCH_DEBUG | ||
210 | int slen = 0; | ||
211 | for (mh = mh->next; mh ; mh = mh->next, slen++) | ||
212 | #else | ||
213 | for (mh = mh->next; mh ; mh = mh->next) | ||
214 | #endif | ||
215 | if (mh->size >= sz) { /* Very naive first fit. */ | ||
216 | size_t *trailer = MCH_TRAILER(mh, sz); | ||
217 | size_t *ptrailer = MCH_PREVTRAILER(mh); | ||
218 | if (mh->size == sz) { /* Exact match: just unchain chunk. */ | ||
219 | mh->prev->next = mh->next; | ||
220 | if (mh->next) | ||
221 | mh->next->prev = mh->prev; | ||
222 | *ptrailer |= MCH_USED; | ||
223 | MCH_DBG((MCH_DBGF, "NEW %p %5x FIT #%d%s\n", | ||
224 | mh, sz, slen, (*ptrailer & MCH_LAST) ? " LAST" : "")); | ||
225 | } else { /* Chunk is larger: rechain remainder chunk. */ | ||
226 | MCodeHead *fh = (MCodeHead *)((char *)mh + sz); | ||
227 | size_t tr; | ||
228 | fh->size = mh->size - sz; | ||
229 | (fh->prev = mh->prev)->next = fh; | ||
230 | if ((fh->next = mh->next) != NULL) | ||
231 | fh->next->prev = fh; | ||
232 | tr = *ptrailer; | ||
233 | if (tr & MCH_LAST) { | ||
234 | *ptrailer = (tr & ~MCH_LAST) | MCH_USED; | ||
235 | *trailer = sz | MCH_LAST; | ||
236 | MCH_DBG((MCH_DBGF, "NEW %p %5x REST %p %5x #%d LAST\n", | ||
237 | mh, sz, fh, fh->size, slen)); | ||
238 | } else { | ||
239 | size_t *ftrailer = MCH_TRAILER(fh, fh->size); | ||
240 | *ftrailer = MCH_TRFLAGS(*ftrailer) | fh->size; | ||
241 | *ptrailer = tr | MCH_USED; | ||
242 | *trailer = sz; | ||
243 | MCH_DBG((MCH_DBGF, "NEW %p %5x REST %p %5x #%d\n", | ||
244 | mh, sz, fh, fh->size, slen)); | ||
245 | } | ||
246 | } | ||
247 | return (void *)mh; | ||
248 | } | ||
249 | } | ||
250 | /* No luck. Allocate a new heap. Next loop iteration will succeed. */ | ||
251 | mcode_newheap(J, sz); | ||
252 | } | ||
253 | } | ||
254 | |||
255 | /* Free a code block. */ | ||
256 | static void mcode_free_(jit_State *J, void *ptr, size_t sz) | ||
257 | { | ||
258 | MCodeHead *mh = (MCodeHead *)ptr; | ||
259 | size_t *trailer = MCH_TRAILER(mh, sz); | ||
260 | size_t *ptrailer = MCH_PREVTRAILER(mh); | ||
261 | size_t tr = *ptrailer; | ||
262 | |||
263 | #ifdef MCH_DEBUG | ||
264 | if (!(tr & MCH_USED)) MCH_DBG((MCH_DBGF, "**unused %p %5x\n", ptr, sz)); | ||
265 | #endif | ||
266 | |||
267 | if (!(tr & MCH_FIRST)) { | ||
268 | MCodeHead *ph = (MCodeHead *)((char *)mh - MCH_TRSIZE(tr)); | ||
269 | size_t *pptrailer = MCH_PREVTRAILER(ph); | ||
270 | if (!(*pptrailer & MCH_USED)) { /* Prev free? */ | ||
271 | if (!(tr & MCH_LAST) && !(*trailer & MCH_USED)) { /* Next free? */ | ||
272 | /* Coalesce with previous and next chunk. */ | ||
273 | MCodeHead *nh = (MCodeHead *)((char *)mh + sz); | ||
274 | MCH_DBG((MCH_DBGF, "free %p %5x PN %p %5x %p %5x%s\n", | ||
275 | mh, sz, ph, ph->size, nh, nh->size, | ||
276 | (*trailer & MCH_LAST) ? " last" : "")); | ||
277 | if ((nh->prev->next = nh->next) != NULL) | ||
278 | nh->next->prev = nh->prev; | ||
279 | ph->size += sz + nh->size; | ||
280 | if (*trailer & MCH_LAST) { | ||
281 | *pptrailer |= MCH_LAST; | ||
282 | } else { | ||
283 | trailer = MCH_TRAILER(nh, nh->size); | ||
284 | *trailer = MCH_TRFLAGS(*trailer) | ph->size; | ||
285 | } | ||
286 | return; | ||
287 | } | ||
288 | MCH_DBG((MCH_DBGF, "free %p %5x P- %p %5x%s\n", | ||
289 | mh, sz, ph, ph->size, | ||
290 | (tr & MCH_LAST) ? " last" : "")); | ||
291 | ph->size += sz; | ||
292 | if (tr & MCH_LAST) | ||
293 | *pptrailer |= MCH_LAST; | ||
294 | else | ||
295 | *trailer = MCH_TRFLAGS(*trailer) | ph->size; | ||
296 | return; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | if (!(tr & MCH_LAST) && !(*trailer & MCH_USED)) { /* Next free? */ | ||
301 | /* Coalesce with next chunk. */ | ||
302 | MCodeHead *nh = (MCodeHead *)((char *)mh + sz); | ||
303 | MCH_DBG((MCH_DBGF, "free %p %5x -N %p %5x%s\n", | ||
304 | mh, sz, nh, nh->size, (*trailer & MCH_LAST) ? " last" : "")); | ||
305 | (mh->prev = nh->prev)->next = mh; | ||
306 | if ((mh->next = nh->next)) | ||
307 | mh->next->prev = mh; | ||
308 | mh->size = nh->size + sz; | ||
309 | if (*trailer & MCH_LAST) { | ||
310 | *ptrailer = (tr & ~MCH_USED) | MCH_LAST; | ||
311 | } else { | ||
312 | trailer = MCH_TRAILER(mh, mh->size); | ||
313 | *trailer = MCH_TRFLAGS(*trailer) | mh->size; | ||
314 | *ptrailer = tr & ~MCH_USED; | ||
315 | } | ||
316 | } else { | ||
317 | /* No coalesce possible, just add to free list. */ | ||
318 | MCodeHead *fh = (MCodeHead *)J->mcodeheap; | ||
319 | MCH_DBG((MCH_DBGF, "free %p %5x --%s\n", | ||
320 | mh, sz, (tr & MCH_LAST) ? " last" : "")); | ||
321 | if ((mh->next = fh->next)) | ||
322 | mh->next->prev = mh; | ||
323 | fh->next = mh; | ||
324 | mh->prev = fh; | ||
325 | mh->size = sz; | ||
326 | *ptrailer = tr & ~MCH_USED; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | #define mcode_free(L, J, p, sz) \ | ||
331 | mcode_free_(J, (p), MCH_ROUNDSIZE((sz) + sizeof(size_t))) | ||
332 | |||
333 | /* ------------------------------------------------------------------------ */ | ||
334 | |||
335 | #else | ||
336 | |||
337 | /* | ||
338 | ** Fallback to Lua's alloc, i.e. probably malloc(). | ||
339 | ** | ||
340 | ** Note: the returned memory is usually not marked executable! | ||
341 | ** Running the code will crash if the CPU/OS checks for this. | ||
342 | ** E.g. on x86 CPUs that support the NX (No eXecute) bit. | ||
343 | */ | ||
344 | |||
345 | /* There's no heap to free, but the JSUB mcode is. */ | ||
346 | void luaJIT_freemcodeheap(jit_State *J) | ||
347 | { | ||
348 | if (J->jsubmcode) luaM_freemem(J->L, J->jsubmcode, J->szjsubmcode); | ||
349 | } | ||
350 | |||
351 | #define mcode_alloc(J, sz) luaM_realloc_(J->L, NULL, 0, (sz)) | ||
352 | #define mcode_free(L, J, p, sz) luaM_freemem(L, p, sz) | ||
353 | |||
354 | #endif | ||
355 | |||
356 | /* ------------------------------------------------------------------------ */ | ||
357 | |||
358 | /* Free mcode. */ | ||
359 | void luaJIT_freemcode(jit_State *J, void *mcode, size_t sz) | ||
360 | { | ||
361 | mcode_free(J->L, J, mcode, sz); | ||
362 | } | ||
363 | |||
364 | /* Free JIT structures in function prototype. */ | ||
365 | void luaJIT_freeproto(lua_State *L, Proto *pt) | ||
366 | { | ||
367 | char *mcode = (char *)pt->jit_mcode; | ||
368 | size_t sz = pt->jit_szmcode; | ||
369 | pt->jit_mcode = NULL; | ||
370 | pt->jit_szmcode = 0; | ||
371 | while (sz != 0) { /* Free whole chain of mcode blocks for this proto. */ | ||
372 | jit_MCTrailer next; | ||
373 | memcpy((void *)&next, JIT_MCTRAILER(mcode, sz), sizeof(jit_MCTrailer)); | ||
374 | MCH_INVALIDATE(mcode, sz); | ||
375 | mcode_free(L, G(L)->jit_state, mcode, sz); | ||
376 | mcode = next.mcode; | ||
377 | sz = next.sz; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | /* Link generated code. Return mcode address, size and status. */ | ||
382 | int luaJIT_link(jit_State *J, void **mcodep, size_t *szp) | ||
383 | { | ||
384 | size_t sz; | ||
385 | void *mcode; | ||
386 | |||
387 | /* Pass 2: link sections. */ | ||
388 | if ((J->dasmstatus = dasm_link(Dst, &sz))) return JIT_S_DASM_ERROR; | ||
389 | |||
390 | /* Check for hardcoded limit on mcode size. */ | ||
391 | if (sz > LUAJIT_LIM_MCODE) return JIT_S_TOOLARGE; | ||
392 | |||
393 | /* TODO: mark mcode readonly when we're done. */ | ||
394 | mcode = mcode_alloc(J, sz); | ||
395 | |||
396 | /* Pass 3: encode sections. */ | ||
397 | if ((J->dasmstatus = dasm_encode(Dst, mcode)) != 0) { | ||
398 | mcode_free(J->L, J, mcode, sz); | ||
399 | return JIT_S_DASM_ERROR; | ||
400 | } | ||
401 | *mcodep = mcode; | ||
402 | *szp = sz; | ||
403 | return JIT_S_OK; | ||
404 | } | ||
405 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_x86.dasc b/libraries/LuaJIT-1.1.7/src/ljit_x86.dasc new file mode 100644 index 0000000..f7be91e --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit_x86.dasc | |||
@@ -0,0 +1,2457 @@ | |||
1 | /* | ||
2 | ** Bytecode to machine code translation for x86 CPUs. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | |// Include common definitions and macros. | ||
7 | |.include ljit_x86.dash | ||
8 | | | ||
9 | |// Place actionlist and globals here at the top of the file. | ||
10 | |.actionlist jit_actionlist | ||
11 | |.globals JSUB_ | ||
12 | |||
13 | /* ------------------------------------------------------------------------ */ | ||
14 | |||
15 | /* Arch string. */ | ||
16 | const char luaJIT_arch[] = "x86"; | ||
17 | |||
18 | /* Forward declarations for C functions called from jsubs. */ | ||
19 | static void jit_hookins(lua_State *L, const Instruction *newpc); | ||
20 | static void jit_gettable_fb(lua_State *L, Table *t, StkId dest); | ||
21 | static void jit_settable_fb(lua_State *L, Table *t, StkId val); | ||
22 | |||
23 | /* ------------------------------------------------------------------------ */ | ||
24 | |||
25 | /* Detect CPU features and set JIT flags. */ | ||
26 | static int jit_cpudetect(jit_State *J) | ||
27 | { | ||
28 | void *mcode; | ||
29 | size_t sz; | ||
30 | int status; | ||
31 | /* Some of the jsubs need the flags. So compile this separately. */ | ||
32 | unsigned int feature; | ||
33 | dasm_setup(Dst, jit_actionlist); | ||
34 | | // Check for CPUID support first. | ||
35 | | pushfd | ||
36 | | pop edx | ||
37 | | mov ecx, edx | ||
38 | | xor edx, 0x00200000 // Toggle ID bit in flags. | ||
39 | | push edx | ||
40 | | popfd | ||
41 | | pushfd | ||
42 | | pop edx | ||
43 | | xor eax, eax // Zero means no features supported. | ||
44 | | cmp ecx, edx | ||
45 | | jz >1 // No ID toggle means no CPUID support. | ||
46 | | | ||
47 | | inc eax // CPUID function 1. | ||
48 | | push ebx // Callee-save ebx modified by CPUID. | ||
49 | | cpuid | ||
50 | | pop ebx | ||
51 | | mov eax, edx // Return feature support bits. | ||
52 | |1: | ||
53 | | ret | ||
54 | (void)dasm_checkstep(Dst, DASM_SECTION_CODE); | ||
55 | status = luaJIT_link(J, &mcode, &sz); | ||
56 | if (status != JIT_S_OK) | ||
57 | return status; | ||
58 | /* Check feature bits. See the Intel/AMD manuals for the bit definitions. */ | ||
59 | feature = ((unsigned int (*)(void))mcode)(); | ||
60 | if (feature & (1<<15)) J->flags |= JIT_F_CPU_CMOV; | ||
61 | if (feature & (1<<26)) J->flags |= JIT_F_CPU_SSE2; | ||
62 | luaJIT_freemcode(J, mcode, sz); /* We don't need this code anymore. */ | ||
63 | return JIT_S_OK; | ||
64 | } | ||
65 | |||
66 | /* Check some assumptions. Should compile to nop. */ | ||
67 | static int jit_consistency_check(jit_State *J) | ||
68 | { | ||
69 | do { | ||
70 | /* Force a compiler error for inconsistent structure sizes. */ | ||
71 | /* Check LUA_TVALUE_ALIGN in luaconf.h, too. */ | ||
72 | ||int check_TVALUE_SIZE_in_ljit_x86_dash[1+TVALUE_SIZE-sizeof(TValue)]; | ||
73 | ||int check_TVALUE_SIZE_in_ljit_x86_dash_[1+sizeof(TValue)-TVALUE_SIZE]; | ||
74 | ((void)check_TVALUE_SIZE_in_ljit_x86_dash[0]); | ||
75 | ((void)check_TVALUE_SIZE_in_ljit_x86_dash_[0]); | ||
76 | if (LUA_TNIL != 0 || LUA_TBOOLEAN != 1 || PCRLUA != 0) break; | ||
77 | if ((int)&(((Node *)0)->i_val) != (int)&(((StkId)0)->value)) break; | ||
78 | return JIT_S_OK; | ||
79 | } while (0); | ||
80 | J->dasmstatus = 999999999; /* Recognizable error. */ | ||
81 | return JIT_S_COMPILER_ERROR; | ||
82 | } | ||
83 | |||
84 | /* Compile JIT subroutines (once). */ | ||
85 | static int jit_compile_jsub(jit_State *J) | ||
86 | { | ||
87 | int status = jit_consistency_check(J); | ||
88 | if (status != JIT_S_OK) return status; | ||
89 | status = jit_cpudetect(J); | ||
90 | if (status != JIT_S_OK) return status; | ||
91 | dasm_setup(Dst, jit_actionlist); | ||
92 | |// Macros to reorder and combine JIT subroutine definitions. | ||
93 | |.macro .jsub, name | ||
94 | |.capture JSUB // Add the entry point. | ||
95 | ||//----------------------------------------------------------------------- | ||
96 | ||//->name: | ||
97 | | .align 16 | ||
98 | |->name: | ||
99 | |.endmacro | ||
100 | |.macro .endjsub; .endcapture; .endmacro | ||
101 | |.macro .dumpjsub; .dumpcapture JSUB; .endmacro | ||
102 | | | ||
103 | |.code | ||
104 | |//----------------------------------------------------------------------- | ||
105 | | .align 16 | ||
106 | | // Must be the first JSUB defined or used. | ||
107 | |->STACKPTR: // Get stack pointer (for jit.util.*). | ||
108 | | lea eax, [esp+aword*1] // But adjust for the return address. | ||
109 | | ret | ||
110 | | | ||
111 | |//----------------------------------------------------------------------- | ||
112 | | .align 16 | ||
113 | |->GATE_LJ: // Lua -> JIT gate. (L, func, nresults) | ||
114 | | push ebp | ||
115 | | mov ebp, esp | ||
116 | | sub esp, LJFRAME_OFFSET | ||
117 | | mov SAVER1, BASE | ||
118 | | mov BASE, CARG2 // func | ||
119 | | mov CARG2, L // Arg used as savereg. Avoids aword*8 stack frame. | ||
120 | | mov L, CARG1 // L | ||
121 | | mov SAVER2, TOP | ||
122 | | mov TOP, L->top | ||
123 | | mov LCL, BASE->value | ||
124 | | mov CI, L->ci | ||
125 | | // Prevent stackless yields. No limit check -- this is not a real C call. | ||
126 | | inc word L->nCcalls // short | ||
127 | | | ||
128 | | call aword LCL->jit_gate // Call the compiled code. | ||
129 | | | ||
130 | | mov CI, L->ci | ||
131 | | mov L->top, TOP // Only correct for LUA_MULTRET. | ||
132 | | mov edx, CI->savedpc | ||
133 | | mov eax, CARG3 // nresults | ||
134 | | mov L->savedpc, edx // L->savedpc = CI->savedpc | ||
135 | | mov edx, CI->base | ||
136 | | test eax, eax | ||
137 | | mov L->base, edx // L->base = CI->base | ||
138 | | js >2 // Skip for nresults == LUA_MULTRET. | ||
139 | | | ||
140 | | TValuemul eax | ||
141 | | add BASE, eax | ||
142 | | xor ecx, ecx | ||
143 | | mov L->top, BASE // L->top = &func[nresults] | ||
144 | |1: // No initial check. May use EXTRA_STACK (once). | ||
145 | | mov TOP->tt, ecx // Clear unset stack slots. | ||
146 | | add TOP, #TOP | ||
147 | | cmp TOP, BASE | ||
148 | | jb <1 | ||
149 | | | ||
150 | |2: | ||
151 | | dec word L->nCcalls // short | ||
152 | | mov eax, PCRC | ||
153 | | mov TOP, SAVER2 | ||
154 | | mov BASE, SAVER1 | ||
155 | | mov L, CARG2 | ||
156 | | mov esp, ebp | ||
157 | | pop ebp | ||
158 | | ret | ||
159 | | | ||
160 | |//----------------------------------------------------------------------- | ||
161 | | .align 16 | ||
162 | |->GATE_JL: // JIT -> Lua callgate. | ||
163 | | mov PROTO:edx, LCL->p | ||
164 | | cmp dword PROTO:edx->jit_status, JIT_S_OK | ||
165 | | jne >1 // Already compiled? | ||
166 | | | ||
167 | | // Yes, copy callgate to closure (so GATE_JL is not called again). | ||
168 | | mov edx, PROTO:edx->jit_mcode | ||
169 | | mov LCL->jit_gate, edx | ||
170 | | jmp edx // Chain to compiled code. | ||
171 | | | ||
172 | |1: // Let luaD_precall do the hard work: compile & run or fallback. | ||
173 | | sub esp, FRAME_OFFSET | ||
174 | | mov eax, CI->savedpc | ||
175 | | mov L->ci, CI // May not be in sync for tailcalls. | ||
176 | | mov L->top, TOP | ||
177 | | mov ARG3, -1 // LUA_MULTRET | ||
178 | | mov L->savedpc, eax // luaD_precall expects it there. | ||
179 | | mov ARG2, BASE | ||
180 | | sub BASE, L->stack // Preserve old BASE (= func). | ||
181 | | mov ARG1, L | ||
182 | | call &luaD_precall // luaD_precall(L, func, nresults) | ||
183 | | test eax,eax // Assumes: PCRLUA == 0 | ||
184 | | jnz >2 // PCRC? PCRYIELD cannot happen. | ||
185 | | | ||
186 | | // Returned PCRLUA: need to call the bytecode interpreter. | ||
187 | | call &luaV_execute, L, 1 | ||
188 | | // Indirect yield (L->status == LUA_YIELD) cannot happen. | ||
189 | | | ||
190 | |2: // Returned PCRC: compile & run done. Frame is already unwound. | ||
191 | | add esp, FRAME_OFFSET | ||
192 | | add BASE, L->stack // Restore stack-relative pointers BASE and TOP. | ||
193 | | mov TOP, L->top | ||
194 | | ret | ||
195 | | | ||
196 | |//----------------------------------------------------------------------- | ||
197 | | .align 16 | ||
198 | |->GATE_JC: // JIT -> C callgate. | ||
199 | | lea eax, TOP[LUA_MINSTACK] | ||
200 | | sub esp, FRAME_OFFSET | ||
201 | | cmp eax, L->stack_last | ||
202 | | jae ->GROW_STACK // Stack overflow? | ||
203 | | cmp CI, L->end_ci | ||
204 | | lea CI, CI[1] | ||
205 | | je ->GROW_CI // CI overflow? | ||
206 | | mov L->ci, CI | ||
207 | | mov CI->func, BASE | ||
208 | | mov CI->top, eax | ||
209 | | mov CCLOSURE:edx, BASE->value | ||
210 | | add BASE, #BASE | ||
211 | | mov L->top, TOP | ||
212 | | mov L->base, BASE | ||
213 | | mov CI->base, BASE | ||
214 | | // ci->nresults is not set because we don't use luaD_poscall(). | ||
215 | | | ||
216 | |->GATE_JC_PATCH: // Patch mark for jmp to GATE_JC_DEBUG. | ||
217 | | | ||
218 | | call aword CCLOSURE:edx->f, L // Call the C function. | ||
219 | | | ||
220 | |2: // Label used below! | ||
221 | | add esp, FRAME_OFFSET | ||
222 | | mov CI, L->ci | ||
223 | | TValuemul eax // eax = nresults*sizeof(TValue) | ||
224 | | mov TOP, CI->func | ||
225 | | jz >4 // Skip loop if nresults == 0. | ||
226 | | // Yield (-1) cannot happen. | ||
227 | | mov BASE, L->top | ||
228 | | mov edx, BASE | ||
229 | | sub BASE, eax // BASE = &L->top[-nresults] | ||
230 | |3: // Relocate [L->top-nresults, L->top) -> [ci->func, ci->func+nresults) | ||
231 | | mov eax, [BASE] | ||
232 | | add BASE, aword*1 | ||
233 | | mov [TOP], eax | ||
234 | | add TOP, aword*1 | ||
235 | | cmp BASE, edx | ||
236 | | jb <3 | ||
237 | | | ||
238 | |4: | ||
239 | | mov BASE, CI->func | ||
240 | | sub CI, #CI | ||
241 | | mov L->ci, CI | ||
242 | | ret | ||
243 | | | ||
244 | |//----------------------------------------------------------------------- | ||
245 | | nop; nop; nop; nop; nop; nop // Save area. See DEBUGPATCH_SIZE. | ||
246 | | .align 16 | ||
247 | |->GATE_JC_DEBUG: // JIT -> C callgate for debugging. | ||
248 | | test byte L->hookmask, LUA_MASKCALL // Need to call hook? | ||
249 | | jnz >7 | ||
250 | |6: | ||
251 | | call aword CCLOSURE:edx->f, L // Call the C function. | ||
252 | | | ||
253 | | test byte L->hookmask, LUA_MASKRET // Need to call hook? | ||
254 | | jz <2 | ||
255 | | | ||
256 | | // Return hook. TODO: LUA_HOOKTAILRET is not called since tailcalls == 0. | ||
257 | | mov BASE, eax // BASE (ebx) is callee-save. | ||
258 | | call &luaD_callhook, L, LUA_HOOKRET, -1 | ||
259 | | mov eax, BASE | ||
260 | | jmp <2 | ||
261 | | | ||
262 | |7: // Call hook. | ||
263 | | mov BASE, CCLOSURE:edx // BASE (ebx) is callee-save. | ||
264 | | call &luaD_callhook, L, LUA_HOOKCALL, -1 | ||
265 | | mov CCLOSURE:edx, BASE | ||
266 | | jmp <6 | ||
267 | | | ||
268 | |//----------------------------------------------------------------------- | ||
269 | | .align 16 | ||
270 | |->GROW_STACK: // Grow stack. Jump from/to prologue. | ||
271 | | sub eax, TOP | ||
272 | | TValuediv eax // eax = (eax-TOP)/sizeof(TValue). | ||
273 | | mov L->top, TOP | ||
274 | | sub BASE, L->stack | ||
275 | | mov ARG3, CI | ||
276 | | call &luaD_growstack, L, eax | ||
277 | | mov CI, ARG3 // CI may not be in sync with L->ci. | ||
278 | | add BASE, L->stack // Restore stack-relative pointers. | ||
279 | | mov TOP, L->top | ||
280 | | mov LCL, BASE->value | ||
281 | | add esp, FRAME_OFFSET // Undo esp adjust of prologue/GATE_JC. | ||
282 | | jmp aword LCL->jit_gate // Retry prologue. | ||
283 | | | ||
284 | |//----------------------------------------------------------------------- | ||
285 | | .align 16 | ||
286 | |->GROW_CI: // Grow CI. Jump from/to prologue. | ||
287 | | mov L->top, TOP // May throw LUA_ERRMEM, so save TOP. | ||
288 | | call &luaD_growCI, L | ||
289 | | lea CI, CINFO:eax[-1] // Undo ci++ (L->ci reset in prologue). | ||
290 | | mov LCL, BASE->value | ||
291 | | mov L->ci, CI | ||
292 | | add esp, FRAME_OFFSET // Undo esp adjust of prologue/GATE_JC. | ||
293 | | jmp aword LCL->jit_gate // Retry prologue. | ||
294 | | | ||
295 | |//----------------------------------------------------------------------- | ||
296 | |.dumpjsub // Dump all captured .jsub's. | ||
297 | | | ||
298 | |// Uncritical jsubs follow. No need to align them. | ||
299 | |//----------------------------------------------------------------------- | ||
300 | |->DEOPTIMIZE_CALLER: // Deoptimize calling instruction. | ||
301 | | pop edx | ||
302 | | jmp ->DEOPTIMIZE | ||
303 | | | ||
304 | |->DEOPTIMIZE_OPEN: // Deoptimize open instruction. | ||
305 | | mov L->top, TOP // Save TOP. | ||
306 | | | ||
307 | |->DEOPTIMIZE: // Deoptimize instruction. | ||
308 | | mov L->savedpc, edx // &J->nextins expected in edx. | ||
309 | | call &luaJIT_deoptimize, L | ||
310 | | mov BASE, L->base | ||
311 | | mov TOP, L->top // Restore TOP for open ins. | ||
312 | | jmp eax // Continue with new mcode addr. | ||
313 | | | ||
314 | | .align 16 | ||
315 | |//----------------------------------------------------------------------- | ||
316 | |||
317 | (void)dasm_checkstep(Dst, DASM_SECTION_CODE); | ||
318 | status = luaJIT_link(J, &J->jsubmcode, &J->szjsubmcode); | ||
319 | if (status != JIT_S_OK) | ||
320 | return status; | ||
321 | |||
322 | /* Copy the callgates from the globals to the global state. */ | ||
323 | G(J->L)->jit_gateLJ = (luaJIT_GateLJ)J->jsub[JSUB_GATE_LJ]; | ||
324 | G(J->L)->jit_gateJL = (lua_CFunction)J->jsub[JSUB_GATE_JL]; | ||
325 | G(J->L)->jit_gateJC = (lua_CFunction)J->jsub[JSUB_GATE_JC]; | ||
326 | return JIT_S_OK; | ||
327 | } | ||
328 | |||
329 | /* Match with number of nops above. Avoid confusing the instruction decoder. */ | ||
330 | #define DEBUGPATCH_SIZE 6 | ||
331 | |||
332 | /* Notify backend that the debug mode may have changed. */ | ||
333 | void luaJIT_debugnotify(jit_State *J) | ||
334 | { | ||
335 | unsigned char *patch = (unsigned char *)J->jsub[JSUB_GATE_JC_PATCH]; | ||
336 | unsigned char *target = (unsigned char *)J->jsub[JSUB_GATE_JC_DEBUG]; | ||
337 | /* Yep, this is self-modifying code -- don't tell anyone. */ | ||
338 | if (patch[0] == 0xe9) { /* Debug patch is active. */ | ||
339 | if (!(J->flags & JIT_F_DEBUG_CALL)) /* Deactivate it. */ | ||
340 | memcpy(patch, target-DEBUGPATCH_SIZE, DEBUGPATCH_SIZE); | ||
341 | } else { /* Debug patch is inactive. */ | ||
342 | if (J->flags & JIT_F_DEBUG_CALL) { /* Activate it. */ | ||
343 | int rel = target-(patch+5); | ||
344 | memcpy(target-DEBUGPATCH_SIZE, patch, DEBUGPATCH_SIZE); | ||
345 | patch[0] = 0xe9; /* jmp */ | ||
346 | memcpy(patch+1, &rel, 4); /* Relative address. */ | ||
347 | memset(patch+5, 0x90, DEBUGPATCH_SIZE-5); /* nop */ | ||
348 | } | ||
349 | } | ||
350 | } | ||
351 | |||
352 | /* Patch a jmp into existing mcode. */ | ||
353 | static void jit_patch_jmp(jit_State *J, void *mcode, void *to) | ||
354 | { | ||
355 | unsigned char *patch = (unsigned char *)mcode; | ||
356 | int rel = ((unsigned char *)to)-(patch+5); | ||
357 | patch[0] = 0xe9; /* jmp */ | ||
358 | memcpy((void *)(patch+1), &rel, 4); /* Relative addr. */ | ||
359 | } | ||
360 | |||
361 | /* ------------------------------------------------------------------------ */ | ||
362 | |||
363 | /* Call line/count hook. */ | ||
364 | static void jit_hookins(lua_State *L, const Instruction *newpc) | ||
365 | { | ||
366 | Proto *pt = ci_func(L->ci)->l.p; | ||
367 | int pc = luaJIT_findpc(pt, newpc); /* Sloooow with mcode addrs. */ | ||
368 | const Instruction *savedpc = L->savedpc; | ||
369 | L->savedpc = pt->code + pc + 1; | ||
370 | if (L->hookmask > LUA_MASKLINE && L->hookcount == 0) { | ||
371 | resethookcount(L); | ||
372 | luaD_callhook(L, LUA_HOOKCOUNT, -1); | ||
373 | } | ||
374 | if (L->hookmask & LUA_MASKLINE) { | ||
375 | int newline = getline(pt, pc); | ||
376 | if (pc != 0) { | ||
377 | int oldpc = luaJIT_findpc(pt, savedpc); | ||
378 | if (!(pc <= oldpc || newline != getline(pt, oldpc))) return; | ||
379 | } | ||
380 | luaD_callhook(L, LUA_HOOKLINE, newline); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | /* Insert hook check for each instruction in full debug mode. */ | ||
385 | static void jit_ins_debug(jit_State *J, int openop) | ||
386 | { | ||
387 | if (openop) { | ||
388 | | mov L->top, TOP | ||
389 | } | ||
390 | |// TODO: Passing bytecode addrs would speed this up (but use more space). | ||
391 | | call ->HOOKINS | ||
392 | |||
393 | |.jsub HOOKINS | ||
394 | | test byte L->hookmask, LUA_MASKLINE|LUA_MASKCOUNT | ||
395 | | jz >2 | ||
396 | | dec dword L->hookcount | ||
397 | | jz >1 | ||
398 | | test byte L->hookmask, LUA_MASKLINE | ||
399 | | jz >2 | ||
400 | |1: | ||
401 | | mov eax, [esp] // Current machine code address. | ||
402 | | sub esp, FRAME_OFFSET | ||
403 | | call &jit_hookins, L, eax | ||
404 | | add esp, FRAME_OFFSET | ||
405 | | mov BASE, L->base // Restore stack-relative pointers. | ||
406 | | mov TOP, L->top | ||
407 | |2: | ||
408 | | ret | ||
409 | |.endjsub | ||
410 | } | ||
411 | |||
412 | /* Called before every instruction. */ | ||
413 | static void jit_ins_start(jit_State *J) | ||
414 | { | ||
415 | |// Always emit PC labels, even for dead code (but not for combined JMP). | ||
416 | |=>J->nextpc: | ||
417 | } | ||
418 | |||
419 | /* Chain to another instruction. */ | ||
420 | static void jit_ins_chainto(jit_State *J, int pc) | ||
421 | { | ||
422 | | jmp =>pc | ||
423 | } | ||
424 | |||
425 | /* Set PC label. */ | ||
426 | static void jit_ins_setpc(jit_State *J, int pc, void *target) | ||
427 | { | ||
428 | |.label =>pc, &target | ||
429 | } | ||
430 | |||
431 | /* Called after the last instruction has been encoded. */ | ||
432 | static void jit_ins_last(jit_State *J, int lastpc, int sizemfm) | ||
433 | { | ||
434 | if (J->tflags & JIT_TF_USED_DEOPT) { /* Deopt section has been used? */ | ||
435 | |.deopt | ||
436 | | jmp ->DEOPTIMIZE // Yes, need to add final jmp. | ||
437 | |.code | ||
438 | } | ||
439 | |=>lastpc+1: // Extra label at the end of .code. | ||
440 | |.tail | ||
441 | |=>lastpc+2: // And at the end of .deopt/.tail. | ||
442 | | .align word // Keep next section word aligned. | ||
443 | | .word 0xffff // Terminate mfm with JIT_MFM_STOP. | ||
444 | |.mfmap | ||
445 | | // <-- Deoptimization hints are inserted here. | ||
446 | | .space sizemfm // To be filled in with inverse mfm. | ||
447 | | .aword 0, 0 // Next mcode block pointer and size. | ||
448 | | // The previous two awords are only word, but not aword aligned. | ||
449 | | // Copying them is easier than aligning them and adjusting mfm handling. | ||
450 | |.code | ||
451 | } | ||
452 | |||
453 | /* Add a deoptimize target for the current instruction. */ | ||
454 | static void jit_deopt_target(jit_State *J, int nargs) | ||
455 | { | ||
456 | |.define L_DEOPTLABEL, 9 // Local deopt label. | ||
457 | |.define L_DEOPTIMIZE, <9 // Local deopt target. Use after call. | ||
458 | |.define L_DEOPTIMIZEF, >9 // Local deopt target. Use before call. | ||
459 | if (nargs != -1) { | ||
460 | |// Alas, x86 doesn't have conditional calls. So branch to the .deopt | ||
461 | |// section to load J->nextins and jump to JSUB_DEOPTIMIZE. | ||
462 | |// Only a single jump is added at the end (if needed) and any | ||
463 | |// intervening code sequences are shadowed (lea trick). | ||
464 | |.deopt // Occupies 6 bytes in .deopt section. | ||
465 | | .byte 0x8d // Shadow mov with lea edi, [edx+ofs]. | ||
466 | |L_DEOPTLABEL: | ||
467 | | mov edx, &J->nextins // Current instruction + 1. | ||
468 | |.code | ||
469 | J->tflags |= JIT_TF_USED_DEOPT; | ||
470 | } else { | ||
471 | |.tail // Occupies 10 bytes in .tail section. | ||
472 | |L_DEOPTLABEL: | ||
473 | | mov edx, &J->nextins | ||
474 | | jmp ->DEOPTIMIZE_OPEN // Open ins need to save TOP, too. | ||
475 | | // And TOP (edi) would be overwritten by the lea trick. | ||
476 | | // So checking for open ops later on wouldn't suffice. Sigh. | ||
477 | |.code | ||
478 | } | ||
479 | } | ||
480 | |||
481 | /* luaC_checkGC() inlined. Destroys caller-saves + TOP (edi). Uses label 7:. */ | ||
482 | /* Use this only at the _end_ of an instruction. */ | ||
483 | static void jit_checkGC(jit_State *J) | ||
484 | { | ||
485 | | mov GL:ecx, L->l_G | ||
486 | | mov eax, GL:ecx->totalbytes // size_t | ||
487 | | mov TOP, >7 | ||
488 | | cmp eax, GL:ecx->GCthreshold // size_t | ||
489 | | jae ->GCSTEP | ||
490 | |7: | ||
491 | |||
492 | |.jsub GCSTEP | ||
493 | | call &luaC_step, L | ||
494 | | mov BASE, L->base | ||
495 | | jmp TOP | ||
496 | |.endjsub | ||
497 | } | ||
498 | |||
499 | /* ------------------------------------------------------------------------ */ | ||
500 | |||
501 | |// JIT->JIT calling conventions: | ||
502 | |// | ||
503 | |// Register/Type | Call Setup | Prologue | Epilogue | Call Finish | ||
504 | |// =========================================================================== | ||
505 | |// eax | LCL | = BASE->value| | * | * | ||
506 | |// ecx | CI | = L->ci | L->ci = ++CI | * | * | ||
507 | |// edx | * | * | * | * | * | ||
508 | |// --------------------------------------------------------------------------- | ||
509 | |// esi | L | | | | | ||
510 | |// ebx | BASE | += f | ++ | -- | -= f | ||
511 | |// edi | TOP | += f+1+nargs | = BASE+maxst | = f+nresults | = BASE+maxst | ||
512 | |// --------------------------------------------------------------------------- | ||
513 | |// L->base | | = BASE | | = BASE | ||
514 | |// L->top | | = TOP | | = TOP | ||
515 | |// L->ci | | ++, -> = ... | -- | | ||
516 | |// L->ci->savedpc| = &code[pc] | [ L-> = ] | | | ||
517 | |// --------------------------------------------------------------------------- | ||
518 | |// args + vars | | setnil | | | ||
519 | |// results | | | move | setnil | ||
520 | |// --------------------------------------------------------------------------- | ||
521 | |||
522 | |||
523 | |// Include support for function inlining. | ||
524 | |.include ljit_x86_inline.dash | ||
525 | |||
526 | |||
527 | #ifdef LUA_COMPAT_VARARG | ||
528 | static void jit_vararg_table(lua_State *L) | ||
529 | { | ||
530 | Table *tab; | ||
531 | StkId base, func; | ||
532 | int i, num, numparams; | ||
533 | luaC_checkGC(L); | ||
534 | base = L->base; | ||
535 | func = L->ci->func; | ||
536 | numparams = clvalue(func)->l.p->numparams; | ||
537 | num = base - func - numparams - 1; | ||
538 | tab = luaH_new(L, num, 1); | ||
539 | for (i = 0; i < num; i++) | ||
540 | setobj2n(L, luaH_setnum(L, tab, i+1), base - num + i); | ||
541 | setnvalue(luaH_setstr(L, tab, luaS_newliteral(L, "n")), (lua_Number)num); | ||
542 | sethvalue(L, base + numparams, tab); | ||
543 | } | ||
544 | #endif | ||
545 | |||
546 | /* Encode JIT function prologue. */ | ||
547 | static void jit_prologue(jit_State *J) | ||
548 | { | ||
549 | Proto *pt = J->pt; | ||
550 | int numparams = pt->numparams; | ||
551 | int stacksize = pt->maxstacksize; | ||
552 | |||
553 | |// Note: the order of the following instructions has been carefully tuned. | ||
554 | | lea eax, TOP[stacksize] | ||
555 | | sub esp, FRAME_OFFSET | ||
556 | | cmp eax, L->stack_last | ||
557 | | jae ->GROW_STACK // Stack overflow? | ||
558 | | // This is a slight overallocation (BASE[1+stacksize] would be enough). | ||
559 | | // We duplicate luaD_precall() behaviour so we can use luaD_growstack(). | ||
560 | | cmp CI, L->end_ci | ||
561 | | lea CI, CI[1] | ||
562 | | je ->GROW_CI // CI overflow? | ||
563 | | xor eax, eax // Assumes: LUA_TNIL == 0 | ||
564 | | mov CI->func, BASE | ||
565 | | add BASE, #BASE | ||
566 | | mov L->ci, CI | ||
567 | |||
568 | if (numparams > 0) { | ||
569 | | lea edx, BASE[numparams] | ||
570 | | cmp TOP, edx // L->top >< L->base+numparams ? | ||
571 | } | ||
572 | |||
573 | if (!pt->is_vararg) { /* Fixarg function. */ | ||
574 | /* Must cap L->top at L->base+numparams because 1st LOADNIL is omitted. */ | ||
575 | if (numparams == 0) { | ||
576 | | mov TOP, BASE | ||
577 | } else if (J->flags & JIT_F_CPU_CMOV) { | ||
578 | | cmova TOP, edx | ||
579 | } else { | ||
580 | | jna >1 | ||
581 | | mov TOP, edx | ||
582 | |1: | ||
583 | } | ||
584 | | lea edx, BASE[stacksize] // New ci->top. | ||
585 | | mov CI->tailcalls, eax // 0 | ||
586 | | mov CI->top, edx | ||
587 | | mov L->top, edx | ||
588 | | mov L->base, BASE | ||
589 | | mov CI->base, BASE | ||
590 | } else { /* Vararg function. */ | ||
591 | int i; | ||
592 | if (numparams > 0) { | ||
593 | |// If some fixargs are missing we need to clear them and | ||
594 | |// bump TOP to get a consistent frame layout for OP_VARARG. | ||
595 | | jb >5 | ||
596 | |4: | ||
597 | |.tail | ||
598 | |5: // This is uncommon. So move it to .tail and use a loop. | ||
599 | | mov TOP->tt, eax | ||
600 | | add TOP, #TOP | ||
601 | | cmp TOP, edx | ||
602 | | jb <5 | ||
603 | | jmp <4 | ||
604 | |.code | ||
605 | } | ||
606 | | mov L->base, TOP // New base is after last arg. | ||
607 | | mov CI->base, TOP | ||
608 | | mov CI->tailcalls, eax // 0 | ||
609 | for (i = 0; i < numparams; i++) { /* Move/clear fixargs. */ | ||
610 | |// Inline this. Vararg funcs usually have very few fixargs. | ||
611 | | copyslot TOP[i], BASE[i], ecx, edx | ||
612 | | mov BASE[i].tt, eax // Clear old fixarg slot (help the GC). | ||
613 | } | ||
614 | if (numparams > 0) { | ||
615 | | mov CI, L->ci // Reload CI = ecx (used by move). | ||
616 | } | ||
617 | | mov BASE, TOP | ||
618 | | lea edx, BASE[stacksize] // New ci->top. | ||
619 | | lea TOP, BASE[numparams] // Start of vars to clear. | ||
620 | | mov CI->top, edx | ||
621 | | mov L->top, edx | ||
622 | stacksize -= numparams; /* Fixargs are already cleared. */ | ||
623 | } | ||
624 | |||
625 | /* Clear undefined args and all vars. Still assumes eax = LUA_TNIL = 0. */ | ||
626 | /* Note: cannot clear only args because L->top has grown. */ | ||
627 | if (stacksize <= EXTRA_STACK) { /* Loopless clear. May use EXTRA_STACK. */ | ||
628 | int i; | ||
629 | for (i = 0; i < stacksize; i++) { | ||
630 | | mov TOP[i].tt, eax | ||
631 | } | ||
632 | } else { /* Standard loop. */ | ||
633 | |2: // Unrolled for 2 stack slots. No initial check. May use EXTRA_STACK. | ||
634 | | mov TOP[0].tt, eax | ||
635 | | mov TOP[1].tt, eax | ||
636 | | add TOP, 2*#TOP | ||
637 | | cmp TOP, edx | ||
638 | | jb <2 | ||
639 | |// Note: TOP is undefined now. TOP is only valid across calls/open ins. | ||
640 | } | ||
641 | |||
642 | #ifdef LUA_COMPAT_VARARG | ||
643 | if (pt->is_vararg & VARARG_NEEDSARG) { | ||
644 | | call &jit_vararg_table, L | ||
645 | } | ||
646 | #endif | ||
647 | |||
648 | /* Call hook check. */ | ||
649 | if (J->flags & JIT_F_DEBUG_CALL) { | ||
650 | | test byte L->hookmask, LUA_MASKCALL | ||
651 | | jz >9 | ||
652 | | call ->HOOKCALL | ||
653 | |9: | ||
654 | |||
655 | |.jsub HOOKCALL | ||
656 | | mov CI, L->ci | ||
657 | | mov TOP, CI->func | ||
658 | | mov LCL, TOP->value | ||
659 | | mov PROTO:edi, LCL->p // clvalue(L->ci->func)->l.p | ||
660 | | mov eax, PROTO:edi->code | ||
661 | | add eax, 4 // Hooks expect incremented PC. | ||
662 | | mov L->savedpc, eax | ||
663 | | sub esp, FRAME_OFFSET | ||
664 | | call &luaD_callhook, L, LUA_HOOKCALL, -1 | ||
665 | | add esp, FRAME_OFFSET | ||
666 | | mov eax, PROTO:edi->code // PROTO:edi is callee-save. | ||
667 | | mov L->savedpc, eax // jit_hookins needs previous PC. | ||
668 | | mov BASE, L->base | ||
669 | | ret | ||
670 | |.endjsub | ||
671 | } | ||
672 | } | ||
673 | |||
674 | /* Check if we can combine 'return const'. */ | ||
675 | static int jit_return_k(jit_State *J) | ||
676 | { | ||
677 | if (!J->combine) return 0; /* COMBINE hint set? */ | ||
678 | /* May need to close open upvalues. */ | ||
679 | if (!fhint_isset(J, NOCLOSE)) { | ||
680 | | call &luaF_close, L, BASE | ||
681 | } | ||
682 | if (!J->pt->is_vararg) { /* Fixarg function. */ | ||
683 | | sub aword L->ci, #CI | ||
684 | | mov TOP, BASE | ||
685 | | sub BASE, #BASE | ||
686 | | add esp, FRAME_OFFSET | ||
687 | } else { /* Vararg function. */ | ||
688 | | mov CI, L->ci | ||
689 | | mov BASE, CI->func | ||
690 | | sub CI, #CI | ||
691 | | mov L->ci, CI | ||
692 | | lea TOP, BASE[1] | ||
693 | | add esp, FRAME_OFFSET | ||
694 | } | ||
695 | jit_assert(J->combine == 1); /* Required to skip next RETURN instruction. */ | ||
696 | return 1; | ||
697 | } | ||
698 | |||
699 | static void jit_op_return(jit_State *J, int rbase, int nresults) | ||
700 | { | ||
701 | /* Return hook check. */ | ||
702 | if (J->flags & JIT_F_DEBUG_CALL) { | ||
703 | if (nresults < 0 && !(J->flags & JIT_F_DEBUG_INS)) { | ||
704 | | mov L->top, TOP | ||
705 | } | ||
706 | |// TODO: LUA_HOOKTAILRET (+ ci->tailcalls counting) or changed debug API. | ||
707 | | test byte L->hookmask, LUA_MASKRET | ||
708 | | jz >7 | ||
709 | | call ->HOOKRET | ||
710 | |7: | ||
711 | if (J->flags & JIT_F_DEBUG_INS) { | ||
712 | | mov eax, FRAME_RETADDR | ||
713 | | mov L->savedpc, eax | ||
714 | } | ||
715 | |||
716 | |.jsub HOOKRET | ||
717 | | mov eax, [esp] // Current machine code address. | ||
718 | | mov L->savedpc, eax | ||
719 | | sub esp, FRAME_OFFSET | ||
720 | | call &luaD_callhook, L, LUA_HOOKRET, -1 | ||
721 | | add esp, FRAME_OFFSET | ||
722 | | mov BASE, L->base // Restore stack-relative pointers. | ||
723 | | mov TOP, L->top | ||
724 | | ret | ||
725 | |.endjsub | ||
726 | } | ||
727 | |||
728 | /* May need to close open upvalues. */ | ||
729 | if (!fhint_isset(J, NOCLOSE)) { | ||
730 | | call &luaF_close, L, BASE | ||
731 | } | ||
732 | |||
733 | /* Previous op was open: 'return f()' or 'return ...' */ | ||
734 | if (nresults < 0) { | ||
735 | |// Relocate [BASE+rbase, TOP) -> [ci->func, *). | ||
736 | | mov CI, L->ci | ||
737 | | addidx BASE, rbase | ||
738 | | mov edx, CI->func | ||
739 | | cmp BASE, TOP | ||
740 | | jnb >2 | ||
741 | |1: | ||
742 | | mov eax, [BASE] | ||
743 | | add BASE, aword*1 | ||
744 | | mov [edx], eax | ||
745 | | add edx, aword*1 | ||
746 | | cmp BASE, TOP | ||
747 | | jb <1 | ||
748 | |2: | ||
749 | | add esp, FRAME_OFFSET | ||
750 | | mov BASE, CI->func | ||
751 | | sub CI, #CI | ||
752 | | mov TOP, edx // Relocated TOP. | ||
753 | | mov L->ci, CI | ||
754 | | ret | ||
755 | return; | ||
756 | } | ||
757 | |||
758 | if (!J->pt->is_vararg) { /* Fixarg function, nresults >= 0. */ | ||
759 | int i; | ||
760 | | sub aword L->ci, #CI | ||
761 | |// Relocate [BASE+rbase,BASE+rbase+nresults) -> [BASE-1, *). | ||
762 | |// TODO: loop for large nresults? | ||
763 | | sub BASE, #BASE | ||
764 | for (i = 0; i < nresults; i++) { | ||
765 | | copyslot BASE[i], BASE[rbase+i+1] | ||
766 | } | ||
767 | | add esp, FRAME_OFFSET | ||
768 | | lea TOP, BASE[nresults] | ||
769 | | ret | ||
770 | } else { /* Vararg function, nresults >= 0. */ | ||
771 | int i; | ||
772 | |// Relocate [BASE+rbase,BASE+rbase+nresults) -> [ci->func, *). | ||
773 | | mov CI, L->ci | ||
774 | | mov TOP, CI->func | ||
775 | | sub CI, #CI | ||
776 | | mov L->ci, CI // CI = ecx is used by copyslot. | ||
777 | for (i = 0; i < nresults; i++) { | ||
778 | | copyslot TOP[i], BASE[rbase+i] | ||
779 | } | ||
780 | | add esp, FRAME_OFFSET | ||
781 | | mov BASE, TOP | ||
782 | | addidx TOP, nresults | ||
783 | | ret | ||
784 | } | ||
785 | } | ||
786 | |||
787 | static void jit_op_call(jit_State *J, int func, int nargs, int nresults) | ||
788 | { | ||
789 | int cltype = jit_inline_call(J, func, nargs, nresults); | ||
790 | if (cltype < 0) return; /* Inlined? */ | ||
791 | |||
792 | |// Note: the order of the following instructions has been carefully tuned. | ||
793 | | addidx BASE, func | ||
794 | | mov CI, L->ci | ||
795 | | isfunction 0 // BASE[0] is L->base[func]. | ||
796 | if (nargs >= 0) { /* Previous op was not open and did not set TOP. */ | ||
797 | | lea TOP, BASE[1+nargs] | ||
798 | } | ||
799 | | mov LCL, BASE->value | ||
800 | | mov edx, &J->nextins | ||
801 | | mov CI->savedpc, edx | ||
802 | if (cltype == LUA_TFUNCTION) { | ||
803 | if (nargs == -1) { | ||
804 | | jne ->DEOPTIMIZE_OPEN // TYPE hint was wrong (open op)? | ||
805 | } else { | ||
806 | | jne ->DEOPTIMIZE // TYPE hint was wrong? | ||
807 | } | ||
808 | } else { | ||
809 | | je >1 // Skip __call handling for functions. | ||
810 | | call ->METACALL | ||
811 | |1: | ||
812 | |||
813 | |.jsub METACALL // CALL to __call metamethod. | ||
814 | | sub esp, FRAME_OFFSET | ||
815 | | mov L->savedpc, edx // May throw errors. Save PC and TOP. | ||
816 | | mov L->top, TOP | ||
817 | | call &luaD_tryfuncTM, L, BASE // Resolve __call metamethod. | ||
818 | | add esp, FRAME_OFFSET | ||
819 | | mov BASE, eax // Restore stack-relative pointers. | ||
820 | | mov TOP, L->top | ||
821 | | mov LCL, BASE->value | ||
822 | | mov CI, L->ci | ||
823 | | ret | ||
824 | |.endjsub | ||
825 | } | ||
826 | | call aword LCL->jit_gate // Call JIT func or GATE_JL/GATE_JC. | ||
827 | | subidx BASE, func | ||
828 | | mov L->base, BASE | ||
829 | |||
830 | /* Clear undefined results TOP <= o < func+nresults. */ | ||
831 | if (nresults > 0) { | ||
832 | | xor eax, eax | ||
833 | if (nresults <= EXTRA_STACK) { /* Loopless clear. May use EXTRA_STACK. */ | ||
834 | int i; | ||
835 | for (i = 0; i < nresults; i++) { | ||
836 | | mov TOP[i].tt, eax | ||
837 | } | ||
838 | } else { /* Standard loop. TODO: move to .tail? */ | ||
839 | | lea edx, BASE[func+nresults] | ||
840 | |1: // Unrolled for 2 stack slots. No initial check. May use EXTRA_STACK. | ||
841 | | mov TOP[0].tt, eax // LUA_TNIL | ||
842 | | mov TOP[1].tt, eax // LUA_TNIL | ||
843 | | add TOP, 2*#TOP | ||
844 | | cmp TOP, edx | ||
845 | | jb <1 | ||
846 | } | ||
847 | } | ||
848 | |||
849 | if (nresults >= 0) { /* Not an open ins. Restore L->top. */ | ||
850 | | lea TOP, BASE[J->pt->maxstacksize] // Faster than getting L->ci->top. | ||
851 | | mov L->top, TOP | ||
852 | } /* Otherwise keep TOP for next instruction. */ | ||
853 | } | ||
854 | |||
855 | static void jit_op_tailcall(jit_State *J, int func, int nargs) | ||
856 | { | ||
857 | int cltype; | ||
858 | |||
859 | if (!fhint_isset(J, NOCLOSE)) { /* May need to close open upvalues. */ | ||
860 | | call &luaF_close, L, BASE | ||
861 | } | ||
862 | |||
863 | cltype = jit_inline_call(J, func, nargs, -2); | ||
864 | if (cltype < 0) goto finish; /* Inlined? */ | ||
865 | |||
866 | if (cltype == LUA_TFUNCTION) { | ||
867 | jit_deopt_target(J, nargs); | ||
868 | | isfunction func | ||
869 | | jne L_DEOPTIMIZE // TYPE hint was wrong? | ||
870 | } else { | ||
871 | | isfunction func; jne >5 // Handle generic callables first. | ||
872 | |.tail | ||
873 | |5: // Fallback for generic callables. | ||
874 | | addidx BASE, func | ||
875 | if (nargs >= 0) { | ||
876 | | lea TOP, BASE[1+nargs] | ||
877 | } | ||
878 | | mov edx, &J->nextins | ||
879 | | jmp ->METATAILCALL | ||
880 | |.code | ||
881 | |||
882 | |.jsub METATAILCALL // TAILCALL to __call metamethod. | ||
883 | | mov L->savedpc, edx | ||
884 | | mov L->top, TOP | ||
885 | | call &luaD_tryfuncTM, L, BASE // Resolve __call metamethod. | ||
886 | | | ||
887 | |// Relocate [eax, L->top) -> [L->ci->func, *). | ||
888 | | mov CI, L->ci | ||
889 | | mov edx, L->top | ||
890 | | mov TOP, CI->func | ||
891 | |1: | ||
892 | | mov BASE, [eax] | ||
893 | | add eax, aword*1 | ||
894 | | mov [TOP], BASE | ||
895 | | add TOP, aword*1 | ||
896 | | cmp eax, edx | ||
897 | | jb <1 | ||
898 | | | ||
899 | | mov BASE, CI->func | ||
900 | | mov LCL, BASE->value | ||
901 | | sub CI, #CI | ||
902 | | add esp, FRAME_OFFSET | ||
903 | | jmp aword LCL->jit_gate // Chain to callgate. | ||
904 | |.endjsub | ||
905 | } | ||
906 | |||
907 | if (nargs >= 0) { /* Previous op was not open and did not set TOP. */ | ||
908 | int i; | ||
909 | /* Relocate [BASE+func, BASE+func+nargs] -> [ci->func, ci->func+nargs]. */ | ||
910 | /* TODO: loop for large nargs? */ | ||
911 | if (!J->pt->is_vararg) { /* Fixarg function. */ | ||
912 | | mov LCL, BASE[func].value | ||
913 | for (i = 0; i < nargs; i++) { | ||
914 | | copyslot BASE[i], BASE[func+1+i], ecx, edx | ||
915 | } | ||
916 | | lea TOP, BASE[nargs] | ||
917 | | sub BASE, #BASE | ||
918 | | mov CI, L->ci | ||
919 | | mov BASE->value, LCL // Sufficient to copy func->value. | ||
920 | } else { /* Vararg function. */ | ||
921 | | mov CI, L->ci | ||
922 | | lea TOP, BASE[func] | ||
923 | | mov BASE, CI->func | ||
924 | | mov LCL, TOP->value | ||
925 | | mov BASE->value, LCL // Sufficient to copy func->value. | ||
926 | for (i = 0; i < nargs; i++) { | ||
927 | | copyslot BASE[i+1], TOP[i+1], eax, edx | ||
928 | } | ||
929 | | lea TOP, BASE[1+nargs] | ||
930 | | mov LCL, BASE->value // Need to reload LCL = eax. | ||
931 | } | ||
932 | } else { /* Previous op was open and set TOP. */ | ||
933 | |// Relocate [BASE+func, TOP) -> [ci->func, *). | ||
934 | | mov CI, L->ci | ||
935 | | addidx BASE, func | ||
936 | | mov edx, CI->func | ||
937 | |1: | ||
938 | | mov eax, [BASE] | ||
939 | | add BASE, aword*1 | ||
940 | | mov [edx], eax | ||
941 | | add edx, aword*1 | ||
942 | | cmp BASE, TOP | ||
943 | | jb <1 | ||
944 | | mov BASE, CI->func | ||
945 | | mov TOP, edx // Relocated TOP. | ||
946 | | mov LCL, BASE->value | ||
947 | } | ||
948 | | sub CI, #CI | ||
949 | | add esp, FRAME_OFFSET | ||
950 | | jmp aword LCL->jit_gate // Chain to JIT function. | ||
951 | |||
952 | finish: | ||
953 | J->combine++; /* Combine with following return instruction. */ | ||
954 | } | ||
955 | |||
956 | /* ------------------------------------------------------------------------ */ | ||
957 | |||
958 | static void jit_op_move(jit_State *J, int dest, int src) | ||
959 | { | ||
960 | | copyslot BASE[dest], BASE[src] | ||
961 | } | ||
962 | |||
963 | static void jit_op_loadk(jit_State *J, int dest, int kidx) | ||
964 | { | ||
965 | const TValue *kk = &J->pt->k[kidx]; | ||
966 | int rk = jit_return_k(J); | ||
967 | if (rk) dest = 0; | ||
968 | | copyconst BASE[dest], kk | ||
969 | if (rk) { | ||
970 | | ret | ||
971 | } | ||
972 | } | ||
973 | |||
974 | static void jit_op_loadnil(jit_State *J, int first, int last) | ||
975 | { | ||
976 | int idx, num = last - first + 1; | ||
977 | int rk = jit_return_k(J); | ||
978 | | xor eax, eax // Assumes: LUA_TNIL == 0 | ||
979 | if (rk) { | ||
980 | | settt BASE[0], eax | ||
981 | | ret | ||
982 | } else if (num <= 8) { | ||
983 | for (idx = first; idx <= last; idx++) { | ||
984 | | settt BASE[idx], eax // 3/6 bytes | ||
985 | } | ||
986 | } else { | ||
987 | | lea ecx, BASE[first].tt // 15-21 bytes | ||
988 | | lea edx, BASE[last].tt | ||
989 | |1: | ||
990 | | mov [ecx], eax | ||
991 | | cmp ecx, edx | ||
992 | | lea ecx, [ecx+#BASE] // Preserves CC. | ||
993 | | jbe <1 | ||
994 | } | ||
995 | } | ||
996 | |||
997 | static void jit_op_loadbool(jit_State *J, int dest, int b, int dojump) | ||
998 | { | ||
999 | int rk = jit_return_k(J); | ||
1000 | if (rk) dest = 0; | ||
1001 | | setbvalue BASE[dest], b | ||
1002 | if (rk) { | ||
1003 | | ret | ||
1004 | } else if (dojump) { | ||
1005 | const TValue *h = hint_getpc(J, COMBINE, J->nextpc); | ||
1006 | if (!(ttisboolean(h) && bvalue(h) == 0)) { /* Avoid jmp around dead ins. */ | ||
1007 | | jmp =>J->nextpc+1 | ||
1008 | } | ||
1009 | } | ||
1010 | } | ||
1011 | |||
1012 | /* ------------------------------------------------------------------------ */ | ||
1013 | |||
1014 | static void jit_op_getupval(jit_State *J, int dest, int uvidx) | ||
1015 | { | ||
1016 | | getLCL | ||
1017 | | mov UPVAL:ecx, LCL->upvals[uvidx] | ||
1018 | | mov TOP, UPVAL:ecx->v | ||
1019 | | copyslot BASE[dest], TOP[0] | ||
1020 | } | ||
1021 | |||
1022 | static void jit_op_setupval(jit_State *J, int src, int uvidx) | ||
1023 | { | ||
1024 | | getLCL | ||
1025 | | mov UPVAL:ecx, LCL->upvals[uvidx] | ||
1026 | | mov TOP, UPVAL:ecx->v | ||
1027 | | // This is really copyslot TOP[0], BASE[src] with compare mixed in. | ||
1028 | | mov eax, BASE[src].tt | ||
1029 | | mov GCOBJECT:edx, BASE[src].value | ||
1030 | | mov TOP->tt, eax | ||
1031 | | cmp eax, LUA_TSTRING // iscollectable(val)? | ||
1032 | | mov eax, BASE[src].value.na[1] | ||
1033 | | mov TOP->value, GCOBJECT:edx | ||
1034 | | mov TOP->value.na[1], eax | ||
1035 | | jae >5 | ||
1036 | |4: | ||
1037 | |.tail | ||
1038 | |5: | ||
1039 | | test byte GCOBJECT:edx->gch.marked, WHITEBITS // && iswhite(val) | ||
1040 | | jz <4 | ||
1041 | | test byte UPVAL:ecx->marked, bitmask(BLACKBIT) // && isblack(uv) | ||
1042 | | jz <4 | ||
1043 | | call ->BARRIERF // Yes, need barrier. | ||
1044 | | jmp <4 | ||
1045 | |.code | ||
1046 | |||
1047 | |.jsub BARRIERF // luaC_barrierf() with regparms. | ||
1048 | | mov ARG4, GCOBJECT:edx | ||
1049 | | mov ARG3, UPVAL:ecx | ||
1050 | | mov ARG2, L | ||
1051 | | jmp &luaC_barrierf // Chain to C code. | ||
1052 | |.endjsub | ||
1053 | } | ||
1054 | |||
1055 | /* ------------------------------------------------------------------------ */ | ||
1056 | |||
1057 | /* Optimized table lookup routines. Enter via jsub, fallback to C. */ | ||
1058 | |||
1059 | /* Fallback for GETTABLE_*. Temporary key is in L->env. */ | ||
1060 | static void jit_gettable_fb(lua_State *L, Table *t, StkId dest) | ||
1061 | { | ||
1062 | Table *mt = t->metatable; | ||
1063 | const TValue *tm = luaH_getstr(mt, G(L)->tmname[TM_INDEX]); | ||
1064 | if (ttisnil(tm)) { /* No __index method? */ | ||
1065 | mt->flags |= 1<<TM_INDEX; /* Cache this fact. */ | ||
1066 | setnilvalue(dest); | ||
1067 | } else if (ttisfunction(tm)) { /* __index function? */ | ||
1068 | ptrdiff_t destr = savestack(L, dest); | ||
1069 | setobj2s(L, L->top, tm); | ||
1070 | sethvalue(L, L->top+1, t); | ||
1071 | setobj2s(L, L->top+2, &L->env); | ||
1072 | luaD_checkstack(L, 3); | ||
1073 | L->top += 3; | ||
1074 | luaD_call(L, L->top - 3, 1); | ||
1075 | dest = restorestack(L, destr); | ||
1076 | L->top--; | ||
1077 | setobjs2s(L, dest, L->top); | ||
1078 | } else { /* Let luaV_gettable() continue with the __index object. */ | ||
1079 | luaV_gettable(L, tm, &L->env, dest); | ||
1080 | } | ||
1081 | |||
1082 | |//----------------------------------------------------------------------- | ||
1083 | |.jsub GETGLOBAL // Lookup global variable. | ||
1084 | |// Call with: TSTRING:edx (key), BASE (dest) | ||
1085 | | mov CI, L->ci | ||
1086 | | mov TOP, CI->func | ||
1087 | | mov LCL, TOP->value | ||
1088 | | mov TABLE:edi, LCL->env | ||
1089 | | jmp >9 | ||
1090 | |.endjsub | ||
1091 | | | ||
1092 | |//----------------------------------------------------------------------- | ||
1093 | |.jsub GETTABLE_KSTR // Lookup constant string in table. | ||
1094 | |// Call with: TOP (tab), TSTRING:edx (key), BASE (dest) | ||
1095 | | cmp dword TOP->tt, LUA_TTABLE | ||
1096 | | mov TABLE:edi, TOP->value | ||
1097 | | jne ->DEOPTIMIZE_CALLER // Not a table? Deoptimize. | ||
1098 | | | ||
1099 | |// Common entry: TABLE:edi (tab), TSTRING:edx (key), BASE (dest) | ||
1100 | |// Restores BASE, destroys eax, ecx, edx, edi (TOP). | ||
1101 | |9: | ||
1102 | | movzx ecx, byte TABLE:edi->lsizenode // hashstr(t, key). | ||
1103 | | mov eax, 1 | ||
1104 | | shl eax, cl | ||
1105 | | dec eax | ||
1106 | | and eax, TSTRING:edx->tsv.hash | ||
1107 | | Nodemul NODE:eax | ||
1108 | | add NODE:eax, TABLE:edi->node | ||
1109 | | | ||
1110 | |1: // Start of inner loop. Check node key. | ||
1111 | | cmp dword NODE:eax->i_key.nk.tt, LUA_TSTRING | ||
1112 | | jne >2 | ||
1113 | | cmp aword NODE:eax->i_key.nk.value, TSTRING:edx | ||
1114 | | jne >2 | ||
1115 | | // Note: swapping the two checks is faster, but valgrind complains. | ||
1116 | |// Assumes: (int)&(((Node *)0)->i_val) == (int)&(((StkId)0)->value) | ||
1117 | | | ||
1118 | |// Ok, key found. Copy node value to destination (stack) slot. | ||
1119 | | mov ecx, NODE:eax->i_val.tt | ||
1120 | | test ecx, ecx; je >3 // Node has nil value? | ||
1121 | ||if (J->flags & JIT_F_CPU_SSE2) { | ||
1122 | | movq xmm0, qword NODE:eax->i_val.value | ||
1123 | | movq qword BASE->value, xmm0 | ||
1124 | ||} else { | ||
1125 | | mov edx, NODE:eax->i_val.value | ||
1126 | | mov edi, NODE:eax->i_val.value.na[1] | ||
1127 | | mov BASE->value, edx | ||
1128 | | mov BASE->value.na[1], edi | ||
1129 | ||} | ||
1130 | | mov BASE->tt, ecx | ||
1131 | | mov BASE, L->base | ||
1132 | | ret | ||
1133 | |2: | ||
1134 | | mov NODE:eax, NODE:eax->i_key.nk.next // Get next key in chain. | ||
1135 | | test NODE:eax, NODE:eax | ||
1136 | | jnz <1 // Loop if non-NULL. | ||
1137 | | | ||
1138 | | xor ecx, ecx | ||
1139 | |3: | ||
1140 | | mov TABLE:eax, TABLE:edi->metatable | ||
1141 | | test TABLE:eax, TABLE:eax | ||
1142 | | jz >4 // No metatable? | ||
1143 | | test byte TABLE:eax->flags, 1<<TM_INDEX | ||
1144 | | jz >5 // Or 'no __index' flag set? | ||
1145 | |4: | ||
1146 | | settt BASE[0], ecx // Yes, set to nil. | ||
1147 | | mov BASE, L->base | ||
1148 | | ret | ||
1149 | | | ||
1150 | |5: // Otherwise chain to C code which eventually calls luaV_gettable. | ||
1151 | | setsvalue L->env, TSTRING:edx // Use L->env as temp key. | ||
1152 | | mov ecx, [esp] | ||
1153 | | sub esp, FRAME_OFFSET | ||
1154 | | mov L->savedpc, ecx | ||
1155 | | call &jit_gettable_fb, L, TABLE:edi, BASE | ||
1156 | | add esp, FRAME_OFFSET | ||
1157 | | mov BASE, L->base | ||
1158 | | ret | ||
1159 | |.endjsub | ||
1160 | | | ||
1161 | |//----------------------------------------------------------------------- | ||
1162 | |.jsub GETTABLE_STR // Lookup string in table. | ||
1163 | |// Call with: TOP (tab), TVALUE:ecx (key), BASE (dest) | ||
1164 | | mov eax, TOP->tt; shl eax, 4; or eax, TVALUE:ecx->tt | ||
1165 | | cmp eax, LUA_TTABLE_STR | ||
1166 | | mov TABLE:edi, TOP->value | ||
1167 | | mov TSTRING:edx, TVALUE:ecx->value | ||
1168 | | je <9 // Types ok? Continue above. | ||
1169 | | jmp ->DEOPTIMIZE_CALLER // Otherwise deoptimize. | ||
1170 | |.endjsub | ||
1171 | } | ||
1172 | |||
1173 | /* Fallback for SETTABLE_*STR. Temporary (string) key is in L->env. */ | ||
1174 | static void jit_settable_fb(lua_State *L, Table *t, StkId val) | ||
1175 | { | ||
1176 | Table *mt = t->metatable; | ||
1177 | const TValue *tm = luaH_getstr(mt, G(L)->tmname[TM_NEWINDEX]); | ||
1178 | if (ttisnil(tm)) { /* No __newindex method? */ | ||
1179 | mt->flags |= 1<<TM_NEWINDEX; /* Cache this fact. */ | ||
1180 | t->flags = 0; /* But need to clear the cache for the table itself. */ | ||
1181 | setobj2t(L, luaH_setstr(L, t, rawtsvalue(&L->env)), val); | ||
1182 | luaC_barriert(L, t, val); | ||
1183 | } else if (ttisfunction(tm)) { /* __newindex function? */ | ||
1184 | setobj2s(L, L->top, tm); | ||
1185 | sethvalue(L, L->top+1, t); | ||
1186 | setobj2s(L, L->top+2, &L->env); | ||
1187 | setobj2s(L, L->top+3, val); | ||
1188 | luaD_checkstack(L, 4); | ||
1189 | L->top += 4; | ||
1190 | luaD_call(L, L->top - 4, 0); | ||
1191 | } else { /* Let luaV_settable() continue with the __newindex object. */ | ||
1192 | luaV_settable(L, tm, &L->env, val); | ||
1193 | } | ||
1194 | |||
1195 | |//----------------------------------------------------------------------- | ||
1196 | |.jsub BARRIERBACK // luaC_barrierback() with regparms. | ||
1197 | |// Call with: TABLE:edi (table). Destroys ecx, edx. | ||
1198 | | mov GL:ecx, L->l_G | ||
1199 | | and byte TABLE:edi->marked, (~bitmask(BLACKBIT))&0xff | ||
1200 | | mov edx, GL:ecx->grayagain | ||
1201 | | mov GL:ecx->grayagain, TABLE:edi | ||
1202 | | mov TABLE:edi->gclist, edx | ||
1203 | | ret | ||
1204 | |.endjsub | ||
1205 | | | ||
1206 | |//----------------------------------------------------------------------- | ||
1207 | |.jsub SETGLOBAL // Set global variable. | ||
1208 | |// Call with: TSTRING:edx (key), BASE (val) | ||
1209 | | mov CI, L->ci | ||
1210 | | mov TOP, CI->func | ||
1211 | | mov LCL, TOP->value | ||
1212 | | mov TABLE:edi, LCL->env | ||
1213 | | jmp >9 | ||
1214 | |.endjsub | ||
1215 | | | ||
1216 | |//----------------------------------------------------------------------- | ||
1217 | |.jsub SETTABLE_KSTR // Set constant string entry in table. | ||
1218 | |// Call with: TOP (tab), TSTRING:edx (key), BASE (val) | ||
1219 | | cmp dword TOP->tt, LUA_TTABLE | ||
1220 | | mov TABLE:edi, TOP->value | ||
1221 | | jne ->DEOPTIMIZE_CALLER // Not a table? Deoptimize. | ||
1222 | | | ||
1223 | |// Common entry: TABLE:edi (tab), TSTRING:edx (key), BASE (val) | ||
1224 | |// Restores BASE, destroys eax, ecx, edx, edi (TOP). | ||
1225 | |9: | ||
1226 | | movzx ecx, byte TABLE:edi->lsizenode // hashstr(t, key). | ||
1227 | | mov eax, 1 | ||
1228 | | shl eax, cl | ||
1229 | | dec eax | ||
1230 | | and eax, TSTRING:edx->tsv.hash | ||
1231 | | Nodemul NODE:eax | ||
1232 | | add NODE:eax, TABLE:edi->node | ||
1233 | | | ||
1234 | |1: // Start of inner loop. Check node key. | ||
1235 | | cmp dword NODE:eax->i_key.nk.tt, LUA_TSTRING | ||
1236 | | jne >4 | ||
1237 | | cmp aword NODE:eax->i_key.nk.value, TSTRING:edx | ||
1238 | | jne >4 | ||
1239 | | // Note: swapping the two checks is faster, but valgrind complains. | ||
1240 | | | ||
1241 | |// Ok, key found. Copy new value to node value. | ||
1242 | | cmp dword NODE:eax->i_val.tt, LUA_TNIL // Previous value is nil? | ||
1243 | | je >6 | ||
1244 | | // Assumes: (int)&(((Node *)0)->i_val) == (int)&(((StkId)0)->value) | ||
1245 | |2: | ||
1246 | | mov byte TABLE:edi->flags, 0 // Clear metamethod cache. | ||
1247 | |3: // Target for SETTABLE_NUM below. | ||
1248 | | test byte TABLE:edi->marked, bitmask(BLACKBIT) // isblack(table) | ||
1249 | | jnz >8 // Unlikely, but set barrier back. | ||
1250 | |7: // Caveat: recycled label. | ||
1251 | | copyslot TVALUE:eax[0], BASE[0], ecx, edx, TOP | ||
1252 | | mov BASE, L->base | ||
1253 | | ret | ||
1254 | | | ||
1255 | |8: // Avoid valiswhite() check -- black2gray(table) is ok. | ||
1256 | | call ->BARRIERBACK | ||
1257 | | jmp <7 | ||
1258 | | | ||
1259 | |4: | ||
1260 | | mov NODE:eax, NODE:eax->i_key.nk.next // Get next key in chain. | ||
1261 | | test NODE:eax, NODE:eax | ||
1262 | | jnz <1 // Loop if non-NULL. | ||
1263 | | | ||
1264 | |// Key not found. Add a new one, but check metatable first. | ||
1265 | | mov TABLE:ecx, TABLE:edi->metatable | ||
1266 | | test TABLE:ecx, TABLE:ecx | ||
1267 | | jz >5 // No metatable? | ||
1268 | | test byte TABLE:ecx->flags, 1<<TM_NEWINDEX | ||
1269 | | jz >7 // Or 'no __newindex' flag set? | ||
1270 | | | ||
1271 | |5: // Add new key. | ||
1272 | | // No need for setting L->savedpc since only LUA_ERRMEM may be thrown. | ||
1273 | | lea TVALUE:eax, L->env | ||
1274 | | setsvalue TVALUE:eax[0], TSTRING:edx | ||
1275 | | sub esp, FRAME_OFFSET | ||
1276 | | call &luaH_newkey, L, TABLE:edi, TVALUE:eax | ||
1277 | | add esp, FRAME_OFFSET | ||
1278 | | jmp <2 // Copy to the returned value. See Node/TValue assumption above. | ||
1279 | | | ||
1280 | |6: // Key found, but previous value is nil. | ||
1281 | | mov TABLE:ecx, TABLE:edi->metatable | ||
1282 | | test TABLE:ecx, TABLE:ecx | ||
1283 | | jz <2 // No metatable? | ||
1284 | | test byte TABLE:ecx->flags, 1<<TM_NEWINDEX | ||
1285 | | jnz <2 // Or 'no __newindex' flag set? | ||
1286 | | | ||
1287 | |7: // Otherwise chain to C code which eventually calls luaV_settable. | ||
1288 | | setsvalue L->env, TSTRING:edx // Use L->env as temp key. | ||
1289 | | mov ecx, [esp] | ||
1290 | | sub esp, FRAME_OFFSET | ||
1291 | | mov L->savedpc, ecx | ||
1292 | | call &jit_settable_fb, L, TABLE:edi, BASE | ||
1293 | | add esp, FRAME_OFFSET | ||
1294 | | mov BASE, L->base | ||
1295 | | ret | ||
1296 | |.endjsub | ||
1297 | | | ||
1298 | |//----------------------------------------------------------------------- | ||
1299 | |.jsub SETTABLE_STR // Set string entry in table. | ||
1300 | |// Call with: TOP (tab), TVALUE:ecx (key), BASE (val) | ||
1301 | | mov eax, TOP->tt; shl eax, 4; or eax, TVALUE:ecx->tt | ||
1302 | | cmp eax, LUA_TTABLE_STR | ||
1303 | | mov TABLE:edi, TOP->value | ||
1304 | | mov TSTRING:edx, TVALUE:ecx->value | ||
1305 | | je <9 // Types ok? Continue above. | ||
1306 | | jmp ->DEOPTIMIZE_CALLER // Otherwise deoptimize. | ||
1307 | |.endjsub | ||
1308 | } | ||
1309 | |||
1310 | /* ------------------------------------------------------------------------ */ | ||
1311 | |||
1312 | static void jit_op_newtable(jit_State *J, int dest, int lnarray, int lnhash) | ||
1313 | { | ||
1314 | | call &luaH_new, L, luaO_fb2int(lnarray), luaO_fb2int(lnhash) | ||
1315 | | sethvalue BASE[dest], eax | ||
1316 | jit_checkGC(J); | ||
1317 | } | ||
1318 | |||
1319 | static void jit_op_getglobal(jit_State *J, int dest, int kidx) | ||
1320 | { | ||
1321 | const TValue *kk = &J->pt->k[kidx]; | ||
1322 | jit_assert(ttisstring(kk)); | ||
1323 | | mov TSTRING:edx, &&kk->value.gc->ts | ||
1324 | | addidx BASE, dest | ||
1325 | | call ->GETGLOBAL | ||
1326 | } | ||
1327 | |||
1328 | static void jit_op_setglobal(jit_State *J, int rval, int kidx) | ||
1329 | { | ||
1330 | const TValue *kk = &J->pt->k[kidx]; | ||
1331 | jit_assert(ttisstring(kk)); | ||
1332 | | mov TSTRING:edx, &&kk->value.gc->ts | ||
1333 | | addidx BASE, rval | ||
1334 | | call ->SETGLOBAL | ||
1335 | } | ||
1336 | |||
1337 | enum { TKEY_KSTR = -2, TKEY_STR = -1, TKEY_ANY = 0 }; | ||
1338 | |||
1339 | /* Optimize key lookup depending on consts or hints type. */ | ||
1340 | static int jit_keylookup(jit_State *J, int tab, int rkey) | ||
1341 | { | ||
1342 | const TValue *tabt = hint_get(J, TYPE); | ||
1343 | const TValue *key; | ||
1344 | if (!ttistable(tabt)) return TKEY_ANY; /* Not a table? Use fallback. */ | ||
1345 | key = ISK(rkey) ? &J->pt->k[INDEXK(rkey)] : hint_get(J, TYPEKEY); | ||
1346 | if (ttisstring(key)) { /* String key? */ | ||
1347 | if (ISK(rkey)) { | ||
1348 | | lea TOP, BASE[tab] | ||
1349 | | mov TSTRING:edx, &&key->value.gc->ts | ||
1350 | return TKEY_KSTR; /* Const string key. */ | ||
1351 | } else { | ||
1352 | | lea TOP, BASE[tab] | ||
1353 | | lea TVALUE:ecx, BASE[rkey] | ||
1354 | return TKEY_STR; /* Var string key. */ | ||
1355 | } | ||
1356 | } else if (ttisnumber(key)) { /* Number key? */ | ||
1357 | lua_Number n = nvalue(key); | ||
1358 | int k; | ||
1359 | lua_number2int(k, n); | ||
1360 | if (!(k >= 1 && k < (1 << 26) && (lua_Number)k == n)) | ||
1361 | return TKEY_ANY; /* Not a proper array key? Use fallback. */ | ||
1362 | if (ISK(rkey)) { | ||
1363 | | istable tab | ||
1364 | | mov TABLE:edi, BASE[tab].value | ||
1365 | | jne >9 // TYPE hint was wrong? | ||
1366 | | mov ecx, k // Needed for hash fallback. | ||
1367 | | mov TVALUE:eax, TABLE:edi->array | ||
1368 | | cmp ecx, TABLE:edi->sizearray; ja >5 // Not in array part? | ||
1369 | return k; /* Const array key (>= 1). */ | ||
1370 | } else { | ||
1371 | | mov eax, BASE[tab].tt; shl eax, 4; or eax, BASE[rkey].tt | ||
1372 | | cmp eax, LUA_TTABLE_NUM; jne >9 // TYPE/TYPEKEY hint was wrong? | ||
1373 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1374 | | movsd xmm0, qword BASE[rkey] | ||
1375 | | cvttsd2si eax, xmm0 | ||
1376 | | cvtsi2sd xmm1, eax | ||
1377 | | dec eax | ||
1378 | | ucomisd xmm1, xmm0 | ||
1379 | | mov TABLE:edi, BASE[tab].value | ||
1380 | | jne >9; jp >9 // Not an integer? Deoptimize. | ||
1381 | } else { | ||
1382 | |// Annoying x87 stuff: check whether a number is an integer. | ||
1383 | |// The latency of fist/fild is the real problem here. | ||
1384 | | fld qword BASE[rkey].value | ||
1385 | | fist dword TMP1 | ||
1386 | | fild dword TMP1 | ||
1387 | | fcomparepp // eax may be modified. | ||
1388 | | jne >9; jp >9 // Not an integer? Deoptimize. | ||
1389 | | mov eax, TMP1 | ||
1390 | | mov TABLE:edi, BASE[tab].value | ||
1391 | | dec eax | ||
1392 | } | ||
1393 | | cmp eax, TABLE:edi->sizearray; jae >5 // Not in array part? | ||
1394 | | TValuemul eax | ||
1395 | | add eax, TABLE:edi->array | ||
1396 | return 1; /* Variable array key. */ | ||
1397 | } | ||
1398 | } | ||
1399 | return TKEY_ANY; /* Use fallback. */ | ||
1400 | } | ||
1401 | |||
1402 | static void jit_op_gettable(jit_State *J, int dest, int tab, int rkey) | ||
1403 | { | ||
1404 | int k = jit_keylookup(J, tab, rkey); | ||
1405 | switch (k) { | ||
1406 | case TKEY_KSTR: /* Const string key. */ | ||
1407 | | addidx BASE, dest | ||
1408 | | call ->GETTABLE_KSTR | ||
1409 | break; | ||
1410 | case TKEY_STR: /* Variable string key. */ | ||
1411 | | addidx BASE, dest | ||
1412 | | call ->GETTABLE_STR | ||
1413 | break; | ||
1414 | case TKEY_ANY: /* Generic gettable fallback. */ | ||
1415 | if (ISK(rkey)) { | ||
1416 | | mov ecx, &&J->pt->k[INDEXK(rkey)] | ||
1417 | } else { | ||
1418 | | lea ecx, BASE[rkey] | ||
1419 | } | ||
1420 | | lea edx, BASE[tab] | ||
1421 | | addidx BASE, dest | ||
1422 | | mov L->savedpc, &J->nextins | ||
1423 | | call &luaV_gettable, L, edx, ecx, BASE | ||
1424 | | mov BASE, L->base | ||
1425 | break; | ||
1426 | default: /* Array key. */ | ||
1427 | |// This is really copyslot BASE[dest], TVALUE:eax[k-1] mixed with compare. | ||
1428 | |1: | ||
1429 | | mov edx, TVALUE:eax[k-1].tt | ||
1430 | | test edx, edx; je >6 // Array has nil value? | ||
1431 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1432 | | movq xmm0, qword TVALUE:eax[k-1].value | ||
1433 | | movq qword BASE[dest].value, xmm0 | ||
1434 | } else { | ||
1435 | | mov ecx, TVALUE:eax[k-1].value | ||
1436 | | mov eax, TVALUE:eax[k-1].value.na[1] | ||
1437 | | mov BASE[dest].value, ecx | ||
1438 | | mov BASE[dest].value.na[1], eax | ||
1439 | } | ||
1440 | |2: | ||
1441 | | mov BASE[dest].tt, edx | ||
1442 | |.tail | ||
1443 | |5: // Fallback to hash part. TABLE:edi is callee-saved. | ||
1444 | if (ISK(rkey)) { | ||
1445 | | call ->GETTABLE_KNUM | ||
1446 | } else { | ||
1447 | | call ->GETTABLE_NUM | ||
1448 | } | ||
1449 | | jmp <1 // Slot is at TVALUE:eax[k-1]. | ||
1450 | | | ||
1451 | |6: // Shortcut for tables without an __index metamethod. | ||
1452 | | mov TABLE:ecx, TABLE:edi->metatable | ||
1453 | | test TABLE:ecx, TABLE:ecx | ||
1454 | | jz <2 // No metatable? | ||
1455 | | test byte TABLE:ecx->flags, 1<<TM_INDEX | ||
1456 | | jnz <2 // Or 'no __index' flag set? | ||
1457 | | | ||
1458 | |9: // Otherwise deoptimize. | ||
1459 | | mov edx, &J->nextins | ||
1460 | | jmp ->DEOPTIMIZE | ||
1461 | |.code | ||
1462 | break; | ||
1463 | } | ||
1464 | |||
1465 | |.jsub GETTABLE_KNUM // Gettable fallback for const numeric keys. | ||
1466 | | mov TMP2, ecx // Save k. | ||
1467 | | sub esp, FRAME_OFFSET | ||
1468 | | call &luaH_getnum, TABLE:edi, ecx | ||
1469 | | add esp, FRAME_OFFSET | ||
1470 | | mov ecx, TMP2 // Restore k. | ||
1471 | | TValuemul ecx | ||
1472 | | sub TVALUE:eax, ecx // Compensate for TVALUE:eax[k-1]. | ||
1473 | | add TVALUE:eax, #TVALUE | ||
1474 | | ret | ||
1475 | |.endjsub | ||
1476 | | | ||
1477 | |.jsub GETTABLE_NUM // Gettable fallback for variable numeric keys. | ||
1478 | | inc eax | ||
1479 | | mov ARG2, TABLE:edi // Really ARG1 and ARG2. | ||
1480 | | mov ARG3, eax | ||
1481 | | jmp &luaH_getnum // Chain to C code. | ||
1482 | |.endjsub | ||
1483 | } | ||
1484 | |||
1485 | static void jit_op_settable(jit_State *J, int tab, int rkey, int rval) | ||
1486 | { | ||
1487 | const TValue *val = ISK(rval) ? &J->pt->k[INDEXK(rval)] : NULL; | ||
1488 | int k = jit_keylookup(J, tab, rkey); | ||
1489 | switch (k) { | ||
1490 | case TKEY_KSTR: /* Const string key. */ | ||
1491 | case TKEY_STR: /* Variable string key. */ | ||
1492 | if (ISK(rval)) { | ||
1493 | | mov BASE, &val | ||
1494 | } else { | ||
1495 | | addidx BASE, rval | ||
1496 | } | ||
1497 | if (k == TKEY_KSTR) { | ||
1498 | | call ->SETTABLE_KSTR | ||
1499 | } else { | ||
1500 | | call ->SETTABLE_STR | ||
1501 | } | ||
1502 | break; | ||
1503 | case TKEY_ANY: /* Generic settable fallback. */ | ||
1504 | if (ISK(rkey)) { | ||
1505 | | mov ecx, &&J->pt->k[INDEXK(rkey)] | ||
1506 | } else { | ||
1507 | | lea ecx, BASE[rkey] | ||
1508 | } | ||
1509 | if (ISK(rval)) { | ||
1510 | | mov edx, &val | ||
1511 | } else { | ||
1512 | | lea edx, BASE[rval] | ||
1513 | } | ||
1514 | | addidx BASE, tab | ||
1515 | | mov L->savedpc, &J->nextins | ||
1516 | | call &luaV_settable, L, BASE, ecx, edx | ||
1517 | | mov BASE, L->base | ||
1518 | break; | ||
1519 | default: /* Array key. */ | ||
1520 | |1: | ||
1521 | | tvisnil TVALUE:eax[k-1]; je >6 // Previous value is nil? | ||
1522 | |2: | ||
1523 | |.tail | ||
1524 | |5: // Fallback to hash part. TABLE:edi is callee-saved. | ||
1525 | if (ISK(rkey)) { | ||
1526 | | call ->SETTABLE_KNUM | ||
1527 | } else { | ||
1528 | | call ->SETTABLE_NUM | ||
1529 | } | ||
1530 | | jmp <1 // Slot is at TVALUE:eax[k-1]. | ||
1531 | | | ||
1532 | |6: // Shortcut for tables without a __newindex metamethod. | ||
1533 | | mov TABLE:ecx, TABLE:edi->metatable | ||
1534 | | test TABLE:ecx, TABLE:ecx | ||
1535 | | jz <2 // No metatable? | ||
1536 | | test byte TABLE:ecx->flags, 1<<TM_NEWINDEX | ||
1537 | | jnz <2 // Or 'no __newindex' flag set? | ||
1538 | | | ||
1539 | |9: // Otherwise deoptimize. | ||
1540 | | mov edx, &J->nextins | ||
1541 | | jmp ->DEOPTIMIZE | ||
1542 | |.code | ||
1543 | if (!ISK(rval) || iscollectable(val)) { | ||
1544 | | test byte TABLE:edi->marked, bitmask(BLACKBIT) // isblack(table) | ||
1545 | | jnz >7 // Unlikely, but set barrier back. | ||
1546 | |3: | ||
1547 | |.tail | ||
1548 | |7: // Avoid valiswhite() check -- black2gray(table) is ok. | ||
1549 | | call ->BARRIERBACK | ||
1550 | | jmp <3 | ||
1551 | |.code | ||
1552 | } | ||
1553 | if (ISK(rval)) { | ||
1554 | | copyconst TVALUE:eax[k-1], val | ||
1555 | } else { | ||
1556 | | copyslot TVALUE:eax[k-1], BASE[rval], ecx, edx, TOP | ||
1557 | } | ||
1558 | break; | ||
1559 | } | ||
1560 | |||
1561 | |.jsub SETTABLE_KNUM // Settable fallback for const numeric keys. | ||
1562 | | mov TMP2, ecx // Save k. | ||
1563 | | sub esp, FRAME_OFFSET | ||
1564 | | call &luaH_setnum, L, TABLE:edi, ecx | ||
1565 | | add esp, FRAME_OFFSET | ||
1566 | | mov ecx, TMP2 // Restore k. | ||
1567 | | TValuemul ecx | ||
1568 | | sub TVALUE:eax, ecx // Compensate for TVALUE:eax[k-1]. | ||
1569 | | add TVALUE:eax, #TVALUE | ||
1570 | | ret | ||
1571 | |.endjsub | ||
1572 | | | ||
1573 | |.jsub SETTABLE_NUM // Settable fallback for variable numeric keys. | ||
1574 | | inc eax | ||
1575 | | mov ARG2, L // Really ARG1, ARG2 and ARG3. | ||
1576 | | mov ARG3, TABLE:edi | ||
1577 | | mov ARG4, eax | ||
1578 | | jmp &luaH_setnum // Chain to C code. | ||
1579 | |.endjsub | ||
1580 | } | ||
1581 | |||
1582 | static void jit_op_self(jit_State *J, int dest, int tab, int rkey) | ||
1583 | { | ||
1584 | | copyslot BASE[dest+1], BASE[tab] | ||
1585 | jit_op_gettable(J, dest, tab, rkey); | ||
1586 | } | ||
1587 | |||
1588 | /* ------------------------------------------------------------------------ */ | ||
1589 | |||
1590 | static void jit_op_setlist(jit_State *J, int ra, int num, int batch) | ||
1591 | { | ||
1592 | if (batch == 0) { batch = (int)(*J->nextins); J->combine++; } | ||
1593 | batch = (batch-1)*LFIELDS_PER_FLUSH; | ||
1594 | if (num == 0) { /* Previous op was open and set TOP: {f()} or {...}. */ | ||
1595 | | mov L->env.value, TOP // Need to save TOP (edi). | ||
1596 | | lea eax, BASE[ra+1] | ||
1597 | | sub eax, TOP | ||
1598 | | neg eax | ||
1599 | | TValuediv eax // num = (TOP-ra-1)/sizeof(TValue). | ||
1600 | | mov TABLE:edi, BASE[ra].value | ||
1601 | | jz >4 // Nothing to set? | ||
1602 | if (batch > 0) { | ||
1603 | | add eax, batch | ||
1604 | } | ||
1605 | | cmp dword TABLE:edi->sizearray, eax | ||
1606 | | jae >1 // Skip resize if not needed. | ||
1607 | | // A resize is likely, so inline it. | ||
1608 | | call &luaH_resizearray, L, TABLE:edi, eax | ||
1609 | |1: | ||
1610 | | test byte TABLE:edi->marked, bitmask(BLACKBIT) // isblack(table) | ||
1611 | | mov edx, TABLE:edi->array | ||
1612 | | jnz >6 // Unlikely, but set barrier back. | ||
1613 | | mov TOP, L->env.value | ||
1614 | | | ||
1615 | |.tail | ||
1616 | |6: // Avoid lots of valiswhite() checks -- black2gray(table) is ok. | ||
1617 | | call ->BARRIERBACK | ||
1618 | | jmp <1 // Need to reload edx. | ||
1619 | |.code | ||
1620 | } else { /* Set fixed number of args. */ | ||
1621 | | mov TABLE:edi, BASE[ra].value // edi is callee-save. | ||
1622 | | cmp dword TABLE:edi->sizearray, batch+num | ||
1623 | | jb >5 // Need to resize array? | ||
1624 | |1: | ||
1625 | | test byte TABLE:edi->marked, bitmask(BLACKBIT) // isblack(table) | ||
1626 | | mov edx, TABLE:edi->array | ||
1627 | | jnz >6 // Unlikely, but set barrier back. | ||
1628 | | lea TOP, BASE[ra+1+num] // Careful: TOP is edi. | ||
1629 | | | ||
1630 | |.tail | ||
1631 | |5: // A resize is unlikely (impossible?). NEWTABLE should've done it. | ||
1632 | | call &luaH_resizearray, L, TABLE:edi, batch+num | ||
1633 | | jmp <1 | ||
1634 | |6: // Avoid lots of valiswhite() checks -- black2gray(table) is ok. | ||
1635 | | call ->BARRIERBACK | ||
1636 | | jmp <1 // Need to reload edx. | ||
1637 | |.code | ||
1638 | } | ||
1639 | if (batch > 0) { | ||
1640 | | add edx, batch*#TVALUE // edx = &t->array[(batch+1)-1] | ||
1641 | } | ||
1642 | | lea ecx, BASE[ra+1] | ||
1643 | |3: // Copy stack slots to array. | ||
1644 | | mov eax, [ecx] | ||
1645 | | add ecx, aword*1 | ||
1646 | | mov [edx], eax | ||
1647 | | add edx, aword*1 | ||
1648 | | cmp ecx, TOP | ||
1649 | | jb <3 | ||
1650 | | | ||
1651 | |4: | ||
1652 | if (num == 0) { /* Previous op was open. Restore L->top. */ | ||
1653 | | lea TOP, BASE[J->pt->maxstacksize] // Faster than getting L->ci->top. | ||
1654 | | mov L->top, TOP | ||
1655 | } | ||
1656 | } | ||
1657 | |||
1658 | /* ------------------------------------------------------------------------ */ | ||
1659 | |||
1660 | static void jit_op_arith(jit_State *J, int dest, int rkb, int rkc, int ev) | ||
1661 | { | ||
1662 | const TValue *kkb = ISK(rkb) ? &J->pt->k[INDEXK(rkb)] : NULL; | ||
1663 | const TValue *kkc = ISK(rkc) ? &J->pt->k[INDEXK(rkc)] : NULL; | ||
1664 | const Value *kval; | ||
1665 | int idx, rev; | ||
1666 | int target = (ev == TM_LT || ev == TM_LE) ? jit_jmp_target(J) : 0; | ||
1667 | int hastail = 0; | ||
1668 | |||
1669 | /* The bytecode compiler already folds constants except for: k/0, k%0, */ | ||
1670 | /* NaN results, k1<k2, k1<=k2. No point in optimizing these cases. */ | ||
1671 | if (ISK(rkb&rkc)) goto fallback; | ||
1672 | |||
1673 | /* Avoid optimization when non-numeric constants are present. */ | ||
1674 | if (kkb ? !ttisnumber(kkb) : (kkc && !ttisnumber(kkc))) goto fallback; | ||
1675 | |||
1676 | /* The TYPE hint selects numeric inlining and/or fallback encoding. */ | ||
1677 | switch (ttype(hint_get(J, TYPE))) { | ||
1678 | case LUA_TNIL: hastail = 1; break; /* No hint: numeric + fallback. */ | ||
1679 | case LUA_TNUMBER: break; /* Numbers: numeric + deoptimization. */ | ||
1680 | default: goto fallback; /* Mixed/other types: fallback only. */ | ||
1681 | } | ||
1682 | |||
1683 | /* The checks above ensure: at most one of the operands is a constant. */ | ||
1684 | /* Reverse operation and swap operands so the 2nd operand is a variable. */ | ||
1685 | if (kkc) { kval = &kkc->value; idx = rkb; rev = 1; } | ||
1686 | else { kval = kkb ? &kkb->value : NULL; idx = rkc; rev = 0; } | ||
1687 | |||
1688 | /* Special handling for some operators. */ | ||
1689 | switch (ev) { | ||
1690 | case TM_MOD: | ||
1691 | /* Check for modulo with positive numbers, so we can use fprem. */ | ||
1692 | if (kval) { | ||
1693 | if (kval->na[1] < 0) { hastail = 0; goto fallback; } /* x%-k, -k%x */ | ||
1694 | | isnumber idx | ||
1695 | | mov eax, BASE[idx].value.na[1] | ||
1696 | | jne L_DEOPTIMIZEF | ||
1697 | | test eax, eax; js L_DEOPTIMIZEF | ||
1698 | |// This will trigger deoptimization in some benchmarks (pidigits). | ||
1699 | |// But it's still a win. | ||
1700 | if (kkb) { | ||
1701 | | fld qword BASE[rkc].value | ||
1702 | | fld qword [kval] | ||
1703 | } else { | ||
1704 | | fld qword [kval] | ||
1705 | | fld qword BASE[rkb].value | ||
1706 | } | ||
1707 | } else { | ||
1708 | | isnumber2 rkb, rkc | ||
1709 | | mov eax, BASE[rkb].value.na[1] | ||
1710 | | jne L_DEOPTIMIZEF | ||
1711 | | or eax, BASE[rkc].value.na[1]; js L_DEOPTIMIZEF | ||
1712 | | fld qword BASE[rkc].value | ||
1713 | | fld qword BASE[rkb].value | ||
1714 | } | ||
1715 | |1: ; fprem; fnstsw ax; sahf; jp <1 | ||
1716 | | fstp st1 | ||
1717 | goto fpstore; | ||
1718 | case TM_POW: | ||
1719 | if (hastail || !kval) break; /* Avoid this if not optimizing. */ | ||
1720 | if (rev) { /* x^k for k > 0, k integer. */ | ||
1721 | lua_Number n = kval->n; | ||
1722 | int k; | ||
1723 | lua_number2int(k, n); | ||
1724 | /* All positive integers would work. But need to limit code explosion. */ | ||
1725 | if (k > 0 && k <= 65536 && (lua_Number)k == n) { | ||
1726 | | isnumber idx; jne L_DEOPTIMIZEF | ||
1727 | | fld qword BASE[idx] | ||
1728 | for (; (k & 1) == 0; k >>= 1) { /* Handle leading zeroes (2^k). */ | ||
1729 | | fmul st0 | ||
1730 | } | ||
1731 | if ((k >>= 1) != 0) { /* Handle trailing bits. */ | ||
1732 | | fld st0 | ||
1733 | | fmul st0 | ||
1734 | for (; k != 1; k >>= 1) { | ||
1735 | if (k & 1) { | ||
1736 | | fmul st1, st0 | ||
1737 | } | ||
1738 | | fmul st0 | ||
1739 | } | ||
1740 | | fmulp st1 | ||
1741 | } | ||
1742 | goto fpstore; | ||
1743 | } | ||
1744 | } else if (kval->n > (lua_Number)0) { /* k^x for k > 0. */ | ||
1745 | int log2kval[3]; /* Enough storage for a tword (80 bits). */ | ||
1746 | log2kval[2] = 0; /* Avoid leaking garbage. */ | ||
1747 | /* Double precision log2(k) doesn't cut it (3^x != 3 for x = 1). */ | ||
1748 | ((void (*)(int *, double))J->jsub[JSUB_LOG2_TWORD])(log2kval, kval->n); | ||
1749 | | mov ARG1, log2kval[0] // Abuse stack for tword const. | ||
1750 | | mov ARG2, log2kval[1] | ||
1751 | | mov ARG3, log2kval[2] // TODO: store2load fwd stall. | ||
1752 | | isnumber idx; jne L_DEOPTIMIZEF | ||
1753 | | fld tword [esp] | ||
1754 | | fmul qword BASE[idx].value // log2(k)*x | ||
1755 | | fld st0; frndint; fsub st1, st0; fxch // Split into fract/int part. | ||
1756 | | f2xm1; fld1; faddp st1; fscale // (2^fract-1 +1) << int. | ||
1757 | | fstp st1 | ||
1758 | |||
1759 | |.jsub LOG2_TWORD // Calculate log2(k) with max. precision. | ||
1760 | |// Called with (int *ptr, double k). | ||
1761 | | fld1; fld FPARG2 // Offset ok due to retaddr. | ||
1762 | | fyl2x | ||
1763 | | mov eax, ARG2 // Really ARG1. | ||
1764 | | fstp tword [eax] | ||
1765 | | ret | ||
1766 | |.endjsub | ||
1767 | goto fpstore; | ||
1768 | } | ||
1769 | break; | ||
1770 | } | ||
1771 | |||
1772 | /* Check number type and load 1st operand. */ | ||
1773 | if (kval) { | ||
1774 | | isnumber idx; jne L_DEOPTIMIZEF | ||
1775 | | loadnvaluek kval | ||
1776 | } else { | ||
1777 | if (rkb == rkc) { | ||
1778 | | isnumber rkb | ||
1779 | } else { | ||
1780 | | isnumber2 rkb, rkc | ||
1781 | } | ||
1782 | | jne L_DEOPTIMIZEF | ||
1783 | | fld qword BASE[rkb].value | ||
1784 | } | ||
1785 | |||
1786 | /* Encode arithmetic operation with 2nd operand. */ | ||
1787 | switch ((ev<<1)+rev) { | ||
1788 | case TM_ADD<<1: case (TM_ADD<<1)+1: | ||
1789 | if (rkb == rkc) { | ||
1790 | | fadd st0 | ||
1791 | } else { | ||
1792 | | fadd qword BASE[idx].value | ||
1793 | } | ||
1794 | break; | ||
1795 | case TM_SUB<<1: | ||
1796 | | fsub qword BASE[idx].value | ||
1797 | break; | ||
1798 | case (TM_SUB<<1)+1: | ||
1799 | | fsubr qword BASE[idx].value | ||
1800 | break; | ||
1801 | case TM_MUL<<1: case (TM_MUL<<1)+1: | ||
1802 | if (rkb == rkc) { | ||
1803 | | fmul st0 | ||
1804 | } else { | ||
1805 | | fmul qword BASE[idx].value | ||
1806 | } | ||
1807 | break; | ||
1808 | case TM_DIV<<1: | ||
1809 | | fdiv qword BASE[idx].value | ||
1810 | break; | ||
1811 | case (TM_DIV<<1)+1: | ||
1812 | | fdivr qword BASE[idx].value | ||
1813 | break; | ||
1814 | case TM_POW<<1: | ||
1815 | | sub esp, S2LFRAME_OFFSET | ||
1816 | | fstp FPARG1 | ||
1817 | | fld qword BASE[idx].value | ||
1818 | | fstp FPARG2 | ||
1819 | | call &pow | ||
1820 | | add esp, S2LFRAME_OFFSET | ||
1821 | break; | ||
1822 | case (TM_POW<<1)+1: | ||
1823 | | sub esp, S2LFRAME_OFFSET | ||
1824 | | fstp FPARG2 | ||
1825 | | fld qword BASE[idx].value | ||
1826 | | fstp FPARG1 | ||
1827 | | call &pow | ||
1828 | | add esp, S2LFRAME_OFFSET | ||
1829 | break; | ||
1830 | case TM_UNM<<1: case (TM_UNM<<1)+1: | ||
1831 | | fchs // No 2nd operand. | ||
1832 | break; | ||
1833 | default: /* TM_LT or TM_LE. */ | ||
1834 | | fld qword BASE[idx].value | ||
1835 | | fcomparepp | ||
1836 | | jp =>dest?(J->nextpc+1):target // Unordered means false. | ||
1837 | jit_assert(dest == 0 || dest == 1); /* Really cond. */ | ||
1838 | switch (((rev^dest)<<1)+(dest^(ev == TM_LT))) { | ||
1839 | case 0: | ||
1840 | | jb =>target | ||
1841 | break; | ||
1842 | case 1: | ||
1843 | | jbe =>target | ||
1844 | break; | ||
1845 | case 2: | ||
1846 | | ja =>target | ||
1847 | break; | ||
1848 | case 3: | ||
1849 | | jae =>target | ||
1850 | break; | ||
1851 | } | ||
1852 | goto skipstore; | ||
1853 | } | ||
1854 | fpstore: | ||
1855 | /* Store result and set result type (if necessary). */ | ||
1856 | | fstp qword BASE[dest].value | ||
1857 | if (dest != rkb && dest != rkc) { | ||
1858 | | settt BASE[dest], LUA_TNUMBER | ||
1859 | } | ||
1860 | |||
1861 | skipstore: | ||
1862 | if (!hastail) { | ||
1863 | jit_deopt_target(J, 0); | ||
1864 | return; | ||
1865 | } | ||
1866 | |||
1867 | |4: | ||
1868 | |.tail | ||
1869 | |L_DEOPTLABEL: // Recycle as fallback label. | ||
1870 | |||
1871 | fallback: | ||
1872 | /* Generic fallback for arithmetic ops. */ | ||
1873 | if (kkb) { | ||
1874 | | mov ecx, &kkb | ||
1875 | } else { | ||
1876 | | lea ecx, BASE[rkb] | ||
1877 | } | ||
1878 | if (kkc) { | ||
1879 | | mov edx, &kkc | ||
1880 | } else { | ||
1881 | | lea edx, BASE[rkc] | ||
1882 | } | ||
1883 | if (target) { /* TM_LT or TM_LE. */ | ||
1884 | | mov L->savedpc, &(J->nextins+1) | ||
1885 | | call &ev==TM_LT?luaV_lessthan:luaV_lessequal, L, ecx, edx | ||
1886 | | test eax, eax | ||
1887 | | mov BASE, L->base | ||
1888 | if (dest) { /* cond */ | ||
1889 | | jnz =>target | ||
1890 | } else { | ||
1891 | | jz =>target | ||
1892 | } | ||
1893 | } else { | ||
1894 | | addidx BASE, dest | ||
1895 | | mov L->savedpc, &J->nextins | ||
1896 | | call &luaV_arith, L, BASE, ecx, edx, ev | ||
1897 | | mov BASE, L->base | ||
1898 | } | ||
1899 | |||
1900 | if (hastail) { | ||
1901 | | jmp <4 | ||
1902 | |.code | ||
1903 | } | ||
1904 | } | ||
1905 | |||
1906 | /* ------------------------------------------------------------------------ */ | ||
1907 | |||
1908 | static void jit_fallback_len(lua_State *L, StkId ra, const TValue *rb) | ||
1909 | { | ||
1910 | switch (ttype(rb)) { | ||
1911 | case LUA_TTABLE: | ||
1912 | setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); | ||
1913 | break; | ||
1914 | case LUA_TSTRING: | ||
1915 | setnvalue(ra, cast_num(tsvalue(rb)->len)); | ||
1916 | break; | ||
1917 | default: { | ||
1918 | const TValue *tm = luaT_gettmbyobj(L, rb, TM_LEN); | ||
1919 | if (ttisfunction(tm)) { | ||
1920 | ptrdiff_t rasave = savestack(L, ra); | ||
1921 | setobj2s(L, L->top, tm); | ||
1922 | setobj2s(L, L->top+1, rb); | ||
1923 | luaD_checkstack(L, 2); | ||
1924 | L->top += 2; | ||
1925 | luaD_call(L, L->top - 2, 1); | ||
1926 | ra = restorestack(L, rasave); | ||
1927 | L->top--; | ||
1928 | setobjs2s(L, ra, L->top); | ||
1929 | } else { | ||
1930 | luaG_typeerror(L, rb, "get length of"); | ||
1931 | } | ||
1932 | break; | ||
1933 | } | ||
1934 | } | ||
1935 | } | ||
1936 | |||
1937 | static void jit_op_len(jit_State *J, int dest, int rb) | ||
1938 | { | ||
1939 | switch (ttype(hint_get(J, TYPE))) { | ||
1940 | case LUA_TTABLE: | ||
1941 | jit_deopt_target(J, 0); | ||
1942 | | istable rb | ||
1943 | | mov TABLE:ecx, BASE[rb].value | ||
1944 | | jne L_DEOPTIMIZE // TYPE hint was wrong? | ||
1945 | | call &luaH_getn, TABLE:ecx | ||
1946 | | mov TMP1, eax | ||
1947 | | fild dword TMP1 | ||
1948 | | fstp qword BASE[dest].value | ||
1949 | | settt BASE[dest], LUA_TNUMBER | ||
1950 | break; | ||
1951 | case LUA_TSTRING: | ||
1952 | jit_deopt_target(J, 0); | ||
1953 | | isstring rb | ||
1954 | | mov TSTRING:ecx, BASE[rb].value | ||
1955 | | jne L_DEOPTIMIZE // TYPE hint was wrong? | ||
1956 | | fild aword TSTRING:ecx->tsv.len // size_t | ||
1957 | | fstp qword BASE[dest].value | ||
1958 | | settt BASE[dest], LUA_TNUMBER | ||
1959 | break; | ||
1960 | default: | ||
1961 | | lea TVALUE:ecx, BASE[rb] | ||
1962 | | addidx BASE, dest | ||
1963 | | mov L->savedpc, &J->nextins | ||
1964 | | call &jit_fallback_len, L, BASE, TVALUE:ecx | ||
1965 | | mov BASE, L->base | ||
1966 | break; | ||
1967 | } | ||
1968 | } | ||
1969 | |||
1970 | static void jit_op_not(jit_State *J, int dest, int rb) | ||
1971 | { | ||
1972 | /* l_isfalse() without a branch -- truly devious. */ | ||
1973 | /* ((value & tt) | (tt>>1)) is only zero for nil/false. */ | ||
1974 | /* Assumes: LUA_TNIL == 0, LUA_TBOOLEAN == 1, bvalue() == 0/1 */ | ||
1975 | | mov eax, BASE[rb].tt | ||
1976 | | mov ecx, BASE[rb].value | ||
1977 | | mov edx, 1 | ||
1978 | | and ecx, eax | ||
1979 | | shr eax, 1 | ||
1980 | | or ecx, eax | ||
1981 | | xor eax, eax | ||
1982 | | cmp ecx, edx | ||
1983 | | adc eax, eax | ||
1984 | | mov BASE[dest].tt, edx | ||
1985 | | mov BASE[dest].value, eax | ||
1986 | } | ||
1987 | |||
1988 | /* ------------------------------------------------------------------------ */ | ||
1989 | |||
1990 | static void jit_op_concat(jit_State *J, int dest, int first, int last) | ||
1991 | { | ||
1992 | int num = last-first+1; | ||
1993 | if (num == 2 && ttisstring(hint_get(J, TYPE))) { /* Optimize common case. */ | ||
1994 | | addidx BASE, first | ||
1995 | | call ->CONCAT_STR2 | ||
1996 | | setsvalue BASE[dest], eax | ||
1997 | } else { /* Generic fallback. */ | ||
1998 | | mov L->savedpc, &J->nextins | ||
1999 | | call &luaV_concat, L, num, last | ||
2000 | | mov BASE, L->base | ||
2001 | if (dest != first) { | ||
2002 | | copyslot BASE[dest], BASE[first] | ||
2003 | } | ||
2004 | } | ||
2005 | jit_checkGC(J); /* Always do this, even for the optimized variant. */ | ||
2006 | |||
2007 | |.jsub CONCAT_STR2 // Concatenate two strings. | ||
2008 | |// Call with: BASE (first). Destroys all regs. L and BASE restored. | ||
2009 | | mov ARG2, L // Save L (esi). | ||
2010 | | mov eax, BASE[0].tt; shl eax, 4; or eax, BASE[1].tt | ||
2011 | | sub eax, LUA_TSTR_STR // eax = 0 on success. | ||
2012 | | jne ->DEOPTIMIZE_CALLER // Wrong types? Deoptimize. | ||
2013 | | | ||
2014 | |1: | ||
2015 | | mov GL:edi, L->l_G | ||
2016 | | mov TSTRING:esi, BASE[0].value // Caveat: L (esi) is gone now! | ||
2017 | | mov TSTRING:edx, BASE[1].value | ||
2018 | | mov ecx, TSTRING:esi->tsv.len // size_t | ||
2019 | | test ecx, ecx | ||
2020 | | jz >2 // 1st string is empty? | ||
2021 | | or eax, TSTRING:edx->tsv.len // eax is known to be zero. | ||
2022 | | jz >4 // 2nd string is empty? | ||
2023 | | add eax, ecx | ||
2024 | | jc >9 // Length overflow? | ||
2025 | | cmp eax, GL:edi->buff.buffsize // size_t | ||
2026 | | ja >5 // Temp buffer overflow? | ||
2027 | | mov edi, GL:edi->buff.buffer | ||
2028 | | add esi, #TSTRING | ||
2029 | | rep; movsb // Copy first string. | ||
2030 | | mov ecx, TSTRING:edx->tsv.len | ||
2031 | | lea esi, TSTRING:edx[1] | ||
2032 | | rep; movsb // Copy second string. | ||
2033 | | | ||
2034 | | sub edi, eax // start = end - total. | ||
2035 | | mov L, ARG2 // Restore L (esi). Reuse as 1st arg. | ||
2036 | | mov ARG3, edi | ||
2037 | | mov ARG4, eax | ||
2038 | | mov BASE, L->base // Restore BASE. | ||
2039 | | jmp &luaS_newlstr | ||
2040 | | | ||
2041 | |2: // 1st string is empty. | ||
2042 | | mov eax, TSTRING:edx // Return 2nd string. | ||
2043 | |3: | ||
2044 | | mov L, ARG2 // Restore L (esi) and BASE. | ||
2045 | | mov BASE, L->base | ||
2046 | | ret | ||
2047 | | | ||
2048 | |4: // 2nd string is empty. | ||
2049 | | mov eax, TSTRING:esi // Return 1st string. | ||
2050 | | jmp <3 | ||
2051 | | | ||
2052 | |5: // Resize temp buffer. | ||
2053 | | // No need for setting L->savedpc since only LUA_ERRMEM may be thrown. | ||
2054 | | mov L, ARG2 // Restore L. | ||
2055 | | lea ecx, GL:edi->buff | ||
2056 | | sub esp, FRAME_OFFSET | ||
2057 | | call &luaZ_openspace, L, ecx, eax | ||
2058 | | add esp, FRAME_OFFSET | ||
2059 | | xor eax, eax // BASE (first) and L saved. eax = 0. | ||
2060 | | jmp <1 // Just restart. | ||
2061 | | | ||
2062 | |9: // Length overflow errors are rare (> 2 GB string required). | ||
2063 | | mov L, ARG2 // Need L for deoptimization. | ||
2064 | | jmp ->DEOPTIMIZE_CALLER | ||
2065 | |.endjsub | ||
2066 | } | ||
2067 | |||
2068 | /* ------------------------------------------------------------------------ */ | ||
2069 | |||
2070 | static void jit_op_eq(jit_State *J, int cond, int rkb, int rkc) | ||
2071 | { | ||
2072 | int target = jit_jmp_target(J); | ||
2073 | int condtarget = cond ? (J->nextpc+1) : target; | ||
2074 | jit_assert(cond == 0 || cond == 1); | ||
2075 | |||
2076 | /* Comparison of two constants. Evaluate at compile time. */ | ||
2077 | if (ISK(rkb&rkc)) { | ||
2078 | if ((rkb == rkc) == cond) { /* Constants are already unique. */ | ||
2079 | | jmp =>target | ||
2080 | } | ||
2081 | return; | ||
2082 | } | ||
2083 | |||
2084 | if (ISK(rkb|rkc)) { /* Compare a variable and a constant. */ | ||
2085 | const TValue *kk; | ||
2086 | if (ISK(rkb)) { int t = rkc; rkc = rkb; rkb = t; } /* rkc holds const. */ | ||
2087 | kk = &J->pt->k[INDEXK(rkc)]; | ||
2088 | switch (ttype(kk)) { | ||
2089 | case LUA_TNIL: | ||
2090 | | isnil rkb | ||
2091 | break; | ||
2092 | case LUA_TBOOLEAN: | ||
2093 | if (bvalue(kk)) { | ||
2094 | | mov eax, BASE[rkb].tt | ||
2095 | | mov ecx, BASE[rkb].value | ||
2096 | | dec eax | ||
2097 | | dec ecx | ||
2098 | | or eax, ecx | ||
2099 | } else { | ||
2100 | | mov eax, BASE[rkb].tt | ||
2101 | | dec eax | ||
2102 | | or eax, BASE[rkb].value | ||
2103 | } | ||
2104 | break; | ||
2105 | case LUA_TNUMBER: | ||
2106 | |// Note: bitwise comparison is not faster (and needs to handle -0 == 0). | ||
2107 | | isnumber rkb | ||
2108 | | jne =>condtarget | ||
2109 | | fld qword BASE[rkb].value | ||
2110 | | fld qword [&kk->value] | ||
2111 | | fcomparepp | ||
2112 | | jp =>condtarget // Unordered means not equal. | ||
2113 | break; | ||
2114 | case LUA_TSTRING: | ||
2115 | | isstring rkb | ||
2116 | | jne =>condtarget | ||
2117 | | cmp aword BASE[rkb].value, &rawtsvalue(kk) | ||
2118 | break; | ||
2119 | default: jit_assert(0); break; | ||
2120 | } | ||
2121 | } else { /* Compare two variables. */ | ||
2122 | | mov eax, BASE[rkb].tt | ||
2123 | | cmp eax, BASE[rkc].tt | ||
2124 | | jne =>condtarget | ||
2125 | switch (ttype(hint_get(J, TYPE))) { | ||
2126 | case LUA_TNUMBER: | ||
2127 | jit_deopt_target(J, 0); | ||
2128 | |// Note: bitwise comparison is not an option (-0 == 0, NaN ~= NaN). | ||
2129 | | cmp eax, LUA_TNUMBER; jne L_DEOPTIMIZE | ||
2130 | | fld qword BASE[rkb].value | ||
2131 | | fld qword BASE[rkc].value | ||
2132 | | fcomparepp | ||
2133 | | jp =>condtarget // Unordered means not equal. | ||
2134 | break; | ||
2135 | case LUA_TSTRING: | ||
2136 | jit_deopt_target(J, 0); | ||
2137 | | cmp eax, LUA_TSTRING; jne L_DEOPTIMIZE | ||
2138 | | mov ecx, BASE[rkb].value | ||
2139 | | cmp ecx, BASE[rkc].value | ||
2140 | break; | ||
2141 | default: | ||
2142 | |// Generic equality comparison fallback. | ||
2143 | | lea edx, BASE[rkc] | ||
2144 | | lea ecx, BASE[rkb] | ||
2145 | | mov L->savedpc, &J->nextins | ||
2146 | | call &luaV_equalval, L, ecx, edx | ||
2147 | | dec eax | ||
2148 | | mov BASE, L->base | ||
2149 | break; | ||
2150 | } | ||
2151 | } | ||
2152 | if (cond) { | ||
2153 | | je =>target | ||
2154 | } else { | ||
2155 | | jne =>target | ||
2156 | } | ||
2157 | } | ||
2158 | |||
2159 | /* ------------------------------------------------------------------------ */ | ||
2160 | |||
2161 | static void jit_op_test(jit_State *J, int cond, int dest, int src) | ||
2162 | { | ||
2163 | int target = jit_jmp_target(J); | ||
2164 | |||
2165 | /* l_isfalse() without a branch. But this time preserve tt/value. */ | ||
2166 | /* (((value & tt) * 2 + tt) >> 1) is only zero for nil/false. */ | ||
2167 | /* Assumes: 3*tt < 2^32, LUA_TNIL == 0, LUA_TBOOLEAN == 1, bvalue() == 0/1 */ | ||
2168 | | mov eax, BASE[src].tt | ||
2169 | | mov ecx, BASE[src].value | ||
2170 | | mov edx, eax | ||
2171 | | and edx, ecx | ||
2172 | | lea edx, [eax+edx*2] | ||
2173 | | shr edx, 1 | ||
2174 | |||
2175 | /* Check if we can omit the stack copy. */ | ||
2176 | if (dest == src) { /* Yes, invert branch condition. */ | ||
2177 | if (cond) { | ||
2178 | | jnz =>target | ||
2179 | } else { | ||
2180 | | jz =>target | ||
2181 | } | ||
2182 | } else { /* No, jump around copy code. */ | ||
2183 | if (cond) { | ||
2184 | | jz >1 | ||
2185 | } else { | ||
2186 | | jnz >1 | ||
2187 | } | ||
2188 | | mov edx, BASE[src].value.na[1] | ||
2189 | | mov BASE[dest].tt, eax | ||
2190 | | mov BASE[dest].value, ecx | ||
2191 | | mov BASE[dest].value.na[1], edx | ||
2192 | | jmp =>target | ||
2193 | |1: | ||
2194 | } | ||
2195 | } | ||
2196 | |||
2197 | static void jit_op_jmp(jit_State *J, int target) | ||
2198 | { | ||
2199 | | jmp =>target | ||
2200 | } | ||
2201 | |||
2202 | /* ------------------------------------------------------------------------ */ | ||
2203 | |||
2204 | enum { FOR_IDX, FOR_LIM, FOR_STP, FOR_EXT }; | ||
2205 | |||
2206 | static const char *const jit_for_coerce_error[] = { | ||
2207 | LUA_QL("for") " initial value must be a number", | ||
2208 | LUA_QL("for") " limit must be a number", | ||
2209 | LUA_QL("for") " step must be a number", | ||
2210 | }; | ||
2211 | |||
2212 | /* Try to coerce for slots with strings to numbers in place or complain. */ | ||
2213 | static void jit_for_coerce(lua_State *L, TValue *o) | ||
2214 | { | ||
2215 | int i; | ||
2216 | for (i = FOR_IDX; i <= FOR_STP; i++, o++) { | ||
2217 | lua_Number num; | ||
2218 | if (ttisnumber(o)) continue; | ||
2219 | if (ttisstring(o) && luaO_str2d(svalue(o), &num)) { | ||
2220 | setnvalue(o, num); | ||
2221 | } else { | ||
2222 | luaG_runerror(L, jit_for_coerce_error[i]); | ||
2223 | } | ||
2224 | } | ||
2225 | } | ||
2226 | |||
2227 | static void jit_op_forprep(jit_State *J, int ra, int target) | ||
2228 | { | ||
2229 | const TValue *step = hint_get(J, FOR_STEP_K); | ||
2230 | if (ttisnumber(step)) { | ||
2231 | | isnumber2 ra+FOR_IDX, ra+FOR_LIM; jne L_DEOPTIMIZEF | ||
2232 | |4: | ||
2233 | | fld qword BASE[ra+FOR_LIM].value // [lim] | ||
2234 | | fld qword BASE[ra+FOR_IDX].value // [idx lim] | ||
2235 | | fst qword BASE[ra+FOR_EXT].value // extidx = idx | ||
2236 | | fcomparepp // idx >< lim ? | ||
2237 | | settt BASE[ra+FOR_EXT], LUA_TNUMBER | ||
2238 | if (nvalue(step) < (lua_Number)0) { | ||
2239 | | jb =>target+1 // step < 0 && idx < lim: skip loop. | ||
2240 | } else { | ||
2241 | | ja =>target+1 // step >= 0 && idx > lim: skip loop. | ||
2242 | } | ||
2243 | } else { | ||
2244 | |4: | ||
2245 | | isnumber3 ra+FOR_IDX, ra+FOR_LIM, ra+FOR_STP | ||
2246 | | mov eax, BASE[ra+FOR_STP].value.na[1] // Sign bit is in hi dword. | ||
2247 | | jne L_DEOPTIMIZEF | ||
2248 | | fld qword BASE[ra+FOR_LIM].value // [lim] (FP stack notation) | ||
2249 | | fld qword BASE[ra+FOR_IDX].value // [idx lim] | ||
2250 | | test eax, eax // step >< 0 ? | ||
2251 | | fst qword BASE[ra+FOR_EXT].value // extidx = idx | ||
2252 | | js >1 | ||
2253 | | fxch // if (step > 0) [lim idx] | ||
2254 | |1: | ||
2255 | | fcomparepp // step > 0 ? lim < idx : idx < lim | ||
2256 | | settt BASE[ra+FOR_EXT], LUA_TNUMBER | ||
2257 | | jb =>target+1 // Skip loop. | ||
2258 | } | ||
2259 | if (ttisnumber(hint_get(J, TYPE))) { | ||
2260 | jit_deopt_target(J, 0); | ||
2261 | } else { | ||
2262 | |.tail | ||
2263 | |L_DEOPTLABEL: // Recycle as fallback label. | ||
2264 | | // Fallback for strings as loop vars. No need to make this fast. | ||
2265 | | lea eax, BASE[ra] | ||
2266 | | mov L->savedpc, &J->nextins | ||
2267 | | call &jit_for_coerce, L, eax // Coerce strings or throw error. | ||
2268 | | jmp <4 // Easier than reloading eax. | ||
2269 | |.code | ||
2270 | } | ||
2271 | } | ||
2272 | |||
2273 | static void jit_op_forloop(jit_State *J, int ra, int target) | ||
2274 | { | ||
2275 | const TValue *step = hint_getpc(J, FOR_STEP_K, target-1); | ||
2276 | if (ttisnumber(step)) { | ||
2277 | | fld qword BASE[ra+FOR_LIM].value // [lim] (FP stack notation) | ||
2278 | | fld qword BASE[ra+FOR_IDX].value // [idx lim] | ||
2279 | | fadd qword BASE[ra+FOR_STP].value // [nidx lim] | ||
2280 | | fst qword BASE[ra+FOR_EXT].value // extidx = nidx | ||
2281 | | fst qword BASE[ra+FOR_IDX].value // idx = nidx | ||
2282 | | settt BASE[ra+FOR_EXT], LUA_TNUMBER | ||
2283 | | fcomparepp // nidx >< lim ? | ||
2284 | if (nvalue(step) < (lua_Number)0) { | ||
2285 | | jae =>target // step < 0 && nidx >= lim: loop again. | ||
2286 | } else { | ||
2287 | | jbe =>target // step >= 0 && nidx <= lim: loop again. | ||
2288 | } | ||
2289 | } else { | ||
2290 | | mov eax, BASE[ra+FOR_STP].value.na[1] // Sign bit is in hi dword. | ||
2291 | | fld qword BASE[ra+FOR_LIM].value // [lim] (FP stack notation) | ||
2292 | | fld qword BASE[ra+FOR_IDX].value // [idx lim] | ||
2293 | | fld qword BASE[ra+FOR_STP].value // [stp idx lim] | ||
2294 | | faddp st1 // [nidx lim] | ||
2295 | | fst qword BASE[ra+FOR_IDX].value // idx = nidx | ||
2296 | | fst qword BASE[ra+FOR_EXT].value // extidx = nidx | ||
2297 | | settt BASE[ra+FOR_EXT], LUA_TNUMBER | ||
2298 | | test eax, eax // step >< 0 ? | ||
2299 | | js >1 | ||
2300 | | fxch // if (step > 0) [lim nidx] | ||
2301 | |1: | ||
2302 | | fcomparepp // step > 0 ? lim >= nidx : nidx >= lim | ||
2303 | | jae =>target // Loop again. | ||
2304 | } | ||
2305 | } | ||
2306 | |||
2307 | /* ------------------------------------------------------------------------ */ | ||
2308 | |||
2309 | static void jit_op_tforloop(jit_State *J, int ra, int nresults) | ||
2310 | { | ||
2311 | int target = jit_jmp_target(J); | ||
2312 | int i; | ||
2313 | if (jit_inline_tforloop(J, ra, nresults, target)) return; /* Inlined? */ | ||
2314 | for (i = 2; i >= 0; i--) { | ||
2315 | | copyslot BASE[ra+i+3], BASE[ra+i] // Copy ctlvar/state/callable. | ||
2316 | } | ||
2317 | jit_op_call(J, ra+3, 2, nresults); | ||
2318 | | isnil ra+3; je >1 | ||
2319 | | copyslot BASE[ra+2], BASE[ra+3] // Save control variable. | ||
2320 | | jmp =>target | ||
2321 | |1: | ||
2322 | } | ||
2323 | |||
2324 | /* ------------------------------------------------------------------------ */ | ||
2325 | |||
2326 | static void jit_op_close(jit_State *J, int ra) | ||
2327 | { | ||
2328 | if (ra) { | ||
2329 | | lea eax, BASE[ra] | ||
2330 | | mov ARG2, eax | ||
2331 | } else { | ||
2332 | | mov ARG2, BASE | ||
2333 | } | ||
2334 | | call &luaF_close, L // , StkId level (ARG2) | ||
2335 | } | ||
2336 | |||
2337 | static void jit_op_closure(jit_State *J, int dest, int ptidx) | ||
2338 | { | ||
2339 | Proto *npt = J->pt->p[ptidx]; | ||
2340 | int nup = npt->nups; | ||
2341 | | getLCL edi // LCL:edi is callee-saved. | ||
2342 | | mov edx, LCL:edi->env | ||
2343 | | call &luaF_newLclosure, L, nup, edx | ||
2344 | | mov LCL->p, &npt // Store new proto in returned closure. | ||
2345 | | mov aword BASE[dest].value, LCL // setclvalue() | ||
2346 | | settt BASE[dest], LUA_TFUNCTION | ||
2347 | /* Process pseudo-instructions for upvalues. */ | ||
2348 | if (nup > 0) { | ||
2349 | const Instruction *uvcode = J->nextins; | ||
2350 | int i, uvuv; | ||
2351 | /* Check which of the two types we need. */ | ||
2352 | for (i = 0, uvuv = 0; i < nup; i++) | ||
2353 | if (GET_OPCODE(uvcode[i]) == OP_GETUPVAL) uvuv++; | ||
2354 | /* Copy upvalues from parent first. */ | ||
2355 | if (uvuv) { | ||
2356 | /* LCL:eax->upvals (new closure) <-- LCL:edi->upvals (own closure). */ | ||
2357 | for (i = 0; i < nup; i++) | ||
2358 | if (GET_OPCODE(uvcode[i]) == OP_GETUPVAL) { | ||
2359 | | mov UPVAL:edx, LCL:edi->upvals[GETARG_B(uvcode[i])] | ||
2360 | | mov LCL->upvals[i], UPVAL:edx | ||
2361 | } | ||
2362 | } | ||
2363 | /* Next find or create upvalues for our own stack slots. */ | ||
2364 | if (nup > uvuv) { | ||
2365 | | mov LCL:edi, LCL // Move new closure to callee-save register. */ | ||
2366 | /* LCL:edi->upvals (new closure) <-- upvalue for stack slot. */ | ||
2367 | for (i = 0; i < nup; i++) | ||
2368 | if (GET_OPCODE(uvcode[i]) == OP_MOVE) { | ||
2369 | int rb = GETARG_B(uvcode[i]); | ||
2370 | if (rb) { | ||
2371 | | lea eax, BASE[rb] | ||
2372 | | mov ARG2, eax | ||
2373 | } else { | ||
2374 | | mov ARG2, BASE | ||
2375 | } | ||
2376 | | call &luaF_findupval, L // , StkId level (ARG2) | ||
2377 | | mov LCL:edi->upvals[i], UPVAL:eax | ||
2378 | } | ||
2379 | } | ||
2380 | J->combine += nup; /* Skip pseudo-instructions. */ | ||
2381 | } | ||
2382 | jit_checkGC(J); | ||
2383 | } | ||
2384 | |||
2385 | /* ------------------------------------------------------------------------ */ | ||
2386 | |||
2387 | static void jit_op_vararg(jit_State *J, int dest, int num) | ||
2388 | { | ||
2389 | if (num < 0) { /* Copy all varargs. */ | ||
2390 | |// Copy [ci->func+1+pt->numparams, BASE) -> [BASE+dest, *). | ||
2391 | |1: | ||
2392 | | mov CI, L->ci | ||
2393 | | mov edx, CI->func | ||
2394 | | add edx, (1+J->pt->numparams)*#TVALUE // Start of varargs. | ||
2395 | | | ||
2396 | | // luaD_checkstack(L, nvararg) with nvararg = L->base - vastart. | ||
2397 | | // This is a slight overallocation (BASE[dest+nvararg] would be enough). | ||
2398 | | // We duplicate OP_VARARG behaviour so we can use luaD_growstack(). | ||
2399 | | lea eax, [BASE+BASE+J->pt->maxstacksize*#TVALUE] // L->base + L->top | ||
2400 | | sub eax, edx // L->top + (L->base - vastart) | ||
2401 | | cmp eax, L->stack_last | ||
2402 | | jae >5 // Need to grow stack? | ||
2403 | | | ||
2404 | | lea TOP, BASE[dest] | ||
2405 | | cmp edx, BASE | ||
2406 | | jnb >3 | ||
2407 | |2: // Copy loop. | ||
2408 | | mov eax, [edx] | ||
2409 | | add edx, aword*1 | ||
2410 | | mov [TOP], eax | ||
2411 | | add TOP, aword*1 | ||
2412 | | cmp edx, BASE | ||
2413 | | jb <2 | ||
2414 | |3: | ||
2415 | |// This is an open ins. Must keep TOP for next instruction. | ||
2416 | | | ||
2417 | |.tail | ||
2418 | |5: // Grow stack for varargs. | ||
2419 | | sub eax, L->top | ||
2420 | | TValuediv eax | ||
2421 | | call &luaD_growstack, L, eax | ||
2422 | | mov BASE, L->base | ||
2423 | | jmp <1 // Just restart op to avoid saving/restoring regs. | ||
2424 | |.code | ||
2425 | } else if (num > 0) { /* Copy limited number of varargs. */ | ||
2426 | |// Copy [ci->func+1+pt->numparams, BASE) -> [BASE+dest, BASE+dest+num). | ||
2427 | | mov CI, L->ci | ||
2428 | | mov edx, CI->func | ||
2429 | | add edx, (1+J->pt->numparams)*#TVALUE | ||
2430 | | lea TOP, BASE[dest] | ||
2431 | | lea ecx, BASE[dest+num] | ||
2432 | | cmp edx, BASE // No varargs present: only fill. | ||
2433 | | jnb >2 | ||
2434 | | | ||
2435 | |1: // Copy loop. | ||
2436 | | mov eax, [edx] | ||
2437 | | add edx, aword*1 | ||
2438 | | mov [TOP], eax | ||
2439 | | add TOP, aword*1 | ||
2440 | | cmp TOP, ecx // Stop if all dest slots got a vararg. | ||
2441 | | jnb >4 | ||
2442 | | cmp edx, BASE // Continue if more varargs present. | ||
2443 | | jb <1 | ||
2444 | | | ||
2445 | |2: // Fill remaining slots with nils. | ||
2446 | | xor eax, eax // Assumes: LUA_TNIL == 0 | ||
2447 | |3: // Fill loop. | ||
2448 | | settt TOP[0], eax | ||
2449 | | add TOP, #TVALUE | ||
2450 | | cmp TOP, ecx | ||
2451 | | jb <3 | ||
2452 | |4: | ||
2453 | } | ||
2454 | } | ||
2455 | |||
2456 | /* ------------------------------------------------------------------------ */ | ||
2457 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_x86.dash b/libraries/LuaJIT-1.1.7/src/ljit_x86.dash new file mode 100644 index 0000000..432e1c8 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit_x86.dash | |||
@@ -0,0 +1,297 @@ | |||
1 | |// | ||
2 | |// Common DynASM definitions and macros for x86 CPUs. | ||
3 | |// Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | |// | ||
5 | | | ||
6 | |// Standard DynASM declarations. | ||
7 | |.arch x86 | ||
8 | |.section code, deopt, tail, mfmap | ||
9 | | | ||
10 | |// Type definitions with (almost) global validity. | ||
11 | |.type L, lua_State, esi // L. | ||
12 | |.type BASE, TValue, ebx // L->base. | ||
13 | |.type TOP, TValue, edi // L->top (calls/open ops). | ||
14 | |.type CI, CallInfo, ecx // L->ci (calls, locally). | ||
15 | |.type LCL, LClosure, eax // func->value (calls). | ||
16 | | | ||
17 | |// Type definitions with local validity. | ||
18 | |.type GL, global_State | ||
19 | |.type TVALUE, TValue | ||
20 | |.type VALUE, Value | ||
21 | |.type CINFO, CallInfo | ||
22 | |.type GCOBJECT, GCObject | ||
23 | |.type TSTRING, TString | ||
24 | |.type TABLE, Table | ||
25 | |.type CCLOSURE, CClosure | ||
26 | |.type PROTO, Proto | ||
27 | |.type UPVAL, UpVal | ||
28 | |.type NODE, Node | ||
29 | | | ||
30 | |// Definitions copied to DynASM domain to avoid unnecessary constant args. | ||
31 | |// CHECK: must match with the definitions in lua.h! | ||
32 | |.define LUA_TNIL, 0 | ||
33 | |.define LUA_TBOOLEAN, 1 | ||
34 | |.define LUA_TLIGHTUSERDATA, 2 | ||
35 | |.define LUA_TNUMBER, 3 | ||
36 | |.define LUA_TSTRING, 4 | ||
37 | |.define LUA_TTABLE, 5 | ||
38 | |.define LUA_TFUNCTION, 6 | ||
39 | |.define LUA_TUSERDATA, 7 | ||
40 | |.define LUA_TTHREAD, 8 | ||
41 | | | ||
42 | |.define LUA_TNUM_NUM, 0x33 | ||
43 | |.define LUA_TNUM_NUM_NUM, 0x333 | ||
44 | |.define LUA_TSTR_STR, 0x44 | ||
45 | |.define LUA_TSTR_NUM, 0x43 | ||
46 | |.define LUA_TSTR_NUM_NUM, 0x433 | ||
47 | |.define LUA_TTABLE_NUM, 0x53 | ||
48 | |.define LUA_TTABLE_STR, 0x54 | ||
49 | | | ||
50 | |// Macros to test, set and copy stack slots. | ||
51 | |.macro istt, idx, tp; cmp dword BASE[idx].tt, tp; .endmacro | ||
52 | |.macro isnil, idx; istt idx, LUA_TNIL; .endmacro | ||
53 | |.macro isnumber, idx; istt idx, LUA_TNUMBER; .endmacro | ||
54 | |.macro isstring, idx; istt idx, LUA_TSTRING; .endmacro | ||
55 | |.macro istable, idx; istt idx, LUA_TTABLE; .endmacro | ||
56 | |.macro isfunction, idx; istt idx, LUA_TFUNCTION; .endmacro | ||
57 | | | ||
58 | |.macro isnumber2, idx1, idx2, reg | ||
59 | | mov reg, BASE[idx1].tt; shl reg, 4; or reg, BASE[idx2].tt | ||
60 | | cmp reg, LUA_TNUM_NUM | ||
61 | |.endmacro | ||
62 | |.macro isnumber2, idx1, idx2; isnumber2, idx1, idx2, eax; .endmacro | ||
63 | | | ||
64 | |.macro isnumber3, idx1, idx2, idx3, reg | ||
65 | | mov reg, BASE[idx1].tt; shl reg, 4; or reg, BASE[idx2].tt | ||
66 | | shl reg, 4; or reg, BASE[idx3].tt; cmp reg, LUA_TNUM_NUM_NUM | ||
67 | |.endmacro | ||
68 | |.macro isnumber3, idx1, idx2, idx3; isnumber3, idx1, idx2, idx3, eax; .endmacro | ||
69 | | | ||
70 | |.macro tvisnil, tv; cmp dword tv.tt, LUA_TNIL; .endmacro | ||
71 | | | ||
72 | |.macro settt, tv, tp; mov dword tv.tt, tp; .endmacro | ||
73 | |.macro setnilvalue, tv; settt tv, LUA_TNIL; .endmacro | ||
74 | | | ||
75 | |.macro setbvalue, tv, val // May use edx. | ||
76 | ||if (val) { /* true */ | ||
77 | | mov edx, LUA_TBOOLEAN | ||
78 | | mov dword tv.value, edx // Assumes: LUA_TBOOLEAN == 1 | ||
79 | | settt tv, edx | ||
80 | ||} else { /* false */ | ||
81 | | mov dword tv.value, 0 | ||
82 | | settt tv, LUA_TBOOLEAN | ||
83 | ||} | ||
84 | |.endmacro | ||
85 | | | ||
86 | |.macro loadnvaluek, vptr | ||
87 | ||if ((vptr)->n == (lua_Number)0) { | ||
88 | | fldz | ||
89 | ||} else if ((vptr)->n == (lua_Number)1) { | ||
90 | | fld1 | ||
91 | ||} else { | ||
92 | | fld qword [vptr] | ||
93 | ||} | ||
94 | |.endmacro | ||
95 | | | ||
96 | |.macro setnvaluek, tv, vptr // Pass a Value *! With permanent addr. | ||
97 | | // SSE2 does not pay off here (I tried). | ||
98 | | loadnvaluek vptr | ||
99 | | fstp qword tv.value | ||
100 | | settt tv, LUA_TNUMBER | ||
101 | |.endmacro | ||
102 | | | ||
103 | |.macro setnvalue, tv, vptr // Pass a Value *! Temporary ok. | ||
104 | | mov dword tv.value, (vptr)->na[0] | ||
105 | | mov dword tv.value.na[1], (vptr)->na[1] | ||
106 | | settt tv, LUA_TNUMBER | ||
107 | |.endmacro | ||
108 | | | ||
109 | |.macro setsvalue, tv, vptr | ||
110 | | mov aword tv.value, vptr | ||
111 | | settt tv, LUA_TSTRING | ||
112 | |.endmacro | ||
113 | | | ||
114 | |.macro sethvalue, tv, vptr | ||
115 | | mov aword tv.value, vptr | ||
116 | | settt tv, LUA_TTABLE | ||
117 | |.endmacro | ||
118 | | | ||
119 | |.macro copyslotSSE, D, S, R1 // May use xmm0. | ||
120 | | mov R1, S.tt; movq xmm0, qword S.value | ||
121 | | mov D.tt, R1; movq qword D.value, xmm0 | ||
122 | |.endmacro | ||
123 | | | ||
124 | |.macro copyslot, D, S, R1, R2, R3 | ||
125 | ||if (J->flags & JIT_F_CPU_SSE2) { | ||
126 | | copyslotSSE D, S, R1 | ||
127 | ||} else { | ||
128 | | mov R1, S.value; mov R2, S.value.na[1]; mov R3, S.tt | ||
129 | | mov D.value, R1; mov D.value.na[1], R2; mov D.tt, R3 | ||
130 | ||} | ||
131 | |.endmacro | ||
132 | | | ||
133 | |.macro copyslot, D, S, R1, R2 | ||
134 | ||if (J->flags & JIT_F_CPU_SSE2) { | ||
135 | | copyslotSSE D, S, R1 | ||
136 | ||} else { | ||
137 | | mov R1, S.value; mov R2, S.value.na[1]; mov D.value, R1 | ||
138 | | mov R1, S.tt; mov D.value.na[1], R2; mov D.tt, R1 | ||
139 | ||} | ||
140 | |.endmacro | ||
141 | | | ||
142 | |.macro copyslot, D, S | ||
143 | | copyslot D, S, ecx, edx, eax | ||
144 | |.endmacro | ||
145 | | | ||
146 | |.macro copyconst, tv, tvk // May use edx. | ||
147 | ||switch (ttype(tvk)) { | ||
148 | ||case LUA_TNIL: | ||
149 | | setnilvalue tv | ||
150 | || break; | ||
151 | ||case LUA_TBOOLEAN: | ||
152 | | setbvalue tv, bvalue(tvk) // May use edx. | ||
153 | || break; | ||
154 | ||case LUA_TNUMBER: { | ||
155 | | setnvaluek tv, &(tvk)->value | ||
156 | || break; | ||
157 | ||} | ||
158 | ||case LUA_TSTRING: | ||
159 | | setsvalue tv, &gcvalue(tvk) | ||
160 | || break; | ||
161 | ||default: lua_assert(0); break; | ||
162 | ||} | ||
163 | |.endmacro | ||
164 | | | ||
165 | |// Macros to get Lua structures. | ||
166 | |.macro getLCL, reg // May use CI and TOP (edi). | ||
167 | ||if (!J->pt->is_vararg) { | ||
168 | | mov LCL:reg, BASE[-1].value | ||
169 | ||} else { | ||
170 | | mov CI, L->ci | ||
171 | | mov TOP, CI->func | ||
172 | | mov LCL:reg, TOP->value | ||
173 | ||} | ||
174 | |.endmacro | ||
175 | |.macro getLCL; getLCL eax; .endmacro | ||
176 | | | ||
177 | |// Macros to handle variants. | ||
178 | |.macro addidx, type, idx | ||
179 | ||if (idx) { | ||
180 | | add type, idx*#type | ||
181 | ||} | ||
182 | |.endmacro | ||
183 | | | ||
184 | |.macro subidx, type, idx | ||
185 | ||if (idx) { | ||
186 | | sub type, idx*#type | ||
187 | ||} | ||
188 | |.endmacro | ||
189 | | | ||
190 | |// Annoying x87 stuff: support for two compare variants. | ||
191 | |.macro fcomparepp // Compare and pop st0 >< st1. | ||
192 | ||if (J->flags & JIT_F_CPU_CMOV) { | ||
193 | | fucomip st1 | ||
194 | | fpop | ||
195 | ||} else { | ||
196 | | fucompp | ||
197 | | fnstsw ax // eax modified! | ||
198 | | sahf | ||
199 | | // Sometimes test ah, imm8 would be faster. | ||
200 | | // But all following compares need to be changed then. | ||
201 | | // Don't bother since this is only compatibility stuff for old CPUs. | ||
202 | ||} | ||
203 | |.endmacro | ||
204 | | | ||
205 | |// If you change LUA_TVALUE_ALIGN, be sure to change the Makefile, too: | ||
206 | |// DASMFLAGS= -D TVALUE_SIZE=... | ||
207 | |// Then rerun make. Or change the default below: | ||
208 | |.if not TVALUE_SIZE; .define TVALUE_SIZE, 16; .endif | ||
209 | | | ||
210 | |.if TVALUE_SIZE == 16 | ||
211 | | .macro TValuemul, reg; sal reg, 4; .endmacro // *16 | ||
212 | | .macro TValuediv, reg; sar reg, 4; .endmacro // /16 | ||
213 | | .macro Nodemul, reg; sal reg, 5; .endmacro // *32 | ||
214 | |.elif TVALUE_SIZE == 12 | ||
215 | | .macro TValuemul, reg; sal reg, 2; lea reg, [reg+reg*2]; .endmacro // *12 | ||
216 | | .macro TValuediv, reg; sal reg, 2; imul reg, 0xaaaaaaab; .endmacro // /12 | ||
217 | | .macro Nodemul, reg; imul reg, 28; .endmacro // *28 | ||
218 | |.else | ||
219 | | .fatal Unsupported TValue size `TVALUE_SIZE'. | ||
220 | |.endif | ||
221 | | | ||
222 | |// | ||
223 | |// x86 C calling conventions and stack frame layout during a JIT call: | ||
224 | |// | ||
225 | |// ebp+aword*4 CARG2 nresults | ||
226 | |// ebp+aword*3 CARG2 func (also used as SAVER3 for L) | ||
227 | |// ebp+aword*2 CARG1 L | ||
228 | |// ------------------------------- call to GATE_LJ | ||
229 | |// ebp+aword*1 retaddr | ||
230 | |// ebp+aword*0 frameptr ebp | ||
231 | |// ebp-aword*1 SAVER1 TOP edi | ||
232 | |// ebp-aword*2 SAVER2 BASE ebx | ||
233 | |// ------------------------------- | ||
234 | |// GATE_LJ retaddr | ||
235 | |// esp+aword*2 ARG3 | ||
236 | |// esp+aword*1 ARG2 | ||
237 | |// esp+aword*0 ARG1 <-- esp for first JIT frame | ||
238 | |// ------------------------------- | ||
239 | |// 1st JIT frame retaddr | ||
240 | |// esp+aword*2 ARG3 | ||
241 | |// esp+aword*1 ARG2 | ||
242 | |// esp+aword*0 ARG1 <-- esp for second JIT frame | ||
243 | |// ------------------------------- | ||
244 | |// 2nd JIT frame retaddr | ||
245 | |// | ||
246 | |// We could omit the fixed frame pointer (ebp) and have one more register | ||
247 | |// available. But there is no pressing need (could use it for CI). | ||
248 | |// And it's easier for debugging (gdb is still confused -- why?). | ||
249 | |// | ||
250 | |// The stack is aligned to 4 awords (16 bytes). Calls to C functions | ||
251 | |// with up to 3 arguments do not need any stack pointer adjustment. | ||
252 | |// | ||
253 | | | ||
254 | |.define CARG3, [ebp+aword*4] | ||
255 | |.define CARG2, [ebp+aword*3] | ||
256 | |.define CARG1, [ebp+aword*2] | ||
257 | |.define SAVER1, [ebp-aword*1] | ||
258 | |.define SAVER2, [ebp-aword*2] | ||
259 | |.define ARG7, aword [esp+aword*6] // Requires large frame. | ||
260 | |.define ARG6, aword [esp+aword*5] // Requires large frame. | ||
261 | |.define ARG5, aword [esp+aword*4] // Requires large frame. | ||
262 | |.define ARG4, aword [esp+aword*3] // Requires large frame. | ||
263 | |.define ARG3, aword [esp+aword*2] | ||
264 | |.define ARG2, aword [esp+aword*1] | ||
265 | |.define ARG1, aword [esp] | ||
266 | |.define FRAME_RETADDR, aword [esp+aword*3] | ||
267 | |.define TMP3, [esp+aword*2] | ||
268 | |.define TMP2, [esp+aword*1] | ||
269 | |.define TMP1, [esp] | ||
270 | |.define FPARG2, qword [esp+qword*1] // Requires large frame. | ||
271 | |.define FPARG1, qword [esp] | ||
272 | |.define LJFRAME_OFFSET, aword*2 // 16 byte aligned with retaddr + ebp. | ||
273 | |.define FRAME_OFFSET, aword*3 // 16 byte aligned with retaddr. | ||
274 | |.define LFRAME_OFFSET, aword*7 // 16 byte aligned with retaddr. | ||
275 | |.define S2LFRAME_OFFSET, aword*4 // Delta to large frame. | ||
276 | | | ||
277 | |.macro call, target, a1 | ||
278 | | mov ARG1, a1; call target; .endmacro | ||
279 | |.macro call, target, a1, a2 | ||
280 | | mov ARG1, a1; mov ARG2, a2; call target; .endmacro | ||
281 | |.macro call, target, a1, a2, a3 | ||
282 | | mov ARG1, a1; mov ARG2, a2; mov ARG3, a3; call target; .endmacro | ||
283 | |.macro call, target, a1, a2, a3, a4 | ||
284 | | push a4; push a3; push a2; push a1 | ||
285 | | call target; add esp, S2LFRAME_OFFSET; .endmacro | ||
286 | |.macro call, target, a1, a2, a3, a4, a5 | ||
287 | | mov ARG1, a5; push a4; push a3; push a2; push a1 | ||
288 | | call target; add esp, S2LFRAME_OFFSET; .endmacro | ||
289 | | | ||
290 | |// The following macros require a large frame. | ||
291 | |.macro call_LFRAME, target, a1, a2, a3, a4 | ||
292 | | mov ARG1, a1; mov ARG2, a2; mov ARG3, a3; mov ARG4, a4 | ||
293 | | call target; .endmacro | ||
294 | |.macro call_LFRAME, target, a1, a2, a3, a4, a5 | ||
295 | | mov ARG1, a1; mov ARG2, a2; mov ARG3, a3; mov ARG4, a4; mov ARG5, a5 | ||
296 | | call target; .endmacro | ||
297 | | | ||
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_x86.h b/libraries/LuaJIT-1.1.7/src/ljit_x86.h new file mode 100644 index 0000000..fc860bc --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit_x86.h | |||
@@ -0,0 +1,2301 @@ | |||
1 | /* | ||
2 | ** This file has been pre-processed with DynASM. | ||
3 | ** http://luajit.org/dynasm.html | ||
4 | ** DynASM version 1.1.4, DynASM x86 version 1.1.4 | ||
5 | ** DO NOT EDIT! The original file is in "ljit_x86.dasc". | ||
6 | */ | ||
7 | |||
8 | #if DASM_VERSION != 10104 | ||
9 | #error "Version mismatch between DynASM and included encoding engine" | ||
10 | #endif | ||
11 | |||
12 | /* | ||
13 | ** Bytecode to machine code translation for x86 CPUs. | ||
14 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
15 | */ | ||
16 | |||
17 | #define DASM_SECTION_CODE 0 | ||
18 | #define DASM_SECTION_DEOPT 1 | ||
19 | #define DASM_SECTION_TAIL 2 | ||
20 | #define DASM_SECTION_MFMAP 3 | ||
21 | #define DASM_MAXSECTION 4 | ||
22 | #define Dt1(_V) (int)&(((lua_State *)0)_V) | ||
23 | #define Dt2(_V) (int)&(((TValue *)0)_V) | ||
24 | #define Dt3(_V) (int)&(((TValue *)0)_V) | ||
25 | #define Dt4(_V) (int)&(((CallInfo *)0)_V) | ||
26 | #define Dt5(_V) (int)&(((LClosure *)0)_V) | ||
27 | #define Dt6(_V) (int)&(((global_State *)0)_V) | ||
28 | #define Dt7(_V) (int)&(((TValue *)0)_V) | ||
29 | #define Dt8(_V) (int)&(((Value *)0)_V) | ||
30 | #define Dt9(_V) (int)&(((CallInfo *)0)_V) | ||
31 | #define DtA(_V) (int)&(((GCObject *)0)_V) | ||
32 | #define DtB(_V) (int)&(((TString *)0)_V) | ||
33 | #define DtC(_V) (int)&(((Table *)0)_V) | ||
34 | #define DtD(_V) (int)&(((CClosure *)0)_V) | ||
35 | #define DtE(_V) (int)&(((Proto *)0)_V) | ||
36 | #define DtF(_V) (int)&(((UpVal *)0)_V) | ||
37 | #define Dt10(_V) (int)&(((Node *)0)_V) | ||
38 | static const unsigned char jit_actionlist[5059] = { | ||
39 | 156,90,137,209,129,252,242,0,0,32,0,82,157,156,90,49,192,57,209,15,132,245, | ||
40 | 247,64,83,15,162,91,137,208,249,1,195,255,254,0,251,15,249,10,141,68,36,4, | ||
41 | 195,251,15,249,11,85,137,229,131,252,236,8,137,93,252,252,139,93,12,137,117, | ||
42 | 12,139,117,8,137,125,252,248,139,190,235,139,131,235,139,142,235,102,252, | ||
43 | 255,134,235,252,255,144,235,139,142,235,137,190,235,139,145,235,139,69,16, | ||
44 | 137,150,235,139,145,235,133,192,137,150,235,15,136,245,248,193,224,4,1,195, | ||
45 | 49,201,137,158,235,249,1,137,143,235,129,199,241,57,223,15,130,245,1,249, | ||
46 | 2,255,102,252,255,142,235,184,239,139,125,252,248,139,93,252,252,139,117, | ||
47 | 12,137,252,236,93,195,251,15,249,12,139,144,235,129,186,235,241,15,133,245, | ||
48 | 247,139,146,235,137,144,235,252,255,226,249,1,131,252,236,12,139,129,235, | ||
49 | 137,142,235,137,190,235,199,68,36,8,252,255,252,255,252,255,252,255,137,134, | ||
50 | 235,137,92,36,4,43,158,235,137,52,36,232,244,133,192,15,133,245,248,137,52, | ||
51 | 36,199,68,36,4,1,0,0,0,232,244,249,2,131,196,12,3,158,235,255,139,190,235, | ||
52 | 195,251,15,249,13,141,135,235,131,252,236,12,59,134,235,15,131,245,14,59, | ||
53 | 142,235,141,137,235,15,132,245,15,137,142,235,137,153,235,137,129,235,139, | ||
54 | 147,235,129,195,241,137,190,235,137,158,235,137,153,235,249,16,137,52,36, | ||
55 | 252,255,146,235,249,2,131,196,12,139,142,235,255,193,224,4,139,185,235,15, | ||
56 | 132,245,250,139,158,235,137,218,41,195,249,3,139,3,131,195,4,137,7,131,199, | ||
57 | 4,57,211,15,130,245,3,249,4,139,153,235,129,233,241,137,142,235,195,144,144, | ||
58 | 144,144,144,144,251,15,249,17,252,246,134,235,237,15,133,245,253,249,6,137, | ||
59 | 52,36,252,255,146,235,252,246,134,235,237,15,132,245,2,255,137,195,137,52, | ||
60 | 36,199,68,36,4,239,199,68,36,8,252,255,252,255,252,255,252,255,232,244,137, | ||
61 | 216,233,245,2,249,7,137,211,137,52,36,199,68,36,4,239,199,68,36,8,252,255, | ||
62 | 252,255,252,255,252,255,232,244,137,218,233,245,6,251,15,249,14,41,252,248, | ||
63 | 193,252,248,4,137,190,235,43,158,235,137,76,36,8,137,52,36,137,68,36,4,232, | ||
64 | 244,139,76,36,8,3,158,235,139,190,235,139,131,235,131,196,12,252,255,160, | ||
65 | 235,251,15,249,15,137,190,235,137,52,36,232,244,141,136,235,255,139,131,235, | ||
66 | 137,142,235,131,196,12,252,255,160,235,255,249,18,90,233,245,19,249,20,137, | ||
67 | 190,235,249,19,137,150,235,137,52,36,232,244,139,158,235,139,190,235,252, | ||
68 | 255,224,251,15,255,137,190,235,255,232,245,21,255,251,15,249,21,252,246,134, | ||
69 | 235,237,15,132,245,248,252,255,142,235,15,132,245,247,252,246,134,235,237, | ||
70 | 15,132,245,248,249,1,139,4,36,131,252,236,12,137,52,36,137,68,36,4,232,244, | ||
71 | 131,196,12,139,158,235,139,190,235,249,2,195,255,250,255,233,246,255,250, | ||
72 | 243,255,254,1,233,245,19,254,0,250,254,2,250,251,1,252,255,252,255,254,3, | ||
73 | 242,0,0,0,0,0,0,0,0,0,254,0,141,249,9,186,239,254,0,249,9,186,239,233,245, | ||
74 | 20,254,0,139,142,235,139,129,235,191,247,253,59,129,235,15,131,245,22,249, | ||
75 | 7,255,251,15,249,22,137,52,36,232,244,139,158,235,252,255,231,255,131,187, | ||
76 | 235,5,15,133,245,9,49,192,137,131,235,137,131,235,254,3,238,238,254,0,131, | ||
77 | 190,235,0,15,132,245,9,199,134,235,239,129,195,241,255,141,187,235,255,137, | ||
78 | 158,235,137,190,235,137,52,36,232,244,139,158,235,139,190,235,255,199,135, | ||
79 | 235,0,0,0,0,255,139,139,235,252,243,15,126,131,235,137,139,235,102,15,214, | ||
80 | 131,235,255,139,139,235,139,147,235,139,131,235,137,139,235,137,147,235,137, | ||
81 | 131,235,255,57,223,15,130,245,9,255,131,187,235,8,15,133,245,9,139,131,235, | ||
82 | 131,184,235,0,15,132,245,9,199,134,235,239,137,190,235,137,52,36,137,92,36, | ||
83 | 4,199,68,36,8,239,232,244,139,158,235,255,137,199,255,131,187,235,4,15,133, | ||
84 | 245,9,139,139,235,219,129,235,199,131,235,3,0,0,0,221,155,235,255,141,187, | ||
85 | 235,232,245,23,137,131,235,199,131,235,4,0,0,0,255,141,187,235,232,245,24, | ||
86 | 137,131,235,199,131,235,4,0,0,0,255,131,187,235,3,15,133,245,9,141,134,235, | ||
87 | 221,131,235,219,24,129,56,252,255,0,0,0,15,135,245,9,137,52,36,137,68,36, | ||
88 | 4,199,68,36,8,1,0,0,0,232,244,137,131,235,199,131,235,4,0,0,0,255,251,15, | ||
89 | 249,23,139,135,235,193,224,4,11,135,235,193,224,4,11,135,235,45,51,4,0,0, | ||
90 | 15,133,245,18,221,135,235,221,135,235,219,92,36,8,219,92,36,4,139,143,235, | ||
91 | 139,185,235,139,84,36,8,57,215,15,130,245,250,249,1,11,68,36,4,15,142,245, | ||
92 | 252,249,2,41,194,15,140,245,253,141,140,253,1,235,66,249,3,137,116,36,4,137, | ||
93 | 76,36,8,137,84,36,12,139,190,235,139,135,235,255,59,135,235,15,131,245,254, | ||
94 | 233,244,249,4,15,140,245,251,141,84,58,1,233,245,1,249,5,137,252,250,233, | ||
95 | 245,1,249,6,15,132,245,251,1,252,248,64,15,143,245,2,249,5,184,1,0,0,0,233, | ||
96 | 245,2,249,7,49,210,233,245,3,255,251,15,249,24,139,135,235,193,224,4,11,135, | ||
97 | 235,131,232,67,15,133,245,18,221,135,235,219,92,36,4,139,143,235,139,185, | ||
98 | 235,137,252,250,233,245,1,249,8,131,252,236,12,137,52,36,232,244,131,196, | ||
99 | 12,139,158,235,233,244,255,131,187,235,5,15,133,245,9,255,141,131,235,137, | ||
100 | 52,36,137,68,36,4,232,244,255,141,131,235,141,139,235,137,52,36,137,68,36, | ||
101 | 4,137,76,36,8,232,244,255,139,131,235,137,4,36,232,244,137,4,36,219,4,36, | ||
102 | 221,155,235,199,131,235,3,0,0,0,255,131,187,235,3,15,133,245,9,221,131,235, | ||
103 | 255,139,131,235,193,224,4,11,131,235,131,252,248,51,15,133,245,9,255,217, | ||
104 | 252,254,255,217,252,255,255,217,252,242,221,216,255,217,60,36,217,45,239, | ||
105 | 217,252,252,217,44,36,255,217,225,255,217,252,250,255,221,131,235,221,131, | ||
106 | 235,249,1,217,252,248,223,224,158,15,138,245,1,221,217,255,221,131,235,221, | ||
107 | 131,235,217,252,243,255,221,28,36,232,244,255,131,187,235,6,15,133,245,9, | ||
108 | 129,187,235,239,15,133,245,9,255,141,131,235,57,199,15,133,245,9,255,141, | ||
109 | 187,235,137,190,235,255,131,196,12,129,252,235,241,129,174,235,241,195,255, | ||
110 | 141,187,235,137,52,36,137,124,36,4,232,244,133,192,15,133,246,255,139,131, | ||
111 | 235,64,139,147,235,137,131,235,137,20,36,137,68,36,4,232,244,139,136,235, | ||
112 | 133,201,15,132,245,255,219,131,235,199,131,235,3,0,0,0,221,155,235,139,144, | ||
113 | 235,139,128,235,137,139,235,137,147,235,137,131,235,233,246,249,9,255,141, | ||
114 | 135,235,131,252,236,12,59,134,235,15,131,245,14,59,142,235,141,137,235,15, | ||
115 | 132,245,15,49,192,137,153,235,129,195,241,137,142,235,255,141,147,235,57, | ||
116 | 215,255,137,223,255,15,71,252,250,255,15,134,245,247,137,215,249,1,255,141, | ||
117 | 147,235,137,129,235,137,145,235,137,150,235,137,158,235,137,153,235,255,15, | ||
118 | 130,245,251,249,4,254,2,249,5,137,135,235,129,199,241,57,215,15,130,245,5, | ||
119 | 233,245,4,254,0,137,190,235,137,185,235,137,129,235,255,139,139,235,252,243, | ||
120 | 15,126,131,235,137,143,235,102,15,214,135,235,255,139,139,235,139,147,235, | ||
121 | 137,143,235,139,139,235,137,151,235,137,143,235,255,137,252,251,141,147,235, | ||
122 | 141,187,235,137,145,235,137,150,235,255,137,135,235,255,249,2,137,135,235, | ||
123 | 137,135,235,129,199,241,57,215,15,130,245,2,255,137,52,36,232,244,255,252, | ||
124 | 246,134,235,237,15,132,245,255,232,245,25,249,9,255,251,15,249,25,139,142, | ||
125 | 235,139,185,235,139,135,235,139,184,235,139,135,235,131,192,4,137,134,235, | ||
126 | 131,252,236,12,137,52,36,199,68,36,4,239,199,68,36,8,252,255,252,255,252, | ||
127 | 255,252,255,232,244,131,196,12,139,135,235,137,134,235,139,158,235,195,255, | ||
128 | 137,52,36,137,92,36,4,232,244,255,129,174,235,241,137,223,129,252,235,241, | ||
129 | 131,196,12,255,139,142,235,139,153,235,129,233,241,137,142,235,141,187,235, | ||
130 | 131,196,12,255,252,246,134,235,237,15,132,245,253,232,245,26,249,7,255,139, | ||
131 | 68,36,12,137,134,235,255,251,15,249,26,139,4,36,137,134,235,131,252,236,12, | ||
132 | 137,52,36,199,68,36,4,239,199,68,36,8,252,255,252,255,252,255,252,255,232, | ||
133 | 244,131,196,12,139,158,235,139,190,235,195,255,139,145,235,57,252,251,15, | ||
134 | 131,245,248,249,1,139,3,131,195,4,137,2,131,194,4,57,252,251,15,130,245,1, | ||
135 | 249,2,131,196,12,139,153,235,129,233,241,137,215,137,142,235,195,255,129, | ||
136 | 174,235,241,129,252,235,241,255,131,196,12,141,187,235,195,255,139,142,235, | ||
137 | 139,185,235,129,233,241,137,142,235,255,139,139,235,139,147,235,139,131,235, | ||
138 | 137,143,235,137,151,235,137,135,235,255,131,196,12,137,252,251,255,129,199, | ||
139 | 241,255,139,142,235,131,187,235,6,255,139,131,235,186,239,137,145,235,255, | ||
140 | 15,133,245,20,255,15,133,245,19,255,15,132,245,247,232,245,27,249,1,255,251, | ||
141 | 15,249,27,131,252,236,12,137,150,235,137,190,235,137,52,36,137,92,36,4,232, | ||
142 | 244,131,196,12,137,195,139,190,235,139,131,235,139,142,235,195,255,252,255, | ||
143 | 144,235,255,137,158,235,255,49,192,255,141,147,235,249,1,137,135,235,137, | ||
144 | 135,235,129,199,241,57,215,15,130,245,1,255,131,187,235,6,15,133,245,9,255, | ||
145 | 131,187,235,6,15,133,245,251,254,2,249,5,255,186,239,233,245,28,254,0,251, | ||
146 | 15,249,28,137,150,235,137,190,235,137,52,36,137,92,36,4,232,244,139,142,235, | ||
147 | 139,150,235,139,185,235,249,1,139,24,131,192,4,137,31,131,199,4,57,208,15, | ||
148 | 130,245,1,139,153,235,139,131,235,129,233,241,131,196,12,252,255,160,235, | ||
149 | 255,139,131,235,255,139,139,235,139,147,235,137,139,235,139,139,235,137,147, | ||
150 | 235,137,139,235,255,141,187,235,129,252,235,241,139,142,235,137,131,235,255, | ||
151 | 139,142,235,141,187,235,139,153,235,139,135,235,137,131,235,255,139,135,235, | ||
152 | 252,243,15,126,135,235,137,131,235,102,15,214,131,235,255,139,135,235,139, | ||
153 | 151,235,137,131,235,139,135,235,137,147,235,137,131,235,255,141,187,235,139, | ||
154 | 131,235,255,139,145,235,249,1,139,3,131,195,4,137,2,131,194,4,57,252,251, | ||
155 | 15,130,245,1,139,153,235,137,215,139,131,235,255,199,131,235,0,0,0,0,255, | ||
156 | 186,1,0,0,0,137,147,235,137,147,235,255,199,131,235,0,0,0,0,199,131,235,1, | ||
157 | 0,0,0,255,217,252,238,255,217,232,255,221,5,239,255,199,131,235,239,199,131, | ||
158 | 235,4,0,0,0,255,137,131,235,195,255,141,139,235,141,147,235,249,1,137,1,57, | ||
159 | 209,141,137,235,15,134,245,1,255,139,142,235,139,185,235,139,135,235,255, | ||
160 | 139,136,235,139,185,235,255,139,143,235,252,243,15,126,135,235,137,139,235, | ||
161 | 102,15,214,131,235,255,139,143,235,139,151,235,139,135,235,137,139,235,137, | ||
162 | 147,235,137,131,235,255,139,136,235,139,185,235,139,131,235,139,147,235,137, | ||
163 | 135,235,131,252,248,4,139,131,235,137,151,235,137,135,235,15,131,245,251, | ||
164 | 249,4,254,2,249,5,252,246,130,235,237,15,132,245,4,252,246,129,235,237,15, | ||
165 | 132,245,4,232,245,29,233,245,4,254,0,251,15,249,29,137,84,36,12,137,76,36, | ||
166 | 8,137,116,36,4,233,244,255,251,15,249,30,139,142,235,139,185,235,139,135, | ||
167 | 235,139,184,235,233,245,255,255,251,15,249,31,131,191,235,5,139,191,235,15, | ||
168 | 133,245,18,249,9,15,182,143,235,184,1,0,0,0,211,224,72,35,130,235,193,224, | ||
169 | 5,3,135,235,249,1,131,184,235,4,15,133,245,248,57,144,235,15,133,245,248, | ||
170 | 139,136,235,133,201,15,132,245,249,255,252,243,15,126,128,235,102,15,214, | ||
171 | 131,235,255,139,144,235,139,184,235,137,147,235,137,187,235,255,137,139,235, | ||
172 | 139,158,235,195,249,2,139,128,235,133,192,15,133,245,1,49,201,249,3,139,135, | ||
173 | 235,133,192,15,132,245,250,252,246,128,235,237,15,132,245,251,249,4,137,139, | ||
174 | 235,139,158,235,195,249,5,137,150,235,199,134,235,4,0,0,0,139,12,36,131,252, | ||
175 | 236,12,137,142,235,137,52,36,137,124,36,4,137,92,36,8,232,244,131,196,12, | ||
176 | 139,158,235,255,251,15,249,32,139,135,235,193,224,4,11,129,235,131,252,248, | ||
177 | 84,139,191,235,139,145,235,15,132,245,9,233,245,18,255,251,15,249,33,139, | ||
178 | 142,235,128,167,235,237,139,145,235,137,185,235,137,151,235,195,255,251,15, | ||
179 | 249,34,139,142,235,139,185,235,139,135,235,139,184,235,233,245,255,255,251, | ||
180 | 15,249,35,131,191,235,5,139,191,235,15,133,245,18,249,9,15,182,143,235,184, | ||
181 | 1,0,0,0,211,224,72,35,130,235,193,224,5,3,135,235,249,1,131,184,235,4,15, | ||
182 | 133,245,250,57,144,235,15,133,245,250,131,184,235,0,15,132,245,252,249,2, | ||
183 | 198,135,235,0,249,3,255,252,246,135,235,237,15,133,245,254,249,7,255,139, | ||
184 | 139,235,252,243,15,126,131,235,137,136,235,102,15,214,128,235,255,139,139, | ||
185 | 235,139,147,235,139,187,235,137,136,235,137,144,235,137,184,235,255,139,158, | ||
186 | 235,195,249,8,232,245,33,233,245,7,249,4,139,128,235,133,192,15,133,245,1, | ||
187 | 139,143,235,133,201,15,132,245,251,252,246,129,235,237,15,132,245,253,249, | ||
188 | 5,141,134,235,137,144,235,199,128,235,4,0,0,0,131,252,236,12,137,52,36,137, | ||
189 | 124,36,4,137,68,36,8,232,244,131,196,12,233,245,2,249,6,255,139,143,235,133, | ||
190 | 201,15,132,245,2,252,246,129,235,237,15,133,245,2,249,7,137,150,235,199,134, | ||
191 | 235,4,0,0,0,139,12,36,131,252,236,12,137,142,235,137,52,36,137,124,36,4,137, | ||
192 | 92,36,8,232,244,131,196,12,139,158,235,195,255,251,15,249,36,139,135,235, | ||
193 | 193,224,4,11,129,235,131,252,248,84,139,191,235,139,145,235,15,132,245,9, | ||
194 | 233,245,18,255,137,52,36,199,68,36,4,239,199,68,36,8,239,232,244,137,131, | ||
195 | 235,199,131,235,5,0,0,0,255,186,239,255,232,245,30,255,232,245,34,255,141, | ||
196 | 187,235,186,239,255,141,187,235,141,139,235,255,131,187,235,5,139,187,235, | ||
197 | 15,133,245,255,185,239,139,135,235,59,143,235,15,135,245,251,255,139,131, | ||
198 | 235,193,224,4,11,131,235,131,252,248,83,15,133,245,255,255,252,242,15,16, | ||
199 | 131,235,252,242,15,44,192,252,242,15,42,200,72,102,15,46,200,139,187,235, | ||
200 | 15,133,245,255,15,138,245,255,255,221,131,235,219,20,36,219,4,36,255,223, | ||
201 | 233,221,216,255,218,233,223,224,158,255,15,133,245,255,15,138,245,255,139, | ||
202 | 4,36,139,187,235,72,255,59,135,235,15,131,245,251,193,224,4,3,135,235,255, | ||
203 | 232,245,31,255,232,245,32,255,185,239,255,141,147,235,255,199,134,235,239, | ||
204 | 83,81,82,86,232,244,131,196,16,139,158,235,255,249,1,139,144,235,133,210, | ||
205 | 15,132,245,252,255,139,136,235,139,128,235,137,139,235,137,131,235,255,249, | ||
206 | 2,137,147,235,254,2,232,245,37,255,232,245,38,255,233,245,1,249,6,139,143, | ||
207 | 235,133,201,15,132,245,2,252,246,129,235,237,15,133,245,2,249,9,186,239,233, | ||
208 | 245,19,254,0,251,15,249,37,137,76,36,4,131,252,236,12,137,60,36,137,76,36, | ||
209 | 4,232,244,131,196,12,139,76,36,4,193,225,4,41,200,129,192,241,195,255,251, | ||
210 | 15,249,38,64,137,124,36,4,137,68,36,8,233,244,255,187,239,255,232,245,35, | ||
211 | 255,232,245,36,255,199,134,235,239,82,81,83,86,232,244,131,196,16,139,158, | ||
212 | 235,255,249,1,131,184,235,0,15,132,245,252,249,2,254,2,232,245,39,255,232, | ||
213 | 245,40,255,252,246,135,235,237,15,133,245,253,249,3,254,2,249,7,232,245,33, | ||
214 | 233,245,3,254,0,199,128,235,0,0,0,0,255,186,1,0,0,0,137,144,235,137,144,235, | ||
215 | 255,199,128,235,0,0,0,0,199,128,235,1,0,0,0,255,221,152,235,199,128,235,3, | ||
216 | 0,0,0,255,199,128,235,239,199,128,235,4,0,0,0,255,251,15,249,39,137,76,36, | ||
217 | 4,131,252,236,12,137,52,36,137,124,36,4,137,76,36,8,232,244,131,196,12,139, | ||
218 | 76,36,4,193,225,4,41,200,129,192,241,195,255,251,15,249,40,64,137,116,36, | ||
219 | 4,137,124,36,8,137,68,36,12,233,244,255,137,190,235,141,131,235,41,252,248, | ||
220 | 252,247,216,193,252,248,4,139,187,235,15,132,245,250,255,129,192,241,255, | ||
221 | 57,135,235,15,131,245,247,137,52,36,137,124,36,4,137,68,36,8,232,244,249, | ||
222 | 1,252,246,135,235,237,139,151,235,15,133,245,252,139,190,235,254,2,249,6, | ||
223 | 232,245,33,233,245,1,254,0,139,187,235,129,191,235,241,15,130,245,251,249, | ||
224 | 1,252,246,135,235,237,139,151,235,15,133,245,252,141,187,235,254,2,249,5, | ||
225 | 137,52,36,137,124,36,4,199,68,36,8,239,232,244,233,245,1,249,6,232,245,33, | ||
226 | 233,245,1,254,0,129,194,241,255,141,139,235,249,3,139,1,131,193,4,137,2,131, | ||
227 | 194,4,57,252,249,15,130,245,3,249,4,255,131,187,235,3,139,131,235,15,133, | ||
228 | 245,255,133,192,15,136,245,255,255,221,131,235,221,5,239,255,221,5,239,221, | ||
229 | 131,235,255,139,131,235,193,224,4,11,131,235,131,252,248,51,139,131,235,15, | ||
230 | 133,245,255,11,131,235,15,136,245,255,221,131,235,221,131,235,255,131,187, | ||
231 | 235,3,15,133,245,255,221,131,235,255,216,200,255,217,192,216,200,255,220, | ||
232 | 201,255,222,201,255,199,4,36,239,199,68,36,4,239,199,68,36,8,239,131,187, | ||
233 | 235,3,15,133,245,255,219,44,36,220,139,235,217,192,217,252,252,220,233,217, | ||
234 | 201,217,252,240,217,232,222,193,217,252,253,221,217,255,251,15,249,41,217, | ||
235 | 232,221,68,36,8,217,252,241,139,68,36,4,219,56,195,255,131,187,235,3,15,133, | ||
236 | 245,255,255,131,187,235,3,255,139,131,235,193,224,4,11,131,235,131,252,248, | ||
237 | 51,255,216,192,255,220,131,235,255,220,163,235,255,220,171,235,255,220,139, | ||
238 | 235,255,220,179,235,255,220,187,235,255,131,252,236,16,221,28,36,221,131, | ||
239 | 235,221,92,36,8,232,244,131,196,16,255,131,252,236,16,221,92,36,8,221,131, | ||
240 | 235,221,28,36,232,244,131,196,16,255,217,224,255,15,138,246,255,15,130,246, | ||
241 | 255,15,134,246,255,15,135,246,255,15,131,246,255,199,134,235,239,137,52,36, | ||
242 | 137,76,36,4,137,84,36,8,232,244,133,192,139,158,235,255,15,132,246,255,199, | ||
243 | 134,235,239,199,4,36,239,82,81,83,86,232,244,131,196,16,139,158,235,255,131, | ||
244 | 187,235,5,139,139,235,15,133,245,9,137,12,36,232,244,137,4,36,219,4,36,221, | ||
245 | 155,235,199,131,235,3,0,0,0,255,131,187,235,4,139,139,235,15,133,245,9,219, | ||
246 | 129,235,221,155,235,199,131,235,3,0,0,0,255,199,134,235,239,137,52,36,137, | ||
247 | 92,36,4,137,76,36,8,232,244,139,158,235,255,139,131,235,139,139,235,186,1, | ||
248 | 0,0,0,33,193,209,232,9,193,49,192,57,209,17,192,137,147,235,137,131,235,255, | ||
249 | 232,245,42,137,131,235,199,131,235,4,0,0,0,255,199,134,235,239,137,52,36, | ||
250 | 199,68,36,4,239,199,68,36,8,239,232,244,139,158,235,255,251,15,249,42,137, | ||
251 | 116,36,4,139,131,235,193,224,4,11,131,235,131,232,68,15,133,245,18,249,1, | ||
252 | 139,190,235,139,179,235,139,147,235,139,142,235,133,201,15,132,245,248,11, | ||
253 | 130,235,15,132,245,250,1,200,15,130,245,255,59,135,235,15,135,245,251,139, | ||
254 | 191,235,129,198,241,255,252,243,164,139,138,235,141,178,235,252,243,164,41, | ||
255 | 199,139,116,36,4,137,124,36,8,137,68,36,12,139,158,235,233,244,249,2,137, | ||
256 | 208,249,3,139,116,36,4,139,158,235,195,249,4,137,252,240,233,245,3,249,5, | ||
257 | 139,116,36,4,141,143,235,131,252,236,12,137,52,36,137,76,36,4,137,68,36,8, | ||
258 | 232,244,131,196,12,49,192,233,245,1,249,9,139,116,36,4,233,245,18,255,131, | ||
259 | 187,235,0,255,139,131,235,139,139,235,72,73,9,200,255,139,131,235,72,11,131, | ||
260 | 235,255,131,187,235,3,15,133,246,221,131,235,221,5,239,255,131,187,235,4, | ||
261 | 15,133,246,129,187,235,239,255,139,131,235,59,131,235,15,133,246,255,131, | ||
262 | 252,248,3,15,133,245,9,221,131,235,221,131,235,255,131,252,248,4,15,133,245, | ||
263 | 9,139,139,235,59,139,235,255,141,147,235,141,139,235,199,134,235,239,137, | ||
264 | 52,36,137,76,36,4,137,84,36,8,232,244,72,139,158,235,255,139,131,235,139, | ||
265 | 139,235,137,194,33,202,141,20,80,209,234,255,15,132,245,247,255,15,133,245, | ||
266 | 247,255,139,147,235,137,131,235,137,139,235,137,147,235,233,246,249,1,255, | ||
267 | 139,131,235,193,224,4,11,131,235,131,252,248,51,15,133,245,255,249,4,221, | ||
268 | 131,235,221,131,235,221,147,235,255,249,4,139,131,235,193,224,4,11,131,235, | ||
269 | 193,224,4,11,131,235,61,51,3,0,0,139,131,235,15,133,245,255,221,131,235,221, | ||
270 | 131,235,133,192,221,147,235,15,136,245,247,217,201,249,1,255,199,131,235, | ||
271 | 3,0,0,0,15,130,246,255,249,9,141,131,235,199,134,235,239,137,52,36,137,68, | ||
272 | 36,4,232,244,233,245,4,254,0,221,131,235,221,131,235,220,131,235,221,147, | ||
273 | 235,221,147,235,199,131,235,3,0,0,0,255,139,131,235,221,131,235,221,131,235, | ||
274 | 221,131,235,222,193,221,147,235,221,147,235,199,131,235,3,0,0,0,133,192,15, | ||
275 | 136,245,247,217,201,249,1,255,131,187,235,0,15,132,245,247,255,141,131,235, | ||
276 | 137,68,36,4,255,137,92,36,4,255,139,187,235,255,139,142,235,139,185,235,139, | ||
277 | 191,235,255,139,151,235,137,52,36,199,68,36,4,239,137,84,36,8,232,244,199, | ||
278 | 128,235,239,137,131,235,199,131,235,6,0,0,0,255,139,151,235,137,144,235,255, | ||
279 | 137,52,36,232,244,137,135,235,255,249,1,139,142,235,139,145,235,129,194,241, | ||
280 | 141,132,253,27,235,41,208,59,134,235,15,131,245,251,141,187,235,57,218,15, | ||
281 | 131,245,249,249,2,139,2,131,194,4,137,7,131,199,4,57,218,15,130,245,2,249, | ||
282 | 3,254,2,249,5,43,134,235,193,252,248,4,137,52,36,137,68,36,4,232,244,139, | ||
283 | 158,235,233,245,1,254,0,139,142,235,139,145,235,129,194,241,141,187,235,141, | ||
284 | 139,235,57,218,15,131,245,248,249,1,139,2,131,194,4,137,7,131,199,4,57,207, | ||
285 | 15,131,245,250,57,218,15,130,245,1,249,2,49,192,249,3,137,135,235,129,199, | ||
286 | 241,57,207,15,130,245,3,249,4,255 | ||
287 | }; | ||
288 | |||
289 | enum { | ||
290 | JSUB_STACKPTR, | ||
291 | JSUB_GATE_LJ, | ||
292 | JSUB_GATE_JL, | ||
293 | JSUB_GATE_JC, | ||
294 | JSUB_GROW_STACK, | ||
295 | JSUB_GROW_CI, | ||
296 | JSUB_GATE_JC_PATCH, | ||
297 | JSUB_GATE_JC_DEBUG, | ||
298 | JSUB_DEOPTIMIZE_CALLER, | ||
299 | JSUB_DEOPTIMIZE, | ||
300 | JSUB_DEOPTIMIZE_OPEN, | ||
301 | JSUB_HOOKINS, | ||
302 | JSUB_GCSTEP, | ||
303 | JSUB_STRING_SUB3, | ||
304 | JSUB_STRING_SUB2, | ||
305 | JSUB_HOOKCALL, | ||
306 | JSUB_HOOKRET, | ||
307 | JSUB_METACALL, | ||
308 | JSUB_METATAILCALL, | ||
309 | JSUB_BARRIERF, | ||
310 | JSUB_GETGLOBAL, | ||
311 | JSUB_GETTABLE_KSTR, | ||
312 | JSUB_GETTABLE_STR, | ||
313 | JSUB_BARRIERBACK, | ||
314 | JSUB_SETGLOBAL, | ||
315 | JSUB_SETTABLE_KSTR, | ||
316 | JSUB_SETTABLE_STR, | ||
317 | JSUB_GETTABLE_KNUM, | ||
318 | JSUB_GETTABLE_NUM, | ||
319 | JSUB_SETTABLE_KNUM, | ||
320 | JSUB_SETTABLE_NUM, | ||
321 | JSUB_LOG2_TWORD, | ||
322 | JSUB_CONCAT_STR2, | ||
323 | JSUB__MAX | ||
324 | }; | ||
325 | |||
326 | /* ------------------------------------------------------------------------ */ | ||
327 | |||
328 | /* Arch string. */ | ||
329 | const char luaJIT_arch[] = "x86"; | ||
330 | |||
331 | /* Forward declarations for C functions called from jsubs. */ | ||
332 | static void jit_hookins(lua_State *L, const Instruction *newpc); | ||
333 | static void jit_gettable_fb(lua_State *L, Table *t, StkId dest); | ||
334 | static void jit_settable_fb(lua_State *L, Table *t, StkId val); | ||
335 | |||
336 | /* ------------------------------------------------------------------------ */ | ||
337 | |||
338 | /* Detect CPU features and set JIT flags. */ | ||
339 | static int jit_cpudetect(jit_State *J) | ||
340 | { | ||
341 | void *mcode; | ||
342 | size_t sz; | ||
343 | int status; | ||
344 | /* Some of the jsubs need the flags. So compile this separately. */ | ||
345 | unsigned int feature; | ||
346 | dasm_setup(Dst, jit_actionlist); | ||
347 | dasm_put(Dst, 0); | ||
348 | (void)dasm_checkstep(Dst, DASM_SECTION_CODE); | ||
349 | status = luaJIT_link(J, &mcode, &sz); | ||
350 | if (status != JIT_S_OK) | ||
351 | return status; | ||
352 | /* Check feature bits. See the Intel/AMD manuals for the bit definitions. */ | ||
353 | feature = ((unsigned int (*)(void))mcode)(); | ||
354 | if (feature & (1<<15)) J->flags |= JIT_F_CPU_CMOV; | ||
355 | if (feature & (1<<26)) J->flags |= JIT_F_CPU_SSE2; | ||
356 | luaJIT_freemcode(J, mcode, sz); /* We don't need this code anymore. */ | ||
357 | return JIT_S_OK; | ||
358 | } | ||
359 | |||
360 | /* Check some assumptions. Should compile to nop. */ | ||
361 | static int jit_consistency_check(jit_State *J) | ||
362 | { | ||
363 | do { | ||
364 | /* Force a compiler error for inconsistent structure sizes. */ | ||
365 | /* Check LUA_TVALUE_ALIGN in luaconf.h, too. */ | ||
366 | int check_TVALUE_SIZE_in_ljit_x86_dash[1+16-sizeof(TValue)]; | ||
367 | int check_TVALUE_SIZE_in_ljit_x86_dash_[1+sizeof(TValue)-16]; | ||
368 | ((void)check_TVALUE_SIZE_in_ljit_x86_dash[0]); | ||
369 | ((void)check_TVALUE_SIZE_in_ljit_x86_dash_[0]); | ||
370 | if (LUA_TNIL != 0 || LUA_TBOOLEAN != 1 || PCRLUA != 0) break; | ||
371 | if ((int)&(((Node *)0)->i_val) != (int)&(((StkId)0)->value)) break; | ||
372 | return JIT_S_OK; | ||
373 | } while (0); | ||
374 | J->dasmstatus = 999999999; /* Recognizable error. */ | ||
375 | return JIT_S_COMPILER_ERROR; | ||
376 | } | ||
377 | |||
378 | /* Compile JIT subroutines (once). */ | ||
379 | static int jit_compile_jsub(jit_State *J) | ||
380 | { | ||
381 | int status = jit_consistency_check(J); | ||
382 | if (status != JIT_S_OK) return status; | ||
383 | status = jit_cpudetect(J); | ||
384 | if (status != JIT_S_OK) return status; | ||
385 | dasm_setup(Dst, jit_actionlist); | ||
386 | dasm_put(Dst, 34); | ||
387 | dasm_put(Dst, 36, Dt1(->top), Dt2(->value), Dt1(->ci), Dt1(->nCcalls), Dt5(->jit_gate), Dt1(->ci), Dt1(->top), Dt4(->savedpc), Dt1(->savedpc), Dt4(->base), Dt1(->base), Dt1(->top), Dt3(->tt), sizeof(TValue)); | ||
388 | dasm_put(Dst, 145, Dt1(->nCcalls), PCRC, Dt5(->p), DtE(->jit_status), JIT_S_OK, DtE(->jit_mcode), Dt5(->jit_gate), Dt4(->savedpc), Dt1(->ci), Dt1(->top), Dt1(->savedpc), Dt1(->stack), (ptrdiff_t)(luaD_precall), (ptrdiff_t)(luaV_execute), Dt1(->stack)); | ||
389 | dasm_put(Dst, 262, Dt1(->top), Dt3([LUA_MINSTACK]), Dt1(->stack_last), Dt1(->end_ci), Dt4([1]), Dt1(->ci), Dt4(->func), Dt4(->top), Dt2(->value), sizeof(TValue), Dt1(->top), Dt1(->base), Dt4(->base), DtD(->f), Dt1(->ci)); | ||
390 | dasm_put(Dst, 336, Dt4(->func), Dt1(->top), Dt4(->func), sizeof(CallInfo), Dt1(->ci), Dt1(->hookmask), LUA_MASKCALL, DtD(->f), Dt1(->hookmask), LUA_MASKRET); | ||
391 | dasm_put(Dst, 421, LUA_HOOKRET, (ptrdiff_t)(luaD_callhook), LUA_HOOKCALL, (ptrdiff_t)(luaD_callhook), Dt1(->top), Dt1(->stack), (ptrdiff_t)(luaD_growstack), Dt1(->stack), Dt1(->top), Dt2(->value), Dt5(->jit_gate), Dt1(->top), (ptrdiff_t)(luaD_growCI), Dt9([-1])); | ||
392 | dasm_put(Dst, 547, Dt2(->value), Dt1(->ci), Dt5(->jit_gate)); | ||
393 | dasm_put(Dst, 602, Dt1(->hookmask), LUA_MASKLINE|LUA_MASKCOUNT, Dt1(->hookcount), Dt1(->hookmask), LUA_MASKLINE, (ptrdiff_t)(jit_hookins), Dt1(->base), Dt1(->top)); | ||
394 | dasm_put(Dst, 737, (ptrdiff_t)(luaC_step), Dt1(->base)); | ||
395 | dasm_put(Dst, 1026, Dt3([0].tt), Dt3([1].tt), Dt3([2].tt), Dt3([1].value), Dt3([2].value), Dt3([0].value), DtB(->tsv.len), sizeof(TString)-1, Dt1(->l_G), Dt6(->totalbytes)); | ||
396 | dasm_put(Dst, 1129, Dt6(->GCthreshold), (ptrdiff_t)(luaS_newlstr)); | ||
397 | dasm_put(Dst, 1191, Dt3([0].tt), Dt3([1].tt), Dt3([1].value), Dt3([0].value), DtB(->tsv.len), (ptrdiff_t)(luaC_step), Dt1(->base), (ptrdiff_t)(luaS_newlstr)); | ||
398 | dasm_put(Dst, 1755, Dt1(->ci), Dt4(->func), Dt3(->value), Dt5(->p), DtE(->code), Dt1(->savedpc), LUA_HOOKCALL, (ptrdiff_t)(luaD_callhook), DtE(->code), Dt1(->savedpc), Dt1(->base)); | ||
399 | dasm_put(Dst, 1886, Dt1(->savedpc), LUA_HOOKRET, (ptrdiff_t)(luaD_callhook), Dt1(->base), Dt1(->top)); | ||
400 | dasm_put(Dst, 2077, Dt1(->savedpc), Dt1(->top), (ptrdiff_t)(luaD_tryfuncTM), Dt1(->top), Dt2(->value), Dt1(->ci)); | ||
401 | dasm_put(Dst, 2178, Dt1(->savedpc), Dt1(->top), (ptrdiff_t)(luaD_tryfuncTM), Dt1(->ci), Dt1(->top), Dt4(->func), Dt4(->func), Dt2(->value), sizeof(CallInfo), Dt5(->jit_gate)); | ||
402 | dasm_put(Dst, 2570, (ptrdiff_t)(luaC_barrierf)); | ||
403 | dasm_put(Dst, 2589, Dt1(->ci), Dt4(->func), Dt3(->value), Dt5(->env)); | ||
404 | dasm_put(Dst, 2609, Dt3(->tt), Dt3(->value), DtC(->lsizenode), DtB(->tsv.hash), DtC(->node), Dt10(->i_key.nk.tt), Dt10(->i_key.nk.value), Dt10(->i_val.tt)); | ||
405 | if (J->flags & JIT_F_CPU_SSE2) { | ||
406 | dasm_put(Dst, 2674, Dt10(->i_val.value), Dt2(->value)); | ||
407 | } else { | ||
408 | dasm_put(Dst, 2686, Dt10(->i_val.value), Dt10(->i_val.value.na[1]), Dt2(->value), Dt2(->value.na[1])); | ||
409 | } | ||
410 | dasm_put(Dst, 2699, Dt2(->tt), Dt1(->base), Dt10(->i_key.nk.next), DtC(->metatable), DtC(->flags), 1<<TM_INDEX, Dt2([0].tt), Dt1(->base), Dt1(->env.value), Dt1(->env.tt), Dt1(->savedpc), (ptrdiff_t)(jit_gettable_fb), Dt1(->base)); | ||
411 | dasm_put(Dst, 32); | ||
412 | dasm_put(Dst, 2790, Dt3(->tt), Dt7(->tt), Dt3(->value), Dt7(->value)); | ||
413 | dasm_put(Dst, 2821, Dt1(->l_G), DtC(->marked), (~bitmask(BLACKBIT))&0xff, Dt6(->grayagain), Dt6(->grayagain), DtC(->gclist)); | ||
414 | dasm_put(Dst, 2843, Dt1(->ci), Dt4(->func), Dt3(->value), Dt5(->env)); | ||
415 | dasm_put(Dst, 2863, Dt3(->tt), Dt3(->value), DtC(->lsizenode), DtB(->tsv.hash), DtC(->node), Dt10(->i_key.nk.tt), Dt10(->i_key.nk.value), Dt10(->i_val.tt), DtC(->flags)); | ||
416 | dasm_put(Dst, 2935, DtC(->marked), bitmask(BLACKBIT)); | ||
417 | if (J->flags & JIT_F_CPU_SSE2) { | ||
418 | dasm_put(Dst, 2947, Dt2([0].tt), Dt2([0].value), Dt7([0].tt), Dt7([0].value)); | ||
419 | } else { | ||
420 | dasm_put(Dst, 2965, Dt2([0].value), Dt2([0].value.na[1]), Dt2([0].tt), Dt7([0].value), Dt7([0].value.na[1]), Dt7([0].tt)); | ||
421 | } | ||
422 | dasm_put(Dst, 2984, Dt1(->base), Dt10(->i_key.nk.next), DtC(->metatable), DtC(->flags), 1<<TM_NEWINDEX, Dt1(->env), Dt7([0].value), Dt7([0].tt), (ptrdiff_t)(luaH_newkey)); | ||
423 | dasm_put(Dst, 3066, DtC(->metatable), DtC(->flags), 1<<TM_NEWINDEX, Dt1(->env.value), Dt1(->env.tt), Dt1(->savedpc), (ptrdiff_t)(jit_settable_fb), Dt1(->base)); | ||
424 | dasm_put(Dst, 3127, Dt3(->tt), Dt7(->tt), Dt3(->value), Dt7(->value)); | ||
425 | dasm_put(Dst, 3438, (ptrdiff_t)(luaH_getnum), sizeof(TValue)); | ||
426 | dasm_put(Dst, 3476, (ptrdiff_t)(luaH_getnum)); | ||
427 | dasm_put(Dst, 3623, (ptrdiff_t)(luaH_setnum), sizeof(TValue)); | ||
428 | dasm_put(Dst, 3665, (ptrdiff_t)(luaH_setnum)); | ||
429 | dasm_put(Dst, 3992); | ||
430 | dasm_put(Dst, 4325, Dt2([0].tt), Dt2([1].tt), Dt1(->l_G), Dt2([0].value), Dt2([1].value), DtB(->tsv.len), DtB(->tsv.len), Dt6(->buff.buffsize), Dt6(->buff.buffer), sizeof(TString)); | ||
431 | dasm_put(Dst, 4396, DtB(->tsv.len), DtB([1]), Dt1(->base), (ptrdiff_t)(luaS_newlstr), Dt1(->base), Dt6(->buff), (ptrdiff_t)(luaZ_openspace)); | ||
432 | dasm_put(Dst, 561, Dt1(->top), Dt1(->savedpc), (ptrdiff_t)(luaJIT_deoptimize), Dt1(->base), Dt1(->top)); | ||
433 | |||
434 | (void)dasm_checkstep(Dst, DASM_SECTION_CODE); | ||
435 | status = luaJIT_link(J, &J->jsubmcode, &J->szjsubmcode); | ||
436 | if (status != JIT_S_OK) | ||
437 | return status; | ||
438 | |||
439 | /* Copy the callgates from the globals to the global state. */ | ||
440 | G(J->L)->jit_gateLJ = (luaJIT_GateLJ)J->jsub[JSUB_GATE_LJ]; | ||
441 | G(J->L)->jit_gateJL = (lua_CFunction)J->jsub[JSUB_GATE_JL]; | ||
442 | G(J->L)->jit_gateJC = (lua_CFunction)J->jsub[JSUB_GATE_JC]; | ||
443 | return JIT_S_OK; | ||
444 | } | ||
445 | |||
446 | /* Match with number of nops above. Avoid confusing the instruction decoder. */ | ||
447 | #define DEBUGPATCH_SIZE 6 | ||
448 | |||
449 | /* Notify backend that the debug mode may have changed. */ | ||
450 | void luaJIT_debugnotify(jit_State *J) | ||
451 | { | ||
452 | unsigned char *patch = (unsigned char *)J->jsub[JSUB_GATE_JC_PATCH]; | ||
453 | unsigned char *target = (unsigned char *)J->jsub[JSUB_GATE_JC_DEBUG]; | ||
454 | /* Yep, this is self-modifying code -- don't tell anyone. */ | ||
455 | if (patch[0] == 0xe9) { /* Debug patch is active. */ | ||
456 | if (!(J->flags & JIT_F_DEBUG_CALL)) /* Deactivate it. */ | ||
457 | memcpy(patch, target-DEBUGPATCH_SIZE, DEBUGPATCH_SIZE); | ||
458 | } else { /* Debug patch is inactive. */ | ||
459 | if (J->flags & JIT_F_DEBUG_CALL) { /* Activate it. */ | ||
460 | int rel = target-(patch+5); | ||
461 | memcpy(target-DEBUGPATCH_SIZE, patch, DEBUGPATCH_SIZE); | ||
462 | patch[0] = 0xe9; /* jmp */ | ||
463 | memcpy(patch+1, &rel, 4); /* Relative address. */ | ||
464 | memset(patch+5, 0x90, DEBUGPATCH_SIZE-5); /* nop */ | ||
465 | } | ||
466 | } | ||
467 | } | ||
468 | |||
469 | /* Patch a jmp into existing mcode. */ | ||
470 | static void jit_patch_jmp(jit_State *J, void *mcode, void *to) | ||
471 | { | ||
472 | unsigned char *patch = (unsigned char *)mcode; | ||
473 | int rel = ((unsigned char *)to)-(patch+5); | ||
474 | patch[0] = 0xe9; /* jmp */ | ||
475 | memcpy((void *)(patch+1), &rel, 4); /* Relative addr. */ | ||
476 | } | ||
477 | |||
478 | /* ------------------------------------------------------------------------ */ | ||
479 | |||
480 | /* Call line/count hook. */ | ||
481 | static void jit_hookins(lua_State *L, const Instruction *newpc) | ||
482 | { | ||
483 | Proto *pt = ci_func(L->ci)->l.p; | ||
484 | int pc = luaJIT_findpc(pt, newpc); /* Sloooow with mcode addrs. */ | ||
485 | const Instruction *savedpc = L->savedpc; | ||
486 | L->savedpc = pt->code + pc + 1; | ||
487 | if (L->hookmask > LUA_MASKLINE && L->hookcount == 0) { | ||
488 | resethookcount(L); | ||
489 | luaD_callhook(L, LUA_HOOKCOUNT, -1); | ||
490 | } | ||
491 | if (L->hookmask & LUA_MASKLINE) { | ||
492 | int newline = getline(pt, pc); | ||
493 | if (pc != 0) { | ||
494 | int oldpc = luaJIT_findpc(pt, savedpc); | ||
495 | if (!(pc <= oldpc || newline != getline(pt, oldpc))) return; | ||
496 | } | ||
497 | luaD_callhook(L, LUA_HOOKLINE, newline); | ||
498 | } | ||
499 | } | ||
500 | |||
501 | /* Insert hook check for each instruction in full debug mode. */ | ||
502 | static void jit_ins_debug(jit_State *J, int openop) | ||
503 | { | ||
504 | if (openop) { | ||
505 | dasm_put(Dst, 594, Dt1(->top)); | ||
506 | } | ||
507 | dasm_put(Dst, 598); | ||
508 | |||
509 | } | ||
510 | |||
511 | /* Called before every instruction. */ | ||
512 | static void jit_ins_start(jit_State *J) | ||
513 | { | ||
514 | dasm_put(Dst, 663, J->nextpc); | ||
515 | } | ||
516 | |||
517 | /* Chain to another instruction. */ | ||
518 | static void jit_ins_chainto(jit_State *J, int pc) | ||
519 | { | ||
520 | dasm_put(Dst, 665, pc); | ||
521 | } | ||
522 | |||
523 | /* Set PC label. */ | ||
524 | static void jit_ins_setpc(jit_State *J, int pc, void *target) | ||
525 | { | ||
526 | dasm_put(Dst, 668, pc, (ptrdiff_t)(target)); | ||
527 | } | ||
528 | |||
529 | /* Called after the last instruction has been encoded. */ | ||
530 | static void jit_ins_last(jit_State *J, int lastpc, int sizemfm) | ||
531 | { | ||
532 | if (J->tflags & JIT_TF_USED_DEOPT) { /* Deopt section has been used? */ | ||
533 | dasm_put(Dst, 671); | ||
534 | dasm_put(Dst, 673); | ||
535 | } | ||
536 | dasm_put(Dst, 678, lastpc+1); | ||
537 | dasm_put(Dst, 681, lastpc+2); | ||
538 | dasm_put(Dst, 690, sizemfm); | ||
539 | } | ||
540 | |||
541 | /* Add a deoptimize target for the current instruction. */ | ||
542 | static void jit_deopt_target(jit_State *J, int nargs) | ||
543 | { | ||
544 | if (nargs != -1) { | ||
545 | dasm_put(Dst, 671); | ||
546 | dasm_put(Dst, 702, (ptrdiff_t)(J->nextins)); | ||
547 | J->tflags |= JIT_TF_USED_DEOPT; | ||
548 | } else { | ||
549 | dasm_put(Dst, 679); | ||
550 | dasm_put(Dst, 709, (ptrdiff_t)(J->nextins)); | ||
551 | } | ||
552 | } | ||
553 | |||
554 | /* luaC_checkGC() inlined. Destroys caller-saves + TOP (edi). Uses label 7:. */ | ||
555 | /* Use this only at the _end_ of an instruction. */ | ||
556 | static void jit_checkGC(jit_State *J) | ||
557 | { | ||
558 | dasm_put(Dst, 718, Dt1(->l_G), Dt6(->totalbytes), Dt6(->GCthreshold)); | ||
559 | |||
560 | } | ||
561 | |||
562 | /* ------------------------------------------------------------------------ */ | ||
563 | |||
564 | |||
565 | |||
566 | /* | ||
567 | ** Function inlining support for x86 CPUs. | ||
568 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
569 | */ | ||
570 | |||
571 | /* ------------------------------------------------------------------------ */ | ||
572 | |||
573 | /* Private structure holding function inlining info. */ | ||
574 | typedef struct jit_InlineInfo { | ||
575 | int func; /* Function slot. 1st arg slot = func+1. */ | ||
576 | int res; /* 1st result slot. Overlaps func/ci->func. */ | ||
577 | int nargs; /* Number of args. */ | ||
578 | int nresults; /* Number of results. */ | ||
579 | int xnargs; /* Expected number of args. */ | ||
580 | int xnresults; /* Returned number of results. */ | ||
581 | int hidx; /* Library/function index numbers. */ | ||
582 | } jit_InlineInfo; | ||
583 | |||
584 | /* ------------------------------------------------------------------------ */ | ||
585 | |||
586 | enum { TFOR_FUNC, TFOR_TAB, TFOR_CTL, TFOR_KEY, TFOR_VAL }; | ||
587 | |||
588 | static void jit_inline_base(jit_State *J, jit_InlineInfo *ii) | ||
589 | { | ||
590 | int func = ii->func; | ||
591 | switch (JIT_IH_IDX(ii->hidx)) { | ||
592 | case JIT_IH_BASE_PAIRS: | ||
593 | case JIT_IH_BASE_IPAIRS: | ||
594 | dasm_put(Dst, 753, Dt2([func+TFOR_TAB].tt), Dt2([func+TFOR_CTL].tt), Dt2([func+TFOR_CTL].value)); | ||
595 | dasm_put(Dst, 771, JIT_MFM_DEOPT_PAIRS, J->nextpc-1); | ||
596 | break; | ||
597 | default: | ||
598 | jit_assert(0); | ||
599 | break; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | /* ------------------------------------------------------------------------ */ | ||
604 | |||
605 | #ifndef COCO_DISABLE | ||
606 | |||
607 | /* Helper function for inlined coroutine.resume(). */ | ||
608 | static StkId jit_coroutine_resume(lua_State *L, StkId base, int nresults) | ||
609 | { | ||
610 | lua_State *co = thvalue(base-1); | ||
611 | /* Check for proper usage. Merge of lua_resume() and auxresume() checks. */ | ||
612 | if (co->status != LUA_YIELD) { | ||
613 | if (co->status > LUA_YIELD) { | ||
614 | errdead: | ||
615 | setsvalue(L, base-1, luaS_newliteral(L, "cannot resume dead coroutine")); | ||
616 | goto err; | ||
617 | } else if (co->ci != co->base_ci) { | ||
618 | setsvalue(L, base-1, | ||
619 | luaS_newliteral(L, "cannot resume non-suspended coroutine")); | ||
620 | goto err; | ||
621 | } else if (co->base == co->top) { | ||
622 | goto errdead; | ||
623 | } | ||
624 | } | ||
625 | { | ||
626 | ptrdiff_t ndelta = (char *)L->top - (char *)base; | ||
627 | int nargs = ndelta/sizeof(TValue); /* Compute nargs. */ | ||
628 | int status; | ||
629 | if ((char *)co->stack_last-(char *)co->top <= ndelta) { | ||
630 | co->ci->top = (StkId)(((char *)co->top) + ndelta); /* Ok before grow. */ | ||
631 | luaD_growstack(co, nargs); /* Grow thread stack. */ | ||
632 | } | ||
633 | /* Copy args. */ | ||
634 | co->top = (StkId)(((char *)co->top) + ndelta); | ||
635 | { StkId t = co->top, f = L->top; while (f > base) setobj2s(co, --t, --f); } | ||
636 | L->top = base; | ||
637 | status = luaCOCO_resume(co, nargs); /* Resume Coco thread. */ | ||
638 | if (status == 0 || status == LUA_YIELD) { /* Ok. */ | ||
639 | StkId f; | ||
640 | if (nresults == 0) return NULL; | ||
641 | if (nresults == -1) { | ||
642 | luaD_checkstack(L, co->top - co->base); /* Grow own stack. */ | ||
643 | } | ||
644 | base = L->top - 2; | ||
645 | setbvalue(base++, 1); /* true */ | ||
646 | /* Copy results. Fill unused result slots with nil. */ | ||
647 | f = co->base; | ||
648 | while (--nresults != 0 && f < co->top) setobj2s(L, base++, f++); | ||
649 | while (nresults-- > 0) setnilvalue(base++); | ||
650 | co->top = co->base; | ||
651 | return base; | ||
652 | } else { /* Error. */ | ||
653 | base = L->top; | ||
654 | setobj2s(L, base-1, co->top-1); /* Copy error object. */ | ||
655 | err: | ||
656 | setbvalue(base-2, 0); /* false */ | ||
657 | nresults -= 2; | ||
658 | while (--nresults >= 0) setnilvalue(base+nresults); /* Fill results. */ | ||
659 | return base; | ||
660 | } | ||
661 | } | ||
662 | } | ||
663 | |||
664 | static void jit_inline_coroutine(jit_State *J, jit_InlineInfo *ii) | ||
665 | { | ||
666 | int arg = ii->func+1; | ||
667 | int res = ii->res; | ||
668 | int i; | ||
669 | switch (JIT_IH_IDX(ii->hidx)) { | ||
670 | case JIT_IH_COROUTINE_YIELD: | ||
671 | dasm_put(Dst, 775, ((int)&LHASCOCO((lua_State *)0)), Dt1(->savedpc), (ptrdiff_t)(J->nextins), arg*sizeof(TValue)); | ||
672 | if (ii->nargs >= 0) { /* Previous op was not open and did not set TOP. */ | ||
673 | dasm_put(Dst, 791, Dt2([ii->nargs])); | ||
674 | } | ||
675 | dasm_put(Dst, 795, Dt1(->base), Dt1(->top), (ptrdiff_t)(luaCOCO_yield), Dt1(->base), Dt1(->top)); | ||
676 | jit_assert(ii->nresults >= 0 && ii->nresults <= EXTRA_STACK); | ||
677 | for (i = 0; i < ii->nresults; i++) { | ||
678 | dasm_put(Dst, 813, Dt3([i].tt)); | ||
679 | if (J->flags & JIT_F_CPU_SSE2) { | ||
680 | dasm_put(Dst, 821, Dt2([arg+i].tt), Dt2([arg+i].value), Dt2([res+i].tt), Dt2([res+i].value)); | ||
681 | } else { | ||
682 | dasm_put(Dst, 839, Dt2([arg+i].value), Dt2([arg+i].value.na[1]), Dt2([arg+i].tt), Dt2([res+i].value), Dt2([res+i].value.na[1]), Dt2([res+i].tt)); | ||
683 | } | ||
684 | } | ||
685 | ii->nargs = -1; /* Force restore of L->top. */ | ||
686 | break; | ||
687 | case JIT_IH_COROUTINE_RESUME: | ||
688 | jit_assert(ii->nargs != 0 && ii->res == ii->func); | ||
689 | dasm_put(Dst, 787, (arg+1)*sizeof(TValue)); | ||
690 | if (ii->nargs >= 0) { /* Previous op was not open and did not set TOP. */ | ||
691 | dasm_put(Dst, 791, Dt2([ii->nargs-1])); | ||
692 | } else { | ||
693 | dasm_put(Dst, 858); | ||
694 | } | ||
695 | dasm_put(Dst, 865, Dt2([-1].tt), Dt2([-1].value), ((int)&LHASCOCO((lua_State *)0)), Dt1(->savedpc), (ptrdiff_t)(J->nextins), Dt1(->top), ii->nresults, (ptrdiff_t)(jit_coroutine_resume), Dt1(->base)); | ||
696 | if (ii->nresults == -1) { | ||
697 | dasm_put(Dst, 909); | ||
698 | } | ||
699 | ii->nargs = -1; /* Force restore of L->top. */ | ||
700 | break; | ||
701 | default: | ||
702 | jit_assert(0); | ||
703 | break; | ||
704 | } | ||
705 | } | ||
706 | |||
707 | #endif /* COCO_DISABLE */ | ||
708 | |||
709 | /* ------------------------------------------------------------------------ */ | ||
710 | |||
711 | static void jit_inline_string(jit_State *J, jit_InlineInfo *ii) | ||
712 | { | ||
713 | int arg = ii->func+1; | ||
714 | int res = ii->res; | ||
715 | switch (JIT_IH_IDX(ii->hidx)) { | ||
716 | case JIT_IH_STRING_LEN: | ||
717 | dasm_put(Dst, 912, Dt2([arg].tt), Dt2([arg].value), DtB(->tsv.len), Dt2([res].tt), Dt2([res].value)); | ||
718 | break; | ||
719 | case JIT_IH_STRING_SUB: | ||
720 | /* TODO: inline numeric constants with help from the optimizer. */ | ||
721 | /* But this would save only another 15-20% in a trivial loop. */ | ||
722 | jit_assert(ii->nargs >= 2); /* Open op caveat is ok, too. */ | ||
723 | if (ii->nargs > 2) { | ||
724 | dasm_put(Dst, 937, Dt2([arg]), Dt2([res].value), Dt2([res].tt)); | ||
725 | } else { | ||
726 | dasm_put(Dst, 954, Dt2([arg]), Dt2([res].value), Dt2([res].tt)); | ||
727 | } | ||
728 | break; | ||
729 | case JIT_IH_STRING_CHAR: | ||
730 | dasm_put(Dst, 971, Dt2([arg].tt), Dt1(->env), Dt2([arg].value), (ptrdiff_t)(luaS_newlstr), Dt2([res].value), Dt2([res].tt)); | ||
731 | break; | ||
732 | default: | ||
733 | jit_assert(0); | ||
734 | break; | ||
735 | } | ||
736 | |||
737 | } | ||
738 | |||
739 | /* ------------------------------------------------------------------------ */ | ||
740 | |||
741 | /* Helper functions for inlined calls to table.*. */ | ||
742 | static void jit_table_insert(lua_State *L, TValue *arg) | ||
743 | { | ||
744 | setobj2t(L, luaH_setnum(L, hvalue(arg), luaH_getn(hvalue(arg))+1), arg+1); | ||
745 | luaC_barriert(L, hvalue(arg), arg+1); | ||
746 | } | ||
747 | |||
748 | static TValue *jit_table_remove(lua_State *L, TValue *arg, TValue *res) | ||
749 | { | ||
750 | int n = luaH_getn(hvalue(arg)); | ||
751 | if (n == 0) { | ||
752 | setnilvalue(res); /* For the nresults == 1 case. Harmless otherwise. */ | ||
753 | return res; /* For the nresults == -1 case. */ | ||
754 | } else { | ||
755 | TValue *val = luaH_setnum(L, hvalue(arg), n); | ||
756 | setobj2s(L, res, val); | ||
757 | setnilvalue(val); | ||
758 | return res+1; /* For the nresults == -1 case. */ | ||
759 | } | ||
760 | } | ||
761 | |||
762 | static void jit_inline_table(jit_State *J, jit_InlineInfo *ii) | ||
763 | { | ||
764 | int arg = ii->func+1; | ||
765 | int res = ii->res; | ||
766 | dasm_put(Dst, 1250, Dt2([arg].tt)); | ||
767 | switch (JIT_IH_IDX(ii->hidx)) { | ||
768 | case JIT_IH_TABLE_INSERT: | ||
769 | dasm_put(Dst, 1259, Dt2([arg]), (ptrdiff_t)(jit_table_insert)); | ||
770 | break; | ||
771 | case JIT_IH_TABLE_REMOVE: | ||
772 | dasm_put(Dst, 1272, Dt2([arg]), Dt2([res]), (ptrdiff_t)(jit_table_remove)); | ||
773 | if (ii->nresults == -1) { | ||
774 | ii->xnresults = -1; | ||
775 | dasm_put(Dst, 909); | ||
776 | } | ||
777 | break; | ||
778 | case JIT_IH_TABLE_GETN: | ||
779 | dasm_put(Dst, 1292, Dt2([arg].value), (ptrdiff_t)(luaH_getn), Dt2([res].value), Dt2([res].tt)); | ||
780 | break; | ||
781 | default: | ||
782 | jit_assert(0); | ||
783 | break; | ||
784 | } | ||
785 | } | ||
786 | |||
787 | /* ------------------------------------------------------------------------ */ | ||
788 | |||
789 | /* This typedef must match the libm function signature. */ | ||
790 | /* Serves as a check against wrong lua_Number or wrong calling conventions. */ | ||
791 | typedef lua_Number (*mathfunc_11)(lua_Number); | ||
792 | |||
793 | /* Partially inlined math functions. */ | ||
794 | /* CHECK: must match with jit_hints.h and jit.opt_lib. */ | ||
795 | static const mathfunc_11 jit_mathfuncs_11[JIT_IH_MATH_SIN] = { | ||
796 | log, log10, exp, sinh, cosh, tanh, asin, acos, atan | ||
797 | }; | ||
798 | |||
799 | /* FPU control words for ceil and floor (exceptions masked, full precision). */ | ||
800 | static const unsigned short jit_fpucw[2] = { 0x0b7f, 0x077f }; | ||
801 | |||
802 | static void jit_inline_math(jit_State *J, jit_InlineInfo *ii) | ||
803 | { | ||
804 | int arg = ii->func+1; | ||
805 | int res = ii->res; | ||
806 | int idx = JIT_IH_IDX(ii->hidx); | ||
807 | |||
808 | if (idx < JIT_IH_MATH__21) { | ||
809 | dasm_put(Dst, 1317, Dt2([arg].tt), Dt2([arg].value)); | ||
810 | } else { | ||
811 | jit_assert(idx < JIT_IH_MATH__LAST); | ||
812 | dasm_put(Dst, 1329, Dt2([arg].tt), Dt2([arg+1].tt)); | ||
813 | } | ||
814 | switch (idx) { | ||
815 | /* We ignore sin/cos/tan range overflows (2^63 rad) just like -ffast-math. */ | ||
816 | case JIT_IH_MATH_SIN: | ||
817 | dasm_put(Dst, 1347); | ||
818 | break; | ||
819 | case JIT_IH_MATH_COS: | ||
820 | dasm_put(Dst, 1351); | ||
821 | break; | ||
822 | case JIT_IH_MATH_TAN: | ||
823 | dasm_put(Dst, 1355); | ||
824 | break; | ||
825 | case JIT_IH_MATH_CEIL: | ||
826 | case JIT_IH_MATH_FLOOR: | ||
827 | dasm_put(Dst, 1361, (ptrdiff_t)&jit_fpucw[idx-JIT_IH_MATH_CEIL]); | ||
828 | break; | ||
829 | case JIT_IH_MATH_ABS: | ||
830 | dasm_put(Dst, 1374); | ||
831 | break; | ||
832 | case JIT_IH_MATH_SQRT: | ||
833 | dasm_put(Dst, 1377); | ||
834 | break; | ||
835 | case JIT_IH_MATH_FMOD: | ||
836 | dasm_put(Dst, 1381, Dt2([arg+1].value), Dt2([arg].value)); | ||
837 | break; | ||
838 | case JIT_IH_MATH_ATAN2: | ||
839 | dasm_put(Dst, 1402, Dt2([arg].value), Dt2([arg+1].value)); | ||
840 | break; | ||
841 | default: | ||
842 | dasm_put(Dst, 1412, (ptrdiff_t)(jit_mathfuncs_11[idx])); | ||
843 | break; | ||
844 | } | ||
845 | dasm_put(Dst, 926, Dt2([res].tt), Dt2([res].value)); | ||
846 | } | ||
847 | |||
848 | /* ------------------------------------------------------------------------ */ | ||
849 | |||
850 | /* Try to inline a CALL or TAILCALL instruction. */ | ||
851 | static int jit_inline_call(jit_State *J, int func, int nargs, int nresults) | ||
852 | { | ||
853 | const TValue *callable = hint_get(J, TYPE); /* TYPE hint = callable. */ | ||
854 | int cltype = ttype(callable); | ||
855 | const TValue *oidx; | ||
856 | jit_InlineInfo ii; | ||
857 | int idx; | ||
858 | |||
859 | if (cltype != LUA_TFUNCTION) goto fail; | ||
860 | if (J->flags & JIT_F_DEBUG) goto fail; /* DWIM. */ | ||
861 | |||
862 | oidx = hint_get(J, INLINE); /* INLINE hint = library/function index. */ | ||
863 | if (!ttisnumber(oidx)) goto fail; | ||
864 | |||
865 | ii.hidx = (int)nvalue(oidx); | ||
866 | idx = JIT_IH_IDX(ii.hidx); | ||
867 | |||
868 | if (nresults == -2) { /* Tailcall. */ | ||
869 | /* Tailcalls from vararg functions don't work with BASE[-1]. */ | ||
870 | if (J->pt->is_vararg) goto fail; /* So forget about this rare case. */ | ||
871 | ii.res = -1; /* Careful: 2nd result overlaps 1st stack slot. */ | ||
872 | ii.nresults = -1; | ||
873 | } else { | ||
874 | ii.res = func; | ||
875 | ii.nresults = nresults; | ||
876 | } | ||
877 | ii.func = func; | ||
878 | ii.nargs = nargs; | ||
879 | ii.xnargs = ii.xnresults = 1; /* Default: 1 arg, 1 result. */ | ||
880 | |||
881 | /* Check for the currently supported cases. */ | ||
882 | switch (JIT_IH_LIB(ii.hidx)) { | ||
883 | case JIT_IHLIB_BASE: | ||
884 | switch (idx) { | ||
885 | case JIT_IH_BASE_PAIRS: | ||
886 | case JIT_IH_BASE_IPAIRS: | ||
887 | if (nresults == -2) goto fail; /* Not useful for tailcalls. */ | ||
888 | ii.xnresults = 3; | ||
889 | goto check; | ||
890 | } | ||
891 | break; | ||
892 | #ifndef COCO_DISABLE | ||
893 | case JIT_IHLIB_COROUTINE: | ||
894 | switch (idx) { | ||
895 | case JIT_IH_COROUTINE_YIELD: | ||
896 | /* Only support common cases: no tailcalls, low number of results. */ | ||
897 | if (nresults < 0 || nresults > EXTRA_STACK) goto fail; | ||
898 | ii.xnargs = ii.xnresults = -1; | ||
899 | goto ok; /* Anything else is ok. */ | ||
900 | case JIT_IH_COROUTINE_RESUME: | ||
901 | /* Only support common cases: no tailcalls, not with 0 args (error). */ | ||
902 | if (nresults == -2 || nargs == 0) goto fail; | ||
903 | ii.xnargs = ii.xnresults = -1; | ||
904 | goto ok; /* Anything else is ok. */ | ||
905 | } | ||
906 | break; | ||
907 | #endif | ||
908 | case JIT_IHLIB_STRING: | ||
909 | switch (idx) { | ||
910 | case JIT_IH_STRING_LEN: | ||
911 | goto check; | ||
912 | case JIT_IH_STRING_SUB: | ||
913 | if (nargs < 2) goto fail; /* No support for open calls, too. */ | ||
914 | goto ok; /* 2 or more args are ok. */ | ||
915 | case JIT_IH_STRING_CHAR: | ||
916 | goto check; /* Only single arg supported. */ | ||
917 | } | ||
918 | break; | ||
919 | case JIT_IHLIB_TABLE: | ||
920 | switch (idx) { | ||
921 | case JIT_IH_TABLE_INSERT: | ||
922 | ii.xnargs = 2; | ||
923 | goto check; /* Only push (append) supported. */ | ||
924 | case JIT_IH_TABLE_REMOVE: | ||
925 | goto check; /* Only pop supported. */ | ||
926 | case JIT_IH_TABLE_GETN: | ||
927 | goto check; | ||
928 | } | ||
929 | break; | ||
930 | case JIT_IHLIB_MATH: | ||
931 | if (idx >= JIT_IH_MATH__LAST) goto fail; | ||
932 | if (idx >= JIT_IH_MATH__21) ii.xnargs = 2; | ||
933 | goto check; | ||
934 | } | ||
935 | fail: | ||
936 | return cltype; /* Call could not be inlined. Return type of callable. */ | ||
937 | |||
938 | check: | ||
939 | if (nargs != ii.xnargs && nargs != -1) goto fail; | ||
940 | /* The optimizer already checks the number of results (avoid setnil). */ | ||
941 | |||
942 | ok: /* Whew, all checks done. Go for it! */ | ||
943 | |||
944 | /* Start with the common leadin for inlined calls. */ | ||
945 | jit_deopt_target(J, nargs); | ||
946 | dasm_put(Dst, 1418, Dt2([func].tt), Dt2([func].value), (ptrdiff_t)(clvalue(callable))); | ||
947 | if (nargs == -1 && ii.xnargs >= 0) { | ||
948 | dasm_put(Dst, 1435, Dt2([func+1+ii.xnargs])); | ||
949 | } | ||
950 | |||
951 | /* Now inline the function itself. */ | ||
952 | switch (JIT_IH_LIB(ii.hidx)) { | ||
953 | case JIT_IHLIB_BASE: jit_inline_base(J, &ii); break; | ||
954 | #ifndef COCO_DISABLE | ||
955 | case JIT_IHLIB_COROUTINE: jit_inline_coroutine(J, &ii); break; | ||
956 | #endif | ||
957 | case JIT_IHLIB_STRING: jit_inline_string(J, &ii); break; | ||
958 | case JIT_IHLIB_TABLE: jit_inline_table(J, &ii); break; | ||
959 | case JIT_IHLIB_MATH: jit_inline_math(J, &ii); break; | ||
960 | default: jit_assert(0); break; | ||
961 | } | ||
962 | |||
963 | /* And add the common leadout for inlined calls. */ | ||
964 | if (ii.nresults == -1) { | ||
965 | if (ii.xnresults >= 0) { | ||
966 | dasm_put(Dst, 791, Dt2([ii.res+ii.xnresults])); | ||
967 | } | ||
968 | } else if (ii.nargs == -1) { /* Restore L->top only if needed. */ | ||
969 | dasm_put(Dst, 1445, Dt2([J->pt->maxstacksize]), Dt1(->top)); | ||
970 | } | ||
971 | |||
972 | if (nresults == -2) { /* Results are in place. Add return for tailcalls. */ | ||
973 | dasm_put(Dst, 1452, sizeof(TValue), Dt1(->ci), sizeof(CallInfo)); | ||
974 | } | ||
975 | |||
976 | return -1; /* Success, call has been inlined. */ | ||
977 | } | ||
978 | |||
979 | /* ------------------------------------------------------------------------ */ | ||
980 | |||
981 | /* Helper function for inlined iterator code. Paraphrased from luaH_next. */ | ||
982 | /* TODO: GCC has trouble optimizing this. */ | ||
983 | static int jit_table_next(lua_State *L, TValue *ra) | ||
984 | { | ||
985 | Table *t = hvalue(&ra[TFOR_TAB]); | ||
986 | int i = ra[TFOR_CTL].value.b; /* Hidden control variable. */ | ||
987 | for (; i < t->sizearray; i++) { /* First the array part. */ | ||
988 | if (!ttisnil(&t->array[i])) { | ||
989 | setnvalue(&ra[TFOR_KEY], cast_num(i+1)); | ||
990 | setobj2s(L, &ra[TFOR_VAL], &t->array[i]); | ||
991 | ra[TFOR_CTL].value.b = i+1; | ||
992 | return 1; | ||
993 | } | ||
994 | } | ||
995 | for (i -= t->sizearray; i < sizenode(t); i++) { /* Then the hash part. */ | ||
996 | if (!ttisnil(gval(gnode(t, i)))) { | ||
997 | setobj2s(L, &ra[TFOR_KEY], key2tval(gnode(t, i))); | ||
998 | setobj2s(L, &ra[TFOR_VAL], gval(gnode(t, i))); | ||
999 | ra[TFOR_CTL].value.b = i+1+t->sizearray; | ||
1000 | return 1; | ||
1001 | } | ||
1002 | } | ||
1003 | return 0; /* End of iteration. */ | ||
1004 | } | ||
1005 | |||
1006 | /* Try to inline a TFORLOOP instruction. */ | ||
1007 | static int jit_inline_tforloop(jit_State *J, int ra, int nresults, int target) | ||
1008 | { | ||
1009 | const TValue *oidx = hint_get(J, INLINE); /* INLINE hint = lib/func idx. */ | ||
1010 | int idx; | ||
1011 | |||
1012 | if (!ttisnumber(oidx)) return 0; /* No hint: don't inline anything. */ | ||
1013 | idx = (int)nvalue(oidx); | ||
1014 | if (J->flags & JIT_F_DEBUG) return 0; /* DWIM. */ | ||
1015 | |||
1016 | switch (idx) { | ||
1017 | case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_PAIRS): | ||
1018 | dasm_put(Dst, 1465, Dt2([ra]), (ptrdiff_t)(jit_table_next), target); | ||
1019 | return 1; /* Success, iterator has been inlined. */ | ||
1020 | case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_IPAIRS): | ||
1021 | dasm_put(Dst, 1483, Dt2([ra+TFOR_CTL].value), Dt2([ra+TFOR_TAB].value), Dt2([ra+TFOR_CTL].value), (ptrdiff_t)(luaH_getnum), Dt7(->tt), Dt2([ra+TFOR_CTL].value), Dt2([ra+TFOR_KEY].tt), Dt2([ra+TFOR_KEY].value), Dt7(->value), Dt7(->value.na[1]), Dt2([ra+TFOR_VAL].tt), Dt2([ra+TFOR_VAL].value), Dt2([ra+TFOR_VAL].value.na[1]), target); | ||
1022 | return 1; /* Success, iterator has been inlined. */ | ||
1023 | } | ||
1024 | |||
1025 | return 0; /* No support for inlining any other iterators. */ | ||
1026 | } | ||
1027 | |||
1028 | /* ------------------------------------------------------------------------ */ | ||
1029 | |||
1030 | |||
1031 | |||
1032 | #ifdef LUA_COMPAT_VARARG | ||
1033 | static void jit_vararg_table(lua_State *L) | ||
1034 | { | ||
1035 | Table *tab; | ||
1036 | StkId base, func; | ||
1037 | int i, num, numparams; | ||
1038 | luaC_checkGC(L); | ||
1039 | base = L->base; | ||
1040 | func = L->ci->func; | ||
1041 | numparams = clvalue(func)->l.p->numparams; | ||
1042 | num = base - func - numparams - 1; | ||
1043 | tab = luaH_new(L, num, 1); | ||
1044 | for (i = 0; i < num; i++) | ||
1045 | setobj2n(L, luaH_setnum(L, tab, i+1), base - num + i); | ||
1046 | setnvalue(luaH_setstr(L, tab, luaS_newliteral(L, "n")), (lua_Number)num); | ||
1047 | sethvalue(L, base + numparams, tab); | ||
1048 | } | ||
1049 | #endif | ||
1050 | |||
1051 | /* Encode JIT function prologue. */ | ||
1052 | static void jit_prologue(jit_State *J) | ||
1053 | { | ||
1054 | Proto *pt = J->pt; | ||
1055 | int numparams = pt->numparams; | ||
1056 | int stacksize = pt->maxstacksize; | ||
1057 | |||
1058 | dasm_put(Dst, 1544, Dt3([stacksize]), Dt1(->stack_last), Dt1(->end_ci), Dt4([1]), Dt4(->func), sizeof(TValue), Dt1(->ci)); | ||
1059 | |||
1060 | if (numparams > 0) { | ||
1061 | dasm_put(Dst, 1580, Dt2([numparams])); | ||
1062 | } | ||
1063 | |||
1064 | if (!pt->is_vararg) { /* Fixarg function. */ | ||
1065 | /* Must cap L->top at L->base+numparams because 1st LOADNIL is omitted. */ | ||
1066 | if (numparams == 0) { | ||
1067 | dasm_put(Dst, 1586); | ||
1068 | } else if (J->flags & JIT_F_CPU_CMOV) { | ||
1069 | dasm_put(Dst, 1589); | ||
1070 | } else { | ||
1071 | dasm_put(Dst, 1594); | ||
1072 | } | ||
1073 | dasm_put(Dst, 1603, Dt2([stacksize]), Dt4(->tailcalls), Dt4(->top), Dt1(->top), Dt1(->base), Dt4(->base)); | ||
1074 | } else { /* Vararg function. */ | ||
1075 | int i; | ||
1076 | if (numparams > 0) { | ||
1077 | dasm_put(Dst, 1622); | ||
1078 | dasm_put(Dst, 1630, Dt3(->tt), sizeof(TValue)); | ||
1079 | } | ||
1080 | dasm_put(Dst, 1649, Dt1(->base), Dt4(->base), Dt4(->tailcalls)); | ||
1081 | for (i = 0; i < numparams; i++) { /* Move/clear fixargs. */ | ||
1082 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1083 | dasm_put(Dst, 1659, Dt2([i].tt), Dt2([i].value), Dt3([i].tt), Dt3([i].value)); | ||
1084 | } else { | ||
1085 | dasm_put(Dst, 1677, Dt2([i].value), Dt2([i].value.na[1]), Dt3([i].value), Dt2([i].tt), Dt3([i].value.na[1]), Dt3([i].tt)); | ||
1086 | } | ||
1087 | dasm_put(Dst, 854, Dt2([i].tt)); | ||
1088 | } | ||
1089 | if (numparams > 0) { | ||
1090 | dasm_put(Dst, 332, Dt1(->ci)); | ||
1091 | } | ||
1092 | dasm_put(Dst, 1696, Dt2([stacksize]), Dt2([numparams]), Dt4(->top), Dt1(->top)); | ||
1093 | stacksize -= numparams; /* Fixargs are already cleared. */ | ||
1094 | } | ||
1095 | |||
1096 | /* Clear undefined args and all vars. Still assumes eax = LUA_TNIL = 0. */ | ||
1097 | /* Note: cannot clear only args because L->top has grown. */ | ||
1098 | if (stacksize <= EXTRA_STACK) { /* Loopless clear. May use EXTRA_STACK. */ | ||
1099 | int i; | ||
1100 | for (i = 0; i < stacksize; i++) { | ||
1101 | dasm_put(Dst, 1712, Dt3([i].tt)); | ||
1102 | } | ||
1103 | } else { /* Standard loop. */ | ||
1104 | dasm_put(Dst, 1716, Dt3([0].tt), Dt3([1].tt), 2*sizeof(TValue)); | ||
1105 | } | ||
1106 | |||
1107 | #ifdef LUA_COMPAT_VARARG | ||
1108 | if (pt->is_vararg & VARARG_NEEDSARG) { | ||
1109 | dasm_put(Dst, 1734, (ptrdiff_t)(jit_vararg_table)); | ||
1110 | } | ||
1111 | #endif | ||
1112 | |||
1113 | /* Call hook check. */ | ||
1114 | if (J->flags & JIT_F_DEBUG_CALL) { | ||
1115 | dasm_put(Dst, 1740, Dt1(->hookmask), LUA_MASKCALL); | ||
1116 | |||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | /* Check if we can combine 'return const'. */ | ||
1121 | static int jit_return_k(jit_State *J) | ||
1122 | { | ||
1123 | if (!J->combine) return 0; /* COMBINE hint set? */ | ||
1124 | /* May need to close open upvalues. */ | ||
1125 | if (!fhint_isset(J, NOCLOSE)) { | ||
1126 | dasm_put(Dst, 1820, (ptrdiff_t)(luaF_close)); | ||
1127 | } | ||
1128 | if (!J->pt->is_vararg) { /* Fixarg function. */ | ||
1129 | dasm_put(Dst, 1830, Dt1(->ci), sizeof(CallInfo), sizeof(TValue)); | ||
1130 | } else { /* Vararg function. */ | ||
1131 | dasm_put(Dst, 1844, Dt1(->ci), Dt4(->func), sizeof(CallInfo), Dt1(->ci), Dt2([1])); | ||
1132 | } | ||
1133 | jit_assert(J->combine == 1); /* Required to skip next RETURN instruction. */ | ||
1134 | return 1; | ||
1135 | } | ||
1136 | |||
1137 | static void jit_op_return(jit_State *J, int rbase, int nresults) | ||
1138 | { | ||
1139 | /* Return hook check. */ | ||
1140 | if (J->flags & JIT_F_DEBUG_CALL) { | ||
1141 | if (nresults < 0 && !(J->flags & JIT_F_DEBUG_INS)) { | ||
1142 | dasm_put(Dst, 594, Dt1(->top)); | ||
1143 | } | ||
1144 | dasm_put(Dst, 1863, Dt1(->hookmask), LUA_MASKRET); | ||
1145 | if (J->flags & JIT_F_DEBUG_INS) { | ||
1146 | dasm_put(Dst, 1878, Dt1(->savedpc)); | ||
1147 | } | ||
1148 | |||
1149 | } | ||
1150 | |||
1151 | /* May need to close open upvalues. */ | ||
1152 | if (!fhint_isset(J, NOCLOSE)) { | ||
1153 | dasm_put(Dst, 1820, (ptrdiff_t)(luaF_close)); | ||
1154 | } | ||
1155 | |||
1156 | /* Previous op was open: 'return f()' or 'return ...' */ | ||
1157 | if (nresults < 0) { | ||
1158 | dasm_put(Dst, 332, Dt1(->ci)); | ||
1159 | if (rbase) { | ||
1160 | dasm_put(Dst, 787, rbase*sizeof(TValue)); | ||
1161 | } | ||
1162 | dasm_put(Dst, 1933, Dt4(->func), Dt4(->func), sizeof(CallInfo), Dt1(->ci)); | ||
1163 | return; | ||
1164 | } | ||
1165 | |||
1166 | if (!J->pt->is_vararg) { /* Fixarg function, nresults >= 0. */ | ||
1167 | int i; | ||
1168 | dasm_put(Dst, 1980, Dt1(->ci), sizeof(CallInfo), sizeof(TValue)); | ||
1169 | for (i = 0; i < nresults; i++) { | ||
1170 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1171 | dasm_put(Dst, 821, Dt2([rbase+i+1].tt), Dt2([rbase+i+1].value), Dt2([i].tt), Dt2([i].value)); | ||
1172 | } else { | ||
1173 | dasm_put(Dst, 839, Dt2([rbase+i+1].value), Dt2([rbase+i+1].value.na[1]), Dt2([rbase+i+1].tt), Dt2([i].value), Dt2([i].value.na[1]), Dt2([i].tt)); | ||
1174 | } | ||
1175 | } | ||
1176 | dasm_put(Dst, 1989, Dt2([nresults])); | ||
1177 | } else { /* Vararg function, nresults >= 0. */ | ||
1178 | int i; | ||
1179 | dasm_put(Dst, 1997, Dt1(->ci), Dt4(->func), sizeof(CallInfo), Dt1(->ci)); | ||
1180 | for (i = 0; i < nresults; i++) { | ||
1181 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1182 | dasm_put(Dst, 1659, Dt2([rbase+i].tt), Dt2([rbase+i].value), Dt3([i].tt), Dt3([i].value)); | ||
1183 | } else { | ||
1184 | dasm_put(Dst, 2010, Dt2([rbase+i].value), Dt2([rbase+i].value.na[1]), Dt2([rbase+i].tt), Dt3([i].value), Dt3([i].value.na[1]), Dt3([i].tt)); | ||
1185 | } | ||
1186 | } | ||
1187 | dasm_put(Dst, 2029); | ||
1188 | if (nresults) { | ||
1189 | dasm_put(Dst, 2036, nresults*sizeof(TValue)); | ||
1190 | } | ||
1191 | dasm_put(Dst, 32); | ||
1192 | } | ||
1193 | } | ||
1194 | |||
1195 | static void jit_op_call(jit_State *J, int func, int nargs, int nresults) | ||
1196 | { | ||
1197 | int cltype = jit_inline_call(J, func, nargs, nresults); | ||
1198 | if (cltype < 0) return; /* Inlined? */ | ||
1199 | |||
1200 | if (func) { | ||
1201 | dasm_put(Dst, 787, func*sizeof(TValue)); | ||
1202 | } | ||
1203 | dasm_put(Dst, 2040, Dt1(->ci), Dt2([0].tt)); | ||
1204 | if (nargs >= 0) { /* Previous op was not open and did not set TOP. */ | ||
1205 | dasm_put(Dst, 791, Dt2([1+nargs])); | ||
1206 | } | ||
1207 | dasm_put(Dst, 2048, Dt2(->value), (ptrdiff_t)(J->nextins), Dt4(->savedpc)); | ||
1208 | if (cltype == LUA_TFUNCTION) { | ||
1209 | if (nargs == -1) { | ||
1210 | dasm_put(Dst, 2057); | ||
1211 | } else { | ||
1212 | dasm_put(Dst, 2062); | ||
1213 | } | ||
1214 | } else { | ||
1215 | dasm_put(Dst, 2067); | ||
1216 | |||
1217 | } | ||
1218 | dasm_put(Dst, 2116, Dt5(->jit_gate)); | ||
1219 | if (func) { | ||
1220 | dasm_put(Dst, 1984, func*sizeof(TValue)); | ||
1221 | } | ||
1222 | dasm_put(Dst, 2121, Dt1(->base)); | ||
1223 | |||
1224 | /* Clear undefined results TOP <= o < func+nresults. */ | ||
1225 | if (nresults > 0) { | ||
1226 | dasm_put(Dst, 2125); | ||
1227 | if (nresults <= EXTRA_STACK) { /* Loopless clear. May use EXTRA_STACK. */ | ||
1228 | int i; | ||
1229 | for (i = 0; i < nresults; i++) { | ||
1230 | dasm_put(Dst, 1712, Dt3([i].tt)); | ||
1231 | } | ||
1232 | } else { /* Standard loop. TODO: move to .tail? */ | ||
1233 | dasm_put(Dst, 2128, Dt2([func+nresults]), Dt3([0].tt), Dt3([1].tt), 2*sizeof(TValue)); | ||
1234 | } | ||
1235 | } | ||
1236 | |||
1237 | if (nresults >= 0) { /* Not an open ins. Restore L->top. */ | ||
1238 | dasm_put(Dst, 1445, Dt2([J->pt->maxstacksize]), Dt1(->top)); | ||
1239 | } /* Otherwise keep TOP for next instruction. */ | ||
1240 | } | ||
1241 | |||
1242 | static void jit_op_tailcall(jit_State *J, int func, int nargs) | ||
1243 | { | ||
1244 | int cltype; | ||
1245 | |||
1246 | if (!fhint_isset(J, NOCLOSE)) { /* May need to close open upvalues. */ | ||
1247 | dasm_put(Dst, 1820, (ptrdiff_t)(luaF_close)); | ||
1248 | } | ||
1249 | |||
1250 | cltype = jit_inline_call(J, func, nargs, -2); | ||
1251 | if (cltype < 0) goto finish; /* Inlined? */ | ||
1252 | |||
1253 | if (cltype == LUA_TFUNCTION) { | ||
1254 | jit_deopt_target(J, nargs); | ||
1255 | dasm_put(Dst, 2149, Dt2([func].tt)); | ||
1256 | } else { | ||
1257 | dasm_put(Dst, 2158, Dt2([func].tt)); | ||
1258 | dasm_put(Dst, 2168); | ||
1259 | if (func) { | ||
1260 | dasm_put(Dst, 787, func*sizeof(TValue)); | ||
1261 | } | ||
1262 | if (nargs >= 0) { | ||
1263 | dasm_put(Dst, 791, Dt2([1+nargs])); | ||
1264 | } | ||
1265 | dasm_put(Dst, 2171, (ptrdiff_t)(J->nextins)); | ||
1266 | |||
1267 | } | ||
1268 | |||
1269 | if (nargs >= 0) { /* Previous op was not open and did not set TOP. */ | ||
1270 | int i; | ||
1271 | /* Relocate [BASE+func, BASE+func+nargs] -> [ci->func, ci->func+nargs]. */ | ||
1272 | /* TODO: loop for large nargs? */ | ||
1273 | if (!J->pt->is_vararg) { /* Fixarg function. */ | ||
1274 | dasm_put(Dst, 2241, Dt2([func].value)); | ||
1275 | for (i = 0; i < nargs; i++) { | ||
1276 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1277 | dasm_put(Dst, 821, Dt2([func+1+i].tt), Dt2([func+1+i].value), Dt2([i].tt), Dt2([i].value)); | ||
1278 | } else { | ||
1279 | dasm_put(Dst, 2245, Dt2([func+1+i].value), Dt2([func+1+i].value.na[1]), Dt2([i].value), Dt2([func+1+i].tt), Dt2([i].value.na[1]), Dt2([i].tt)); | ||
1280 | } | ||
1281 | } | ||
1282 | dasm_put(Dst, 2264, Dt2([nargs]), sizeof(TValue), Dt1(->ci), Dt2(->value)); | ||
1283 | } else { /* Vararg function. */ | ||
1284 | dasm_put(Dst, 2278, Dt1(->ci), Dt2([func]), Dt4(->func), Dt3(->value), Dt2(->value)); | ||
1285 | for (i = 0; i < nargs; i++) { | ||
1286 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1287 | dasm_put(Dst, 2294, Dt3([i+1].tt), Dt3([i+1].value), Dt2([i+1].tt), Dt2([i+1].value)); | ||
1288 | } else { | ||
1289 | dasm_put(Dst, 2312, Dt3([i+1].value), Dt3([i+1].value.na[1]), Dt2([i+1].value), Dt3([i+1].tt), Dt2([i+1].value.na[1]), Dt2([i+1].tt)); | ||
1290 | } | ||
1291 | } | ||
1292 | dasm_put(Dst, 2331, Dt2([1+nargs]), Dt2(->value)); | ||
1293 | } | ||
1294 | } else { /* Previous op was open and set TOP. */ | ||
1295 | dasm_put(Dst, 332, Dt1(->ci)); | ||
1296 | if (func) { | ||
1297 | dasm_put(Dst, 787, func*sizeof(TValue)); | ||
1298 | } | ||
1299 | dasm_put(Dst, 2338, Dt4(->func), Dt4(->func), Dt2(->value)); | ||
1300 | } | ||
1301 | dasm_put(Dst, 2230, sizeof(CallInfo), Dt5(->jit_gate)); | ||
1302 | |||
1303 | finish: | ||
1304 | J->combine++; /* Combine with following return instruction. */ | ||
1305 | } | ||
1306 | |||
1307 | /* ------------------------------------------------------------------------ */ | ||
1308 | |||
1309 | static void jit_op_move(jit_State *J, int dest, int src) | ||
1310 | { | ||
1311 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1312 | dasm_put(Dst, 821, Dt2([src].tt), Dt2([src].value), Dt2([dest].tt), Dt2([dest].value)); | ||
1313 | } else { | ||
1314 | dasm_put(Dst, 839, Dt2([src].value), Dt2([src].value.na[1]), Dt2([src].tt), Dt2([dest].value), Dt2([dest].value.na[1]), Dt2([dest].tt)); | ||
1315 | } | ||
1316 | } | ||
1317 | |||
1318 | static void jit_op_loadk(jit_State *J, int dest, int kidx) | ||
1319 | { | ||
1320 | const TValue *kk = &J->pt->k[kidx]; | ||
1321 | int rk = jit_return_k(J); | ||
1322 | if (rk) dest = 0; | ||
1323 | switch (ttype(kk)) { | ||
1324 | case 0: | ||
1325 | dasm_put(Dst, 2369, Dt2([dest].tt)); | ||
1326 | break; | ||
1327 | case 1: | ||
1328 | if (bvalue(kk)) { /* true */ | ||
1329 | dasm_put(Dst, 2377, Dt2([dest].value), Dt2([dest].tt)); | ||
1330 | } else { /* false */ | ||
1331 | dasm_put(Dst, 2389, Dt2([dest].value), Dt2([dest].tt)); | ||
1332 | } | ||
1333 | break; | ||
1334 | case 3: { | ||
1335 | if ((&(kk)->value)->n == (lua_Number)0) { | ||
1336 | dasm_put(Dst, 2404); | ||
1337 | } else if ((&(kk)->value)->n == (lua_Number)1) { | ||
1338 | dasm_put(Dst, 2408); | ||
1339 | } else { | ||
1340 | dasm_put(Dst, 2411, &(kk)->value); | ||
1341 | } | ||
1342 | dasm_put(Dst, 1306, Dt2([dest].value), Dt2([dest].tt)); | ||
1343 | break; | ||
1344 | } | ||
1345 | case 4: | ||
1346 | dasm_put(Dst, 2415, Dt2([dest].value), (ptrdiff_t)(gcvalue(kk)), Dt2([dest].tt)); | ||
1347 | break; | ||
1348 | default: lua_assert(0); break; | ||
1349 | } | ||
1350 | if (rk) { | ||
1351 | dasm_put(Dst, 32); | ||
1352 | } | ||
1353 | } | ||
1354 | |||
1355 | static void jit_op_loadnil(jit_State *J, int first, int last) | ||
1356 | { | ||
1357 | int idx, num = last - first + 1; | ||
1358 | int rk = jit_return_k(J); | ||
1359 | dasm_put(Dst, 2125); | ||
1360 | if (rk) { | ||
1361 | dasm_put(Dst, 2427, Dt2([0].tt)); | ||
1362 | } else if (num <= 8) { | ||
1363 | for (idx = first; idx <= last; idx++) { | ||
1364 | dasm_put(Dst, 854, Dt2([idx].tt)); | ||
1365 | } | ||
1366 | } else { | ||
1367 | dasm_put(Dst, 2432, Dt2([first].tt), Dt2([last].tt), sizeof(TValue)); | ||
1368 | } | ||
1369 | } | ||
1370 | |||
1371 | static void jit_op_loadbool(jit_State *J, int dest, int b, int dojump) | ||
1372 | { | ||
1373 | int rk = jit_return_k(J); | ||
1374 | if (rk) dest = 0; | ||
1375 | if (b) { /* true */ | ||
1376 | dasm_put(Dst, 2377, Dt2([dest].value), Dt2([dest].tt)); | ||
1377 | } else { /* false */ | ||
1378 | dasm_put(Dst, 2389, Dt2([dest].value), Dt2([dest].tt)); | ||
1379 | } | ||
1380 | if (rk) { | ||
1381 | dasm_put(Dst, 32); | ||
1382 | } else if (dojump) { | ||
1383 | const TValue *h = hint_getpc(J, COMBINE, J->nextpc); | ||
1384 | if (!(ttisboolean(h) && bvalue(h) == 0)) { /* Avoid jmp around dead ins. */ | ||
1385 | dasm_put(Dst, 665, J->nextpc+1); | ||
1386 | } | ||
1387 | } | ||
1388 | } | ||
1389 | |||
1390 | /* ------------------------------------------------------------------------ */ | ||
1391 | |||
1392 | static void jit_op_getupval(jit_State *J, int dest, int uvidx) | ||
1393 | { | ||
1394 | if (!J->pt->is_vararg) { | ||
1395 | dasm_put(Dst, 2241, Dt2([-1].value)); | ||
1396 | } else { | ||
1397 | dasm_put(Dst, 2452, Dt1(->ci), Dt4(->func), Dt3(->value)); | ||
1398 | } | ||
1399 | dasm_put(Dst, 2462, Dt5(->upvals[uvidx]), DtF(->v)); | ||
1400 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1401 | dasm_put(Dst, 2469, Dt3([0].tt), Dt3([0].value), Dt2([dest].tt), Dt2([dest].value)); | ||
1402 | } else { | ||
1403 | dasm_put(Dst, 2487, Dt3([0].value), Dt3([0].value.na[1]), Dt3([0].tt), Dt2([dest].value), Dt2([dest].value.na[1]), Dt2([dest].tt)); | ||
1404 | } | ||
1405 | } | ||
1406 | |||
1407 | static void jit_op_setupval(jit_State *J, int src, int uvidx) | ||
1408 | { | ||
1409 | if (!J->pt->is_vararg) { | ||
1410 | dasm_put(Dst, 2241, Dt2([-1].value)); | ||
1411 | } else { | ||
1412 | dasm_put(Dst, 2452, Dt1(->ci), Dt4(->func), Dt3(->value)); | ||
1413 | } | ||
1414 | dasm_put(Dst, 2506, Dt5(->upvals[uvidx]), DtF(->v), Dt2([src].tt), Dt2([src].value), Dt3(->tt), Dt2([src].value.na[1]), Dt3(->value), Dt3(->value.na[1])); | ||
1415 | dasm_put(Dst, 2542, DtA(->gch.marked), WHITEBITS, DtF(->marked), bitmask(BLACKBIT)); | ||
1416 | |||
1417 | } | ||
1418 | |||
1419 | /* ------------------------------------------------------------------------ */ | ||
1420 | |||
1421 | /* Optimized table lookup routines. Enter via jsub, fallback to C. */ | ||
1422 | |||
1423 | /* Fallback for GETTABLE_*. Temporary key is in L->env. */ | ||
1424 | static void jit_gettable_fb(lua_State *L, Table *t, StkId dest) | ||
1425 | { | ||
1426 | Table *mt = t->metatable; | ||
1427 | const TValue *tm = luaH_getstr(mt, G(L)->tmname[TM_INDEX]); | ||
1428 | if (ttisnil(tm)) { /* No __index method? */ | ||
1429 | mt->flags |= 1<<TM_INDEX; /* Cache this fact. */ | ||
1430 | setnilvalue(dest); | ||
1431 | } else if (ttisfunction(tm)) { /* __index function? */ | ||
1432 | ptrdiff_t destr = savestack(L, dest); | ||
1433 | setobj2s(L, L->top, tm); | ||
1434 | sethvalue(L, L->top+1, t); | ||
1435 | setobj2s(L, L->top+2, &L->env); | ||
1436 | luaD_checkstack(L, 3); | ||
1437 | L->top += 3; | ||
1438 | luaD_call(L, L->top - 3, 1); | ||
1439 | dest = restorestack(L, destr); | ||
1440 | L->top--; | ||
1441 | setobjs2s(L, dest, L->top); | ||
1442 | } else { /* Let luaV_gettable() continue with the __index object. */ | ||
1443 | luaV_gettable(L, tm, &L->env, dest); | ||
1444 | } | ||
1445 | |||
1446 | } | ||
1447 | |||
1448 | /* Fallback for SETTABLE_*STR. Temporary (string) key is in L->env. */ | ||
1449 | static void jit_settable_fb(lua_State *L, Table *t, StkId val) | ||
1450 | { | ||
1451 | Table *mt = t->metatable; | ||
1452 | const TValue *tm = luaH_getstr(mt, G(L)->tmname[TM_NEWINDEX]); | ||
1453 | if (ttisnil(tm)) { /* No __newindex method? */ | ||
1454 | mt->flags |= 1<<TM_NEWINDEX; /* Cache this fact. */ | ||
1455 | t->flags = 0; /* But need to clear the cache for the table itself. */ | ||
1456 | setobj2t(L, luaH_setstr(L, t, rawtsvalue(&L->env)), val); | ||
1457 | luaC_barriert(L, t, val); | ||
1458 | } else if (ttisfunction(tm)) { /* __newindex function? */ | ||
1459 | setobj2s(L, L->top, tm); | ||
1460 | sethvalue(L, L->top+1, t); | ||
1461 | setobj2s(L, L->top+2, &L->env); | ||
1462 | setobj2s(L, L->top+3, val); | ||
1463 | luaD_checkstack(L, 4); | ||
1464 | L->top += 4; | ||
1465 | luaD_call(L, L->top - 4, 0); | ||
1466 | } else { /* Let luaV_settable() continue with the __newindex object. */ | ||
1467 | luaV_settable(L, tm, &L->env, val); | ||
1468 | } | ||
1469 | |||
1470 | } | ||
1471 | |||
1472 | /* ------------------------------------------------------------------------ */ | ||
1473 | |||
1474 | static void jit_op_newtable(jit_State *J, int dest, int lnarray, int lnhash) | ||
1475 | { | ||
1476 | dasm_put(Dst, 3158, luaO_fb2int(lnarray), luaO_fb2int(lnhash), (ptrdiff_t)(luaH_new), Dt2([dest].value), Dt2([dest].tt)); | ||
1477 | jit_checkGC(J); | ||
1478 | } | ||
1479 | |||
1480 | static void jit_op_getglobal(jit_State *J, int dest, int kidx) | ||
1481 | { | ||
1482 | const TValue *kk = &J->pt->k[kidx]; | ||
1483 | jit_assert(ttisstring(kk)); | ||
1484 | dasm_put(Dst, 3184, (ptrdiff_t)(&kk->value.gc->ts)); | ||
1485 | if (dest) { | ||
1486 | dasm_put(Dst, 787, dest*sizeof(TValue)); | ||
1487 | } | ||
1488 | dasm_put(Dst, 3187); | ||
1489 | } | ||
1490 | |||
1491 | static void jit_op_setglobal(jit_State *J, int rval, int kidx) | ||
1492 | { | ||
1493 | const TValue *kk = &J->pt->k[kidx]; | ||
1494 | jit_assert(ttisstring(kk)); | ||
1495 | dasm_put(Dst, 3184, (ptrdiff_t)(&kk->value.gc->ts)); | ||
1496 | if (rval) { | ||
1497 | dasm_put(Dst, 787, rval*sizeof(TValue)); | ||
1498 | } | ||
1499 | dasm_put(Dst, 3191); | ||
1500 | } | ||
1501 | |||
1502 | enum { TKEY_KSTR = -2, TKEY_STR = -1, TKEY_ANY = 0 }; | ||
1503 | |||
1504 | /* Optimize key lookup depending on consts or hints type. */ | ||
1505 | static int jit_keylookup(jit_State *J, int tab, int rkey) | ||
1506 | { | ||
1507 | const TValue *tabt = hint_get(J, TYPE); | ||
1508 | const TValue *key; | ||
1509 | if (!ttistable(tabt)) return TKEY_ANY; /* Not a table? Use fallback. */ | ||
1510 | key = ISK(rkey) ? &J->pt->k[INDEXK(rkey)] : hint_get(J, TYPEKEY); | ||
1511 | if (ttisstring(key)) { /* String key? */ | ||
1512 | if (ISK(rkey)) { | ||
1513 | dasm_put(Dst, 3195, Dt2([tab]), (ptrdiff_t)(&key->value.gc->ts)); | ||
1514 | return TKEY_KSTR; /* Const string key. */ | ||
1515 | } else { | ||
1516 | dasm_put(Dst, 3201, Dt2([tab]), Dt2([rkey])); | ||
1517 | return TKEY_STR; /* Var string key. */ | ||
1518 | } | ||
1519 | } else if (ttisnumber(key)) { /* Number key? */ | ||
1520 | lua_Number n = nvalue(key); | ||
1521 | int k; | ||
1522 | lua_number2int(k, n); | ||
1523 | if (!(k >= 1 && k < (1 << 26) && (lua_Number)k == n)) | ||
1524 | return TKEY_ANY; /* Not a proper array key? Use fallback. */ | ||
1525 | if (ISK(rkey)) { | ||
1526 | dasm_put(Dst, 3208, Dt2([tab].tt), Dt2([tab].value), k, DtC(->array), DtC(->sizearray)); | ||
1527 | return k; /* Const array key (>= 1). */ | ||
1528 | } else { | ||
1529 | dasm_put(Dst, 3232, Dt2([tab].tt), Dt2([rkey].tt)); | ||
1530 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1531 | dasm_put(Dst, 3250, Dt2([rkey]), Dt2([tab].value)); | ||
1532 | } else { | ||
1533 | dasm_put(Dst, 3283, Dt2([rkey].value)); | ||
1534 | if (J->flags & JIT_F_CPU_CMOV) { | ||
1535 | dasm_put(Dst, 3293); | ||
1536 | } else { | ||
1537 | dasm_put(Dst, 3298); | ||
1538 | } | ||
1539 | dasm_put(Dst, 3304, Dt2([tab].value)); | ||
1540 | } | ||
1541 | dasm_put(Dst, 3320, DtC(->sizearray), DtC(->array)); | ||
1542 | return 1; /* Variable array key. */ | ||
1543 | } | ||
1544 | } | ||
1545 | return TKEY_ANY; /* Use fallback. */ | ||
1546 | } | ||
1547 | |||
1548 | static void jit_op_gettable(jit_State *J, int dest, int tab, int rkey) | ||
1549 | { | ||
1550 | int k = jit_keylookup(J, tab, rkey); | ||
1551 | switch (k) { | ||
1552 | case TKEY_KSTR: /* Const string key. */ | ||
1553 | if (dest) { | ||
1554 | dasm_put(Dst, 787, dest*sizeof(TValue)); | ||
1555 | } | ||
1556 | dasm_put(Dst, 3334); | ||
1557 | break; | ||
1558 | case TKEY_STR: /* Variable string key. */ | ||
1559 | if (dest) { | ||
1560 | dasm_put(Dst, 787, dest*sizeof(TValue)); | ||
1561 | } | ||
1562 | dasm_put(Dst, 3338); | ||
1563 | break; | ||
1564 | case TKEY_ANY: /* Generic gettable fallback. */ | ||
1565 | if (ISK(rkey)) { | ||
1566 | dasm_put(Dst, 3342, (ptrdiff_t)(&J->pt->k[INDEXK(rkey)])); | ||
1567 | } else { | ||
1568 | dasm_put(Dst, 3204, Dt2([rkey])); | ||
1569 | } | ||
1570 | dasm_put(Dst, 3345, Dt2([tab])); | ||
1571 | if (dest) { | ||
1572 | dasm_put(Dst, 787, dest*sizeof(TValue)); | ||
1573 | } | ||
1574 | dasm_put(Dst, 3349, Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(luaV_gettable), Dt1(->base)); | ||
1575 | break; | ||
1576 | default: /* Array key. */ | ||
1577 | dasm_put(Dst, 3366, Dt7([k-1].tt)); | ||
1578 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1579 | dasm_put(Dst, 2674, Dt7([k-1].value), Dt2([dest].value)); | ||
1580 | } else { | ||
1581 | dasm_put(Dst, 3378, Dt7([k-1].value), Dt7([k-1].value.na[1]), Dt2([dest].value), Dt2([dest].value.na[1])); | ||
1582 | } | ||
1583 | dasm_put(Dst, 3391, Dt2([dest].tt)); | ||
1584 | dasm_put(Dst, 2168); | ||
1585 | if (ISK(rkey)) { | ||
1586 | dasm_put(Dst, 3398); | ||
1587 | } else { | ||
1588 | dasm_put(Dst, 3402); | ||
1589 | } | ||
1590 | dasm_put(Dst, 3406, DtC(->metatable), DtC(->flags), 1<<TM_INDEX, (ptrdiff_t)(J->nextins)); | ||
1591 | break; | ||
1592 | } | ||
1593 | |||
1594 | } | ||
1595 | |||
1596 | static void jit_op_settable(jit_State *J, int tab, int rkey, int rval) | ||
1597 | { | ||
1598 | const TValue *val = ISK(rval) ? &J->pt->k[INDEXK(rval)] : NULL; | ||
1599 | int k = jit_keylookup(J, tab, rkey); | ||
1600 | switch (k) { | ||
1601 | case TKEY_KSTR: /* Const string key. */ | ||
1602 | case TKEY_STR: /* Variable string key. */ | ||
1603 | if (ISK(rval)) { | ||
1604 | dasm_put(Dst, 3492, (ptrdiff_t)(val)); | ||
1605 | } else { | ||
1606 | if (rval) { | ||
1607 | dasm_put(Dst, 787, rval*sizeof(TValue)); | ||
1608 | } | ||
1609 | } | ||
1610 | if (k == TKEY_KSTR) { | ||
1611 | dasm_put(Dst, 3495); | ||
1612 | } else { | ||
1613 | dasm_put(Dst, 3499); | ||
1614 | } | ||
1615 | break; | ||
1616 | case TKEY_ANY: /* Generic settable fallback. */ | ||
1617 | if (ISK(rkey)) { | ||
1618 | dasm_put(Dst, 3342, (ptrdiff_t)(&J->pt->k[INDEXK(rkey)])); | ||
1619 | } else { | ||
1620 | dasm_put(Dst, 3204, Dt2([rkey])); | ||
1621 | } | ||
1622 | if (ISK(rval)) { | ||
1623 | dasm_put(Dst, 3184, (ptrdiff_t)(val)); | ||
1624 | } else { | ||
1625 | dasm_put(Dst, 3345, Dt2([rval])); | ||
1626 | } | ||
1627 | if (tab) { | ||
1628 | dasm_put(Dst, 787, tab*sizeof(TValue)); | ||
1629 | } | ||
1630 | dasm_put(Dst, 3503, Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(luaV_settable), Dt1(->base)); | ||
1631 | break; | ||
1632 | default: /* Array key. */ | ||
1633 | dasm_put(Dst, 3520, Dt7([k-1].tt)); | ||
1634 | dasm_put(Dst, 2168); | ||
1635 | if (ISK(rkey)) { | ||
1636 | dasm_put(Dst, 3534); | ||
1637 | } else { | ||
1638 | dasm_put(Dst, 3538); | ||
1639 | } | ||
1640 | dasm_put(Dst, 3406, DtC(->metatable), DtC(->flags), 1<<TM_NEWINDEX, (ptrdiff_t)(J->nextins)); | ||
1641 | if (!ISK(rval) || iscollectable(val)) { | ||
1642 | dasm_put(Dst, 3542, DtC(->marked), bitmask(BLACKBIT)); | ||
1643 | dasm_put(Dst, 3555); | ||
1644 | } | ||
1645 | if (ISK(rval)) { | ||
1646 | switch (ttype(val)) { | ||
1647 | case 0: | ||
1648 | dasm_put(Dst, 3565, Dt7([k-1].tt)); | ||
1649 | break; | ||
1650 | case 1: | ||
1651 | if (bvalue(val)) { /* true */ | ||
1652 | dasm_put(Dst, 3573, Dt7([k-1].value), Dt7([k-1].tt)); | ||
1653 | } else { /* false */ | ||
1654 | dasm_put(Dst, 3585, Dt7([k-1].value), Dt7([k-1].tt)); | ||
1655 | } | ||
1656 | break; | ||
1657 | case 3: { | ||
1658 | if ((&(val)->value)->n == (lua_Number)0) { | ||
1659 | dasm_put(Dst, 2404); | ||
1660 | } else if ((&(val)->value)->n == (lua_Number)1) { | ||
1661 | dasm_put(Dst, 2408); | ||
1662 | } else { | ||
1663 | dasm_put(Dst, 2411, &(val)->value); | ||
1664 | } | ||
1665 | dasm_put(Dst, 3600, Dt7([k-1].value), Dt7([k-1].tt)); | ||
1666 | break; | ||
1667 | } | ||
1668 | case 4: | ||
1669 | dasm_put(Dst, 3611, Dt7([k-1].value), (ptrdiff_t)(gcvalue(val)), Dt7([k-1].tt)); | ||
1670 | break; | ||
1671 | default: lua_assert(0); break; | ||
1672 | } | ||
1673 | } else { | ||
1674 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1675 | dasm_put(Dst, 2947, Dt2([rval].tt), Dt2([rval].value), Dt7([k-1].tt), Dt7([k-1].value)); | ||
1676 | } else { | ||
1677 | dasm_put(Dst, 2965, Dt2([rval].value), Dt2([rval].value.na[1]), Dt2([rval].tt), Dt7([k-1].value), Dt7([k-1].value.na[1]), Dt7([k-1].tt)); | ||
1678 | } | ||
1679 | } | ||
1680 | break; | ||
1681 | } | ||
1682 | |||
1683 | } | ||
1684 | |||
1685 | static void jit_op_self(jit_State *J, int dest, int tab, int rkey) | ||
1686 | { | ||
1687 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1688 | dasm_put(Dst, 821, Dt2([tab].tt), Dt2([tab].value), Dt2([dest+1].tt), Dt2([dest+1].value)); | ||
1689 | } else { | ||
1690 | dasm_put(Dst, 839, Dt2([tab].value), Dt2([tab].value.na[1]), Dt2([tab].tt), Dt2([dest+1].value), Dt2([dest+1].value.na[1]), Dt2([dest+1].tt)); | ||
1691 | } | ||
1692 | jit_op_gettable(J, dest, tab, rkey); | ||
1693 | } | ||
1694 | |||
1695 | /* ------------------------------------------------------------------------ */ | ||
1696 | |||
1697 | static void jit_op_setlist(jit_State *J, int ra, int num, int batch) | ||
1698 | { | ||
1699 | if (batch == 0) { batch = (int)(*J->nextins); J->combine++; } | ||
1700 | batch = (batch-1)*LFIELDS_PER_FLUSH; | ||
1701 | if (num == 0) { /* Previous op was open and set TOP: {f()} or {...}. */ | ||
1702 | dasm_put(Dst, 3685, Dt1(->env.value), Dt2([ra+1]), Dt2([ra].value)); | ||
1703 | if (batch > 0) { | ||
1704 | dasm_put(Dst, 3709, batch); | ||
1705 | } | ||
1706 | dasm_put(Dst, 3713, DtC(->sizearray), (ptrdiff_t)(luaH_resizearray), DtC(->marked), bitmask(BLACKBIT), DtC(->array), Dt1(->env.value)); | ||
1707 | dasm_put(Dst, 3752); | ||
1708 | } else { /* Set fixed number of args. */ | ||
1709 | dasm_put(Dst, 3762, Dt2([ra].value), DtC(->sizearray), batch+num, DtC(->marked), bitmask(BLACKBIT), DtC(->array), Dt2([ra+1+num])); | ||
1710 | dasm_put(Dst, 3792, batch+num, (ptrdiff_t)(luaH_resizearray)); | ||
1711 | } | ||
1712 | if (batch > 0) { | ||
1713 | dasm_put(Dst, 3821, batch*sizeof(TValue)); | ||
1714 | } | ||
1715 | dasm_put(Dst, 3825, Dt2([ra+1])); | ||
1716 | if (num == 0) { /* Previous op was open. Restore L->top. */ | ||
1717 | dasm_put(Dst, 1445, Dt2([J->pt->maxstacksize]), Dt1(->top)); | ||
1718 | } | ||
1719 | } | ||
1720 | |||
1721 | /* ------------------------------------------------------------------------ */ | ||
1722 | |||
1723 | static void jit_op_arith(jit_State *J, int dest, int rkb, int rkc, int ev) | ||
1724 | { | ||
1725 | const TValue *kkb = ISK(rkb) ? &J->pt->k[INDEXK(rkb)] : NULL; | ||
1726 | const TValue *kkc = ISK(rkc) ? &J->pt->k[INDEXK(rkc)] : NULL; | ||
1727 | const Value *kval; | ||
1728 | int idx, rev; | ||
1729 | int target = (ev == TM_LT || ev == TM_LE) ? jit_jmp_target(J) : 0; | ||
1730 | int hastail = 0; | ||
1731 | |||
1732 | /* The bytecode compiler already folds constants except for: k/0, k%0, */ | ||
1733 | /* NaN results, k1<k2, k1<=k2. No point in optimizing these cases. */ | ||
1734 | if (ISK(rkb&rkc)) goto fallback; | ||
1735 | |||
1736 | /* Avoid optimization when non-numeric constants are present. */ | ||
1737 | if (kkb ? !ttisnumber(kkb) : (kkc && !ttisnumber(kkc))) goto fallback; | ||
1738 | |||
1739 | /* The TYPE hint selects numeric inlining and/or fallback encoding. */ | ||
1740 | switch (ttype(hint_get(J, TYPE))) { | ||
1741 | case LUA_TNIL: hastail = 1; break; /* No hint: numeric + fallback. */ | ||
1742 | case LUA_TNUMBER: break; /* Numbers: numeric + deoptimization. */ | ||
1743 | default: goto fallback; /* Mixed/other types: fallback only. */ | ||
1744 | } | ||
1745 | |||
1746 | /* The checks above ensure: at most one of the operands is a constant. */ | ||
1747 | /* Reverse operation and swap operands so the 2nd operand is a variable. */ | ||
1748 | if (kkc) { kval = &kkc->value; idx = rkb; rev = 1; } | ||
1749 | else { kval = kkb ? &kkb->value : NULL; idx = rkc; rev = 0; } | ||
1750 | |||
1751 | /* Special handling for some operators. */ | ||
1752 | switch (ev) { | ||
1753 | case TM_MOD: | ||
1754 | /* Check for modulo with positive numbers, so we can use fprem. */ | ||
1755 | if (kval) { | ||
1756 | if (kval->na[1] < 0) { hastail = 0; goto fallback; } /* x%-k, -k%x */ | ||
1757 | dasm_put(Dst, 3850, Dt2([idx].tt), Dt2([idx].value.na[1])); | ||
1758 | if (kkb) { | ||
1759 | dasm_put(Dst, 3868, Dt2([rkc].value), kval); | ||
1760 | } else { | ||
1761 | dasm_put(Dst, 3875, kval, Dt2([rkb].value)); | ||
1762 | } | ||
1763 | } else { | ||
1764 | dasm_put(Dst, 3882, Dt2([rkb].tt), Dt2([rkc].tt), Dt2([rkb].value.na[1]), Dt2([rkc].value.na[1]), Dt2([rkc].value), Dt2([rkb].value)); | ||
1765 | } | ||
1766 | dasm_put(Dst, 1387); | ||
1767 | goto fpstore; | ||
1768 | case TM_POW: | ||
1769 | if (hastail || !kval) break; /* Avoid this if not optimizing. */ | ||
1770 | if (rev) { /* x^k for k > 0, k integer. */ | ||
1771 | lua_Number n = kval->n; | ||
1772 | int k; | ||
1773 | lua_number2int(k, n); | ||
1774 | /* All positive integers would work. But need to limit code explosion. */ | ||
1775 | if (k > 0 && k <= 65536 && (lua_Number)k == n) { | ||
1776 | dasm_put(Dst, 3916, Dt2([idx].tt), Dt2([idx])); | ||
1777 | for (; (k & 1) == 0; k >>= 1) { /* Handle leading zeroes (2^k). */ | ||
1778 | dasm_put(Dst, 3928); | ||
1779 | } | ||
1780 | if ((k >>= 1) != 0) { /* Handle trailing bits. */ | ||
1781 | dasm_put(Dst, 3931); | ||
1782 | for (; k != 1; k >>= 1) { | ||
1783 | if (k & 1) { | ||
1784 | dasm_put(Dst, 3936); | ||
1785 | } | ||
1786 | dasm_put(Dst, 3928); | ||
1787 | } | ||
1788 | dasm_put(Dst, 3939); | ||
1789 | } | ||
1790 | goto fpstore; | ||
1791 | } | ||
1792 | } else if (kval->n > (lua_Number)0) { /* k^x for k > 0. */ | ||
1793 | int log2kval[3]; /* Enough storage for a tword (80 bits). */ | ||
1794 | log2kval[2] = 0; /* Avoid leaking garbage. */ | ||
1795 | /* Double precision log2(k) doesn't cut it (3^x != 3 for x = 1). */ | ||
1796 | ((void (*)(int *, double))J->jsub[JSUB_LOG2_TWORD])(log2kval, kval->n); | ||
1797 | dasm_put(Dst, 3942, log2kval[0], log2kval[1], log2kval[2], Dt2([idx].tt), Dt2([idx].value)); | ||
1798 | |||
1799 | goto fpstore; | ||
1800 | } | ||
1801 | break; | ||
1802 | } | ||
1803 | |||
1804 | /* Check number type and load 1st operand. */ | ||
1805 | if (kval) { | ||
1806 | dasm_put(Dst, 4013, Dt2([idx].tt)); | ||
1807 | if ((kval)->n == (lua_Number)0) { | ||
1808 | dasm_put(Dst, 2404); | ||
1809 | } else if ((kval)->n == (lua_Number)1) { | ||
1810 | dasm_put(Dst, 2408); | ||
1811 | } else { | ||
1812 | dasm_put(Dst, 2411, kval); | ||
1813 | } | ||
1814 | } else { | ||
1815 | if (rkb == rkc) { | ||
1816 | dasm_put(Dst, 4022, Dt2([rkb].tt)); | ||
1817 | } else { | ||
1818 | dasm_put(Dst, 4027, Dt2([rkb].tt), Dt2([rkc].tt)); | ||
1819 | } | ||
1820 | dasm_put(Dst, 3920, Dt2([rkb].value)); | ||
1821 | } | ||
1822 | |||
1823 | /* Encode arithmetic operation with 2nd operand. */ | ||
1824 | switch ((ev<<1)+rev) { | ||
1825 | case TM_ADD<<1: case (TM_ADD<<1)+1: | ||
1826 | if (rkb == rkc) { | ||
1827 | dasm_put(Dst, 4041); | ||
1828 | } else { | ||
1829 | dasm_put(Dst, 4044, Dt2([idx].value)); | ||
1830 | } | ||
1831 | break; | ||
1832 | case TM_SUB<<1: | ||
1833 | dasm_put(Dst, 4048, Dt2([idx].value)); | ||
1834 | break; | ||
1835 | case (TM_SUB<<1)+1: | ||
1836 | dasm_put(Dst, 4052, Dt2([idx].value)); | ||
1837 | break; | ||
1838 | case TM_MUL<<1: case (TM_MUL<<1)+1: | ||
1839 | if (rkb == rkc) { | ||
1840 | dasm_put(Dst, 3928); | ||
1841 | } else { | ||
1842 | dasm_put(Dst, 4056, Dt2([idx].value)); | ||
1843 | } | ||
1844 | break; | ||
1845 | case TM_DIV<<1: | ||
1846 | dasm_put(Dst, 4060, Dt2([idx].value)); | ||
1847 | break; | ||
1848 | case (TM_DIV<<1)+1: | ||
1849 | dasm_put(Dst, 4064, Dt2([idx].value)); | ||
1850 | break; | ||
1851 | case TM_POW<<1: | ||
1852 | dasm_put(Dst, 4068, Dt2([idx].value), (ptrdiff_t)(pow)); | ||
1853 | break; | ||
1854 | case (TM_POW<<1)+1: | ||
1855 | dasm_put(Dst, 4088, Dt2([idx].value), (ptrdiff_t)(pow)); | ||
1856 | break; | ||
1857 | case TM_UNM<<1: case (TM_UNM<<1)+1: | ||
1858 | dasm_put(Dst, 4108); | ||
1859 | break; | ||
1860 | default: /* TM_LT or TM_LE. */ | ||
1861 | dasm_put(Dst, 1325, Dt2([idx].value)); | ||
1862 | if (J->flags & JIT_F_CPU_CMOV) { | ||
1863 | dasm_put(Dst, 3293); | ||
1864 | } else { | ||
1865 | dasm_put(Dst, 3298); | ||
1866 | } | ||
1867 | dasm_put(Dst, 4111, dest?(J->nextpc+1):target); | ||
1868 | jit_assert(dest == 0 || dest == 1); /* Really cond. */ | ||
1869 | switch (((rev^dest)<<1)+(dest^(ev == TM_LT))) { | ||
1870 | case 0: | ||
1871 | dasm_put(Dst, 4115, target); | ||
1872 | break; | ||
1873 | case 1: | ||
1874 | dasm_put(Dst, 4119, target); | ||
1875 | break; | ||
1876 | case 2: | ||
1877 | dasm_put(Dst, 4123, target); | ||
1878 | break; | ||
1879 | case 3: | ||
1880 | dasm_put(Dst, 4127, target); | ||
1881 | break; | ||
1882 | } | ||
1883 | goto skipstore; | ||
1884 | } | ||
1885 | fpstore: | ||
1886 | /* Store result and set result type (if necessary). */ | ||
1887 | dasm_put(Dst, 933, Dt2([dest].value)); | ||
1888 | if (dest != rkb && dest != rkc) { | ||
1889 | dasm_put(Dst, 1309, Dt2([dest].tt)); | ||
1890 | } | ||
1891 | |||
1892 | skipstore: | ||
1893 | if (!hastail) { | ||
1894 | jit_deopt_target(J, 0); | ||
1895 | return; | ||
1896 | } | ||
1897 | |||
1898 | dasm_put(Dst, 1626); | ||
1899 | dasm_put(Dst, 1541); | ||
1900 | |||
1901 | fallback: | ||
1902 | /* Generic fallback for arithmetic ops. */ | ||
1903 | if (kkb) { | ||
1904 | dasm_put(Dst, 3342, (ptrdiff_t)(kkb)); | ||
1905 | } else { | ||
1906 | dasm_put(Dst, 3204, Dt2([rkb])); | ||
1907 | } | ||
1908 | if (kkc) { | ||
1909 | dasm_put(Dst, 3184, (ptrdiff_t)(kkc)); | ||
1910 | } else { | ||
1911 | dasm_put(Dst, 3345, Dt2([rkc])); | ||
1912 | } | ||
1913 | if (target) { /* TM_LT or TM_LE. */ | ||
1914 | dasm_put(Dst, 4131, Dt1(->savedpc), (ptrdiff_t)((J->nextins+1)), (ptrdiff_t)(ev==TM_LT?luaV_lessthan:luaV_lessequal), Dt1(->base)); | ||
1915 | if (dest) { /* cond */ | ||
1916 | dasm_put(Dst, 1479, target); | ||
1917 | } else { | ||
1918 | dasm_put(Dst, 4154, target); | ||
1919 | } | ||
1920 | } else { | ||
1921 | if (dest) { | ||
1922 | dasm_put(Dst, 787, dest*sizeof(TValue)); | ||
1923 | } | ||
1924 | dasm_put(Dst, 4158, Dt1(->savedpc), (ptrdiff_t)(J->nextins), ev, (ptrdiff_t)(luaV_arith), Dt1(->base)); | ||
1925 | } | ||
1926 | |||
1927 | if (hastail) { | ||
1928 | dasm_put(Dst, 1644); | ||
1929 | } | ||
1930 | } | ||
1931 | |||
1932 | /* ------------------------------------------------------------------------ */ | ||
1933 | |||
1934 | static void jit_fallback_len(lua_State *L, StkId ra, const TValue *rb) | ||
1935 | { | ||
1936 | switch (ttype(rb)) { | ||
1937 | case LUA_TTABLE: | ||
1938 | setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); | ||
1939 | break; | ||
1940 | case LUA_TSTRING: | ||
1941 | setnvalue(ra, cast_num(tsvalue(rb)->len)); | ||
1942 | break; | ||
1943 | default: { | ||
1944 | const TValue *tm = luaT_gettmbyobj(L, rb, TM_LEN); | ||
1945 | if (ttisfunction(tm)) { | ||
1946 | ptrdiff_t rasave = savestack(L, ra); | ||
1947 | setobj2s(L, L->top, tm); | ||
1948 | setobj2s(L, L->top+1, rb); | ||
1949 | luaD_checkstack(L, 2); | ||
1950 | L->top += 2; | ||
1951 | luaD_call(L, L->top - 2, 1); | ||
1952 | ra = restorestack(L, rasave); | ||
1953 | L->top--; | ||
1954 | setobjs2s(L, ra, L->top); | ||
1955 | } else { | ||
1956 | luaG_typeerror(L, rb, "get length of"); | ||
1957 | } | ||
1958 | break; | ||
1959 | } | ||
1960 | } | ||
1961 | } | ||
1962 | |||
1963 | static void jit_op_len(jit_State *J, int dest, int rb) | ||
1964 | { | ||
1965 | switch (ttype(hint_get(J, TYPE))) { | ||
1966 | case LUA_TTABLE: | ||
1967 | jit_deopt_target(J, 0); | ||
1968 | dasm_put(Dst, 4179, Dt2([rb].tt), Dt2([rb].value), (ptrdiff_t)(luaH_getn), Dt2([dest].value), Dt2([dest].tt)); | ||
1969 | break; | ||
1970 | case LUA_TSTRING: | ||
1971 | jit_deopt_target(J, 0); | ||
1972 | dasm_put(Dst, 4212, Dt2([rb].tt), Dt2([rb].value), DtB(->tsv.len), Dt2([dest].value), Dt2([dest].tt)); | ||
1973 | break; | ||
1974 | default: | ||
1975 | dasm_put(Dst, 3204, Dt2([rb])); | ||
1976 | if (dest) { | ||
1977 | dasm_put(Dst, 787, dest*sizeof(TValue)); | ||
1978 | } | ||
1979 | dasm_put(Dst, 4237, Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(jit_fallback_len), Dt1(->base)); | ||
1980 | break; | ||
1981 | } | ||
1982 | } | ||
1983 | |||
1984 | static void jit_op_not(jit_State *J, int dest, int rb) | ||
1985 | { | ||
1986 | /* l_isfalse() without a branch -- truly devious. */ | ||
1987 | /* ((value & tt) | (tt>>1)) is only zero for nil/false. */ | ||
1988 | /* Assumes: LUA_TNIL == 0, LUA_TBOOLEAN == 1, bvalue() == 0/1 */ | ||
1989 | dasm_put(Dst, 4258, Dt2([rb].tt), Dt2([rb].value), Dt2([dest].tt), Dt2([dest].value)); | ||
1990 | } | ||
1991 | |||
1992 | /* ------------------------------------------------------------------------ */ | ||
1993 | |||
1994 | static void jit_op_concat(jit_State *J, int dest, int first, int last) | ||
1995 | { | ||
1996 | int num = last-first+1; | ||
1997 | if (num == 2 && ttisstring(hint_get(J, TYPE))) { /* Optimize common case. */ | ||
1998 | if (first) { | ||
1999 | dasm_put(Dst, 787, first*sizeof(TValue)); | ||
2000 | } | ||
2001 | dasm_put(Dst, 4288, Dt2([dest].value), Dt2([dest].tt)); | ||
2002 | } else { /* Generic fallback. */ | ||
2003 | dasm_put(Dst, 4302, Dt1(->savedpc), (ptrdiff_t)(J->nextins), num, last, (ptrdiff_t)(luaV_concat), Dt1(->base)); | ||
2004 | if (dest != first) { | ||
2005 | if (J->flags & JIT_F_CPU_SSE2) { | ||
2006 | dasm_put(Dst, 821, Dt2([first].tt), Dt2([first].value), Dt2([dest].tt), Dt2([dest].value)); | ||
2007 | } else { | ||
2008 | dasm_put(Dst, 839, Dt2([first].value), Dt2([first].value.na[1]), Dt2([first].tt), Dt2([dest].value), Dt2([dest].value.na[1]), Dt2([dest].tt)); | ||
2009 | } | ||
2010 | } | ||
2011 | } | ||
2012 | jit_checkGC(J); /* Always do this, even for the optimized variant. */ | ||
2013 | |||
2014 | } | ||
2015 | |||
2016 | /* ------------------------------------------------------------------------ */ | ||
2017 | |||
2018 | static void jit_op_eq(jit_State *J, int cond, int rkb, int rkc) | ||
2019 | { | ||
2020 | int target = jit_jmp_target(J); | ||
2021 | int condtarget = cond ? (J->nextpc+1) : target; | ||
2022 | jit_assert(cond == 0 || cond == 1); | ||
2023 | |||
2024 | /* Comparison of two constants. Evaluate at compile time. */ | ||
2025 | if (ISK(rkb&rkc)) { | ||
2026 | if ((rkb == rkc) == cond) { /* Constants are already unique. */ | ||
2027 | dasm_put(Dst, 665, target); | ||
2028 | } | ||
2029 | return; | ||
2030 | } | ||
2031 | |||
2032 | if (ISK(rkb|rkc)) { /* Compare a variable and a constant. */ | ||
2033 | const TValue *kk; | ||
2034 | if (ISK(rkb)) { int t = rkc; rkc = rkb; rkb = t; } /* rkc holds const. */ | ||
2035 | kk = &J->pt->k[INDEXK(rkc)]; | ||
2036 | switch (ttype(kk)) { | ||
2037 | case LUA_TNIL: | ||
2038 | dasm_put(Dst, 4493, Dt2([rkb].tt)); | ||
2039 | break; | ||
2040 | case LUA_TBOOLEAN: | ||
2041 | if (bvalue(kk)) { | ||
2042 | dasm_put(Dst, 4498, Dt2([rkb].tt), Dt2([rkb].value)); | ||
2043 | } else { | ||
2044 | dasm_put(Dst, 4509, Dt2([rkb].tt), Dt2([rkb].value)); | ||
2045 | } | ||
2046 | break; | ||
2047 | case LUA_TNUMBER: | ||
2048 | dasm_put(Dst, 4517, Dt2([rkb].tt), condtarget, Dt2([rkb].value), &kk->value); | ||
2049 | if (J->flags & JIT_F_CPU_CMOV) { | ||
2050 | dasm_put(Dst, 3293); | ||
2051 | } else { | ||
2052 | dasm_put(Dst, 3298); | ||
2053 | } | ||
2054 | dasm_put(Dst, 4111, condtarget); | ||
2055 | break; | ||
2056 | case LUA_TSTRING: | ||
2057 | dasm_put(Dst, 4531, Dt2([rkb].tt), condtarget, Dt2([rkb].value), (ptrdiff_t)(rawtsvalue(kk))); | ||
2058 | break; | ||
2059 | default: jit_assert(0); break; | ||
2060 | } | ||
2061 | } else { /* Compare two variables. */ | ||
2062 | dasm_put(Dst, 4543, Dt2([rkb].tt), Dt2([rkc].tt), condtarget); | ||
2063 | switch (ttype(hint_get(J, TYPE))) { | ||
2064 | case LUA_TNUMBER: | ||
2065 | jit_deopt_target(J, 0); | ||
2066 | dasm_put(Dst, 4553, Dt2([rkb].value), Dt2([rkc].value)); | ||
2067 | if (J->flags & JIT_F_CPU_CMOV) { | ||
2068 | dasm_put(Dst, 3293); | ||
2069 | } else { | ||
2070 | dasm_put(Dst, 3298); | ||
2071 | } | ||
2072 | dasm_put(Dst, 4111, condtarget); | ||
2073 | break; | ||
2074 | case LUA_TSTRING: | ||
2075 | jit_deopt_target(J, 0); | ||
2076 | dasm_put(Dst, 4568, Dt2([rkb].value), Dt2([rkc].value)); | ||
2077 | break; | ||
2078 | default: | ||
2079 | dasm_put(Dst, 4583, Dt2([rkc]), Dt2([rkb]), Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(luaV_equalval), Dt1(->base)); | ||
2080 | break; | ||
2081 | } | ||
2082 | } | ||
2083 | if (cond) { | ||
2084 | dasm_put(Dst, 4154, target); | ||
2085 | } else { | ||
2086 | dasm_put(Dst, 1479, target); | ||
2087 | } | ||
2088 | } | ||
2089 | |||
2090 | /* ------------------------------------------------------------------------ */ | ||
2091 | |||
2092 | static void jit_op_test(jit_State *J, int cond, int dest, int src) | ||
2093 | { | ||
2094 | int target = jit_jmp_target(J); | ||
2095 | |||
2096 | /* l_isfalse() without a branch. But this time preserve tt/value. */ | ||
2097 | /* (((value & tt) * 2 + tt) >> 1) is only zero for nil/false. */ | ||
2098 | /* Assumes: 3*tt < 2^32, LUA_TNIL == 0, LUA_TBOOLEAN == 1, bvalue() == 0/1 */ | ||
2099 | dasm_put(Dst, 4611, Dt2([src].tt), Dt2([src].value)); | ||
2100 | |||
2101 | /* Check if we can omit the stack copy. */ | ||
2102 | if (dest == src) { /* Yes, invert branch condition. */ | ||
2103 | if (cond) { | ||
2104 | dasm_put(Dst, 1479, target); | ||
2105 | } else { | ||
2106 | dasm_put(Dst, 4154, target); | ||
2107 | } | ||
2108 | } else { /* No, jump around copy code. */ | ||
2109 | if (cond) { | ||
2110 | dasm_put(Dst, 4627); | ||
2111 | } else { | ||
2112 | dasm_put(Dst, 4632); | ||
2113 | } | ||
2114 | dasm_put(Dst, 4637, Dt2([src].value.na[1]), Dt2([dest].tt), Dt2([dest].value), Dt2([dest].value.na[1]), target); | ||
2115 | } | ||
2116 | } | ||
2117 | |||
2118 | static void jit_op_jmp(jit_State *J, int target) | ||
2119 | { | ||
2120 | dasm_put(Dst, 665, target); | ||
2121 | } | ||
2122 | |||
2123 | /* ------------------------------------------------------------------------ */ | ||
2124 | |||
2125 | enum { FOR_IDX, FOR_LIM, FOR_STP, FOR_EXT }; | ||
2126 | |||
2127 | static const char *const jit_for_coerce_error[] = { | ||
2128 | LUA_QL("for") " initial value must be a number", | ||
2129 | LUA_QL("for") " limit must be a number", | ||
2130 | LUA_QL("for") " step must be a number", | ||
2131 | }; | ||
2132 | |||
2133 | /* Try to coerce for slots with strings to numbers in place or complain. */ | ||
2134 | static void jit_for_coerce(lua_State *L, TValue *o) | ||
2135 | { | ||
2136 | int i; | ||
2137 | for (i = FOR_IDX; i <= FOR_STP; i++, o++) { | ||
2138 | lua_Number num; | ||
2139 | if (ttisnumber(o)) continue; | ||
2140 | if (ttisstring(o) && luaO_str2d(svalue(o), &num)) { | ||
2141 | setnvalue(o, num); | ||
2142 | } else { | ||
2143 | luaG_runerror(L, jit_for_coerce_error[i]); | ||
2144 | } | ||
2145 | } | ||
2146 | } | ||
2147 | |||
2148 | static void jit_op_forprep(jit_State *J, int ra, int target) | ||
2149 | { | ||
2150 | const TValue *step = hint_get(J, FOR_STEP_K); | ||
2151 | if (ttisnumber(step)) { | ||
2152 | dasm_put(Dst, 4654, Dt2([ra+FOR_IDX].tt), Dt2([ra+FOR_LIM].tt), Dt2([ra+FOR_LIM].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_EXT].value)); | ||
2153 | if (J->flags & JIT_F_CPU_CMOV) { | ||
2154 | dasm_put(Dst, 3293); | ||
2155 | } else { | ||
2156 | dasm_put(Dst, 3298); | ||
2157 | } | ||
2158 | dasm_put(Dst, 1309, Dt2([ra+FOR_EXT].tt)); | ||
2159 | if (nvalue(step) < (lua_Number)0) { | ||
2160 | dasm_put(Dst, 4115, target+1); | ||
2161 | } else { | ||
2162 | dasm_put(Dst, 4123, target+1); | ||
2163 | } | ||
2164 | } else { | ||
2165 | dasm_put(Dst, 4683, Dt2([ra+FOR_IDX].tt), Dt2([ra+FOR_LIM].tt), Dt2([ra+FOR_STP].tt), Dt2([ra+FOR_STP].value.na[1]), Dt2([ra+FOR_LIM].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_EXT].value)); | ||
2166 | if (J->flags & JIT_F_CPU_CMOV) { | ||
2167 | dasm_put(Dst, 3293); | ||
2168 | } else { | ||
2169 | dasm_put(Dst, 3298); | ||
2170 | } | ||
2171 | dasm_put(Dst, 4732, Dt2([ra+FOR_EXT].tt), target+1); | ||
2172 | } | ||
2173 | if (ttisnumber(hint_get(J, TYPE))) { | ||
2174 | jit_deopt_target(J, 0); | ||
2175 | } else { | ||
2176 | dasm_put(Dst, 679); | ||
2177 | dasm_put(Dst, 4743, Dt2([ra]), Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(jit_for_coerce)); | ||
2178 | } | ||
2179 | } | ||
2180 | |||
2181 | static void jit_op_forloop(jit_State *J, int ra, int target) | ||
2182 | { | ||
2183 | const TValue *step = hint_getpc(J, FOR_STEP_K, target-1); | ||
2184 | if (ttisnumber(step)) { | ||
2185 | dasm_put(Dst, 4766, Dt2([ra+FOR_LIM].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_STP].value), Dt2([ra+FOR_EXT].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_EXT].tt)); | ||
2186 | if (J->flags & JIT_F_CPU_CMOV) { | ||
2187 | dasm_put(Dst, 3293); | ||
2188 | } else { | ||
2189 | dasm_put(Dst, 3298); | ||
2190 | } | ||
2191 | if (nvalue(step) < (lua_Number)0) { | ||
2192 | dasm_put(Dst, 4127, target); | ||
2193 | } else { | ||
2194 | dasm_put(Dst, 4119, target); | ||
2195 | } | ||
2196 | } else { | ||
2197 | dasm_put(Dst, 4789, Dt2([ra+FOR_STP].value.na[1]), Dt2([ra+FOR_LIM].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_STP].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_EXT].value), Dt2([ra+FOR_EXT].tt)); | ||
2198 | if (J->flags & JIT_F_CPU_CMOV) { | ||
2199 | dasm_put(Dst, 3293); | ||
2200 | } else { | ||
2201 | dasm_put(Dst, 3298); | ||
2202 | } | ||
2203 | dasm_put(Dst, 4127, target); | ||
2204 | } | ||
2205 | } | ||
2206 | |||
2207 | /* ------------------------------------------------------------------------ */ | ||
2208 | |||
2209 | static void jit_op_tforloop(jit_State *J, int ra, int nresults) | ||
2210 | { | ||
2211 | int target = jit_jmp_target(J); | ||
2212 | int i; | ||
2213 | if (jit_inline_tforloop(J, ra, nresults, target)) return; /* Inlined? */ | ||
2214 | for (i = 2; i >= 0; i--) { | ||
2215 | if (J->flags & JIT_F_CPU_SSE2) { | ||
2216 | dasm_put(Dst, 821, Dt2([ra+i].tt), Dt2([ra+i].value), Dt2([ra+i+3].tt), Dt2([ra+i+3].value)); | ||
2217 | } else { | ||
2218 | dasm_put(Dst, 839, Dt2([ra+i].value), Dt2([ra+i].value.na[1]), Dt2([ra+i].tt), Dt2([ra+i+3].value), Dt2([ra+i+3].value.na[1]), Dt2([ra+i+3].tt)); | ||
2219 | } | ||
2220 | } | ||
2221 | jit_op_call(J, ra+3, 2, nresults); | ||
2222 | dasm_put(Dst, 4827, Dt2([ra+3].tt)); | ||
2223 | if (J->flags & JIT_F_CPU_SSE2) { | ||
2224 | dasm_put(Dst, 821, Dt2([ra+3].tt), Dt2([ra+3].value), Dt2([ra+2].tt), Dt2([ra+2].value)); | ||
2225 | } else { | ||
2226 | dasm_put(Dst, 839, Dt2([ra+3].value), Dt2([ra+3].value.na[1]), Dt2([ra+3].tt), Dt2([ra+2].value), Dt2([ra+2].value.na[1]), Dt2([ra+2].tt)); | ||
2227 | } | ||
2228 | dasm_put(Dst, 4649, target); | ||
2229 | } | ||
2230 | |||
2231 | /* ------------------------------------------------------------------------ */ | ||
2232 | |||
2233 | static void jit_op_close(jit_State *J, int ra) | ||
2234 | { | ||
2235 | if (ra) { | ||
2236 | dasm_put(Dst, 4836, Dt2([ra])); | ||
2237 | } else { | ||
2238 | dasm_put(Dst, 4844); | ||
2239 | } | ||
2240 | dasm_put(Dst, 1734, (ptrdiff_t)(luaF_close)); | ||
2241 | } | ||
2242 | |||
2243 | static void jit_op_closure(jit_State *J, int dest, int ptidx) | ||
2244 | { | ||
2245 | Proto *npt = J->pt->p[ptidx]; | ||
2246 | int nup = npt->nups; | ||
2247 | if (!J->pt->is_vararg) { | ||
2248 | dasm_put(Dst, 4849, Dt2([-1].value)); | ||
2249 | } else { | ||
2250 | dasm_put(Dst, 4853, Dt1(->ci), Dt4(->func), Dt3(->value)); | ||
2251 | } | ||
2252 | dasm_put(Dst, 4863, Dt5(->env), nup, (ptrdiff_t)(luaF_newLclosure), Dt5(->p), (ptrdiff_t)(npt), Dt2([dest].value), Dt2([dest].tt)); | ||
2253 | /* Process pseudo-instructions for upvalues. */ | ||
2254 | if (nup > 0) { | ||
2255 | const Instruction *uvcode = J->nextins; | ||
2256 | int i, uvuv; | ||
2257 | /* Check which of the two types we need. */ | ||
2258 | for (i = 0, uvuv = 0; i < nup; i++) | ||
2259 | if (GET_OPCODE(uvcode[i]) == OP_GETUPVAL) uvuv++; | ||
2260 | /* Copy upvalues from parent first. */ | ||
2261 | if (uvuv) { | ||
2262 | /* LCL:eax->upvals (new closure) <-- LCL:edi->upvals (own closure). */ | ||
2263 | for (i = 0; i < nup; i++) | ||
2264 | if (GET_OPCODE(uvcode[i]) == OP_GETUPVAL) { | ||
2265 | dasm_put(Dst, 4895, Dt5(->upvals[GETARG_B(uvcode[i])]), Dt5(->upvals[i])); | ||
2266 | } | ||
2267 | } | ||
2268 | /* Next find or create upvalues for our own stack slots. */ | ||
2269 | if (nup > uvuv) { | ||
2270 | dasm_put(Dst, 909); | ||
2271 | /* LCL:edi->upvals (new closure) <-- upvalue for stack slot. */ | ||
2272 | for (i = 0; i < nup; i++) | ||
2273 | if (GET_OPCODE(uvcode[i]) == OP_MOVE) { | ||
2274 | int rb = GETARG_B(uvcode[i]); | ||
2275 | if (rb) { | ||
2276 | dasm_put(Dst, 4836, Dt2([rb])); | ||
2277 | } else { | ||
2278 | dasm_put(Dst, 4844); | ||
2279 | } | ||
2280 | dasm_put(Dst, 4902, (ptrdiff_t)(luaF_findupval), Dt5(->upvals[i])); | ||
2281 | } | ||
2282 | } | ||
2283 | J->combine += nup; /* Skip pseudo-instructions. */ | ||
2284 | } | ||
2285 | jit_checkGC(J); | ||
2286 | } | ||
2287 | |||
2288 | /* ------------------------------------------------------------------------ */ | ||
2289 | |||
2290 | static void jit_op_vararg(jit_State *J, int dest, int num) | ||
2291 | { | ||
2292 | if (num < 0) { /* Copy all varargs. */ | ||
2293 | dasm_put(Dst, 4911, Dt1(->ci), Dt4(->func), (1+J->pt->numparams)*sizeof(TValue), J->pt->maxstacksize*sizeof(TValue), Dt1(->stack_last), Dt2([dest])); | ||
2294 | dasm_put(Dst, 4967, Dt1(->top), (ptrdiff_t)(luaD_growstack), Dt1(->base)); | ||
2295 | } else if (num > 0) { /* Copy limited number of varargs. */ | ||
2296 | dasm_put(Dst, 4993, Dt1(->ci), Dt4(->func), (1+J->pt->numparams)*sizeof(TValue), Dt2([dest]), Dt2([dest+num]), Dt3([0].tt), sizeof(TValue)); | ||
2297 | } | ||
2298 | } | ||
2299 | |||
2300 | /* ------------------------------------------------------------------------ */ | ||
2301 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_x86_inline.dash b/libraries/LuaJIT-1.1.7/src/ljit_x86_inline.dash new file mode 100644 index 0000000..203642f --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit_x86_inline.dash | |||
@@ -0,0 +1,625 @@ | |||
1 | /* | ||
2 | ** Function inlining support for x86 CPUs. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | /* ------------------------------------------------------------------------ */ | ||
7 | |||
8 | /* Private structure holding function inlining info. */ | ||
9 | typedef struct jit_InlineInfo { | ||
10 | int func; /* Function slot. 1st arg slot = func+1. */ | ||
11 | int res; /* 1st result slot. Overlaps func/ci->func. */ | ||
12 | int nargs; /* Number of args. */ | ||
13 | int nresults; /* Number of results. */ | ||
14 | int xnargs; /* Expected number of args. */ | ||
15 | int xnresults; /* Returned number of results. */ | ||
16 | int hidx; /* Library/function index numbers. */ | ||
17 | } jit_InlineInfo; | ||
18 | |||
19 | /* ------------------------------------------------------------------------ */ | ||
20 | |||
21 | enum { TFOR_FUNC, TFOR_TAB, TFOR_CTL, TFOR_KEY, TFOR_VAL }; | ||
22 | |||
23 | static void jit_inline_base(jit_State *J, jit_InlineInfo *ii) | ||
24 | { | ||
25 | int func = ii->func; | ||
26 | switch (JIT_IH_IDX(ii->hidx)) { | ||
27 | case JIT_IH_BASE_PAIRS: | ||
28 | case JIT_IH_BASE_IPAIRS: | ||
29 | |// Easy for regular calls: res == func. Not inlined for tailcalls. | ||
30 | |// Guaranteed to be inlined only if used in conjunction with TFORLOOP. | ||
31 | |// So we omit setting the iterator function and fake the control var. | ||
32 | | istable func+TFOR_TAB; jne L_DEOPTIMIZE // Caveat: deopt TFORLOOP, too! | ||
33 | | xor eax, eax // Assumes: LUA_TNIL == 0. | ||
34 | | mov BASE[func+TFOR_CTL].tt, eax // Fake nil type. | ||
35 | | mov BASE[func+TFOR_CTL].value, eax // Hidden control var = 0. | ||
36 | |// mov BASE[func+TFOR_FUNC].tt, eax // Kill function (not needed). | ||
37 | |.mfmap | ||
38 | | .word JIT_MFM_DEOPT_PAIRS, J->nextpc-1 // Deoptimize TFORLOOP, too. | ||
39 | |.code | ||
40 | break; | ||
41 | default: | ||
42 | jit_assert(0); | ||
43 | break; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | /* ------------------------------------------------------------------------ */ | ||
48 | |||
49 | #ifndef COCO_DISABLE | ||
50 | |||
51 | /* Helper function for inlined coroutine.resume(). */ | ||
52 | static StkId jit_coroutine_resume(lua_State *L, StkId base, int nresults) | ||
53 | { | ||
54 | lua_State *co = thvalue(base-1); | ||
55 | /* Check for proper usage. Merge of lua_resume() and auxresume() checks. */ | ||
56 | if (co->status != LUA_YIELD) { | ||
57 | if (co->status > LUA_YIELD) { | ||
58 | errdead: | ||
59 | setsvalue(L, base-1, luaS_newliteral(L, "cannot resume dead coroutine")); | ||
60 | goto err; | ||
61 | } else if (co->ci != co->base_ci) { | ||
62 | setsvalue(L, base-1, | ||
63 | luaS_newliteral(L, "cannot resume non-suspended coroutine")); | ||
64 | goto err; | ||
65 | } else if (co->base == co->top) { | ||
66 | goto errdead; | ||
67 | } | ||
68 | } | ||
69 | { | ||
70 | ptrdiff_t ndelta = (char *)L->top - (char *)base; | ||
71 | int nargs = ndelta/sizeof(TValue); /* Compute nargs. */ | ||
72 | int status; | ||
73 | if ((char *)co->stack_last-(char *)co->top <= ndelta) { | ||
74 | co->ci->top = (StkId)(((char *)co->top) + ndelta); /* Ok before grow. */ | ||
75 | luaD_growstack(co, nargs); /* Grow thread stack. */ | ||
76 | } | ||
77 | /* Copy args. */ | ||
78 | co->top = (StkId)(((char *)co->top) + ndelta); | ||
79 | { StkId t = co->top, f = L->top; while (f > base) setobj2s(co, --t, --f); } | ||
80 | L->top = base; | ||
81 | status = luaCOCO_resume(co, nargs); /* Resume Coco thread. */ | ||
82 | if (status == 0 || status == LUA_YIELD) { /* Ok. */ | ||
83 | StkId f; | ||
84 | if (nresults == 0) return NULL; | ||
85 | if (nresults == -1) { | ||
86 | luaD_checkstack(L, co->top - co->base); /* Grow own stack. */ | ||
87 | } | ||
88 | base = L->top - 2; | ||
89 | setbvalue(base++, 1); /* true */ | ||
90 | /* Copy results. Fill unused result slots with nil. */ | ||
91 | f = co->base; | ||
92 | while (--nresults != 0 && f < co->top) setobj2s(L, base++, f++); | ||
93 | while (nresults-- > 0) setnilvalue(base++); | ||
94 | co->top = co->base; | ||
95 | return base; | ||
96 | } else { /* Error. */ | ||
97 | base = L->top; | ||
98 | setobj2s(L, base-1, co->top-1); /* Copy error object. */ | ||
99 | err: | ||
100 | setbvalue(base-2, 0); /* false */ | ||
101 | nresults -= 2; | ||
102 | while (--nresults >= 0) setnilvalue(base+nresults); /* Fill results. */ | ||
103 | return base; | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | |||
108 | static void jit_inline_coroutine(jit_State *J, jit_InlineInfo *ii) | ||
109 | { | ||
110 | int arg = ii->func+1; | ||
111 | int res = ii->res; | ||
112 | int i; | ||
113 | switch (JIT_IH_IDX(ii->hidx)) { | ||
114 | case JIT_IH_COROUTINE_YIELD: | ||
115 | | cmp aword [L+((int)&LHASCOCO((lua_State *)0))], 0 // Got a C stack? | ||
116 | | je L_DEOPTIMIZE | ||
117 | | mov L->savedpc, &J->nextins // Debugger-friendly. | ||
118 | | add BASE, arg*#TVALUE | ||
119 | if (ii->nargs >= 0) { /* Previous op was not open and did not set TOP. */ | ||
120 | | lea TOP, BASE[ii->nargs] | ||
121 | } | ||
122 | | mov L->base, BASE | ||
123 | | mov L->top, TOP | ||
124 | | call &luaCOCO_yield, L | ||
125 | | mov BASE, L->base | ||
126 | | mov TOP, L->top | ||
127 | jit_assert(ii->nresults >= 0 && ii->nresults <= EXTRA_STACK); | ||
128 | for (i = 0; i < ii->nresults; i++) { | ||
129 | | setnilvalue TOP[i] // Clear undefined result. | ||
130 | | copyslot BASE[res+i], BASE[arg+i] // Move result down. | ||
131 | } | ||
132 | ii->nargs = -1; /* Force restore of L->top. */ | ||
133 | break; | ||
134 | case JIT_IH_COROUTINE_RESUME: | ||
135 | jit_assert(ii->nargs != 0 && ii->res == ii->func); | ||
136 | | add BASE, (arg+1)*#TVALUE | ||
137 | if (ii->nargs >= 0) { /* Previous op was not open and did not set TOP. */ | ||
138 | | lea TOP, BASE[ii->nargs-1] | ||
139 | } else { | ||
140 | | cmp TOP, BASE; jb L_DEOPTIMIZE // No thread arg? Deoptimize. | ||
141 | } | ||
142 | | istt -1, LUA_TTHREAD; jne L_DEOPTIMIZE // Wrong type? Deoptimize. | ||
143 | | mov L:eax, BASE[-1].value | ||
144 | | cmp aword [L:eax+((int)&LHASCOCO((lua_State *)0))], 0 | ||
145 | | je L_DEOPTIMIZE // No C stack? Deoptimize. | ||
146 | | mov L->savedpc, &J->nextins // Debugger-friendly. | ||
147 | | mov L->top, TOP | ||
148 | | call &jit_coroutine_resume, L, BASE, ii->nresults | ||
149 | | mov BASE, L->base | ||
150 | if (ii->nresults == -1) { | ||
151 | | mov TOP, eax | ||
152 | } | ||
153 | ii->nargs = -1; /* Force restore of L->top. */ | ||
154 | break; | ||
155 | default: | ||
156 | jit_assert(0); | ||
157 | break; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | #endif /* COCO_DISABLE */ | ||
162 | |||
163 | /* ------------------------------------------------------------------------ */ | ||
164 | |||
165 | static void jit_inline_string(jit_State *J, jit_InlineInfo *ii) | ||
166 | { | ||
167 | int arg = ii->func+1; | ||
168 | int res = ii->res; | ||
169 | switch (JIT_IH_IDX(ii->hidx)) { | ||
170 | case JIT_IH_STRING_LEN: | ||
171 | | isstring arg; jne L_DEOPTIMIZE | ||
172 | | mov TSTRING:ecx, BASE[arg].value | ||
173 | | fild aword TSTRING:ecx->tsv.len // size_t | ||
174 | | settt BASE[res], LUA_TNUMBER | ||
175 | | fstp qword BASE[res].value | ||
176 | break; | ||
177 | case JIT_IH_STRING_SUB: | ||
178 | /* TODO: inline numeric constants with help from the optimizer. */ | ||
179 | /* But this would save only another 15-20% in a trivial loop. */ | ||
180 | jit_assert(ii->nargs >= 2); /* Open op caveat is ok, too. */ | ||
181 | if (ii->nargs > 2) { | ||
182 | | lea TOP, BASE[arg] | ||
183 | | call ->STRING_SUB3 | ||
184 | | setsvalue BASE[res], eax | ||
185 | } else { | ||
186 | | lea TOP, BASE[arg] | ||
187 | | call ->STRING_SUB2 | ||
188 | | setsvalue BASE[res], eax | ||
189 | } | ||
190 | break; | ||
191 | case JIT_IH_STRING_CHAR: | ||
192 | | isnumber arg; jne L_DEOPTIMIZE | ||
193 | | lea eax, L->env // Abuse L->env to hold temp string. | ||
194 | | fld qword BASE[arg].value | ||
195 | | fistp dword [eax] // LSB is at start (little-endian). | ||
196 | | cmp dword [eax], 255; ja L_DEOPTIMIZE | ||
197 | | call &luaS_newlstr, L, eax, 1 | ||
198 | | setsvalue BASE[res], eax | ||
199 | break; | ||
200 | default: | ||
201 | jit_assert(0); | ||
202 | break; | ||
203 | } | ||
204 | |||
205 | |//----------------------------------------------------------------------- | ||
206 | |.jsub STRING_SUB3 // string.sub(str, start, end) | ||
207 | | mov eax, TOP[0].tt; shl eax, 4; or eax, TOP[1].tt; shl eax, 4 | ||
208 | | or eax, TOP[2].tt; sub eax, LUA_TSTR_NUM_NUM | ||
209 | | jne ->DEOPTIMIZE_CALLER // Wrong types? Deoptimize. | ||
210 | | // eax must be zero here! | ||
211 | | fld qword TOP[1].value | ||
212 | | fld qword TOP[2].value | ||
213 | | fistp aword TMP3 // size_t | ||
214 | | fistp aword TMP2 // size_t | ||
215 | | mov TSTRING:ecx, TOP[0].value | ||
216 | | mov TOP, aword TSTRING:ecx->tsv.len // size_t | ||
217 | | mov edx, TMP3 | ||
218 | | cmp TOP, edx | ||
219 | | jb >4 | ||
220 | |1: | ||
221 | | or eax, TMP2 // eax is known to be zero. | ||
222 | | jle >6 // start <= 0? | ||
223 | |2: | ||
224 | | sub edx, eax // newlen = end-start | ||
225 | | jl >7 // start > end? | ||
226 | | lea ecx, [TSTRING:ecx+eax+#TSTRING-1] // svalue()-1+start | ||
227 | | inc edx | ||
228 | |3: | ||
229 | | mov ARG2, L // First arg for tailcall is ARG2. | ||
230 | | mov ARG3, ecx // Pointer to start. | ||
231 | | mov ARG4, edx // Length. | ||
232 | | mov GL:edi, L->l_G | ||
233 | | mov eax, GL:edi->totalbytes // size_t | ||
234 | | cmp eax, GL:edi->GCthreshold // size_t | ||
235 | | jae >8 // G->totalbytes >= G->GCthreshold? | ||
236 | | jmp &luaS_newlstr // Tailcall to C function. | ||
237 | | | ||
238 | |4: // Negative end or overflow. | ||
239 | | jl >5 | ||
240 | | lea edx, [edx+TOP+1] // end = end+(len+1) | ||
241 | | jmp <1 | ||
242 | |5: // Overflow | ||
243 | | mov edx, TOP // end = len | ||
244 | | jmp <1 | ||
245 | | | ||
246 | |6: // Negative start or underflow. | ||
247 | | je >5 | ||
248 | | add eax, TOP // start = start+(len+1) | ||
249 | | inc eax | ||
250 | | jg <2 // start > 0? | ||
251 | |5: // Underflow. | ||
252 | | mov eax, 1 // start = 1 | ||
253 | | jmp <2 | ||
254 | | | ||
255 | |7: // Range underflow. | ||
256 | | xor edx, edx // Zero length. | ||
257 | | jmp <3 // Any pointer in ecx is ok. | ||
258 | |.endjsub | ||
259 | | | ||
260 | |//----------------------------------------------------------------------- | ||
261 | |.jsub STRING_SUB2 // string.sub(str, start) | ||
262 | | mov eax, TOP[0].tt; shl eax, 4; or eax, TOP[1].tt; sub eax, LUA_TSTR_NUM | ||
263 | | jne ->DEOPTIMIZE_CALLER // Wrong types? Deoptimize. | ||
264 | | // eax must be zero here! | ||
265 | | fld qword TOP[1].value | ||
266 | | fistp aword TMP2 // size_t | ||
267 | | mov TSTRING:ecx, TOP[0].value | ||
268 | | mov TOP, aword TSTRING:ecx->tsv.len // size_t | ||
269 | | mov edx, TOP | ||
270 | | jmp <1 // See STRING_SUB3. | ||
271 | | | ||
272 | |8: // GC threshold reached. | ||
273 | | sub esp, FRAME_OFFSET | ||
274 | | call &luaC_step, L | ||
275 | | add esp, FRAME_OFFSET | ||
276 | | mov BASE, L->base | ||
277 | | jmp &luaS_newlstr // Tailcall to C function. | ||
278 | |.endjsub | ||
279 | } | ||
280 | |||
281 | /* ------------------------------------------------------------------------ */ | ||
282 | |||
283 | /* Helper functions for inlined calls to table.*. */ | ||
284 | static void jit_table_insert(lua_State *L, TValue *arg) | ||
285 | { | ||
286 | setobj2t(L, luaH_setnum(L, hvalue(arg), luaH_getn(hvalue(arg))+1), arg+1); | ||
287 | luaC_barriert(L, hvalue(arg), arg+1); | ||
288 | } | ||
289 | |||
290 | static TValue *jit_table_remove(lua_State *L, TValue *arg, TValue *res) | ||
291 | { | ||
292 | int n = luaH_getn(hvalue(arg)); | ||
293 | if (n == 0) { | ||
294 | setnilvalue(res); /* For the nresults == 1 case. Harmless otherwise. */ | ||
295 | return res; /* For the nresults == -1 case. */ | ||
296 | } else { | ||
297 | TValue *val = luaH_setnum(L, hvalue(arg), n); | ||
298 | setobj2s(L, res, val); | ||
299 | setnilvalue(val); | ||
300 | return res+1; /* For the nresults == -1 case. */ | ||
301 | } | ||
302 | } | ||
303 | |||
304 | static void jit_inline_table(jit_State *J, jit_InlineInfo *ii) | ||
305 | { | ||
306 | int arg = ii->func+1; | ||
307 | int res = ii->res; | ||
308 | | istable arg; jne L_DEOPTIMIZE | ||
309 | switch (JIT_IH_IDX(ii->hidx)) { | ||
310 | case JIT_IH_TABLE_INSERT: | ||
311 | | lea TVALUE:eax, BASE[arg] | ||
312 | | call &jit_table_insert, L, TVALUE:eax | ||
313 | break; | ||
314 | case JIT_IH_TABLE_REMOVE: | ||
315 | | lea TVALUE:eax, BASE[arg] | ||
316 | | lea TVALUE:ecx, BASE[res] | ||
317 | | call &jit_table_remove, L, TVALUE:eax, TVALUE:ecx | ||
318 | if (ii->nresults == -1) { | ||
319 | ii->xnresults = -1; | ||
320 | | mov TOP, TVALUE:eax | ||
321 | } | ||
322 | break; | ||
323 | case JIT_IH_TABLE_GETN: | ||
324 | | mov TABLE:eax, BASE[arg].value | ||
325 | | call &luaH_getn, TABLE:eax | ||
326 | | mov TMP1, eax | ||
327 | | fild dword TMP1 | ||
328 | | fstp qword BASE[res].value | ||
329 | | settt BASE[res], LUA_TNUMBER | ||
330 | break; | ||
331 | default: | ||
332 | jit_assert(0); | ||
333 | break; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | /* ------------------------------------------------------------------------ */ | ||
338 | |||
339 | /* This typedef must match the libm function signature. */ | ||
340 | /* Serves as a check against wrong lua_Number or wrong calling conventions. */ | ||
341 | typedef lua_Number (*mathfunc_11)(lua_Number); | ||
342 | |||
343 | /* Partially inlined math functions. */ | ||
344 | /* CHECK: must match with jit_hints.h and jit.opt_lib. */ | ||
345 | static const mathfunc_11 jit_mathfuncs_11[JIT_IH_MATH_SIN] = { | ||
346 | log, log10, exp, sinh, cosh, tanh, asin, acos, atan | ||
347 | }; | ||
348 | |||
349 | /* FPU control words for ceil and floor (exceptions masked, full precision). */ | ||
350 | static const unsigned short jit_fpucw[2] = { 0x0b7f, 0x077f }; | ||
351 | |||
352 | static void jit_inline_math(jit_State *J, jit_InlineInfo *ii) | ||
353 | { | ||
354 | int arg = ii->func+1; | ||
355 | int res = ii->res; | ||
356 | int idx = JIT_IH_IDX(ii->hidx); | ||
357 | |||
358 | if (idx < JIT_IH_MATH__21) { | ||
359 | | isnumber arg; jne L_DEOPTIMIZE | ||
360 | | fld qword BASE[arg].value | ||
361 | } else { | ||
362 | jit_assert(idx < JIT_IH_MATH__LAST); | ||
363 | | isnumber2 arg, arg+1; jne L_DEOPTIMIZE | ||
364 | } | ||
365 | switch (idx) { | ||
366 | /* We ignore sin/cos/tan range overflows (2^63 rad) just like -ffast-math. */ | ||
367 | case JIT_IH_MATH_SIN: | ||
368 | | fsin | ||
369 | break; | ||
370 | case JIT_IH_MATH_COS: | ||
371 | | fcos | ||
372 | break; | ||
373 | case JIT_IH_MATH_TAN: | ||
374 | | fptan; fpop | ||
375 | break; | ||
376 | case JIT_IH_MATH_CEIL: | ||
377 | case JIT_IH_MATH_FLOOR: | ||
378 | | fnstcw word TMP1 | ||
379 | | fldcw word [(ptrdiff_t)&jit_fpucw[idx-JIT_IH_MATH_CEIL]] | ||
380 | | frndint | ||
381 | | fldcw word TMP1 | ||
382 | break; | ||
383 | case JIT_IH_MATH_ABS: | ||
384 | | fabs | ||
385 | break; | ||
386 | case JIT_IH_MATH_SQRT: | ||
387 | | fsqrt | ||
388 | break; | ||
389 | case JIT_IH_MATH_FMOD: | ||
390 | | fld qword BASE[arg+1].value | ||
391 | | fld qword BASE[arg].value | ||
392 | |1: ; fprem; fnstsw ax; sahf; jp <1 | ||
393 | | fstp st1 | ||
394 | break; | ||
395 | case JIT_IH_MATH_ATAN2: | ||
396 | |// Inlining is easier than calling atan2(). | ||
397 | | fld qword BASE[arg].value | ||
398 | | fld qword BASE[arg+1].value | ||
399 | | fpatan | ||
400 | break; | ||
401 | default: | ||
402 | |// Partially inlined. Just call the libm function (__cdecl!). | ||
403 | | fstp FPARG1 | ||
404 | | call &jit_mathfuncs_11[idx] | ||
405 | break; | ||
406 | } | ||
407 | | settt BASE[res], LUA_TNUMBER | ||
408 | | fstp qword BASE[res].value | ||
409 | } | ||
410 | |||
411 | /* ------------------------------------------------------------------------ */ | ||
412 | |||
413 | /* Try to inline a CALL or TAILCALL instruction. */ | ||
414 | static int jit_inline_call(jit_State *J, int func, int nargs, int nresults) | ||
415 | { | ||
416 | const TValue *callable = hint_get(J, TYPE); /* TYPE hint = callable. */ | ||
417 | int cltype = ttype(callable); | ||
418 | const TValue *oidx; | ||
419 | jit_InlineInfo ii; | ||
420 | int idx; | ||
421 | |||
422 | if (cltype != LUA_TFUNCTION) goto fail; | ||
423 | if (J->flags & JIT_F_DEBUG) goto fail; /* DWIM. */ | ||
424 | |||
425 | oidx = hint_get(J, INLINE); /* INLINE hint = library/function index. */ | ||
426 | if (!ttisnumber(oidx)) goto fail; | ||
427 | |||
428 | ii.hidx = (int)nvalue(oidx); | ||
429 | idx = JIT_IH_IDX(ii.hidx); | ||
430 | |||
431 | if (nresults == -2) { /* Tailcall. */ | ||
432 | /* Tailcalls from vararg functions don't work with BASE[-1]. */ | ||
433 | if (J->pt->is_vararg) goto fail; /* So forget about this rare case. */ | ||
434 | ii.res = -1; /* Careful: 2nd result overlaps 1st stack slot. */ | ||
435 | ii.nresults = -1; | ||
436 | } else { | ||
437 | ii.res = func; | ||
438 | ii.nresults = nresults; | ||
439 | } | ||
440 | ii.func = func; | ||
441 | ii.nargs = nargs; | ||
442 | ii.xnargs = ii.xnresults = 1; /* Default: 1 arg, 1 result. */ | ||
443 | |||
444 | /* Check for the currently supported cases. */ | ||
445 | switch (JIT_IH_LIB(ii.hidx)) { | ||
446 | case JIT_IHLIB_BASE: | ||
447 | switch (idx) { | ||
448 | case JIT_IH_BASE_PAIRS: | ||
449 | case JIT_IH_BASE_IPAIRS: | ||
450 | if (nresults == -2) goto fail; /* Not useful for tailcalls. */ | ||
451 | ii.xnresults = 3; | ||
452 | goto check; | ||
453 | } | ||
454 | break; | ||
455 | #ifndef COCO_DISABLE | ||
456 | case JIT_IHLIB_COROUTINE: | ||
457 | switch (idx) { | ||
458 | case JIT_IH_COROUTINE_YIELD: | ||
459 | /* Only support common cases: no tailcalls, low number of results. */ | ||
460 | if (nresults < 0 || nresults > EXTRA_STACK) goto fail; | ||
461 | ii.xnargs = ii.xnresults = -1; | ||
462 | goto ok; /* Anything else is ok. */ | ||
463 | case JIT_IH_COROUTINE_RESUME: | ||
464 | /* Only support common cases: no tailcalls, not with 0 args (error). */ | ||
465 | if (nresults == -2 || nargs == 0) goto fail; | ||
466 | ii.xnargs = ii.xnresults = -1; | ||
467 | goto ok; /* Anything else is ok. */ | ||
468 | } | ||
469 | break; | ||
470 | #endif | ||
471 | case JIT_IHLIB_STRING: | ||
472 | switch (idx) { | ||
473 | case JIT_IH_STRING_LEN: | ||
474 | goto check; | ||
475 | case JIT_IH_STRING_SUB: | ||
476 | if (nargs < 2) goto fail; /* No support for open calls, too. */ | ||
477 | goto ok; /* 2 or more args are ok. */ | ||
478 | case JIT_IH_STRING_CHAR: | ||
479 | goto check; /* Only single arg supported. */ | ||
480 | } | ||
481 | break; | ||
482 | case JIT_IHLIB_TABLE: | ||
483 | switch (idx) { | ||
484 | case JIT_IH_TABLE_INSERT: | ||
485 | ii.xnargs = 2; | ||
486 | goto check; /* Only push (append) supported. */ | ||
487 | case JIT_IH_TABLE_REMOVE: | ||
488 | goto check; /* Only pop supported. */ | ||
489 | case JIT_IH_TABLE_GETN: | ||
490 | goto check; | ||
491 | } | ||
492 | break; | ||
493 | case JIT_IHLIB_MATH: | ||
494 | if (idx >= JIT_IH_MATH__LAST) goto fail; | ||
495 | if (idx >= JIT_IH_MATH__21) ii.xnargs = 2; | ||
496 | goto check; | ||
497 | } | ||
498 | fail: | ||
499 | return cltype; /* Call could not be inlined. Return type of callable. */ | ||
500 | |||
501 | check: | ||
502 | if (nargs != ii.xnargs && nargs != -1) goto fail; | ||
503 | /* The optimizer already checks the number of results (avoid setnil). */ | ||
504 | |||
505 | ok: /* Whew, all checks done. Go for it! */ | ||
506 | |||
507 | /* Start with the common leadin for inlined calls. */ | ||
508 | jit_deopt_target(J, nargs); | ||
509 | |// Caveat: Must save TOP for open ops if jsub uses DEOPTIMIZE_CALLER. | ||
510 | | isfunction func | ||
511 | | jne L_DEOPTIMIZE // Not a function? Deoptimize. | ||
512 | | cmp aword BASE[func].value, &clvalue(callable) | ||
513 | | jne L_DEOPTIMIZE // Wrong closure? Deoptimize. | ||
514 | if (nargs == -1 && ii.xnargs >= 0) { | ||
515 | | lea eax, BASE[func+1+ii.xnargs] | ||
516 | | cmp TOP, eax | ||
517 | | jne L_DEOPTIMIZE // Wrong #args? Deoptimize. | ||
518 | } | ||
519 | |||
520 | /* Now inline the function itself. */ | ||
521 | switch (JIT_IH_LIB(ii.hidx)) { | ||
522 | case JIT_IHLIB_BASE: jit_inline_base(J, &ii); break; | ||
523 | #ifndef COCO_DISABLE | ||
524 | case JIT_IHLIB_COROUTINE: jit_inline_coroutine(J, &ii); break; | ||
525 | #endif | ||
526 | case JIT_IHLIB_STRING: jit_inline_string(J, &ii); break; | ||
527 | case JIT_IHLIB_TABLE: jit_inline_table(J, &ii); break; | ||
528 | case JIT_IHLIB_MATH: jit_inline_math(J, &ii); break; | ||
529 | default: jit_assert(0); break; | ||
530 | } | ||
531 | |||
532 | /* And add the common leadout for inlined calls. */ | ||
533 | if (ii.nresults == -1) { | ||
534 | if (ii.xnresults >= 0) { | ||
535 | | lea TOP, BASE[ii.res+ii.xnresults] | ||
536 | } | ||
537 | } else if (ii.nargs == -1) { /* Restore L->top only if needed. */ | ||
538 | | lea TOP, BASE[J->pt->maxstacksize] | ||
539 | | mov L->top, TOP | ||
540 | } | ||
541 | |||
542 | if (nresults == -2) { /* Results are in place. Add return for tailcalls. */ | ||
543 | | add esp, FRAME_OFFSET | ||
544 | | sub BASE, #BASE | ||
545 | | sub aword L->ci, #CI | ||
546 | | ret | ||
547 | } | ||
548 | |||
549 | return -1; /* Success, call has been inlined. */ | ||
550 | } | ||
551 | |||
552 | /* ------------------------------------------------------------------------ */ | ||
553 | |||
554 | /* Helper function for inlined iterator code. Paraphrased from luaH_next. */ | ||
555 | /* TODO: GCC has trouble optimizing this. */ | ||
556 | static int jit_table_next(lua_State *L, TValue *ra) | ||
557 | { | ||
558 | Table *t = hvalue(&ra[TFOR_TAB]); | ||
559 | int i = ra[TFOR_CTL].value.b; /* Hidden control variable. */ | ||
560 | for (; i < t->sizearray; i++) { /* First the array part. */ | ||
561 | if (!ttisnil(&t->array[i])) { | ||
562 | setnvalue(&ra[TFOR_KEY], cast_num(i+1)); | ||
563 | setobj2s(L, &ra[TFOR_VAL], &t->array[i]); | ||
564 | ra[TFOR_CTL].value.b = i+1; | ||
565 | return 1; | ||
566 | } | ||
567 | } | ||
568 | for (i -= t->sizearray; i < sizenode(t); i++) { /* Then the hash part. */ | ||
569 | if (!ttisnil(gval(gnode(t, i)))) { | ||
570 | setobj2s(L, &ra[TFOR_KEY], key2tval(gnode(t, i))); | ||
571 | setobj2s(L, &ra[TFOR_VAL], gval(gnode(t, i))); | ||
572 | ra[TFOR_CTL].value.b = i+1+t->sizearray; | ||
573 | return 1; | ||
574 | } | ||
575 | } | ||
576 | return 0; /* End of iteration. */ | ||
577 | } | ||
578 | |||
579 | /* Try to inline a TFORLOOP instruction. */ | ||
580 | static int jit_inline_tforloop(jit_State *J, int ra, int nresults, int target) | ||
581 | { | ||
582 | const TValue *oidx = hint_get(J, INLINE); /* INLINE hint = lib/func idx. */ | ||
583 | int idx; | ||
584 | |||
585 | if (!ttisnumber(oidx)) return 0; /* No hint: don't inline anything. */ | ||
586 | idx = (int)nvalue(oidx); | ||
587 | if (J->flags & JIT_F_DEBUG) return 0; /* DWIM. */ | ||
588 | |||
589 | switch (idx) { | ||
590 | case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_PAIRS): | ||
591 | |// The type checks can be omitted -- see the iterator constructor. | ||
592 | | lea TOP, BASE[ra] | ||
593 | | call &jit_table_next, L, TOP | ||
594 | | test eax, eax | ||
595 | | jnz =>target | ||
596 | return 1; /* Success, iterator has been inlined. */ | ||
597 | case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_IPAIRS): | ||
598 | |// The type checks can be omitted -- see the iterator constructor. | ||
599 | | mov eax, BASE[ra+TFOR_CTL].value // Hidden control variable. | ||
600 | | inc eax | ||
601 | | mov TABLE:edx, BASE[ra+TFOR_TAB].value // Table object. | ||
602 | | mov BASE[ra+TFOR_CTL].value, eax | ||
603 | | call &luaH_getnum, TABLE:edx, eax | ||
604 | | // This is really copyslot BASE[ra+TFOR_VAL], TVALUE:eax[0] plus compare. | ||
605 | | mov ecx, TVALUE:eax->tt | ||
606 | | test ecx, ecx // Assumes: LUA_TNIL == 0. | ||
607 | | jz >9 // nil value stops iteration. | ||
608 | | fild dword BASE[ra+TFOR_CTL].value // Set numeric key. | ||
609 | | settt BASE[ra+TFOR_KEY], LUA_TNUMBER | ||
610 | | fstp qword BASE[ra+TFOR_KEY].value | ||
611 | | mov edx, TVALUE:eax->value | ||
612 | | mov eax, TVALUE:eax->value.na[1] // Overwrites eax. | ||
613 | | mov BASE[ra+TFOR_VAL].tt, ecx // Copy value from table slot. | ||
614 | | mov BASE[ra+TFOR_VAL].value, edx | ||
615 | | mov BASE[ra+TFOR_VAL].value.na[1], eax | ||
616 | | jmp =>target | ||
617 | |9: | ||
618 | return 1; /* Success, iterator has been inlined. */ | ||
619 | } | ||
620 | |||
621 | return 0; /* No support for inlining any other iterators. */ | ||
622 | } | ||
623 | |||
624 | /* ------------------------------------------------------------------------ */ | ||
625 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ljitlib.c b/libraries/LuaJIT-1.1.7/src/ljitlib.c new file mode 100644 index 0000000..4efc04d --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljitlib.c | |||
@@ -0,0 +1,637 @@ | |||
1 | /* | ||
2 | ** Lua library for the JIT engine. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #include <stdio.h> | ||
7 | #include <string.h> | ||
8 | |||
9 | #define ljitlib_c | ||
10 | #define LUA_LIB | ||
11 | |||
12 | #include "lua.h" | ||
13 | #include "lauxlib.h" | ||
14 | #include "luajit.h" | ||
15 | #include "lualib.h" | ||
16 | |||
17 | /* This file is not a pure C API user. Some internals are required. */ | ||
18 | #include "lobject.h" | ||
19 | #include "lstate.h" | ||
20 | #include "lstring.h" | ||
21 | #include "ltable.h" | ||
22 | #include "lfunc.h" | ||
23 | #include "lgc.h" | ||
24 | #include "lopcodes.h" | ||
25 | |||
26 | #include "ljit.h" | ||
27 | #include "ljit_hints.h" | ||
28 | |||
29 | #define STRING_HINTS | ||
30 | #include "ljit_hints.h" | ||
31 | |||
32 | /* ------------------------------------------------------------------------ */ | ||
33 | |||
34 | /* Static pointer addresses used as registry keys. */ | ||
35 | /* The values do not matter, but must be different to prevent joining. */ | ||
36 | static const int regkey_frontend = 0x6c6a6c01; | ||
37 | static const int regkey_comthread = 0x6c6a6c02; | ||
38 | |||
39 | /* Check that the first argument is a Lua function and return its closure. */ | ||
40 | static Closure *check_LCL(lua_State *L) | ||
41 | { | ||
42 | StkId o = L->base; | ||
43 | switch (lua_type(L, 1)) { | ||
44 | case LUA_TBOOLEAN: | ||
45 | o = (L->ci-1)->func; | ||
46 | case LUA_TFUNCTION: | ||
47 | if (isLfunction(o)) | ||
48 | return clvalue(o); | ||
49 | break; | ||
50 | } | ||
51 | luaL_argerror(L, 1, "Lua function expected"); | ||
52 | return NULL; | ||
53 | } | ||
54 | |||
55 | /* Create a new closure from a prototype. */ | ||
56 | /* Note: upvalues are assumed to be after first two slots. */ | ||
57 | static void push_LCL(lua_State *L, Proto *pt, Table *env) | ||
58 | { | ||
59 | Closure *cl; | ||
60 | int i, nup = pt->nups; | ||
61 | /* Adjust the number of stack slots to the number of upvalues. */ | ||
62 | luaL_checkstack(L, nup, "too many upvalues"); | ||
63 | lua_settop(L, 2+nup); | ||
64 | /* Create a closure from the subroutine prototype. */ | ||
65 | cl = luaF_newLclosure(L, nup, env); | ||
66 | cl->l.p = pt; | ||
67 | /* Allocate new upvalues and close them. */ | ||
68 | for (i = 0; i < nup; i++) | ||
69 | cl->l.upvals[i] = luaF_findupval(L, L->base + (2+i)); | ||
70 | luaF_close(L, L->base + 2); | ||
71 | lua_settop(L, 2); /* Remove upvalues. */ | ||
72 | setclvalue(L, L->top++, cl); /* Return closure on top of stack. */ | ||
73 | luaC_checkGC(L); | ||
74 | } | ||
75 | |||
76 | /* ------------------------------------------------------------------------ */ | ||
77 | |||
78 | /* Set JIT mode for the engine or a closure and/or its subroutines. */ | ||
79 | static int setmode(lua_State *L, int mode) | ||
80 | { | ||
81 | int idx = 0; | ||
82 | switch (lua_type(L, 1)) { | ||
83 | case LUA_TNONE: /* jit.on/off() */ | ||
84 | case LUA_TNIL: /* jit.on/off(nil) */ | ||
85 | luaJIT_setmode(L, 0, mode | LUAJIT_MODE_ENGINE); | ||
86 | break; | ||
87 | case LUA_TFUNCTION: /* jit.on/off(func, nil|true|false) */ | ||
88 | idx = 1; | ||
89 | case LUA_TBOOLEAN: /* jit.on/off(true, nil|true|false) (parent frame) */ | ||
90 | if (lua_isboolean(L, 2)) | ||
91 | mode |= lua_toboolean(L, 2)?LUAJIT_MODE_ALLFUNC:LUAJIT_MODE_ALLSUBFUNC; | ||
92 | else | ||
93 | mode |= LUAJIT_MODE_FUNC; | ||
94 | if (luaJIT_setmode(L, idx, mode) == 1) /* Ok? */ | ||
95 | break; | ||
96 | default: | ||
97 | luaL_argerror(L, 1, "Lua function expected"); | ||
98 | break; | ||
99 | } | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | /* Set JIT mode to on: (re-)enable compilation. */ | ||
104 | static int j_on(lua_State *L) | ||
105 | { | ||
106 | return setmode(L, LUAJIT_MODE_ON); | ||
107 | } | ||
108 | |||
109 | /* Set JIT mode to off: disable compilation. */ | ||
110 | static int j_off(lua_State *L) | ||
111 | { | ||
112 | return setmode(L, LUAJIT_MODE_OFF); | ||
113 | } | ||
114 | |||
115 | /* Set JIT debug level. Defaults to maximum level for use with -j. */ | ||
116 | static int j_debug(lua_State *L) | ||
117 | { | ||
118 | luaJIT_setmode(L, luaL_optinteger(L, 1, 100), LUAJIT_MODE_DEBUG); | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | /* ------------------------------------------------------------------------ */ | ||
123 | |||
124 | /* Report the compilation status. */ | ||
125 | static int compstatus(lua_State *L, int status) | ||
126 | { | ||
127 | if (status == -1) | ||
128 | return luaL_argerror(L, 1, "Lua function expected"); | ||
129 | else if (status == JIT_S_OK) | ||
130 | return 0; | ||
131 | else { | ||
132 | lua_pushinteger(L, status); | ||
133 | return 1; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | /* Compile a function. Pass typical args to help the optimizer. */ | ||
138 | static int j_compile(lua_State *L) | ||
139 | { | ||
140 | int nargs = lua_gettop(L) - 1; | ||
141 | return compstatus(L, nargs >= 0 ? luaJIT_compile(L, nargs) : -1); | ||
142 | } | ||
143 | |||
144 | /* Recursively compile all subroutine prototypes. */ | ||
145 | static int rec_compile(lua_State *L, Proto *pt, Table *env, int stoponerror) | ||
146 | { | ||
147 | int rstatus = JIT_S_OK; | ||
148 | int i; | ||
149 | for (i = 0; i < pt->sizep; i++) { | ||
150 | Proto *pti = pt->p[i]; | ||
151 | int status; | ||
152 | push_LCL(L, pti, env); /* Assumes stack is at 2 (no upvalues). */ | ||
153 | status = luaJIT_compile(L, 0); | ||
154 | lua_settop(L, 2); /* Clear stack */ | ||
155 | if (status != JIT_S_OK) { | ||
156 | rstatus = status; | ||
157 | if (stoponerror) break; | ||
158 | } | ||
159 | status = rec_compile(L, pti, env, stoponerror); | ||
160 | if (status != JIT_S_OK) { | ||
161 | rstatus = status; | ||
162 | if (stoponerror) break; | ||
163 | } | ||
164 | } | ||
165 | return rstatus; | ||
166 | } | ||
167 | |||
168 | /* Compile all subroutines of a function. */ | ||
169 | /* Note: the function itself is _not_ compiled (use jit.compile()). */ | ||
170 | static int j_compilesub(lua_State *L) | ||
171 | { | ||
172 | Closure *cl = check_LCL(L); | ||
173 | int stoponerror = lua_toboolean(L, 2); /* Stop on first error? */ | ||
174 | lua_settop(L, 2); | ||
175 | return compstatus(L, rec_compile(L, cl->l.p, cl->l.env, stoponerror)); | ||
176 | } | ||
177 | |||
178 | /* jit.* functions. */ | ||
179 | static const luaL_Reg jitlib[] = { | ||
180 | { "on", j_on }, | ||
181 | { "off", j_off }, | ||
182 | { "debug", j_debug }, | ||
183 | { "compile", j_compile }, | ||
184 | { "compilesub", j_compilesub }, | ||
185 | /* j_attach is added below. */ | ||
186 | { NULL, NULL } | ||
187 | }; | ||
188 | |||
189 | /* ------------------------------------------------------------------------ */ | ||
190 | |||
191 | /* Get the compiler pipeline table from an upvalue (j_attach, j_frontend). */ | ||
192 | #define COMPIPE lua_upvalueindex(1) | ||
193 | |||
194 | /* Attach/detach handler to/from compiler pipeline. */ | ||
195 | static int j_attach(lua_State *L) | ||
196 | { | ||
197 | int pipesz; | ||
198 | luaL_checktype(L, 1, LUA_TFUNCTION); | ||
199 | pipesz = lua_objlen(L, COMPIPE); | ||
200 | if (lua_isnoneornil(L, 2)) { /* Detach if no priority given. */ | ||
201 | int i; | ||
202 | for (i = 1; i <= pipesz; i += 2) { | ||
203 | lua_rawgeti(L, COMPIPE, i); | ||
204 | if (lua_rawequal(L, 1, -1)) { /* Found: delete from pipeline. */ | ||
205 | for (; i+2 <= pipesz; i++) { /* Shift down. */ | ||
206 | lua_rawgeti(L, COMPIPE, i+2); | ||
207 | lua_rawseti(L, COMPIPE, i); | ||
208 | } | ||
209 | /* Clear last two elements. */ | ||
210 | lua_pushnil(L); lua_rawseti(L, COMPIPE, i); | ||
211 | lua_pushnil(L); lua_rawseti(L, COMPIPE, i+1); | ||
212 | return 0; | ||
213 | } | ||
214 | lua_pop(L, 1); | ||
215 | } | ||
216 | return 0; /* Not found: ignore detach request. */ | ||
217 | } else { /* Attach if priority given. */ | ||
218 | int prio = luaL_checkint(L, 2); | ||
219 | int pos, i; | ||
220 | for (pos = 2; pos <= pipesz; pos += 2) { | ||
221 | lua_rawgeti(L, COMPIPE, pos); | ||
222 | if (prio > (int)lua_tointeger(L, -1)) break; /* Insertion point found. */ | ||
223 | lua_pop(L, 1); | ||
224 | } | ||
225 | for (i = pipesz+2; i > pos; i--) { /* Shift up. */ | ||
226 | lua_rawgeti(L, COMPIPE, i-2); | ||
227 | lua_rawseti(L, COMPIPE, i); | ||
228 | } | ||
229 | /* Set handler and priority. */ | ||
230 | lua_pushvalue(L, 1); lua_rawseti(L, COMPIPE, i-1); | ||
231 | lua_pushvalue(L, 2); lua_rawseti(L, COMPIPE, i); | ||
232 | return 0; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | /* Compiler frontend. Runs in the compiler thread. */ | ||
237 | /* First and only arg is the compiler state table. */ | ||
238 | static int j_frontend(lua_State *L) | ||
239 | { | ||
240 | int status = JIT_S_OK; | ||
241 | int pos; | ||
242 | /* Loop through all handlers in the compiler pipeline. */ | ||
243 | for (pos = 1; ; pos += 2) { | ||
244 | if (status != JIT_S_OK) { /* Pending failure? */ | ||
245 | int prio; | ||
246 | lua_rawgeti(L, COMPIPE, pos+1); /* Must check for odd/even priority. */ | ||
247 | if (lua_isnil(L, -1)) break; /* End of pipeline. */ | ||
248 | prio = (int)lua_tointeger(L, -1); | ||
249 | lua_pop(L, 1); | ||
250 | if ((prio & 1) == 0) continue; /* Skip handlers with even priority. */ | ||
251 | } | ||
252 | /* Call handler with compiler state table and optional failure status. */ | ||
253 | lua_rawgeti(L, COMPIPE, pos); | ||
254 | if (lua_isnil(L, -1)) break; /* End of pipeline. */ | ||
255 | lua_pushvalue(L, 1); | ||
256 | if (status != JIT_S_OK) | ||
257 | lua_pushinteger(L, status); | ||
258 | lua_call(L, status ? 2 : 1, 1); | ||
259 | if (!lua_isnil(L, -1)) /* Remember failure status. */ | ||
260 | status = (int)lua_tointeger(L, -1); | ||
261 | lua_pop(L, 1); | ||
262 | } | ||
263 | lua_pushinteger(L, status); | ||
264 | return 1; | ||
265 | } | ||
266 | |||
267 | /* Compiler frontend wrapper. */ | ||
268 | static int frontwrap(lua_State *L, Table *st) | ||
269 | { | ||
270 | jit_State *J = G(L)->jit_state; | ||
271 | lua_State *JL; | ||
272 | int status; | ||
273 | |||
274 | /* Allocate compiler thread on demand. */ | ||
275 | if (J->L == NULL) { | ||
276 | if (!lua_checkstack(L, 3)) return JIT_S_COMPILER_ERROR; | ||
277 | sethvalue(L, L->top++, st); /* Prevent GC of state table. */ | ||
278 | lua_pushlightuserdata(L, (void *)®key_comthread); | ||
279 | /* Cannot use C stack, since it's deallocated early in Coco. */ | ||
280 | /* But we don't need one -- the compiler thread never yields, anyway. */ | ||
281 | J->L = lua_newthread(L); | ||
282 | lua_rawset(L, LUA_REGISTRYINDEX); | ||
283 | L->top--; /* Remove state table from this stack. */ | ||
284 | } | ||
285 | JL = J->L; | ||
286 | |||
287 | /* Initialize compiler thread stack with frontend and state table. */ | ||
288 | lua_settop(JL, 0); | ||
289 | lua_pushlightuserdata(JL, (void *)®key_frontend); | ||
290 | lua_rawget(JL, LUA_REGISTRYINDEX); | ||
291 | sethvalue(JL, JL->top, st); | ||
292 | JL->top++; | ||
293 | |||
294 | /* Start the frontend by resuming the compiler thread. */ | ||
295 | if (lua_resume(JL, 1) != 0) { /* Failed? */ | ||
296 | /* Note: LUA_YIELD is treated like any other error. */ | ||
297 | J->L = NULL; /* Get a new thread next time. */ | ||
298 | fprintf(stderr, "[LuaJIT frontend failed: %s]\n", | ||
299 | lua_isstring(JL, -1) ? lua_tostring(JL, -1) : "(unknown error)"); | ||
300 | return JIT_S_COMPILER_ERROR; | ||
301 | } | ||
302 | |||
303 | /* Get status from terminated thread. */ | ||
304 | status = (int)lua_tointeger(JL, -1); | ||
305 | lua_settop(JL, 0); /* Help the GC. */ | ||
306 | return status; | ||
307 | } | ||
308 | |||
309 | /* Create the compiler pipeline and register it. */ | ||
310 | static void makepipeline(lua_State *L) | ||
311 | { | ||
312 | lua_createtable(L, 20, 0); /* 10 handlers+priorities should be enough. */ | ||
313 | lua_pushcfunction(L, luaJIT_backend); | ||
314 | lua_rawseti(L, -2, 1); | ||
315 | lua_pushinteger(L, 0); /* Fill in the backend at prio 0. */ | ||
316 | lua_rawseti(L, -2, 2); | ||
317 | |||
318 | /* Store the compiler frontend in the registry. */ | ||
319 | lua_pushlightuserdata(L, (void *)®key_frontend); | ||
320 | lua_pushvalue(L, -2); /* Pipeline table as upvalue. */ | ||
321 | lua_pushcclosure(L, j_frontend, 1); | ||
322 | lua_rawset(L, LUA_REGISTRYINDEX); | ||
323 | |||
324 | /* Register the frontend wrapper. */ | ||
325 | G(L)->jit_state->frontwrap = frontwrap; | ||
326 | |||
327 | /* Add jit.attach with the pipeline table as upvalue. */ | ||
328 | lua_pushcclosure(L, j_attach, 1); | ||
329 | lua_setfield(L, -2, "attach"); /* "jit" table must be below. */ | ||
330 | } | ||
331 | |||
332 | /* ------------------------------------------------------------------------ */ | ||
333 | |||
334 | /* Calculate total mcode size without mfm and only for active mcode blocks. */ | ||
335 | static size_t mcodesize(Proto *pt) | ||
336 | { | ||
337 | jit_MCTrailer tr; | ||
338 | size_t sz = 0; | ||
339 | tr.mcode = (char *)pt->jit_mcode; | ||
340 | tr.sz = pt->jit_szmcode; | ||
341 | do { | ||
342 | jit_Mfm *mfm = JIT_MCMFM(tr.mcode, tr.sz); | ||
343 | if (sz != 0 && jit_mfm_ismain(mfm)) break; /* Stop at old main mfm. */ | ||
344 | while (*mfm != JIT_MFM_STOP) mfm--; /* Search for end of mcode. */ | ||
345 | sz += (char *)mfm-(char *)tr.mcode; /* Add size of mcode without mfm. */ | ||
346 | memcpy((void *)&tr, JIT_MCTRAILER(tr.mcode, tr.sz), sizeof(jit_MCTrailer)); | ||
347 | } while (tr.mcode != NULL); | ||
348 | return sz; | ||
349 | } | ||
350 | |||
351 | #define setintfield(name, i) \ | ||
352 | do { lua_pushinteger(L, i); lua_setfield(L, -2, name); } while (0) | ||
353 | |||
354 | /* local stats = jit.util.stats(func) */ | ||
355 | static int ju_stats(lua_State *L) | ||
356 | { | ||
357 | if (!(L->top > L->base)) | ||
358 | luaL_argerror(L, 1, "Lua function expected"); | ||
359 | if (isLfunction(L->base)) { | ||
360 | Proto *pt = clvalue(L->base)->l.p; | ||
361 | lua_createtable(L, 0, 11); | ||
362 | setintfield("status", pt->jit_status); | ||
363 | setintfield("stackslots", pt->maxstacksize); | ||
364 | setintfield("params", pt->numparams); | ||
365 | setintfield("bytecodes", pt->sizecode); | ||
366 | setintfield("consts", pt->sizek); | ||
367 | setintfield("upvalues", pt->nups); | ||
368 | setintfield("subs", pt->sizep); | ||
369 | lua_pushboolean(L, pt->is_vararg); | ||
370 | lua_setfield(L, -2, "isvararg"); | ||
371 | lua_getfenv(L, 1); | ||
372 | lua_setfield(L, -2, "env"); | ||
373 | if (pt->jit_szmcode != 0) { | ||
374 | setintfield("mcodesize", (int)mcodesize(pt)); | ||
375 | lua_pushnumber(L, (lua_Number)(size_t)pt->jit_mcode); | ||
376 | lua_setfield(L, -2, "mcodeaddr"); | ||
377 | } | ||
378 | return 1; | ||
379 | } else { | ||
380 | return 0; /* Don't throw an error like the other util functions. */ | ||
381 | } | ||
382 | } | ||
383 | |||
384 | /* local op, a, b, c, test = jit.util.bytecode(func, pc) */ | ||
385 | static int ju_bytecode(lua_State *L) | ||
386 | { | ||
387 | Proto *pt = check_LCL(L)->l.p; | ||
388 | int pc = luaL_checkint(L, 2); | ||
389 | if (pc >= 1 && pc <= pt->sizecode) { | ||
390 | Instruction ins = pt->code[pc-1]; | ||
391 | OpCode op = GET_OPCODE(ins); | ||
392 | if (pc > 1 && (((int)OP_SETLIST) << POS_OP) == | ||
393 | (pt->code[pc-2] & (MASK1(SIZE_OP,POS_OP) | MASK1(SIZE_C,POS_C)))) { | ||
394 | lua_pushstring(L, luaP_opnames[OP_SETLIST]); | ||
395 | lua_pushnumber(L, (lua_Number)ins); /* Fake extended op. */ | ||
396 | return 1; | ||
397 | } | ||
398 | if (op >= NUM_OPCODES) return 0; /* Just in case. */ | ||
399 | lua_pushstring(L, luaP_opnames[op]); | ||
400 | lua_pushinteger(L, GETARG_A(ins)); | ||
401 | switch (getOpMode(op)) { | ||
402 | case iABC: { | ||
403 | int b = GETARG_B(ins), c = GETARG_C(ins); | ||
404 | switch (getBMode(op)) { | ||
405 | case OpArgN: lua_pushnil(L); break; | ||
406 | case OpArgK: if (ISK(b)) b = -1-INDEXK(b); | ||
407 | case OpArgR: case OpArgU: lua_pushinteger(L, b); break; | ||
408 | } | ||
409 | switch (getCMode(op)) { | ||
410 | case OpArgN: lua_pushnil(L); break; | ||
411 | case OpArgK: if (ISK(c)) c = -1-INDEXK(c); | ||
412 | case OpArgR: case OpArgU: lua_pushinteger(L, c); break; | ||
413 | } | ||
414 | lua_pushboolean(L, testTMode(op)); | ||
415 | return 5; | ||
416 | } | ||
417 | case iABx: { | ||
418 | int bx = GETARG_Bx(ins); | ||
419 | lua_pushinteger(L, getBMode(op) == OpArgK ? -1-bx : bx); | ||
420 | return 3; | ||
421 | } | ||
422 | case iAsBx: | ||
423 | lua_pushinteger(L, GETARG_sBx(ins)); | ||
424 | return 3; | ||
425 | } | ||
426 | } | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | /* local const, ok = jit.util.const(func, idx) */ | ||
431 | static int ju_const(lua_State *L) | ||
432 | { | ||
433 | Proto *pt = check_LCL(L)->l.p; | ||
434 | int idx = luaL_checkint(L, 2); | ||
435 | if (idx < 0) idx = -idx; /* Handle both positive and negative indices. */ | ||
436 | if (idx >= 1 && idx <= pt->sizek) { | ||
437 | setobj2s(L, L->top-1, &pt->k[idx-1]); | ||
438 | lua_pushboolean(L, 1); | ||
439 | return 2; | ||
440 | } | ||
441 | lua_pushnil(L); | ||
442 | lua_pushboolean(L, 0); | ||
443 | return 2; | ||
444 | } | ||
445 | |||
446 | /* local upvalue, ok = jit.util.upvalue(func, idx) */ | ||
447 | static int ju_upvalue(lua_State *L) | ||
448 | { | ||
449 | Closure *cl = check_LCL(L); | ||
450 | Proto *pt = cl->l.p; | ||
451 | int idx = luaL_checkint(L, 2); | ||
452 | if (idx >= 0 && idx < pt->nups) { | ||
453 | setobj2s(L, L->top-1, cl->l.upvals[idx]->v); | ||
454 | lua_pushboolean(L, 1); | ||
455 | return 2; | ||
456 | } | ||
457 | lua_pushnil(L); | ||
458 | lua_pushboolean(L, 0); | ||
459 | return 2; | ||
460 | } | ||
461 | |||
462 | /* local nup = jit.util.closurenup(func, idx) */ | ||
463 | static int ju_closurenup(lua_State *L) | ||
464 | { | ||
465 | Closure *cl = check_LCL(L); | ||
466 | Proto *pt = cl->l.p; | ||
467 | int idx = luaL_checkint(L, 2); | ||
468 | if (idx >= 0 && idx < pt->sizep) { | ||
469 | lua_pushinteger(L, pt->p[idx]->nups); | ||
470 | return 1; | ||
471 | } | ||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | /* for tag, mark in mfmiter do ... end. */ | ||
476 | static int ju_mfmiter(lua_State *L) | ||
477 | { | ||
478 | jit_Mfm *mfm = (jit_Mfm *)lua_touserdata(L, lua_upvalueindex(1)); | ||
479 | int m = *mfm--; | ||
480 | switch (m) { | ||
481 | case JIT_MFM_STOP: return 0; | ||
482 | case JIT_MFM_COMBINE: lua_pushliteral(L, "COMBINE"); lua_pushnil(L); break; | ||
483 | case JIT_MFM_DEAD: lua_pushliteral(L, "DEAD"); lua_pushnil(L); break; | ||
484 | default: | ||
485 | lua_pushinteger(L, m & JIT_MFM_MASK); | ||
486 | lua_pushboolean(L, m & JIT_MFM_MARK); | ||
487 | break; | ||
488 | } | ||
489 | lua_pushlightuserdata(L, (void *)mfm); | ||
490 | lua_replace(L, lua_upvalueindex(1)); | ||
491 | return 2; | ||
492 | } | ||
493 | |||
494 | /* local addr, mcode, mfmiter = jit.util.mcode(func, block) */ | ||
495 | static int ju_mcode(lua_State *L) | ||
496 | { | ||
497 | Proto *pt = check_LCL(L)->l.p; | ||
498 | if (pt->jit_szmcode == 0) { /* Not compiled (yet): return nil, status. */ | ||
499 | lua_pushnil(L); | ||
500 | lua_pushinteger(L, pt->jit_status); | ||
501 | return 2; | ||
502 | } else { | ||
503 | jit_Mfm *mfm; | ||
504 | jit_MCTrailer tr; | ||
505 | int block = luaL_checkint(L, 2); | ||
506 | tr.mcode = (char *)pt->jit_mcode; | ||
507 | tr.sz = pt->jit_szmcode; | ||
508 | while (--block > 0) { | ||
509 | void *trp = JIT_MCTRAILER(tr.mcode, tr.sz); | ||
510 | memcpy((void *)&tr, trp, sizeof(jit_MCTrailer)); | ||
511 | if (tr.sz == 0) return 0; | ||
512 | } | ||
513 | mfm = JIT_MCMFM(tr.mcode, tr.sz); | ||
514 | while (*mfm != JIT_MFM_STOP) mfm--; /* Search for end of mcode. */ | ||
515 | lua_pushnumber(L, (lua_Number)(size_t)tr.mcode); | ||
516 | lua_pushlstring(L, (const char *)tr.mcode, (char *)mfm-(char *)tr.mcode); | ||
517 | lua_pushlightuserdata(L, (void *)JIT_MCMFM(tr.mcode, tr.sz)); | ||
518 | lua_pushvalue(L, 1); /* Must hold onto function to avoid GC. */ | ||
519 | lua_pushcclosure(L, ju_mfmiter, 2); | ||
520 | return 3; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | /* local addr [, mcode] = jit.util.jsubmcode([idx]) */ | ||
525 | static int ju_jsubmcode(lua_State *L) | ||
526 | { | ||
527 | jit_State *J = G(L)->jit_state; | ||
528 | if (lua_isnoneornil(L, 1)) { | ||
529 | lua_pushnumber(L, (lua_Number)(size_t)J->jsubmcode); | ||
530 | lua_pushlstring(L, (const char *)J->jsubmcode, J->szjsubmcode); | ||
531 | return 2; | ||
532 | } else { | ||
533 | int idx = luaL_checkint(L, 1); | ||
534 | if (idx >= 0 && idx < J->numjsub) { | ||
535 | lua_pushnumber(L, (lua_Number)(size_t)J->jsub[idx]); | ||
536 | return 1; | ||
537 | } | ||
538 | return 0; | ||
539 | } | ||
540 | } | ||
541 | |||
542 | /* FOR INTERNAL DEBUGGING USE ONLY: local addr = jit.util.stackptr() */ | ||
543 | static int ju_stackptr(lua_State *L) | ||
544 | { | ||
545 | jit_State *J = G(L)->jit_state; | ||
546 | size_t addr = cast(size_t (*)(void), J->jsub[0])(); /* JSUB_STACKPTR == 0! */ | ||
547 | lua_pushnumber(L, (lua_Number)addr); | ||
548 | return 1; | ||
549 | } | ||
550 | |||
551 | /* jit.util.* functions. */ | ||
552 | static const luaL_Reg jitutillib[] = { | ||
553 | {"stats", ju_stats }, | ||
554 | {"bytecode", ju_bytecode }, | ||
555 | {"const", ju_const }, | ||
556 | {"upvalue", ju_upvalue }, | ||
557 | {"closurenup", ju_closurenup }, | ||
558 | {"mcode", ju_mcode }, | ||
559 | {"jsubmcode", ju_jsubmcode }, | ||
560 | {"stackptr", ju_stackptr }, | ||
561 | { NULL, NULL } | ||
562 | }; | ||
563 | |||
564 | /* Make hint name to hint number map. */ | ||
565 | static void makehints(lua_State *L, const char *const *t, int tmax, | ||
566 | const char *name) | ||
567 | { | ||
568 | int i; | ||
569 | lua_createtable(L, 0, tmax); | ||
570 | for (i = 1; i < tmax; i++) { | ||
571 | lua_pushinteger(L, JIT_H2NUM(i)); | ||
572 | lua_setfield(L, -2, t[i-1]); | ||
573 | } | ||
574 | lua_setfield(L, -2, name); | ||
575 | } | ||
576 | |||
577 | /* CHECK: must match with ljit.h (grep "ORDER JIT_S"). */ | ||
578 | static const char *const status_list[] = { | ||
579 | "OK", | ||
580 | "NONE", | ||
581 | "OFF", | ||
582 | "ENGINE_OFF", | ||
583 | "DELAYED", | ||
584 | "TOOLARGE", | ||
585 | "COMPILER_ERROR", | ||
586 | "DASM_ERROR" | ||
587 | }; | ||
588 | |||
589 | /* Make bidirectional status name to status number map. */ | ||
590 | static void makestatus(lua_State *L, const char *name) | ||
591 | { | ||
592 | int i; | ||
593 | lua_createtable(L, JIT_S_MAX-1, JIT_S_MAX+1); /* Codes are not 1-based. */ | ||
594 | for (i = 0; i < JIT_S_MAX; i++) { | ||
595 | lua_pushstring(L, status_list[i]); | ||
596 | lua_pushinteger(L, i); | ||
597 | lua_pushvalue(L, -2); | ||
598 | lua_rawseti(L, -4, i); | ||
599 | lua_rawset(L, -3); | ||
600 | } | ||
601 | lua_setfield(L, -2, name); | ||
602 | } | ||
603 | |||
604 | /* ------------------------------------------------------------------------ */ | ||
605 | |||
606 | /* | ||
607 | ** Open JIT library | ||
608 | */ | ||
609 | LUALIB_API int luaopen_jit(lua_State *L) | ||
610 | { | ||
611 | /* Add the core JIT library. */ | ||
612 | luaL_register(L, LUA_JITLIBNAME, jitlib); | ||
613 | lua_pushliteral(L, LUAJIT_VERSION); | ||
614 | lua_setfield(L, -2, "version"); | ||
615 | setintfield("version_num", LUAJIT_VERSION_NUM); | ||
616 | lua_pushstring(L, luaJIT_arch); | ||
617 | lua_setfield(L, -2, "arch"); | ||
618 | makepipeline(L); | ||
619 | |||
620 | /* Add the utility JIT library. */ | ||
621 | luaL_register(L, LUA_JITLIBNAME ".util", jitutillib); | ||
622 | makestatus(L, "status"); | ||
623 | makehints(L, hints_H, JIT_H_MAX, "hints"); | ||
624 | makehints(L, hints_FH, JIT_FH_MAX, "fhints"); | ||
625 | lua_pop(L, 1); | ||
626 | |||
627 | /* Everything ok, so turn the JIT engine on. Vroooom! */ | ||
628 | if (luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|LUAJIT_MODE_ON) <= 0) { | ||
629 | /* Ouch. Someone screwed up DynASM or the JSUBs. Probably me. */ | ||
630 | /* But if you get 999999999, look at jit_consistency_check(). */ | ||
631 | return luaL_error(L, "JIT engine init failed (%d)", | ||
632 | G(L)->jit_state->dasmstatus); | ||
633 | } | ||
634 | |||
635 | return 1; | ||
636 | } | ||
637 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/llex.c b/libraries/LuaJIT-1.1.7/src/llex.c new file mode 100644 index 0000000..92d6575 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/llex.c | |||
@@ -0,0 +1,463 @@ | |||
1 | /* | ||
2 | ** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Lexical Analyzer | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <ctype.h> | ||
9 | #include <locale.h> | ||
10 | #include <string.h> | ||
11 | |||
12 | #define llex_c | ||
13 | #define LUA_CORE | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "ldo.h" | ||
18 | #include "llex.h" | ||
19 | #include "lobject.h" | ||
20 | #include "lparser.h" | ||
21 | #include "lstate.h" | ||
22 | #include "lstring.h" | ||
23 | #include "ltable.h" | ||
24 | #include "lzio.h" | ||
25 | |||
26 | |||
27 | |||
28 | #define next(ls) (ls->current = zgetc(ls->z)) | ||
29 | |||
30 | |||
31 | |||
32 | |||
33 | #define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') | ||
34 | |||
35 | |||
36 | /* ORDER RESERVED */ | ||
37 | const char *const luaX_tokens [] = { | ||
38 | "and", "break", "do", "else", "elseif", | ||
39 | "end", "false", "for", "function", "if", | ||
40 | "in", "local", "nil", "not", "or", "repeat", | ||
41 | "return", "then", "true", "until", "while", | ||
42 | "..", "...", "==", ">=", "<=", "~=", | ||
43 | "<number>", "<name>", "<string>", "<eof>", | ||
44 | NULL | ||
45 | }; | ||
46 | |||
47 | |||
48 | #define save_and_next(ls) (save(ls, ls->current), next(ls)) | ||
49 | |||
50 | |||
51 | static void save (LexState *ls, int c) { | ||
52 | Mbuffer *b = ls->buff; | ||
53 | if (b->n + 1 > b->buffsize) { | ||
54 | size_t newsize; | ||
55 | if (b->buffsize >= MAX_SIZET/2) | ||
56 | luaX_lexerror(ls, "lexical element too long", 0); | ||
57 | newsize = b->buffsize * 2; | ||
58 | luaZ_resizebuffer(ls->L, b, newsize); | ||
59 | } | ||
60 | b->buffer[b->n++] = cast(char, c); | ||
61 | } | ||
62 | |||
63 | |||
64 | void luaX_init (lua_State *L) { | ||
65 | int i; | ||
66 | for (i=0; i<NUM_RESERVED; i++) { | ||
67 | TString *ts = luaS_new(L, luaX_tokens[i]); | ||
68 | luaS_fix(ts); /* reserved words are never collected */ | ||
69 | lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN); | ||
70 | ts->tsv.reserved = cast_byte(i+1); /* reserved word */ | ||
71 | } | ||
72 | } | ||
73 | |||
74 | |||
75 | #define MAXSRC 80 | ||
76 | |||
77 | |||
78 | const char *luaX_token2str (LexState *ls, int token) { | ||
79 | if (token < FIRST_RESERVED) { | ||
80 | lua_assert(token == cast(unsigned char, token)); | ||
81 | return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : | ||
82 | luaO_pushfstring(ls->L, "%c", token); | ||
83 | } | ||
84 | else | ||
85 | return luaX_tokens[token-FIRST_RESERVED]; | ||
86 | } | ||
87 | |||
88 | |||
89 | static const char *txtToken (LexState *ls, int token) { | ||
90 | switch (token) { | ||
91 | case TK_NAME: | ||
92 | case TK_STRING: | ||
93 | case TK_NUMBER: | ||
94 | save(ls, '\0'); | ||
95 | return luaZ_buffer(ls->buff); | ||
96 | default: | ||
97 | return luaX_token2str(ls, token); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | |||
102 | void luaX_lexerror (LexState *ls, const char *msg, int token) { | ||
103 | char buff[MAXSRC]; | ||
104 | luaO_chunkid(buff, getstr(ls->source), MAXSRC); | ||
105 | msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); | ||
106 | if (token) | ||
107 | luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); | ||
108 | luaD_throw(ls->L, LUA_ERRSYNTAX); | ||
109 | } | ||
110 | |||
111 | |||
112 | void luaX_syntaxerror (LexState *ls, const char *msg) { | ||
113 | luaX_lexerror(ls, msg, ls->t.token); | ||
114 | } | ||
115 | |||
116 | |||
117 | TString *luaX_newstring (LexState *ls, const char *str, size_t l) { | ||
118 | lua_State *L = ls->L; | ||
119 | TString *ts = luaS_newlstr(L, str, l); | ||
120 | TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ | ||
121 | if (ttisnil(o)) { | ||
122 | setbvalue(o, 1); /* make sure `str' will not be collected */ | ||
123 | luaC_checkGC(L); | ||
124 | } | ||
125 | return ts; | ||
126 | } | ||
127 | |||
128 | |||
129 | static void inclinenumber (LexState *ls) { | ||
130 | int old = ls->current; | ||
131 | lua_assert(currIsNewline(ls)); | ||
132 | next(ls); /* skip `\n' or `\r' */ | ||
133 | if (currIsNewline(ls) && ls->current != old) | ||
134 | next(ls); /* skip `\n\r' or `\r\n' */ | ||
135 | if (++ls->linenumber >= MAX_INT) | ||
136 | luaX_syntaxerror(ls, "chunk has too many lines"); | ||
137 | } | ||
138 | |||
139 | |||
140 | void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { | ||
141 | ls->decpoint = '.'; | ||
142 | ls->L = L; | ||
143 | ls->lookahead.token = TK_EOS; /* no look-ahead token */ | ||
144 | ls->z = z; | ||
145 | ls->fs = NULL; | ||
146 | ls->linenumber = 1; | ||
147 | ls->lastline = 1; | ||
148 | ls->source = source; | ||
149 | luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ | ||
150 | next(ls); /* read first char */ | ||
151 | } | ||
152 | |||
153 | |||
154 | |||
155 | /* | ||
156 | ** ======================================================= | ||
157 | ** LEXICAL ANALYZER | ||
158 | ** ======================================================= | ||
159 | */ | ||
160 | |||
161 | |||
162 | |||
163 | static int check_next (LexState *ls, const char *set) { | ||
164 | if (!strchr(set, ls->current)) | ||
165 | return 0; | ||
166 | save_and_next(ls); | ||
167 | return 1; | ||
168 | } | ||
169 | |||
170 | |||
171 | static void buffreplace (LexState *ls, char from, char to) { | ||
172 | size_t n = luaZ_bufflen(ls->buff); | ||
173 | char *p = luaZ_buffer(ls->buff); | ||
174 | while (n--) | ||
175 | if (p[n] == from) p[n] = to; | ||
176 | } | ||
177 | |||
178 | |||
179 | static void trydecpoint (LexState *ls, SemInfo *seminfo) { | ||
180 | /* format error: try to update decimal point separator */ | ||
181 | struct lconv *cv = localeconv(); | ||
182 | char old = ls->decpoint; | ||
183 | ls->decpoint = (cv ? cv->decimal_point[0] : '.'); | ||
184 | buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ | ||
185 | if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { | ||
186 | /* format error with correct decimal point: no more options */ | ||
187 | buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ | ||
188 | luaX_lexerror(ls, "malformed number", TK_NUMBER); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | |||
193 | /* LUA_NUMBER */ | ||
194 | static void read_numeral (LexState *ls, SemInfo *seminfo) { | ||
195 | lua_assert(isdigit(ls->current)); | ||
196 | do { | ||
197 | save_and_next(ls); | ||
198 | } while (isdigit(ls->current) || ls->current == '.'); | ||
199 | if (check_next(ls, "Ee")) /* `E'? */ | ||
200 | check_next(ls, "+-"); /* optional exponent sign */ | ||
201 | while (isalnum(ls->current) || ls->current == '_') | ||
202 | save_and_next(ls); | ||
203 | save(ls, '\0'); | ||
204 | buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ | ||
205 | if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ | ||
206 | trydecpoint(ls, seminfo); /* try to update decimal point separator */ | ||
207 | } | ||
208 | |||
209 | |||
210 | static int skip_sep (LexState *ls) { | ||
211 | int count = 0; | ||
212 | int s = ls->current; | ||
213 | lua_assert(s == '[' || s == ']'); | ||
214 | save_and_next(ls); | ||
215 | while (ls->current == '=') { | ||
216 | save_and_next(ls); | ||
217 | count++; | ||
218 | } | ||
219 | return (ls->current == s) ? count : (-count) - 1; | ||
220 | } | ||
221 | |||
222 | |||
223 | static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { | ||
224 | int cont = 0; | ||
225 | (void)(cont); /* avoid warnings when `cont' is not used */ | ||
226 | save_and_next(ls); /* skip 2nd `[' */ | ||
227 | if (currIsNewline(ls)) /* string starts with a newline? */ | ||
228 | inclinenumber(ls); /* skip it */ | ||
229 | for (;;) { | ||
230 | switch (ls->current) { | ||
231 | case EOZ: | ||
232 | luaX_lexerror(ls, (seminfo) ? "unfinished long string" : | ||
233 | "unfinished long comment", TK_EOS); | ||
234 | break; /* to avoid warnings */ | ||
235 | #if defined(LUA_COMPAT_LSTR) | ||
236 | case '[': { | ||
237 | if (skip_sep(ls) == sep) { | ||
238 | save_and_next(ls); /* skip 2nd `[' */ | ||
239 | cont++; | ||
240 | #if LUA_COMPAT_LSTR == 1 | ||
241 | if (sep == 0) | ||
242 | luaX_lexerror(ls, "nesting of [[...]] is deprecated", '['); | ||
243 | #endif | ||
244 | } | ||
245 | break; | ||
246 | } | ||
247 | #endif | ||
248 | case ']': { | ||
249 | if (skip_sep(ls) == sep) { | ||
250 | save_and_next(ls); /* skip 2nd `]' */ | ||
251 | #if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2 | ||
252 | cont--; | ||
253 | if (sep == 0 && cont >= 0) break; | ||
254 | #endif | ||
255 | goto endloop; | ||
256 | } | ||
257 | break; | ||
258 | } | ||
259 | case '\n': | ||
260 | case '\r': { | ||
261 | save(ls, '\n'); | ||
262 | inclinenumber(ls); | ||
263 | if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ | ||
264 | break; | ||
265 | } | ||
266 | default: { | ||
267 | if (seminfo) save_and_next(ls); | ||
268 | else next(ls); | ||
269 | } | ||
270 | } | ||
271 | } endloop: | ||
272 | if (seminfo) | ||
273 | seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), | ||
274 | luaZ_bufflen(ls->buff) - 2*(2 + sep)); | ||
275 | } | ||
276 | |||
277 | |||
278 | static void read_string (LexState *ls, int del, SemInfo *seminfo) { | ||
279 | save_and_next(ls); | ||
280 | while (ls->current != del) { | ||
281 | switch (ls->current) { | ||
282 | case EOZ: | ||
283 | luaX_lexerror(ls, "unfinished string", TK_EOS); | ||
284 | continue; /* to avoid warnings */ | ||
285 | case '\n': | ||
286 | case '\r': | ||
287 | luaX_lexerror(ls, "unfinished string", TK_STRING); | ||
288 | continue; /* to avoid warnings */ | ||
289 | case '\\': { | ||
290 | int c; | ||
291 | next(ls); /* do not save the `\' */ | ||
292 | switch (ls->current) { | ||
293 | case 'a': c = '\a'; break; | ||
294 | case 'b': c = '\b'; break; | ||
295 | case 'f': c = '\f'; break; | ||
296 | case 'n': c = '\n'; break; | ||
297 | case 'r': c = '\r'; break; | ||
298 | case 't': c = '\t'; break; | ||
299 | case 'v': c = '\v'; break; | ||
300 | case '\n': /* go through */ | ||
301 | case '\r': save(ls, '\n'); inclinenumber(ls); continue; | ||
302 | case EOZ: continue; /* will raise an error next loop */ | ||
303 | default: { | ||
304 | if (!isdigit(ls->current)) | ||
305 | save_and_next(ls); /* handles \\, \", \', and \? */ | ||
306 | else { /* \xxx */ | ||
307 | int i = 0; | ||
308 | c = 0; | ||
309 | do { | ||
310 | c = 10*c + (ls->current-'0'); | ||
311 | next(ls); | ||
312 | } while (++i<3 && isdigit(ls->current)); | ||
313 | if (c > UCHAR_MAX) | ||
314 | luaX_lexerror(ls, "escape sequence too large", TK_STRING); | ||
315 | save(ls, c); | ||
316 | } | ||
317 | continue; | ||
318 | } | ||
319 | } | ||
320 | save(ls, c); | ||
321 | next(ls); | ||
322 | continue; | ||
323 | } | ||
324 | default: | ||
325 | save_and_next(ls); | ||
326 | } | ||
327 | } | ||
328 | save_and_next(ls); /* skip delimiter */ | ||
329 | seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, | ||
330 | luaZ_bufflen(ls->buff) - 2); | ||
331 | } | ||
332 | |||
333 | |||
334 | static int llex (LexState *ls, SemInfo *seminfo) { | ||
335 | luaZ_resetbuffer(ls->buff); | ||
336 | for (;;) { | ||
337 | switch (ls->current) { | ||
338 | case '\n': | ||
339 | case '\r': { | ||
340 | inclinenumber(ls); | ||
341 | continue; | ||
342 | } | ||
343 | case '-': { | ||
344 | next(ls); | ||
345 | if (ls->current != '-') return '-'; | ||
346 | /* else is a comment */ | ||
347 | next(ls); | ||
348 | if (ls->current == '[') { | ||
349 | int sep = skip_sep(ls); | ||
350 | luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ | ||
351 | if (sep >= 0) { | ||
352 | read_long_string(ls, NULL, sep); /* long comment */ | ||
353 | luaZ_resetbuffer(ls->buff); | ||
354 | continue; | ||
355 | } | ||
356 | } | ||
357 | /* else short comment */ | ||
358 | while (!currIsNewline(ls) && ls->current != EOZ) | ||
359 | next(ls); | ||
360 | continue; | ||
361 | } | ||
362 | case '[': { | ||
363 | int sep = skip_sep(ls); | ||
364 | if (sep >= 0) { | ||
365 | read_long_string(ls, seminfo, sep); | ||
366 | return TK_STRING; | ||
367 | } | ||
368 | else if (sep == -1) return '['; | ||
369 | else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); | ||
370 | } | ||
371 | case '=': { | ||
372 | next(ls); | ||
373 | if (ls->current != '=') return '='; | ||
374 | else { next(ls); return TK_EQ; } | ||
375 | } | ||
376 | case '<': { | ||
377 | next(ls); | ||
378 | if (ls->current != '=') return '<'; | ||
379 | else { next(ls); return TK_LE; } | ||
380 | } | ||
381 | case '>': { | ||
382 | next(ls); | ||
383 | if (ls->current != '=') return '>'; | ||
384 | else { next(ls); return TK_GE; } | ||
385 | } | ||
386 | case '~': { | ||
387 | next(ls); | ||
388 | if (ls->current != '=') return '~'; | ||
389 | else { next(ls); return TK_NE; } | ||
390 | } | ||
391 | case '"': | ||
392 | case '\'': { | ||
393 | read_string(ls, ls->current, seminfo); | ||
394 | return TK_STRING; | ||
395 | } | ||
396 | case '.': { | ||
397 | save_and_next(ls); | ||
398 | if (check_next(ls, ".")) { | ||
399 | if (check_next(ls, ".")) | ||
400 | return TK_DOTS; /* ... */ | ||
401 | else return TK_CONCAT; /* .. */ | ||
402 | } | ||
403 | else if (!isdigit(ls->current)) return '.'; | ||
404 | else { | ||
405 | read_numeral(ls, seminfo); | ||
406 | return TK_NUMBER; | ||
407 | } | ||
408 | } | ||
409 | case EOZ: { | ||
410 | return TK_EOS; | ||
411 | } | ||
412 | default: { | ||
413 | if (isspace(ls->current)) { | ||
414 | lua_assert(!currIsNewline(ls)); | ||
415 | next(ls); | ||
416 | continue; | ||
417 | } | ||
418 | else if (isdigit(ls->current)) { | ||
419 | read_numeral(ls, seminfo); | ||
420 | return TK_NUMBER; | ||
421 | } | ||
422 | else if (isalpha(ls->current) || ls->current == '_') { | ||
423 | /* identifier or reserved word */ | ||
424 | TString *ts; | ||
425 | do { | ||
426 | save_and_next(ls); | ||
427 | } while (isalnum(ls->current) || ls->current == '_'); | ||
428 | ts = luaX_newstring(ls, luaZ_buffer(ls->buff), | ||
429 | luaZ_bufflen(ls->buff)); | ||
430 | if (ts->tsv.reserved > 0) /* reserved word? */ | ||
431 | return ts->tsv.reserved - 1 + FIRST_RESERVED; | ||
432 | else { | ||
433 | seminfo->ts = ts; | ||
434 | return TK_NAME; | ||
435 | } | ||
436 | } | ||
437 | else { | ||
438 | int c = ls->current; | ||
439 | next(ls); | ||
440 | return c; /* single-char tokens (+ - / ...) */ | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | } | ||
445 | } | ||
446 | |||
447 | |||
448 | void luaX_next (LexState *ls) { | ||
449 | ls->lastline = ls->linenumber; | ||
450 | if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ | ||
451 | ls->t = ls->lookahead; /* use this one */ | ||
452 | ls->lookahead.token = TK_EOS; /* and discharge it */ | ||
453 | } | ||
454 | else | ||
455 | ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ | ||
456 | } | ||
457 | |||
458 | |||
459 | void luaX_lookahead (LexState *ls) { | ||
460 | lua_assert(ls->lookahead.token == TK_EOS); | ||
461 | ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); | ||
462 | } | ||
463 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/llex.h b/libraries/LuaJIT-1.1.7/src/llex.h new file mode 100644 index 0000000..a9201ce --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/llex.h | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | ** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Lexical Analyzer | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef llex_h | ||
8 | #define llex_h | ||
9 | |||
10 | #include "lobject.h" | ||
11 | #include "lzio.h" | ||
12 | |||
13 | |||
14 | #define FIRST_RESERVED 257 | ||
15 | |||
16 | /* maximum length of a reserved word */ | ||
17 | #define TOKEN_LEN (sizeof("function")/sizeof(char)) | ||
18 | |||
19 | |||
20 | /* | ||
21 | * WARNING: if you change the order of this enumeration, | ||
22 | * grep "ORDER RESERVED" | ||
23 | */ | ||
24 | enum RESERVED { | ||
25 | /* terminal symbols denoted by reserved words */ | ||
26 | TK_AND = FIRST_RESERVED, TK_BREAK, | ||
27 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, | ||
28 | TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, | ||
29 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, | ||
30 | /* other terminal symbols */ | ||
31 | TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, | ||
32 | TK_NAME, TK_STRING, TK_EOS | ||
33 | }; | ||
34 | |||
35 | /* number of reserved words */ | ||
36 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) | ||
37 | |||
38 | |||
39 | /* array with token `names' */ | ||
40 | LUAI_DATA const char *const luaX_tokens []; | ||
41 | |||
42 | |||
43 | typedef union { | ||
44 | lua_Number r; | ||
45 | TString *ts; | ||
46 | } SemInfo; /* semantics information */ | ||
47 | |||
48 | |||
49 | typedef struct Token { | ||
50 | int token; | ||
51 | SemInfo seminfo; | ||
52 | } Token; | ||
53 | |||
54 | |||
55 | typedef struct LexState { | ||
56 | int current; /* current character (charint) */ | ||
57 | int linenumber; /* input line counter */ | ||
58 | int lastline; /* line of last token `consumed' */ | ||
59 | Token t; /* current token */ | ||
60 | Token lookahead; /* look ahead token */ | ||
61 | struct FuncState *fs; /* `FuncState' is private to the parser */ | ||
62 | struct lua_State *L; | ||
63 | ZIO *z; /* input stream */ | ||
64 | Mbuffer *buff; /* buffer for tokens */ | ||
65 | TString *source; /* current source name */ | ||
66 | char decpoint; /* locale decimal point */ | ||
67 | } LexState; | ||
68 | |||
69 | |||
70 | LUAI_FUNC void luaX_init (lua_State *L); | ||
71 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, | ||
72 | TString *source); | ||
73 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); | ||
74 | LUAI_FUNC void luaX_next (LexState *ls); | ||
75 | LUAI_FUNC void luaX_lookahead (LexState *ls); | ||
76 | LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); | ||
77 | LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s); | ||
78 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); | ||
79 | |||
80 | |||
81 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/llimits.h b/libraries/LuaJIT-1.1.7/src/llimits.h new file mode 100644 index 0000000..ca8dcb7 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/llimits.h | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | ** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Limits, basic types, and some other `installation-dependent' definitions | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef llimits_h | ||
8 | #define llimits_h | ||
9 | |||
10 | |||
11 | #include <limits.h> | ||
12 | #include <stddef.h> | ||
13 | |||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | |||
18 | typedef LUAI_UINT32 lu_int32; | ||
19 | |||
20 | typedef LUAI_UMEM lu_mem; | ||
21 | |||
22 | typedef LUAI_MEM l_mem; | ||
23 | |||
24 | |||
25 | |||
26 | /* chars used as small naturals (so that `char' is reserved for characters) */ | ||
27 | typedef unsigned char lu_byte; | ||
28 | |||
29 | |||
30 | #define MAX_SIZET ((size_t)(~(size_t)0)-2) | ||
31 | |||
32 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) | ||
33 | |||
34 | |||
35 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ | ||
36 | |||
37 | /* | ||
38 | ** conversion of pointer to integer | ||
39 | ** this is for hashing only; there is no problem if the integer | ||
40 | ** cannot hold the whole pointer value | ||
41 | */ | ||
42 | #define IntPoint(p) ((unsigned int)(lu_mem)(p)) | ||
43 | |||
44 | |||
45 | |||
46 | /* type to ensure maximum alignment */ | ||
47 | typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; | ||
48 | |||
49 | |||
50 | /* result of a `usual argument conversion' over lua_Number */ | ||
51 | typedef LUAI_UACNUMBER l_uacNumber; | ||
52 | |||
53 | |||
54 | /* internal assertions for in-house debugging */ | ||
55 | #ifdef lua_assert | ||
56 | |||
57 | #define check_exp(c,e) (lua_assert(c), (e)) | ||
58 | #define api_check(l,e) lua_assert(e) | ||
59 | |||
60 | #else | ||
61 | |||
62 | #define lua_assert(c) ((void)0) | ||
63 | #define check_exp(c,e) (e) | ||
64 | #define api_check luai_apicheck | ||
65 | |||
66 | #endif | ||
67 | |||
68 | |||
69 | #ifndef UNUSED | ||
70 | #define UNUSED(x) ((void)(x)) /* to avoid warnings */ | ||
71 | #endif | ||
72 | |||
73 | |||
74 | #ifndef cast | ||
75 | #define cast(t, exp) ((t)(exp)) | ||
76 | #endif | ||
77 | |||
78 | #define cast_byte(i) cast(lu_byte, (i)) | ||
79 | #define cast_num(i) cast(lua_Number, (i)) | ||
80 | #define cast_int(i) cast(int, (i)) | ||
81 | |||
82 | |||
83 | |||
84 | /* | ||
85 | ** type for virtual-machine instructions | ||
86 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) | ||
87 | */ | ||
88 | typedef lu_int32 Instruction; | ||
89 | |||
90 | |||
91 | |||
92 | /* maximum stack for a Lua function */ | ||
93 | #define MAXSTACK 250 | ||
94 | |||
95 | |||
96 | |||
97 | /* minimum size for the string table (must be power of 2) */ | ||
98 | #ifndef MINSTRTABSIZE | ||
99 | #define MINSTRTABSIZE 32 | ||
100 | #endif | ||
101 | |||
102 | |||
103 | /* minimum size for string buffer */ | ||
104 | #ifndef LUA_MINBUFFER | ||
105 | #define LUA_MINBUFFER 32 | ||
106 | #endif | ||
107 | |||
108 | |||
109 | #ifndef lua_lock | ||
110 | #define lua_lock(L) ((void) 0) | ||
111 | #define lua_unlock(L) ((void) 0) | ||
112 | #endif | ||
113 | |||
114 | #ifndef luai_threadyield | ||
115 | #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} | ||
116 | #endif | ||
117 | |||
118 | |||
119 | /* | ||
120 | ** macro to control inclusion of some hard tests on stack reallocation | ||
121 | */ | ||
122 | #ifndef HARDSTACKTESTS | ||
123 | #define condhardstacktests(x) ((void)0) | ||
124 | #else | ||
125 | #define condhardstacktests(x) x | ||
126 | #endif | ||
127 | |||
128 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lmathlib.c b/libraries/LuaJIT-1.1.7/src/lmathlib.c new file mode 100644 index 0000000..441fbf7 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lmathlib.c | |||
@@ -0,0 +1,263 @@ | |||
1 | /* | ||
2 | ** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Standard mathematical library | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <stdlib.h> | ||
9 | #include <math.h> | ||
10 | |||
11 | #define lmathlib_c | ||
12 | #define LUA_LIB | ||
13 | |||
14 | #include "lua.h" | ||
15 | |||
16 | #include "lauxlib.h" | ||
17 | #include "lualib.h" | ||
18 | |||
19 | |||
20 | #undef PI | ||
21 | #define PI (3.14159265358979323846) | ||
22 | #define RADIANS_PER_DEGREE (PI/180.0) | ||
23 | |||
24 | |||
25 | |||
26 | static int math_abs (lua_State *L) { | ||
27 | lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); | ||
28 | return 1; | ||
29 | } | ||
30 | |||
31 | static int math_sin (lua_State *L) { | ||
32 | lua_pushnumber(L, sin(luaL_checknumber(L, 1))); | ||
33 | return 1; | ||
34 | } | ||
35 | |||
36 | static int math_sinh (lua_State *L) { | ||
37 | lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); | ||
38 | return 1; | ||
39 | } | ||
40 | |||
41 | static int math_cos (lua_State *L) { | ||
42 | lua_pushnumber(L, cos(luaL_checknumber(L, 1))); | ||
43 | return 1; | ||
44 | } | ||
45 | |||
46 | static int math_cosh (lua_State *L) { | ||
47 | lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); | ||
48 | return 1; | ||
49 | } | ||
50 | |||
51 | static int math_tan (lua_State *L) { | ||
52 | lua_pushnumber(L, tan(luaL_checknumber(L, 1))); | ||
53 | return 1; | ||
54 | } | ||
55 | |||
56 | static int math_tanh (lua_State *L) { | ||
57 | lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); | ||
58 | return 1; | ||
59 | } | ||
60 | |||
61 | static int math_asin (lua_State *L) { | ||
62 | lua_pushnumber(L, asin(luaL_checknumber(L, 1))); | ||
63 | return 1; | ||
64 | } | ||
65 | |||
66 | static int math_acos (lua_State *L) { | ||
67 | lua_pushnumber(L, acos(luaL_checknumber(L, 1))); | ||
68 | return 1; | ||
69 | } | ||
70 | |||
71 | static int math_atan (lua_State *L) { | ||
72 | lua_pushnumber(L, atan(luaL_checknumber(L, 1))); | ||
73 | return 1; | ||
74 | } | ||
75 | |||
76 | static int math_atan2 (lua_State *L) { | ||
77 | lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); | ||
78 | return 1; | ||
79 | } | ||
80 | |||
81 | static int math_ceil (lua_State *L) { | ||
82 | lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); | ||
83 | return 1; | ||
84 | } | ||
85 | |||
86 | static int math_floor (lua_State *L) { | ||
87 | lua_pushnumber(L, floor(luaL_checknumber(L, 1))); | ||
88 | return 1; | ||
89 | } | ||
90 | |||
91 | static int math_fmod (lua_State *L) { | ||
92 | lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); | ||
93 | return 1; | ||
94 | } | ||
95 | |||
96 | static int math_modf (lua_State *L) { | ||
97 | double ip; | ||
98 | double fp = modf(luaL_checknumber(L, 1), &ip); | ||
99 | lua_pushnumber(L, ip); | ||
100 | lua_pushnumber(L, fp); | ||
101 | return 2; | ||
102 | } | ||
103 | |||
104 | static int math_sqrt (lua_State *L) { | ||
105 | lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | static int math_pow (lua_State *L) { | ||
110 | lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); | ||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | static int math_log (lua_State *L) { | ||
115 | lua_pushnumber(L, log(luaL_checknumber(L, 1))); | ||
116 | return 1; | ||
117 | } | ||
118 | |||
119 | static int math_log10 (lua_State *L) { | ||
120 | lua_pushnumber(L, log10(luaL_checknumber(L, 1))); | ||
121 | return 1; | ||
122 | } | ||
123 | |||
124 | static int math_exp (lua_State *L) { | ||
125 | lua_pushnumber(L, exp(luaL_checknumber(L, 1))); | ||
126 | return 1; | ||
127 | } | ||
128 | |||
129 | static int math_deg (lua_State *L) { | ||
130 | lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); | ||
131 | return 1; | ||
132 | } | ||
133 | |||
134 | static int math_rad (lua_State *L) { | ||
135 | lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); | ||
136 | return 1; | ||
137 | } | ||
138 | |||
139 | static int math_frexp (lua_State *L) { | ||
140 | int e; | ||
141 | lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); | ||
142 | lua_pushinteger(L, e); | ||
143 | return 2; | ||
144 | } | ||
145 | |||
146 | static int math_ldexp (lua_State *L) { | ||
147 | lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); | ||
148 | return 1; | ||
149 | } | ||
150 | |||
151 | |||
152 | |||
153 | static int math_min (lua_State *L) { | ||
154 | int n = lua_gettop(L); /* number of arguments */ | ||
155 | lua_Number dmin = luaL_checknumber(L, 1); | ||
156 | int i; | ||
157 | for (i=2; i<=n; i++) { | ||
158 | lua_Number d = luaL_checknumber(L, i); | ||
159 | if (d < dmin) | ||
160 | dmin = d; | ||
161 | } | ||
162 | lua_pushnumber(L, dmin); | ||
163 | return 1; | ||
164 | } | ||
165 | |||
166 | |||
167 | static int math_max (lua_State *L) { | ||
168 | int n = lua_gettop(L); /* number of arguments */ | ||
169 | lua_Number dmax = luaL_checknumber(L, 1); | ||
170 | int i; | ||
171 | for (i=2; i<=n; i++) { | ||
172 | lua_Number d = luaL_checknumber(L, i); | ||
173 | if (d > dmax) | ||
174 | dmax = d; | ||
175 | } | ||
176 | lua_pushnumber(L, dmax); | ||
177 | return 1; | ||
178 | } | ||
179 | |||
180 | |||
181 | static int math_random (lua_State *L) { | ||
182 | /* the `%' avoids the (rare) case of r==1, and is needed also because on | ||
183 | some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ | ||
184 | lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; | ||
185 | switch (lua_gettop(L)) { /* check number of arguments */ | ||
186 | case 0: { /* no arguments */ | ||
187 | lua_pushnumber(L, r); /* Number between 0 and 1 */ | ||
188 | break; | ||
189 | } | ||
190 | case 1: { /* only upper limit */ | ||
191 | int u = luaL_checkint(L, 1); | ||
192 | luaL_argcheck(L, 1<=u, 1, "interval is empty"); | ||
193 | lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ | ||
194 | break; | ||
195 | } | ||
196 | case 2: { /* lower and upper limits */ | ||
197 | int l = luaL_checkint(L, 1); | ||
198 | int u = luaL_checkint(L, 2); | ||
199 | luaL_argcheck(L, l<=u, 2, "interval is empty"); | ||
200 | lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ | ||
201 | break; | ||
202 | } | ||
203 | default: return luaL_error(L, "wrong number of arguments"); | ||
204 | } | ||
205 | return 1; | ||
206 | } | ||
207 | |||
208 | |||
209 | static int math_randomseed (lua_State *L) { | ||
210 | srand(luaL_checkint(L, 1)); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | |||
215 | static const luaL_Reg mathlib[] = { | ||
216 | {"abs", math_abs}, | ||
217 | {"acos", math_acos}, | ||
218 | {"asin", math_asin}, | ||
219 | {"atan2", math_atan2}, | ||
220 | {"atan", math_atan}, | ||
221 | {"ceil", math_ceil}, | ||
222 | {"cosh", math_cosh}, | ||
223 | {"cos", math_cos}, | ||
224 | {"deg", math_deg}, | ||
225 | {"exp", math_exp}, | ||
226 | {"floor", math_floor}, | ||
227 | {"fmod", math_fmod}, | ||
228 | {"frexp", math_frexp}, | ||
229 | {"ldexp", math_ldexp}, | ||
230 | {"log10", math_log10}, | ||
231 | {"log", math_log}, | ||
232 | {"max", math_max}, | ||
233 | {"min", math_min}, | ||
234 | {"modf", math_modf}, | ||
235 | {"pow", math_pow}, | ||
236 | {"rad", math_rad}, | ||
237 | {"random", math_random}, | ||
238 | {"randomseed", math_randomseed}, | ||
239 | {"sinh", math_sinh}, | ||
240 | {"sin", math_sin}, | ||
241 | {"sqrt", math_sqrt}, | ||
242 | {"tanh", math_tanh}, | ||
243 | {"tan", math_tan}, | ||
244 | {NULL, NULL} | ||
245 | }; | ||
246 | |||
247 | |||
248 | /* | ||
249 | ** Open math library | ||
250 | */ | ||
251 | LUALIB_API int luaopen_math (lua_State *L) { | ||
252 | luaL_register(L, LUA_MATHLIBNAME, mathlib); | ||
253 | lua_pushnumber(L, PI); | ||
254 | lua_setfield(L, -2, "pi"); | ||
255 | lua_pushnumber(L, HUGE_VAL); | ||
256 | lua_setfield(L, -2, "huge"); | ||
257 | #if defined(LUA_COMPAT_MOD) | ||
258 | lua_getfield(L, -1, "fmod"); | ||
259 | lua_setfield(L, -2, "mod"); | ||
260 | #endif | ||
261 | return 1; | ||
262 | } | ||
263 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lmem.c b/libraries/LuaJIT-1.1.7/src/lmem.c new file mode 100644 index 0000000..ae7d8c9 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lmem.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /* | ||
2 | ** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Interface to Memory Manager | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <stddef.h> | ||
9 | |||
10 | #define lmem_c | ||
11 | #define LUA_CORE | ||
12 | |||
13 | #include "lua.h" | ||
14 | |||
15 | #include "ldebug.h" | ||
16 | #include "ldo.h" | ||
17 | #include "lmem.h" | ||
18 | #include "lobject.h" | ||
19 | #include "lstate.h" | ||
20 | |||
21 | |||
22 | |||
23 | /* | ||
24 | ** About the realloc function: | ||
25 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); | ||
26 | ** (`osize' is the old size, `nsize' is the new size) | ||
27 | ** | ||
28 | ** Lua ensures that (ptr == NULL) iff (osize == 0). | ||
29 | ** | ||
30 | ** * frealloc(ud, NULL, 0, x) creates a new block of size `x' | ||
31 | ** | ||
32 | ** * frealloc(ud, p, x, 0) frees the block `p' | ||
33 | ** (in this specific case, frealloc must return NULL). | ||
34 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing | ||
35 | ** (which is equivalent to free(NULL) in ANSI C) | ||
36 | ** | ||
37 | ** frealloc returns NULL if it cannot create or reallocate the area | ||
38 | ** (any reallocation to an equal or smaller size cannot fail!) | ||
39 | */ | ||
40 | |||
41 | |||
42 | |||
43 | #define MINSIZEARRAY 4 | ||
44 | |||
45 | |||
46 | void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, | ||
47 | int limit, const char *errormsg) { | ||
48 | void *newblock; | ||
49 | int newsize; | ||
50 | if (*size >= limit/2) { /* cannot double it? */ | ||
51 | if (*size >= limit) /* cannot grow even a little? */ | ||
52 | luaG_runerror(L, errormsg); | ||
53 | newsize = limit; /* still have at least one free place */ | ||
54 | } | ||
55 | else { | ||
56 | newsize = (*size)*2; | ||
57 | if (newsize < MINSIZEARRAY) | ||
58 | newsize = MINSIZEARRAY; /* minimum size */ | ||
59 | } | ||
60 | newblock = luaM_reallocv(L, block, *size, newsize, size_elems); | ||
61 | *size = newsize; /* update only when everything else is OK */ | ||
62 | return newblock; | ||
63 | } | ||
64 | |||
65 | |||
66 | void *luaM_toobig (lua_State *L) { | ||
67 | luaG_runerror(L, "memory allocation error: block too big"); | ||
68 | return NULL; /* to avoid warnings */ | ||
69 | } | ||
70 | |||
71 | |||
72 | |||
73 | /* | ||
74 | ** generic allocation routine. | ||
75 | */ | ||
76 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { | ||
77 | global_State *g = G(L); | ||
78 | lua_assert((osize == 0) == (block == NULL)); | ||
79 | block = (*g->frealloc)(g->ud, block, osize, nsize); | ||
80 | if (block == NULL && nsize > 0) | ||
81 | luaD_throw(L, LUA_ERRMEM); | ||
82 | lua_assert((nsize == 0) == (block == NULL)); | ||
83 | g->totalbytes = (g->totalbytes - osize) + nsize; | ||
84 | return block; | ||
85 | } | ||
86 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lmem.h b/libraries/LuaJIT-1.1.7/src/lmem.h new file mode 100644 index 0000000..7c2dcb3 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lmem.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | ** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Interface to Memory Manager | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lmem_h | ||
8 | #define lmem_h | ||
9 | |||
10 | |||
11 | #include <stddef.h> | ||
12 | |||
13 | #include "llimits.h" | ||
14 | #include "lua.h" | ||
15 | |||
16 | #define MEMERRMSG "not enough memory" | ||
17 | |||
18 | |||
19 | #define luaM_reallocv(L,b,on,n,e) \ | ||
20 | ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ | ||
21 | luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ | ||
22 | luaM_toobig(L)) | ||
23 | |||
24 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) | ||
25 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) | ||
26 | #define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) | ||
27 | |||
28 | #define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) | ||
29 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) | ||
30 | #define luaM_newvector(L,n,t) \ | ||
31 | cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) | ||
32 | |||
33 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ | ||
34 | if ((nelems)+1 > (size)) \ | ||
35 | ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) | ||
36 | |||
37 | #define luaM_reallocvector(L, v,oldn,n,t) \ | ||
38 | ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) | ||
39 | |||
40 | |||
41 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, | ||
42 | size_t size); | ||
43 | LUAI_FUNC void *luaM_toobig (lua_State *L); | ||
44 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, | ||
45 | size_t size_elem, int limit, | ||
46 | const char *errormsg); | ||
47 | |||
48 | #endif | ||
49 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/loadlib.c b/libraries/LuaJIT-1.1.7/src/loadlib.c new file mode 100644 index 0000000..a2da9fc --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/loadlib.c | |||
@@ -0,0 +1,669 @@ | |||
1 | /* | ||
2 | ** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $ | ||
3 | ** Dynamic library loader for Lua | ||
4 | ** See Copyright Notice in lua.h | ||
5 | ** | ||
6 | ** This module contains an implementation of loadlib for Unix systems | ||
7 | ** that have dlfcn, an implementation for Darwin (Mac OS X), an | ||
8 | ** implementation for Windows, and a stub for other systems. | ||
9 | */ | ||
10 | |||
11 | |||
12 | #include <stdlib.h> | ||
13 | #include <string.h> | ||
14 | |||
15 | |||
16 | #define loadlib_c | ||
17 | #define LUA_LIB | ||
18 | |||
19 | #include "lua.h" | ||
20 | |||
21 | #include "lauxlib.h" | ||
22 | #include "lualib.h" | ||
23 | #include "luajit.h" | ||
24 | |||
25 | |||
26 | /* prefix for open functions in C libraries */ | ||
27 | #define LUA_POF "luaopen_" | ||
28 | |||
29 | /* separator for open functions in C libraries */ | ||
30 | #define LUA_OFSEP "_" | ||
31 | |||
32 | |||
33 | #define LIBPREFIX "LOADLIB: " | ||
34 | |||
35 | #define POF LUA_POF | ||
36 | #define LIB_FAIL "open" | ||
37 | |||
38 | |||
39 | /* error codes for ll_loadfunc */ | ||
40 | #define ERRLIB 1 | ||
41 | #define ERRFUNC 2 | ||
42 | |||
43 | #define setprogdir(L) ((void)0) | ||
44 | |||
45 | |||
46 | static void ll_unloadlib (void *lib); | ||
47 | static void *ll_load (lua_State *L, const char *path); | ||
48 | static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); | ||
49 | |||
50 | |||
51 | |||
52 | #if defined(LUA_DL_DLOPEN) | ||
53 | /* | ||
54 | ** {======================================================================== | ||
55 | ** This is an implementation of loadlib based on the dlfcn interface. | ||
56 | ** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, | ||
57 | ** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least | ||
58 | ** as an emulation layer on top of native functions. | ||
59 | ** ========================================================================= | ||
60 | */ | ||
61 | |||
62 | #include <dlfcn.h> | ||
63 | |||
64 | static void ll_unloadlib (void *lib) { | ||
65 | dlclose(lib); | ||
66 | } | ||
67 | |||
68 | |||
69 | static void *ll_load (lua_State *L, const char *path) { | ||
70 | void *lib = dlopen(path, RTLD_NOW); | ||
71 | if (lib == NULL) lua_pushstring(L, dlerror()); | ||
72 | return lib; | ||
73 | } | ||
74 | |||
75 | |||
76 | static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { | ||
77 | lua_CFunction f = (lua_CFunction)dlsym(lib, sym); | ||
78 | if (f == NULL) lua_pushstring(L, dlerror()); | ||
79 | return f; | ||
80 | } | ||
81 | |||
82 | /* }====================================================== */ | ||
83 | |||
84 | |||
85 | |||
86 | #elif defined(LUA_DL_DLL) | ||
87 | /* | ||
88 | ** {====================================================================== | ||
89 | ** This is an implementation of loadlib for Windows using native functions. | ||
90 | ** ======================================================================= | ||
91 | */ | ||
92 | |||
93 | #include <windows.h> | ||
94 | |||
95 | |||
96 | #undef setprogdir | ||
97 | |||
98 | static void setprogdir (lua_State *L) { | ||
99 | char buff[MAX_PATH + 1]; | ||
100 | char *lb; | ||
101 | DWORD nsize = sizeof(buff)/sizeof(char); | ||
102 | DWORD n = GetModuleFileNameA(NULL, buff, nsize); | ||
103 | if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) | ||
104 | luaL_error(L, "unable to get ModuleFileName"); | ||
105 | else { | ||
106 | *lb = '\0'; | ||
107 | luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); | ||
108 | lua_remove(L, -2); /* remove original string */ | ||
109 | } | ||
110 | } | ||
111 | |||
112 | |||
113 | static void pusherror (lua_State *L) { | ||
114 | int error = GetLastError(); | ||
115 | char buffer[128]; | ||
116 | if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, | ||
117 | NULL, error, 0, buffer, sizeof(buffer), NULL)) | ||
118 | lua_pushstring(L, buffer); | ||
119 | else | ||
120 | lua_pushfstring(L, "system error %d\n", error); | ||
121 | } | ||
122 | |||
123 | static void ll_unloadlib (void *lib) { | ||
124 | FreeLibrary((HINSTANCE)lib); | ||
125 | } | ||
126 | |||
127 | |||
128 | static void *ll_load (lua_State *L, const char *path) { | ||
129 | HINSTANCE lib = LoadLibraryA(path); | ||
130 | if (lib == NULL) pusherror(L); | ||
131 | return lib; | ||
132 | } | ||
133 | |||
134 | |||
135 | static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { | ||
136 | lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym); | ||
137 | if (f == NULL) pusherror(L); | ||
138 | return f; | ||
139 | } | ||
140 | |||
141 | /* }====================================================== */ | ||
142 | |||
143 | |||
144 | |||
145 | #elif defined(LUA_DL_DYLD) | ||
146 | /* | ||
147 | ** {====================================================================== | ||
148 | ** Native Mac OS X / Darwin Implementation | ||
149 | ** ======================================================================= | ||
150 | */ | ||
151 | |||
152 | #include <mach-o/dyld.h> | ||
153 | |||
154 | |||
155 | /* Mac appends a `_' before C function names */ | ||
156 | #undef POF | ||
157 | #define POF "_" LUA_POF | ||
158 | |||
159 | |||
160 | static void pusherror (lua_State *L) { | ||
161 | const char *err_str; | ||
162 | const char *err_file; | ||
163 | NSLinkEditErrors err; | ||
164 | int err_num; | ||
165 | NSLinkEditError(&err, &err_num, &err_file, &err_str); | ||
166 | lua_pushstring(L, err_str); | ||
167 | } | ||
168 | |||
169 | |||
170 | static const char *errorfromcode (NSObjectFileImageReturnCode ret) { | ||
171 | switch (ret) { | ||
172 | case NSObjectFileImageInappropriateFile: | ||
173 | return "file is not a bundle"; | ||
174 | case NSObjectFileImageArch: | ||
175 | return "library is for wrong CPU type"; | ||
176 | case NSObjectFileImageFormat: | ||
177 | return "bad format"; | ||
178 | case NSObjectFileImageAccess: | ||
179 | return "cannot access file"; | ||
180 | case NSObjectFileImageFailure: | ||
181 | default: | ||
182 | return "unable to load library"; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | |||
187 | static void ll_unloadlib (void *lib) { | ||
188 | NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); | ||
189 | } | ||
190 | |||
191 | |||
192 | static void *ll_load (lua_State *L, const char *path) { | ||
193 | NSObjectFileImage img; | ||
194 | NSObjectFileImageReturnCode ret; | ||
195 | /* this would be a rare case, but prevents crashing if it happens */ | ||
196 | if(!_dyld_present()) { | ||
197 | lua_pushliteral(L, "dyld not present"); | ||
198 | return NULL; | ||
199 | } | ||
200 | ret = NSCreateObjectFileImageFromFile(path, &img); | ||
201 | if (ret == NSObjectFileImageSuccess) { | ||
202 | NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | | ||
203 | NSLINKMODULE_OPTION_RETURN_ON_ERROR); | ||
204 | NSDestroyObjectFileImage(img); | ||
205 | if (mod == NULL) pusherror(L); | ||
206 | return mod; | ||
207 | } | ||
208 | lua_pushstring(L, errorfromcode(ret)); | ||
209 | return NULL; | ||
210 | } | ||
211 | |||
212 | |||
213 | static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { | ||
214 | NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym); | ||
215 | if (nss == NULL) { | ||
216 | lua_pushfstring(L, "symbol " LUA_QS " not found", sym); | ||
217 | return NULL; | ||
218 | } | ||
219 | return (lua_CFunction)NSAddressOfSymbol(nss); | ||
220 | } | ||
221 | |||
222 | /* }====================================================== */ | ||
223 | |||
224 | |||
225 | |||
226 | #else | ||
227 | /* | ||
228 | ** {====================================================== | ||
229 | ** Fallback for other systems | ||
230 | ** ======================================================= | ||
231 | */ | ||
232 | |||
233 | #undef LIB_FAIL | ||
234 | #define LIB_FAIL "absent" | ||
235 | |||
236 | |||
237 | #define DLMSG "dynamic libraries not enabled; check your Lua installation" | ||
238 | |||
239 | |||
240 | static void ll_unloadlib (void *lib) { | ||
241 | (void)lib; /* to avoid warnings */ | ||
242 | } | ||
243 | |||
244 | |||
245 | static void *ll_load (lua_State *L, const char *path) { | ||
246 | (void)path; /* to avoid warnings */ | ||
247 | lua_pushliteral(L, DLMSG); | ||
248 | return NULL; | ||
249 | } | ||
250 | |||
251 | |||
252 | static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { | ||
253 | (void)lib; (void)sym; /* to avoid warnings */ | ||
254 | lua_pushliteral(L, DLMSG); | ||
255 | return NULL; | ||
256 | } | ||
257 | |||
258 | /* }====================================================== */ | ||
259 | #endif | ||
260 | |||
261 | |||
262 | |||
263 | static void **ll_register (lua_State *L, const char *path) { | ||
264 | void **plib; | ||
265 | lua_pushfstring(L, "%s%s", LIBPREFIX, path); | ||
266 | lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */ | ||
267 | if (!lua_isnil(L, -1)) /* is there an entry? */ | ||
268 | plib = (void **)lua_touserdata(L, -1); | ||
269 | else { /* no entry yet; create one */ | ||
270 | lua_pop(L, 1); | ||
271 | plib = (void **)lua_newuserdata(L, sizeof(const void *)); | ||
272 | *plib = NULL; | ||
273 | luaL_getmetatable(L, "_LOADLIB"); | ||
274 | lua_setmetatable(L, -2); | ||
275 | lua_pushfstring(L, "%s%s", LIBPREFIX, path); | ||
276 | lua_pushvalue(L, -2); | ||
277 | lua_settable(L, LUA_REGISTRYINDEX); | ||
278 | } | ||
279 | return plib; | ||
280 | } | ||
281 | |||
282 | |||
283 | /* | ||
284 | ** __gc tag method: calls library's `ll_unloadlib' function with the lib | ||
285 | ** handle | ||
286 | */ | ||
287 | static int gctm (lua_State *L) { | ||
288 | void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB"); | ||
289 | if (*lib) ll_unloadlib(*lib); | ||
290 | *lib = NULL; /* mark library as closed */ | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | |||
295 | static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { | ||
296 | void **reg = ll_register(L, path); | ||
297 | if (*reg == NULL) *reg = ll_load(L, path); | ||
298 | if (*reg == NULL) | ||
299 | return ERRLIB; /* unable to load library */ | ||
300 | else { | ||
301 | lua_CFunction f = ll_sym(L, *reg, sym); | ||
302 | if (f == NULL) | ||
303 | return ERRFUNC; /* unable to find function */ | ||
304 | lua_pushcfunction(L, f); | ||
305 | return 0; /* return function */ | ||
306 | } | ||
307 | } | ||
308 | |||
309 | |||
310 | static int ll_loadlib (lua_State *L) { | ||
311 | const char *path = luaL_checkstring(L, 1); | ||
312 | const char *init = luaL_checkstring(L, 2); | ||
313 | int stat = ll_loadfunc(L, path, init); | ||
314 | if (stat == 0) /* no errors? */ | ||
315 | return 1; /* return the loaded function */ | ||
316 | else { /* error; error message is on stack top */ | ||
317 | lua_pushnil(L); | ||
318 | lua_insert(L, -2); | ||
319 | lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); | ||
320 | return 3; /* return nil, error message, and where */ | ||
321 | } | ||
322 | } | ||
323 | |||
324 | |||
325 | |||
326 | /* | ||
327 | ** {====================================================== | ||
328 | ** 'require' function | ||
329 | ** ======================================================= | ||
330 | */ | ||
331 | |||
332 | |||
333 | static int readable (const char *filename) { | ||
334 | FILE *f = fopen(filename, "r"); /* try to open file */ | ||
335 | if (f == NULL) return 0; /* open failed */ | ||
336 | fclose(f); | ||
337 | return 1; | ||
338 | } | ||
339 | |||
340 | |||
341 | static const char *pushnexttemplate (lua_State *L, const char *path) { | ||
342 | const char *l; | ||
343 | while (*path == *LUA_PATHSEP) path++; /* skip separators */ | ||
344 | if (*path == '\0') return NULL; /* no more templates */ | ||
345 | l = strchr(path, *LUA_PATHSEP); /* find next separator */ | ||
346 | if (l == NULL) l = path + strlen(path); | ||
347 | lua_pushlstring(L, path, l - path); /* template */ | ||
348 | return l; | ||
349 | } | ||
350 | |||
351 | |||
352 | static const char *findfile (lua_State *L, const char *name, | ||
353 | const char *pname) { | ||
354 | const char *path; | ||
355 | name = luaL_gsub(L, name, ".", LUA_DIRSEP); | ||
356 | lua_getfield(L, LUA_ENVIRONINDEX, pname); | ||
357 | path = lua_tostring(L, -1); | ||
358 | if (path == NULL) | ||
359 | luaL_error(L, LUA_QL("package.%s") " must be a string", pname); | ||
360 | lua_pushliteral(L, ""); /* error accumulator */ | ||
361 | while ((path = pushnexttemplate(L, path)) != NULL) { | ||
362 | const char *filename; | ||
363 | filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); | ||
364 | lua_remove(L, -2); /* remove path template */ | ||
365 | if (readable(filename)) /* does file exist and is readable? */ | ||
366 | return filename; /* return that file name */ | ||
367 | lua_pushfstring(L, "\n\tno file " LUA_QS, filename); | ||
368 | lua_remove(L, -2); /* remove file name */ | ||
369 | lua_concat(L, 2); /* add entry to possible error message */ | ||
370 | } | ||
371 | return NULL; /* not found */ | ||
372 | } | ||
373 | |||
374 | |||
375 | static void loaderror (lua_State *L, const char *filename) { | ||
376 | luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", | ||
377 | lua_tostring(L, 1), filename, lua_tostring(L, -1)); | ||
378 | } | ||
379 | |||
380 | |||
381 | static int loader_Lua (lua_State *L) { | ||
382 | const char *filename; | ||
383 | const char *name = luaL_checkstring(L, 1); | ||
384 | filename = findfile(L, name, "path"); | ||
385 | if (filename == NULL) return 1; /* library not found in this path */ | ||
386 | if (luaL_loadfile(L, filename) != 0) | ||
387 | loaderror(L, filename); | ||
388 | /* not useful to JIT compile main chunk of a module */ | ||
389 | luaJIT_setmode(L, -1, LUAJIT_MODE_FUNC|LUAJIT_MODE_OFF); | ||
390 | return 1; /* library loaded successfully */ | ||
391 | } | ||
392 | |||
393 | |||
394 | static const char *mkfuncname (lua_State *L, const char *modname) { | ||
395 | const char *funcname; | ||
396 | const char *mark = strchr(modname, *LUA_IGMARK); | ||
397 | if (mark) modname = mark + 1; | ||
398 | funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); | ||
399 | funcname = lua_pushfstring(L, POF"%s", funcname); | ||
400 | lua_remove(L, -2); /* remove 'gsub' result */ | ||
401 | return funcname; | ||
402 | } | ||
403 | |||
404 | |||
405 | static int loader_C (lua_State *L) { | ||
406 | const char *funcname; | ||
407 | const char *name = luaL_checkstring(L, 1); | ||
408 | const char *filename = findfile(L, name, "cpath"); | ||
409 | if (filename == NULL) return 1; /* library not found in this path */ | ||
410 | funcname = mkfuncname(L, name); | ||
411 | if (ll_loadfunc(L, filename, funcname) != 0) | ||
412 | loaderror(L, filename); | ||
413 | return 1; /* library loaded successfully */ | ||
414 | } | ||
415 | |||
416 | |||
417 | static int loader_Croot (lua_State *L) { | ||
418 | const char *funcname; | ||
419 | const char *filename; | ||
420 | const char *name = luaL_checkstring(L, 1); | ||
421 | const char *p = strchr(name, '.'); | ||
422 | int stat; | ||
423 | if (p == NULL) return 0; /* is root */ | ||
424 | lua_pushlstring(L, name, p - name); | ||
425 | filename = findfile(L, lua_tostring(L, -1), "cpath"); | ||
426 | if (filename == NULL) return 1; /* root not found */ | ||
427 | funcname = mkfuncname(L, name); | ||
428 | if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { | ||
429 | if (stat != ERRFUNC) loaderror(L, filename); /* real error */ | ||
430 | lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, | ||
431 | name, filename); | ||
432 | return 1; /* function not found */ | ||
433 | } | ||
434 | return 1; | ||
435 | } | ||
436 | |||
437 | |||
438 | static int loader_preload (lua_State *L) { | ||
439 | const char *name = luaL_checkstring(L, 1); | ||
440 | lua_getfield(L, LUA_ENVIRONINDEX, "preload"); | ||
441 | if (!lua_istable(L, -1)) | ||
442 | luaL_error(L, LUA_QL("package.preload") " must be a table"); | ||
443 | lua_getfield(L, -1, name); | ||
444 | if (lua_isnil(L, -1)) /* not found? */ | ||
445 | lua_pushfstring(L, "\n\tno field package.preload['%s']", name); | ||
446 | return 1; | ||
447 | } | ||
448 | |||
449 | |||
450 | static const int sentinel_ = 0; | ||
451 | #define sentinel ((void *)&sentinel_) | ||
452 | |||
453 | |||
454 | static int ll_require (lua_State *L) { | ||
455 | const char *name = luaL_checkstring(L, 1); | ||
456 | int i; | ||
457 | lua_settop(L, 1); /* _LOADED table will be at index 2 */ | ||
458 | lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); | ||
459 | lua_getfield(L, 2, name); | ||
460 | if (lua_toboolean(L, -1)) { /* is it there? */ | ||
461 | if (lua_touserdata(L, -1) == sentinel) /* check loops */ | ||
462 | luaL_error(L, "loop or previous error loading module " LUA_QS, name); | ||
463 | return 1; /* package is already loaded */ | ||
464 | } | ||
465 | /* else must load it; iterate over available loaders */ | ||
466 | lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); | ||
467 | if (!lua_istable(L, -1)) | ||
468 | luaL_error(L, LUA_QL("package.loaders") " must be a table"); | ||
469 | lua_pushliteral(L, ""); /* error message accumulator */ | ||
470 | for (i=1; ; i++) { | ||
471 | lua_rawgeti(L, -2, i); /* get a loader */ | ||
472 | if (lua_isnil(L, -1)) | ||
473 | luaL_error(L, "module " LUA_QS " not found:%s", | ||
474 | name, lua_tostring(L, -2)); | ||
475 | lua_pushstring(L, name); | ||
476 | lua_call(L, 1, 1); /* call it */ | ||
477 | if (lua_isfunction(L, -1)) /* did it find module? */ | ||
478 | break; /* module loaded successfully */ | ||
479 | else if (lua_isstring(L, -1)) /* loader returned error message? */ | ||
480 | lua_concat(L, 2); /* accumulate it */ | ||
481 | else | ||
482 | lua_pop(L, 1); | ||
483 | } | ||
484 | lua_pushlightuserdata(L, sentinel); | ||
485 | lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ | ||
486 | lua_pushstring(L, name); /* pass name as argument to module */ | ||
487 | lua_call(L, 1, 1); /* run loaded module */ | ||
488 | if (!lua_isnil(L, -1)) /* non-nil return? */ | ||
489 | lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ | ||
490 | lua_getfield(L, 2, name); | ||
491 | if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ | ||
492 | lua_pushboolean(L, 1); /* use true as result */ | ||
493 | lua_pushvalue(L, -1); /* extra copy to be returned */ | ||
494 | lua_setfield(L, 2, name); /* _LOADED[name] = true */ | ||
495 | } | ||
496 | return 1; | ||
497 | } | ||
498 | |||
499 | /* }====================================================== */ | ||
500 | |||
501 | |||
502 | |||
503 | /* | ||
504 | ** {====================================================== | ||
505 | ** 'module' function | ||
506 | ** ======================================================= | ||
507 | */ | ||
508 | |||
509 | |||
510 | static void setfenv (lua_State *L) { | ||
511 | lua_Debug ar; | ||
512 | if (lua_getstack(L, 1, &ar) == 0 || | ||
513 | lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ | ||
514 | lua_iscfunction(L, -1)) | ||
515 | luaL_error(L, LUA_QL("module") " not called from a Lua function"); | ||
516 | lua_pushvalue(L, -2); | ||
517 | lua_setfenv(L, -2); | ||
518 | lua_pop(L, 1); | ||
519 | } | ||
520 | |||
521 | |||
522 | static void dooptions (lua_State *L, int n) { | ||
523 | int i; | ||
524 | for (i = 2; i <= n; i++) { | ||
525 | lua_pushvalue(L, i); /* get option (a function) */ | ||
526 | lua_pushvalue(L, -2); /* module */ | ||
527 | lua_call(L, 1, 0); | ||
528 | } | ||
529 | } | ||
530 | |||
531 | |||
532 | static void modinit (lua_State *L, const char *modname) { | ||
533 | const char *dot; | ||
534 | lua_pushvalue(L, -1); | ||
535 | lua_setfield(L, -2, "_M"); /* module._M = module */ | ||
536 | lua_pushstring(L, modname); | ||
537 | lua_setfield(L, -2, "_NAME"); | ||
538 | dot = strrchr(modname, '.'); /* look for last dot in module name */ | ||
539 | if (dot == NULL) dot = modname; | ||
540 | else dot++; | ||
541 | /* set _PACKAGE as package name (full module name minus last part) */ | ||
542 | lua_pushlstring(L, modname, dot - modname); | ||
543 | lua_setfield(L, -2, "_PACKAGE"); | ||
544 | } | ||
545 | |||
546 | |||
547 | static int ll_module (lua_State *L) { | ||
548 | const char *modname = luaL_checkstring(L, 1); | ||
549 | int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ | ||
550 | lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); | ||
551 | lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ | ||
552 | if (!lua_istable(L, -1)) { /* not found? */ | ||
553 | lua_pop(L, 1); /* remove previous result */ | ||
554 | /* try global variable (and create one if it does not exist) */ | ||
555 | if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) | ||
556 | return luaL_error(L, "name conflict for module " LUA_QS, modname); | ||
557 | lua_pushvalue(L, -1); | ||
558 | lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ | ||
559 | } | ||
560 | /* check whether table already has a _NAME field */ | ||
561 | lua_getfield(L, -1, "_NAME"); | ||
562 | if (!lua_isnil(L, -1)) /* is table an initialized module? */ | ||
563 | lua_pop(L, 1); | ||
564 | else { /* no; initialize it */ | ||
565 | lua_pop(L, 1); | ||
566 | modinit(L, modname); | ||
567 | } | ||
568 | lua_pushvalue(L, -1); | ||
569 | setfenv(L); | ||
570 | dooptions(L, loaded - 1); | ||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | |||
575 | static int ll_seeall (lua_State *L) { | ||
576 | luaL_checktype(L, 1, LUA_TTABLE); | ||
577 | if (!lua_getmetatable(L, 1)) { | ||
578 | lua_createtable(L, 0, 1); /* create new metatable */ | ||
579 | lua_pushvalue(L, -1); | ||
580 | lua_setmetatable(L, 1); | ||
581 | } | ||
582 | lua_pushvalue(L, LUA_GLOBALSINDEX); | ||
583 | lua_setfield(L, -2, "__index"); /* mt.__index = _G */ | ||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | |||
588 | /* }====================================================== */ | ||
589 | |||
590 | |||
591 | |||
592 | /* auxiliary mark (for internal use) */ | ||
593 | #define AUXMARK "\1" | ||
594 | |||
595 | static void setpath (lua_State *L, const char *fieldname, const char *envname, | ||
596 | const char *def) { | ||
597 | const char *path = getenv(envname); | ||
598 | if (path == NULL) /* no environment variable? */ | ||
599 | lua_pushstring(L, def); /* use default */ | ||
600 | else { | ||
601 | /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ | ||
602 | path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, | ||
603 | LUA_PATHSEP AUXMARK LUA_PATHSEP); | ||
604 | luaL_gsub(L, path, AUXMARK, def); | ||
605 | lua_remove(L, -2); | ||
606 | } | ||
607 | setprogdir(L); | ||
608 | lua_setfield(L, -2, fieldname); | ||
609 | } | ||
610 | |||
611 | |||
612 | static const luaL_Reg pk_funcs[] = { | ||
613 | {"loadlib", ll_loadlib}, | ||
614 | {"seeall", ll_seeall}, | ||
615 | {NULL, NULL} | ||
616 | }; | ||
617 | |||
618 | |||
619 | static const luaL_Reg ll_funcs[] = { | ||
620 | {"module", ll_module}, | ||
621 | {"require", ll_require}, | ||
622 | {NULL, NULL} | ||
623 | }; | ||
624 | |||
625 | |||
626 | static const lua_CFunction loaders[] = | ||
627 | {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; | ||
628 | |||
629 | |||
630 | LUALIB_API int luaopen_package (lua_State *L) { | ||
631 | int i; | ||
632 | /* create new type _LOADLIB */ | ||
633 | luaL_newmetatable(L, "_LOADLIB"); | ||
634 | lua_pushcfunction(L, gctm); | ||
635 | lua_setfield(L, -2, "__gc"); | ||
636 | /* create `package' table */ | ||
637 | luaL_register(L, LUA_LOADLIBNAME, pk_funcs); | ||
638 | #if defined(LUA_COMPAT_LOADLIB) | ||
639 | lua_getfield(L, -1, "loadlib"); | ||
640 | lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); | ||
641 | #endif | ||
642 | lua_pushvalue(L, -1); | ||
643 | lua_replace(L, LUA_ENVIRONINDEX); | ||
644 | /* create `loaders' table */ | ||
645 | lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0); | ||
646 | /* fill it with pre-defined loaders */ | ||
647 | for (i=0; loaders[i] != NULL; i++) { | ||
648 | lua_pushcfunction(L, loaders[i]); | ||
649 | lua_rawseti(L, -2, i+1); | ||
650 | } | ||
651 | lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ | ||
652 | setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */ | ||
653 | setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */ | ||
654 | /* store config information */ | ||
655 | lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" | ||
656 | LUA_EXECDIR "\n" LUA_IGMARK); | ||
657 | lua_setfield(L, -2, "config"); | ||
658 | /* set field `loaded' */ | ||
659 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); | ||
660 | lua_setfield(L, -2, "loaded"); | ||
661 | /* set field `preload' */ | ||
662 | lua_newtable(L); | ||
663 | lua_setfield(L, -2, "preload"); | ||
664 | lua_pushvalue(L, LUA_GLOBALSINDEX); | ||
665 | luaL_register(L, NULL, ll_funcs); /* open lib into global table */ | ||
666 | lua_pop(L, 1); | ||
667 | return 1; /* return 'package' table */ | ||
668 | } | ||
669 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lobject.c b/libraries/LuaJIT-1.1.7/src/lobject.c new file mode 100644 index 0000000..4ff5073 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lobject.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | ** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Some generic functions over Lua objects | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #include <ctype.h> | ||
8 | #include <stdarg.h> | ||
9 | #include <stdio.h> | ||
10 | #include <stdlib.h> | ||
11 | #include <string.h> | ||
12 | |||
13 | #define lobject_c | ||
14 | #define LUA_CORE | ||
15 | |||
16 | #include "lua.h" | ||
17 | |||
18 | #include "ldo.h" | ||
19 | #include "lmem.h" | ||
20 | #include "lobject.h" | ||
21 | #include "lstate.h" | ||
22 | #include "lstring.h" | ||
23 | #include "lvm.h" | ||
24 | |||
25 | |||
26 | |||
27 | const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; | ||
28 | |||
29 | |||
30 | /* | ||
31 | ** converts an integer to a "floating point byte", represented as | ||
32 | ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if | ||
33 | ** eeeee != 0 and (xxx) otherwise. | ||
34 | */ | ||
35 | int luaO_int2fb (unsigned int x) { | ||
36 | int e = 0; /* expoent */ | ||
37 | while (x >= 16) { | ||
38 | x = (x+1) >> 1; | ||
39 | e++; | ||
40 | } | ||
41 | if (x < 8) return x; | ||
42 | else return ((e+1) << 3) | (cast_int(x) - 8); | ||
43 | } | ||
44 | |||
45 | |||
46 | /* converts back */ | ||
47 | int luaO_fb2int (int x) { | ||
48 | int e = (x >> 3) & 31; | ||
49 | if (e == 0) return x; | ||
50 | else return ((x & 7)+8) << (e - 1); | ||
51 | } | ||
52 | |||
53 | |||
54 | int luaO_log2 (unsigned int x) { | ||
55 | static const lu_byte log_2[256] = { | ||
56 | 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, | ||
57 | 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, | ||
58 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, | ||
59 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, | ||
60 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, | ||
61 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, | ||
62 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, | ||
63 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 | ||
64 | }; | ||
65 | int l = -1; | ||
66 | while (x >= 256) { l += 8; x >>= 8; } | ||
67 | return l + log_2[x]; | ||
68 | |||
69 | } | ||
70 | |||
71 | |||
72 | int luaO_rawequalObj (const TValue *t1, const TValue *t2) { | ||
73 | if (ttype(t1) != ttype(t2)) return 0; | ||
74 | else switch (ttype(t1)) { | ||
75 | case LUA_TNIL: | ||
76 | return 1; | ||
77 | case LUA_TNUMBER: | ||
78 | return luai_numeq(nvalue(t1), nvalue(t2)); | ||
79 | case LUA_TBOOLEAN: | ||
80 | return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ | ||
81 | case LUA_TLIGHTUSERDATA: | ||
82 | return pvalue(t1) == pvalue(t2); | ||
83 | default: | ||
84 | lua_assert(iscollectable(t1)); | ||
85 | return gcvalue(t1) == gcvalue(t2); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | |||
90 | int luaO_str2d (const char *s, lua_Number *result) { | ||
91 | char *endptr; | ||
92 | *result = lua_str2number(s, &endptr); | ||
93 | if (endptr == s) return 0; /* conversion failed */ | ||
94 | if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ | ||
95 | *result = cast_num(strtoul(s, &endptr, 16)); | ||
96 | if (*endptr == '\0') return 1; /* most common case */ | ||
97 | while (isspace(cast(unsigned char, *endptr))) endptr++; | ||
98 | if (*endptr != '\0') return 0; /* invalid trailing characters? */ | ||
99 | return 1; | ||
100 | } | ||
101 | |||
102 | |||
103 | |||
104 | static void pushstr (lua_State *L, const char *str) { | ||
105 | setsvalue2s(L, L->top, luaS_new(L, str)); | ||
106 | incr_top(L); | ||
107 | } | ||
108 | |||
109 | |||
110 | /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ | ||
111 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | ||
112 | int n = 1; | ||
113 | pushstr(L, ""); | ||
114 | for (;;) { | ||
115 | const char *e = strchr(fmt, '%'); | ||
116 | if (e == NULL) break; | ||
117 | setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); | ||
118 | incr_top(L); | ||
119 | switch (*(e+1)) { | ||
120 | case 's': { | ||
121 | const char *s = va_arg(argp, char *); | ||
122 | if (s == NULL) s = "(null)"; | ||
123 | pushstr(L, s); | ||
124 | break; | ||
125 | } | ||
126 | case 'c': { | ||
127 | char buff[2]; | ||
128 | buff[0] = cast(char, va_arg(argp, int)); | ||
129 | buff[1] = '\0'; | ||
130 | pushstr(L, buff); | ||
131 | break; | ||
132 | } | ||
133 | case 'd': { | ||
134 | setnvalue(L->top, cast_num(va_arg(argp, int))); | ||
135 | incr_top(L); | ||
136 | break; | ||
137 | } | ||
138 | case 'f': { | ||
139 | setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); | ||
140 | incr_top(L); | ||
141 | break; | ||
142 | } | ||
143 | case 'p': { | ||
144 | char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ | ||
145 | sprintf(buff, "%p", va_arg(argp, void *)); | ||
146 | pushstr(L, buff); | ||
147 | break; | ||
148 | } | ||
149 | case '%': { | ||
150 | pushstr(L, "%"); | ||
151 | break; | ||
152 | } | ||
153 | default: { | ||
154 | char buff[3]; | ||
155 | buff[0] = '%'; | ||
156 | buff[1] = *(e+1); | ||
157 | buff[2] = '\0'; | ||
158 | pushstr(L, buff); | ||
159 | break; | ||
160 | } | ||
161 | } | ||
162 | n += 2; | ||
163 | fmt = e+2; | ||
164 | } | ||
165 | pushstr(L, fmt); | ||
166 | luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); | ||
167 | L->top -= n; | ||
168 | return svalue(L->top - 1); | ||
169 | } | ||
170 | |||
171 | |||
172 | const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { | ||
173 | const char *msg; | ||
174 | va_list argp; | ||
175 | va_start(argp, fmt); | ||
176 | msg = luaO_pushvfstring(L, fmt, argp); | ||
177 | va_end(argp); | ||
178 | return msg; | ||
179 | } | ||
180 | |||
181 | |||
182 | void luaO_chunkid (char *out, const char *source, size_t bufflen) { | ||
183 | if (*source == '=') { | ||
184 | strncpy(out, source+1, bufflen); /* remove first char */ | ||
185 | out[bufflen-1] = '\0'; /* ensures null termination */ | ||
186 | } | ||
187 | else { /* out = "source", or "...source" */ | ||
188 | if (*source == '@') { | ||
189 | size_t l; | ||
190 | source++; /* skip the `@' */ | ||
191 | bufflen -= sizeof(" '...' "); | ||
192 | l = strlen(source); | ||
193 | strcpy(out, ""); | ||
194 | if (l > bufflen) { | ||
195 | source += (l-bufflen); /* get last part of file name */ | ||
196 | strcat(out, "..."); | ||
197 | } | ||
198 | strcat(out, source); | ||
199 | } | ||
200 | else { /* out = [string "string"] */ | ||
201 | size_t len = strcspn(source, "\n\r"); /* stop at first newline */ | ||
202 | bufflen -= sizeof(" [string \"...\"] "); | ||
203 | if (len > bufflen) len = bufflen; | ||
204 | strcpy(out, "[string \""); | ||
205 | if (source[len] != '\0') { /* must truncate? */ | ||
206 | strncat(out, source, len); | ||
207 | strcat(out, "..."); | ||
208 | } | ||
209 | else | ||
210 | strcat(out, source); | ||
211 | strcat(out, "\"]"); | ||
212 | } | ||
213 | } | ||
214 | } | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lobject.h b/libraries/LuaJIT-1.1.7/src/lobject.h new file mode 100644 index 0000000..df9c528 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lobject.h | |||
@@ -0,0 +1,386 @@ | |||
1 | /* | ||
2 | ** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $ | ||
3 | ** Type definitions for Lua objects | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #ifndef lobject_h | ||
9 | #define lobject_h | ||
10 | |||
11 | |||
12 | #include <stdarg.h> | ||
13 | |||
14 | |||
15 | #include "llimits.h" | ||
16 | #include "lua.h" | ||
17 | |||
18 | |||
19 | /* tags for values visible from Lua */ | ||
20 | #define LAST_TAG LUA_TTHREAD | ||
21 | |||
22 | #define NUM_TAGS (LAST_TAG+1) | ||
23 | |||
24 | |||
25 | /* | ||
26 | ** Extra tags for non-values | ||
27 | */ | ||
28 | #define LUA_TPROTO (LAST_TAG+1) | ||
29 | #define LUA_TUPVAL (LAST_TAG+2) | ||
30 | #define LUA_TDEADKEY (LAST_TAG+3) | ||
31 | |||
32 | |||
33 | /* | ||
34 | ** Union of all collectable objects | ||
35 | */ | ||
36 | typedef union GCObject GCObject; | ||
37 | |||
38 | |||
39 | /* | ||
40 | ** Common Header for all collectable objects (in macro form, to be | ||
41 | ** included in other objects) | ||
42 | */ | ||
43 | #define CommonHeader GCObject *next; lu_byte tt; lu_byte marked | ||
44 | |||
45 | |||
46 | /* | ||
47 | ** Common header in struct form | ||
48 | */ | ||
49 | typedef struct GCheader { | ||
50 | CommonHeader; | ||
51 | } GCheader; | ||
52 | |||
53 | |||
54 | |||
55 | |||
56 | /* | ||
57 | ** Union of all Lua values | ||
58 | */ | ||
59 | typedef union { | ||
60 | GCObject *gc; | ||
61 | void *p; | ||
62 | lua_Number n; | ||
63 | ptrdiff_t na[sizeof(lua_Number)/sizeof(ptrdiff_t)]; /* LuaJIT kludge */ | ||
64 | int b; | ||
65 | } Value; | ||
66 | |||
67 | |||
68 | /* | ||
69 | ** Tagged Values | ||
70 | */ | ||
71 | |||
72 | #define TValuefields Value value; int tt | ||
73 | |||
74 | typedef struct lua_TValue { | ||
75 | TValuefields; | ||
76 | } LUA_TVALUE_ALIGN TValue; | ||
77 | |||
78 | |||
79 | /* Macros to test type */ | ||
80 | #define ttisnil(o) (ttype(o) == LUA_TNIL) | ||
81 | #define ttisnumber(o) (ttype(o) == LUA_TNUMBER) | ||
82 | #define ttisstring(o) (ttype(o) == LUA_TSTRING) | ||
83 | #define ttistable(o) (ttype(o) == LUA_TTABLE) | ||
84 | #define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) | ||
85 | #define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) | ||
86 | #define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) | ||
87 | #define ttisthread(o) (ttype(o) == LUA_TTHREAD) | ||
88 | #define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) | ||
89 | |||
90 | /* Macros to access values */ | ||
91 | #define ttype(o) ((o)->tt) | ||
92 | #define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) | ||
93 | #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) | ||
94 | #define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) | ||
95 | #define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) | ||
96 | #define tsvalue(o) (&rawtsvalue(o)->tsv) | ||
97 | #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) | ||
98 | #define uvalue(o) (&rawuvalue(o)->uv) | ||
99 | #define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) | ||
100 | #define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) | ||
101 | #define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) | ||
102 | #define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) | ||
103 | |||
104 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) | ||
105 | |||
106 | /* | ||
107 | ** for internal debug only | ||
108 | */ | ||
109 | #define checkconsistency(obj) \ | ||
110 | lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) | ||
111 | |||
112 | #define checkliveness(g,obj) \ | ||
113 | lua_assert(!iscollectable(obj) || \ | ||
114 | ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) | ||
115 | |||
116 | |||
117 | /* Macros to set values */ | ||
118 | #define setnilvalue(obj) ((obj)->tt=LUA_TNIL) | ||
119 | |||
120 | #define setnvalue(obj,x) \ | ||
121 | { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } | ||
122 | |||
123 | #define setpvalue(obj,x) \ | ||
124 | { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } | ||
125 | |||
126 | #define setbvalue(obj,x) \ | ||
127 | { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; } | ||
128 | |||
129 | #define setsvalue(L,obj,x) \ | ||
130 | { TValue *i_o=(obj); \ | ||
131 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \ | ||
132 | checkliveness(G(L),i_o); } | ||
133 | |||
134 | #define setuvalue(L,obj,x) \ | ||
135 | { TValue *i_o=(obj); \ | ||
136 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \ | ||
137 | checkliveness(G(L),i_o); } | ||
138 | |||
139 | #define setthvalue(L,obj,x) \ | ||
140 | { TValue *i_o=(obj); \ | ||
141 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \ | ||
142 | checkliveness(G(L),i_o); } | ||
143 | |||
144 | #define setclvalue(L,obj,x) \ | ||
145 | { TValue *i_o=(obj); \ | ||
146 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \ | ||
147 | checkliveness(G(L),i_o); } | ||
148 | |||
149 | #define sethvalue(L,obj,x) \ | ||
150 | { TValue *i_o=(obj); \ | ||
151 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \ | ||
152 | checkliveness(G(L),i_o); } | ||
153 | |||
154 | #define setptvalue(L,obj,x) \ | ||
155 | { TValue *i_o=(obj); \ | ||
156 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ | ||
157 | checkliveness(G(L),i_o); } | ||
158 | |||
159 | |||
160 | |||
161 | |||
162 | #define setobj(L,obj1,obj2) \ | ||
163 | { const TValue *o2=(obj2); TValue *o1=(obj1); \ | ||
164 | o1->value = o2->value; o1->tt=o2->tt; \ | ||
165 | checkliveness(G(L),o1); } | ||
166 | |||
167 | |||
168 | /* | ||
169 | ** different types of sets, according to destination | ||
170 | */ | ||
171 | |||
172 | /* from stack to (same) stack */ | ||
173 | #define setobjs2s setobj | ||
174 | /* to stack (not from same stack) */ | ||
175 | #define setobj2s setobj | ||
176 | #define setsvalue2s setsvalue | ||
177 | #define sethvalue2s sethvalue | ||
178 | #define setptvalue2s setptvalue | ||
179 | /* from table to same table */ | ||
180 | #define setobjt2t setobj | ||
181 | /* to table */ | ||
182 | #define setobj2t setobj | ||
183 | /* to new object */ | ||
184 | #define setobj2n setobj | ||
185 | #define setsvalue2n setsvalue | ||
186 | |||
187 | #define setttype(obj, tt) (ttype(obj) = (tt)) | ||
188 | |||
189 | |||
190 | #define iscollectable(o) (ttype(o) >= LUA_TSTRING) | ||
191 | |||
192 | |||
193 | |||
194 | typedef TValue *StkId; /* index to stack elements */ | ||
195 | |||
196 | |||
197 | /* | ||
198 | ** String headers for string table | ||
199 | */ | ||
200 | typedef union TString { | ||
201 | L_Umaxalign dummy; /* ensures maximum alignment for strings */ | ||
202 | struct { | ||
203 | CommonHeader; | ||
204 | lu_byte reserved; | ||
205 | unsigned int hash; | ||
206 | size_t len; | ||
207 | } tsv; | ||
208 | } TString; | ||
209 | |||
210 | |||
211 | #define getstr(ts) cast(const char *, (ts) + 1) | ||
212 | #define svalue(o) getstr(rawtsvalue(o)) | ||
213 | |||
214 | |||
215 | |||
216 | typedef union Udata { | ||
217 | L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ | ||
218 | struct { | ||
219 | CommonHeader; | ||
220 | struct Table *metatable; | ||
221 | struct Table *env; | ||
222 | size_t len; | ||
223 | } uv; | ||
224 | } Udata; | ||
225 | |||
226 | |||
227 | |||
228 | |||
229 | /* | ||
230 | ** Function Prototypes | ||
231 | */ | ||
232 | typedef struct Proto { | ||
233 | CommonHeader; | ||
234 | TValue *k; /* constants used by the function */ | ||
235 | Instruction *code; | ||
236 | struct Proto **p; /* functions defined inside the function */ | ||
237 | int *lineinfo; /* map from opcodes to source lines */ | ||
238 | struct LocVar *locvars; /* information about local variables */ | ||
239 | TString **upvalues; /* upvalue names */ | ||
240 | TString *source; | ||
241 | int sizeupvalues; | ||
242 | int sizek; /* size of `k' */ | ||
243 | int sizecode; | ||
244 | int sizelineinfo; | ||
245 | int sizep; /* size of `p' */ | ||
246 | int sizelocvars; | ||
247 | int linedefined; | ||
248 | int lastlinedefined; | ||
249 | GCObject *gclist; | ||
250 | lu_byte nups; /* number of upvalues */ | ||
251 | lu_byte numparams; | ||
252 | lu_byte is_vararg; | ||
253 | lu_byte maxstacksize; | ||
254 | /* LuaJIT extensions */ | ||
255 | void *jit_mcode; /* compiled machine code base address */ | ||
256 | size_t jit_szmcode; /* size of compiled mcode */ | ||
257 | int jit_status; /* JIT engine status code */ | ||
258 | } Proto; | ||
259 | |||
260 | |||
261 | /* masks for new-style vararg */ | ||
262 | #define VARARG_HASARG 1 | ||
263 | #define VARARG_ISVARARG 2 | ||
264 | #define VARARG_NEEDSARG 4 | ||
265 | |||
266 | |||
267 | typedef struct LocVar { | ||
268 | TString *varname; | ||
269 | int startpc; /* first point where variable is active */ | ||
270 | int endpc; /* first point where variable is dead */ | ||
271 | } LocVar; | ||
272 | |||
273 | |||
274 | |||
275 | /* | ||
276 | ** Upvalues | ||
277 | */ | ||
278 | |||
279 | typedef struct UpVal { | ||
280 | CommonHeader; | ||
281 | TValue *v; /* points to stack or to its own value */ | ||
282 | union { | ||
283 | TValue value; /* the value (when closed) */ | ||
284 | struct { /* double linked list (when open) */ | ||
285 | struct UpVal *prev; | ||
286 | struct UpVal *next; | ||
287 | } l; | ||
288 | } u; | ||
289 | } UpVal; | ||
290 | |||
291 | |||
292 | /* | ||
293 | ** Closures | ||
294 | */ | ||
295 | |||
296 | #define ClosureHeader \ | ||
297 | CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ | ||
298 | struct Table *env; lua_CFunction jit_gate | ||
299 | |||
300 | typedef struct CClosure { | ||
301 | ClosureHeader; | ||
302 | lua_CFunction f; | ||
303 | TValue upvalue[1]; | ||
304 | } CClosure; | ||
305 | |||
306 | |||
307 | typedef struct LClosure { | ||
308 | ClosureHeader; | ||
309 | struct Proto *p; | ||
310 | UpVal *upvals[1]; | ||
311 | } LClosure; | ||
312 | |||
313 | |||
314 | typedef union Closure { | ||
315 | CClosure c; | ||
316 | LClosure l; | ||
317 | } Closure; | ||
318 | |||
319 | |||
320 | #define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) | ||
321 | #define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) | ||
322 | |||
323 | |||
324 | /* | ||
325 | ** Tables | ||
326 | */ | ||
327 | |||
328 | typedef union TKey { | ||
329 | struct { | ||
330 | TValuefields; | ||
331 | struct Node *next; /* for chaining */ | ||
332 | } nk; | ||
333 | TValue tvk; | ||
334 | } TKey; | ||
335 | |||
336 | |||
337 | typedef struct Node { | ||
338 | TValue i_val; | ||
339 | TKey i_key; | ||
340 | } Node; | ||
341 | |||
342 | |||
343 | typedef struct Table { | ||
344 | CommonHeader; | ||
345 | lu_byte flags; /* 1<<p means tagmethod(p) is not present */ | ||
346 | lu_byte lsizenode; /* log2 of size of `node' array */ | ||
347 | struct Table *metatable; | ||
348 | TValue *array; /* array part */ | ||
349 | Node *node; | ||
350 | Node *lastfree; /* any free position is before this position */ | ||
351 | GCObject *gclist; | ||
352 | int sizearray; /* size of `array' array */ | ||
353 | } Table; | ||
354 | |||
355 | |||
356 | |||
357 | /* | ||
358 | ** `module' operation for hashing (size is always a power of 2) | ||
359 | */ | ||
360 | #define lmod(s,size) \ | ||
361 | (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1))))) | ||
362 | |||
363 | |||
364 | #define twoto(x) (1<<(x)) | ||
365 | #define sizenode(t) (twoto((t)->lsizenode)) | ||
366 | |||
367 | |||
368 | #define luaO_nilobject (&luaO_nilobject_) | ||
369 | |||
370 | LUAI_DATA const TValue luaO_nilobject_; | ||
371 | |||
372 | #define ceillog2(x) (luaO_log2((x)-1) + 1) | ||
373 | |||
374 | LUAI_FUNC int luaO_log2 (unsigned int x); | ||
375 | LUAI_FUNC int luaO_int2fb (unsigned int x); | ||
376 | LUAI_FUNC int luaO_fb2int (int x); | ||
377 | LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); | ||
378 | LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); | ||
379 | LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, | ||
380 | va_list argp); | ||
381 | LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); | ||
382 | LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); | ||
383 | |||
384 | |||
385 | #endif | ||
386 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lopcodes.c b/libraries/LuaJIT-1.1.7/src/lopcodes.c new file mode 100644 index 0000000..4cc7452 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lopcodes.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | ** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** See Copyright Notice in lua.h | ||
4 | */ | ||
5 | |||
6 | |||
7 | #define lopcodes_c | ||
8 | #define LUA_CORE | ||
9 | |||
10 | |||
11 | #include "lopcodes.h" | ||
12 | |||
13 | |||
14 | /* ORDER OP */ | ||
15 | |||
16 | const char *const luaP_opnames[NUM_OPCODES+1] = { | ||
17 | "MOVE", | ||
18 | "LOADK", | ||
19 | "LOADBOOL", | ||
20 | "LOADNIL", | ||
21 | "GETUPVAL", | ||
22 | "GETGLOBAL", | ||
23 | "GETTABLE", | ||
24 | "SETGLOBAL", | ||
25 | "SETUPVAL", | ||
26 | "SETTABLE", | ||
27 | "NEWTABLE", | ||
28 | "SELF", | ||
29 | "ADD", | ||
30 | "SUB", | ||
31 | "MUL", | ||
32 | "DIV", | ||
33 | "MOD", | ||
34 | "POW", | ||
35 | "UNM", | ||
36 | "NOT", | ||
37 | "LEN", | ||
38 | "CONCAT", | ||
39 | "JMP", | ||
40 | "EQ", | ||
41 | "LT", | ||
42 | "LE", | ||
43 | "TEST", | ||
44 | "TESTSET", | ||
45 | "CALL", | ||
46 | "TAILCALL", | ||
47 | "RETURN", | ||
48 | "FORLOOP", | ||
49 | "FORPREP", | ||
50 | "TFORLOOP", | ||
51 | "SETLIST", | ||
52 | "CLOSE", | ||
53 | "CLOSURE", | ||
54 | "VARARG", | ||
55 | NULL | ||
56 | }; | ||
57 | |||
58 | |||
59 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) | ||
60 | |||
61 | const lu_byte luaP_opmodes[NUM_OPCODES] = { | ||
62 | /* T A B C mode opcode */ | ||
63 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ | ||
64 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ | ||
65 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ | ||
66 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ | ||
67 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ | ||
68 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ | ||
69 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ | ||
70 | ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ | ||
71 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ | ||
72 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ | ||
73 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ | ||
74 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ | ||
75 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ | ||
76 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ | ||
77 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ | ||
78 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ | ||
79 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ | ||
80 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ | ||
81 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ | ||
82 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ | ||
83 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ | ||
84 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ | ||
85 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ | ||
86 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ | ||
87 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ | ||
88 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ | ||
89 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ | ||
90 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ | ||
91 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ | ||
92 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ | ||
93 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ | ||
94 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ | ||
95 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ | ||
96 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ | ||
97 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ | ||
98 | ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ | ||
99 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ | ||
100 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ | ||
101 | }; | ||
102 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lopcodes.h b/libraries/LuaJIT-1.1.7/src/lopcodes.h new file mode 100644 index 0000000..41224d6 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lopcodes.h | |||
@@ -0,0 +1,268 @@ | |||
1 | /* | ||
2 | ** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Opcodes for Lua virtual machine | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lopcodes_h | ||
8 | #define lopcodes_h | ||
9 | |||
10 | #include "llimits.h" | ||
11 | |||
12 | |||
13 | /*=========================================================================== | ||
14 | We assume that instructions are unsigned numbers. | ||
15 | All instructions have an opcode in the first 6 bits. | ||
16 | Instructions can have the following fields: | ||
17 | `A' : 8 bits | ||
18 | `B' : 9 bits | ||
19 | `C' : 9 bits | ||
20 | `Bx' : 18 bits (`B' and `C' together) | ||
21 | `sBx' : signed Bx | ||
22 | |||
23 | A signed argument is represented in excess K; that is, the number | ||
24 | value is the unsigned value minus K. K is exactly the maximum value | ||
25 | for that argument (so that -max is represented by 0, and +max is | ||
26 | represented by 2*max), which is half the maximum for the corresponding | ||
27 | unsigned argument. | ||
28 | ===========================================================================*/ | ||
29 | |||
30 | |||
31 | enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ | ||
32 | |||
33 | |||
34 | /* | ||
35 | ** size and position of opcode arguments. | ||
36 | */ | ||
37 | #define SIZE_C 9 | ||
38 | #define SIZE_B 9 | ||
39 | #define SIZE_Bx (SIZE_C + SIZE_B) | ||
40 | #define SIZE_A 8 | ||
41 | |||
42 | #define SIZE_OP 6 | ||
43 | |||
44 | #define POS_OP 0 | ||
45 | #define POS_A (POS_OP + SIZE_OP) | ||
46 | #define POS_C (POS_A + SIZE_A) | ||
47 | #define POS_B (POS_C + SIZE_C) | ||
48 | #define POS_Bx POS_C | ||
49 | |||
50 | |||
51 | /* | ||
52 | ** limits for opcode arguments. | ||
53 | ** we use (signed) int to manipulate most arguments, | ||
54 | ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) | ||
55 | */ | ||
56 | #if SIZE_Bx < LUAI_BITSINT-1 | ||
57 | #define MAXARG_Bx ((1<<SIZE_Bx)-1) | ||
58 | #define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */ | ||
59 | #else | ||
60 | #define MAXARG_Bx MAX_INT | ||
61 | #define MAXARG_sBx MAX_INT | ||
62 | #endif | ||
63 | |||
64 | |||
65 | #define MAXARG_A ((1<<SIZE_A)-1) | ||
66 | #define MAXARG_B ((1<<SIZE_B)-1) | ||
67 | #define MAXARG_C ((1<<SIZE_C)-1) | ||
68 | |||
69 | |||
70 | /* creates a mask with `n' 1 bits at position `p' */ | ||
71 | #define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p) | ||
72 | |||
73 | /* creates a mask with `n' 0 bits at position `p' */ | ||
74 | #define MASK0(n,p) (~MASK1(n,p)) | ||
75 | |||
76 | /* | ||
77 | ** the following macros help to manipulate instructions | ||
78 | */ | ||
79 | |||
80 | #define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0))) | ||
81 | #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ | ||
82 | ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP)))) | ||
83 | |||
84 | #define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0))) | ||
85 | #define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ | ||
86 | ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A)))) | ||
87 | |||
88 | #define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0))) | ||
89 | #define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ | ||
90 | ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B)))) | ||
91 | |||
92 | #define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0))) | ||
93 | #define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ | ||
94 | ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C)))) | ||
95 | |||
96 | #define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0))) | ||
97 | #define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ | ||
98 | ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx)))) | ||
99 | |||
100 | #define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx) | ||
101 | #define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx)) | ||
102 | |||
103 | |||
104 | #define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \ | ||
105 | | (cast(Instruction, a)<<POS_A) \ | ||
106 | | (cast(Instruction, b)<<POS_B) \ | ||
107 | | (cast(Instruction, c)<<POS_C)) | ||
108 | |||
109 | #define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \ | ||
110 | | (cast(Instruction, a)<<POS_A) \ | ||
111 | | (cast(Instruction, bc)<<POS_Bx)) | ||
112 | |||
113 | |||
114 | /* | ||
115 | ** Macros to operate RK indices | ||
116 | */ | ||
117 | |||
118 | /* this bit 1 means constant (0 means register) */ | ||
119 | #define BITRK (1 << (SIZE_B - 1)) | ||
120 | |||
121 | /* test whether value is a constant */ | ||
122 | #define ISK(x) ((x) & BITRK) | ||
123 | |||
124 | /* gets the index of the constant */ | ||
125 | #define INDEXK(r) ((int)(r) & ~BITRK) | ||
126 | |||
127 | #define MAXINDEXRK (BITRK - 1) | ||
128 | |||
129 | /* code a constant index as a RK value */ | ||
130 | #define RKASK(x) ((x) | BITRK) | ||
131 | |||
132 | |||
133 | /* | ||
134 | ** invalid register that fits in 8 bits | ||
135 | */ | ||
136 | #define NO_REG MAXARG_A | ||
137 | |||
138 | |||
139 | /* | ||
140 | ** R(x) - register | ||
141 | ** Kst(x) - constant (in constant table) | ||
142 | ** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x) | ||
143 | */ | ||
144 | |||
145 | |||
146 | /* | ||
147 | ** grep "ORDER OP" if you change these enums | ||
148 | */ | ||
149 | |||
150 | typedef enum { | ||
151 | /*---------------------------------------------------------------------- | ||
152 | name args description | ||
153 | ------------------------------------------------------------------------*/ | ||
154 | OP_MOVE,/* A B R(A) := R(B) */ | ||
155 | OP_LOADK,/* A Bx R(A) := Kst(Bx) */ | ||
156 | OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */ | ||
157 | OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ | ||
158 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ | ||
159 | |||
160 | OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */ | ||
161 | OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */ | ||
162 | |||
163 | OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */ | ||
164 | OP_SETUPVAL,/* A B UpValue[B] := R(A) */ | ||
165 | OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */ | ||
166 | |||
167 | OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */ | ||
168 | |||
169 | OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */ | ||
170 | |||
171 | OP_ADD,/* A B C R(A) := RK(B) + RK(C) */ | ||
172 | OP_SUB,/* A B C R(A) := RK(B) - RK(C) */ | ||
173 | OP_MUL,/* A B C R(A) := RK(B) * RK(C) */ | ||
174 | OP_DIV,/* A B C R(A) := RK(B) / RK(C) */ | ||
175 | OP_MOD,/* A B C R(A) := RK(B) % RK(C) */ | ||
176 | OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */ | ||
177 | OP_UNM,/* A B R(A) := -R(B) */ | ||
178 | OP_NOT,/* A B R(A) := not R(B) */ | ||
179 | OP_LEN,/* A B R(A) := length of R(B) */ | ||
180 | |||
181 | OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ | ||
182 | |||
183 | OP_JMP,/* sBx pc+=sBx */ | ||
184 | |||
185 | OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ | ||
186 | OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ | ||
187 | OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ | ||
188 | |||
189 | OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ | ||
190 | OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ | ||
191 | |||
192 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ | ||
193 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ | ||
194 | OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ | ||
195 | |||
196 | OP_FORLOOP,/* A sBx R(A)+=R(A+2); | ||
197 | if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/ | ||
198 | OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */ | ||
199 | |||
200 | OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); | ||
201 | if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */ | ||
202 | OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ | ||
203 | |||
204 | OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ | ||
205 | OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ | ||
206 | |||
207 | OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ | ||
208 | } OpCode; | ||
209 | |||
210 | |||
211 | #define NUM_OPCODES (cast(int, OP_VARARG) + 1) | ||
212 | |||
213 | |||
214 | |||
215 | /*=========================================================================== | ||
216 | Notes: | ||
217 | (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, | ||
218 | and can be 0: OP_CALL then sets `top' to last_result+1, so | ||
219 | next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. | ||
220 | |||
221 | (*) In OP_VARARG, if (B == 0) then use actual number of varargs and | ||
222 | set top (like in OP_CALL with C == 0). | ||
223 | |||
224 | (*) In OP_RETURN, if (B == 0) then return up to `top' | ||
225 | |||
226 | (*) In OP_SETLIST, if (B == 0) then B = `top'; | ||
227 | if (C == 0) then next `instruction' is real C | ||
228 | |||
229 | (*) For comparisons, A specifies what condition the test should accept | ||
230 | (true or false). | ||
231 | |||
232 | (*) All `skips' (pc++) assume that next instruction is a jump | ||
233 | ===========================================================================*/ | ||
234 | |||
235 | |||
236 | /* | ||
237 | ** masks for instruction properties. The format is: | ||
238 | ** bits 0-1: op mode | ||
239 | ** bits 2-3: C arg mode | ||
240 | ** bits 4-5: B arg mode | ||
241 | ** bit 6: instruction set register A | ||
242 | ** bit 7: operator is a test | ||
243 | */ | ||
244 | |||
245 | enum OpArgMask { | ||
246 | OpArgN, /* argument is not used */ | ||
247 | OpArgU, /* argument is used */ | ||
248 | OpArgR, /* argument is a register or a jump offset */ | ||
249 | OpArgK /* argument is a constant or register/constant */ | ||
250 | }; | ||
251 | |||
252 | LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; | ||
253 | |||
254 | #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) | ||
255 | #define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) | ||
256 | #define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) | ||
257 | #define testAMode(m) (luaP_opmodes[m] & (1 << 6)) | ||
258 | #define testTMode(m) (luaP_opmodes[m] & (1 << 7)) | ||
259 | |||
260 | |||
261 | LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ | ||
262 | |||
263 | |||
264 | /* number of list items to accumulate before a SETLIST instruction */ | ||
265 | #define LFIELDS_PER_FLUSH 50 | ||
266 | |||
267 | |||
268 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/loslib.c b/libraries/LuaJIT-1.1.7/src/loslib.c new file mode 100644 index 0000000..01a02a2 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/loslib.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | ** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ | ||
3 | ** Standard Operating System library | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <errno.h> | ||
9 | #include <locale.h> | ||
10 | #include <stdlib.h> | ||
11 | #include <string.h> | ||
12 | #include <time.h> | ||
13 | |||
14 | #define loslib_c | ||
15 | #define LUA_LIB | ||
16 | |||
17 | #include "lua.h" | ||
18 | |||
19 | #include "lauxlib.h" | ||
20 | #include "lualib.h" | ||
21 | |||
22 | |||
23 | static int os_pushresult (lua_State *L, int i, const char *filename) { | ||
24 | int en = errno; /* calls to Lua API may change this value */ | ||
25 | if (i) { | ||
26 | lua_pushboolean(L, 1); | ||
27 | return 1; | ||
28 | } | ||
29 | else { | ||
30 | lua_pushnil(L); | ||
31 | lua_pushfstring(L, "%s: %s", filename, strerror(en)); | ||
32 | lua_pushinteger(L, en); | ||
33 | return 3; | ||
34 | } | ||
35 | } | ||
36 | |||
37 | |||
38 | static int os_execute (lua_State *L) { | ||
39 | lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); | ||
40 | return 1; | ||
41 | } | ||
42 | |||
43 | |||
44 | static int os_remove (lua_State *L) { | ||
45 | const char *filename = luaL_checkstring(L, 1); | ||
46 | return os_pushresult(L, remove(filename) == 0, filename); | ||
47 | } | ||
48 | |||
49 | |||
50 | static int os_rename (lua_State *L) { | ||
51 | const char *fromname = luaL_checkstring(L, 1); | ||
52 | const char *toname = luaL_checkstring(L, 2); | ||
53 | return os_pushresult(L, rename(fromname, toname) == 0, fromname); | ||
54 | } | ||
55 | |||
56 | |||
57 | static int os_tmpname (lua_State *L) { | ||
58 | char buff[LUA_TMPNAMBUFSIZE]; | ||
59 | int err; | ||
60 | lua_tmpnam(buff, err); | ||
61 | if (err) | ||
62 | return luaL_error(L, "unable to generate a unique filename"); | ||
63 | lua_pushstring(L, buff); | ||
64 | return 1; | ||
65 | } | ||
66 | |||
67 | |||
68 | static int os_getenv (lua_State *L) { | ||
69 | lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ | ||
70 | return 1; | ||
71 | } | ||
72 | |||
73 | |||
74 | static int os_clock (lua_State *L) { | ||
75 | lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); | ||
76 | return 1; | ||
77 | } | ||
78 | |||
79 | |||
80 | /* | ||
81 | ** {====================================================== | ||
82 | ** Time/Date operations | ||
83 | ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, | ||
84 | ** wday=%w+1, yday=%j, isdst=? } | ||
85 | ** ======================================================= | ||
86 | */ | ||
87 | |||
88 | static void setfield (lua_State *L, const char *key, int value) { | ||
89 | lua_pushinteger(L, value); | ||
90 | lua_setfield(L, -2, key); | ||
91 | } | ||
92 | |||
93 | static void setboolfield (lua_State *L, const char *key, int value) { | ||
94 | if (value < 0) /* undefined? */ | ||
95 | return; /* does not set field */ | ||
96 | lua_pushboolean(L, value); | ||
97 | lua_setfield(L, -2, key); | ||
98 | } | ||
99 | |||
100 | static int getboolfield (lua_State *L, const char *key) { | ||
101 | int res; | ||
102 | lua_getfield(L, -1, key); | ||
103 | res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); | ||
104 | lua_pop(L, 1); | ||
105 | return res; | ||
106 | } | ||
107 | |||
108 | |||
109 | static int getfield (lua_State *L, const char *key, int d) { | ||
110 | int res; | ||
111 | lua_getfield(L, -1, key); | ||
112 | if (lua_isnumber(L, -1)) | ||
113 | res = (int)lua_tointeger(L, -1); | ||
114 | else { | ||
115 | if (d < 0) | ||
116 | return luaL_error(L, "field " LUA_QS " missing in date table", key); | ||
117 | res = d; | ||
118 | } | ||
119 | lua_pop(L, 1); | ||
120 | return res; | ||
121 | } | ||
122 | |||
123 | |||
124 | static int os_date (lua_State *L) { | ||
125 | const char *s = luaL_optstring(L, 1, "%c"); | ||
126 | time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); | ||
127 | struct tm *stm; | ||
128 | if (*s == '!') { /* UTC? */ | ||
129 | stm = gmtime(&t); | ||
130 | s++; /* skip `!' */ | ||
131 | } | ||
132 | else | ||
133 | stm = localtime(&t); | ||
134 | if (stm == NULL) /* invalid date? */ | ||
135 | lua_pushnil(L); | ||
136 | else if (strcmp(s, "*t") == 0) { | ||
137 | lua_createtable(L, 0, 9); /* 9 = number of fields */ | ||
138 | setfield(L, "sec", stm->tm_sec); | ||
139 | setfield(L, "min", stm->tm_min); | ||
140 | setfield(L, "hour", stm->tm_hour); | ||
141 | setfield(L, "day", stm->tm_mday); | ||
142 | setfield(L, "month", stm->tm_mon+1); | ||
143 | setfield(L, "year", stm->tm_year+1900); | ||
144 | setfield(L, "wday", stm->tm_wday+1); | ||
145 | setfield(L, "yday", stm->tm_yday+1); | ||
146 | setboolfield(L, "isdst", stm->tm_isdst); | ||
147 | } | ||
148 | else { | ||
149 | char cc[3]; | ||
150 | luaL_Buffer b; | ||
151 | cc[0] = '%'; cc[2] = '\0'; | ||
152 | luaL_buffinit(L, &b); | ||
153 | for (; *s; s++) { | ||
154 | if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ | ||
155 | luaL_addchar(&b, *s); | ||
156 | else { | ||
157 | size_t reslen; | ||
158 | char buff[200]; /* should be big enough for any conversion result */ | ||
159 | cc[1] = *(++s); | ||
160 | reslen = strftime(buff, sizeof(buff), cc, stm); | ||
161 | luaL_addlstring(&b, buff, reslen); | ||
162 | } | ||
163 | } | ||
164 | luaL_pushresult(&b); | ||
165 | } | ||
166 | return 1; | ||
167 | } | ||
168 | |||
169 | |||
170 | static int os_time (lua_State *L) { | ||
171 | time_t t; | ||
172 | if (lua_isnoneornil(L, 1)) /* called without args? */ | ||
173 | t = time(NULL); /* get current time */ | ||
174 | else { | ||
175 | struct tm ts; | ||
176 | luaL_checktype(L, 1, LUA_TTABLE); | ||
177 | lua_settop(L, 1); /* make sure table is at the top */ | ||
178 | ts.tm_sec = getfield(L, "sec", 0); | ||
179 | ts.tm_min = getfield(L, "min", 0); | ||
180 | ts.tm_hour = getfield(L, "hour", 12); | ||
181 | ts.tm_mday = getfield(L, "day", -1); | ||
182 | ts.tm_mon = getfield(L, "month", -1) - 1; | ||
183 | ts.tm_year = getfield(L, "year", -1) - 1900; | ||
184 | ts.tm_isdst = getboolfield(L, "isdst"); | ||
185 | t = mktime(&ts); | ||
186 | } | ||
187 | if (t == (time_t)(-1)) | ||
188 | lua_pushnil(L); | ||
189 | else | ||
190 | lua_pushnumber(L, (lua_Number)t); | ||
191 | return 1; | ||
192 | } | ||
193 | |||
194 | |||
195 | static int os_difftime (lua_State *L) { | ||
196 | lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), | ||
197 | (time_t)(luaL_optnumber(L, 2, 0)))); | ||
198 | return 1; | ||
199 | } | ||
200 | |||
201 | /* }====================================================== */ | ||
202 | |||
203 | |||
204 | static int os_setlocale (lua_State *L) { | ||
205 | static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, | ||
206 | LC_NUMERIC, LC_TIME}; | ||
207 | static const char *const catnames[] = {"all", "collate", "ctype", "monetary", | ||
208 | "numeric", "time", NULL}; | ||
209 | const char *l = luaL_optstring(L, 1, NULL); | ||
210 | int op = luaL_checkoption(L, 2, "all", catnames); | ||
211 | lua_pushstring(L, setlocale(cat[op], l)); | ||
212 | return 1; | ||
213 | } | ||
214 | |||
215 | |||
216 | static int os_exit (lua_State *L) { | ||
217 | exit(luaL_optint(L, 1, EXIT_SUCCESS)); | ||
218 | return 0; /* to avoid warnings */ | ||
219 | } | ||
220 | |||
221 | static const luaL_Reg syslib[] = { | ||
222 | {"clock", os_clock}, | ||
223 | {"date", os_date}, | ||
224 | {"difftime", os_difftime}, | ||
225 | {"execute", os_execute}, | ||
226 | {"exit", os_exit}, | ||
227 | {"getenv", os_getenv}, | ||
228 | {"remove", os_remove}, | ||
229 | {"rename", os_rename}, | ||
230 | {"setlocale", os_setlocale}, | ||
231 | {"time", os_time}, | ||
232 | {"tmpname", os_tmpname}, | ||
233 | {NULL, NULL} | ||
234 | }; | ||
235 | |||
236 | /* }====================================================== */ | ||
237 | |||
238 | |||
239 | |||
240 | LUALIB_API int luaopen_os (lua_State *L) { | ||
241 | luaL_register(L, LUA_OSLIBNAME, syslib); | ||
242 | return 1; | ||
243 | } | ||
244 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lparser.c b/libraries/LuaJIT-1.1.7/src/lparser.c new file mode 100644 index 0000000..1e2a9a8 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lparser.c | |||
@@ -0,0 +1,1339 @@ | |||
1 | /* | ||
2 | ** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $ | ||
3 | ** Lua Parser | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <string.h> | ||
9 | |||
10 | #define lparser_c | ||
11 | #define LUA_CORE | ||
12 | |||
13 | #include "lua.h" | ||
14 | |||
15 | #include "lcode.h" | ||
16 | #include "ldebug.h" | ||
17 | #include "ldo.h" | ||
18 | #include "lfunc.h" | ||
19 | #include "llex.h" | ||
20 | #include "lmem.h" | ||
21 | #include "lobject.h" | ||
22 | #include "lopcodes.h" | ||
23 | #include "lparser.h" | ||
24 | #include "lstate.h" | ||
25 | #include "lstring.h" | ||
26 | #include "ltable.h" | ||
27 | |||
28 | |||
29 | |||
30 | #define hasmultret(k) ((k) == VCALL || (k) == VVARARG) | ||
31 | |||
32 | #define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) | ||
33 | |||
34 | #define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) | ||
35 | |||
36 | |||
37 | /* | ||
38 | ** nodes for block list (list of active blocks) | ||
39 | */ | ||
40 | typedef struct BlockCnt { | ||
41 | struct BlockCnt *previous; /* chain */ | ||
42 | int breaklist; /* list of jumps out of this loop */ | ||
43 | lu_byte nactvar; /* # active locals outside the breakable structure */ | ||
44 | lu_byte upval; /* true if some variable in the block is an upvalue */ | ||
45 | lu_byte isbreakable; /* true if `block' is a loop */ | ||
46 | } BlockCnt; | ||
47 | |||
48 | |||
49 | |||
50 | /* | ||
51 | ** prototypes for recursive non-terminal functions | ||
52 | */ | ||
53 | static void chunk (LexState *ls); | ||
54 | static void expr (LexState *ls, expdesc *v); | ||
55 | |||
56 | |||
57 | static void anchor_token (LexState *ls) { | ||
58 | if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { | ||
59 | TString *ts = ls->t.seminfo.ts; | ||
60 | luaX_newstring(ls, getstr(ts), ts->tsv.len); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | |||
65 | static void error_expected (LexState *ls, int token) { | ||
66 | luaX_syntaxerror(ls, | ||
67 | luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); | ||
68 | } | ||
69 | |||
70 | |||
71 | static void errorlimit (FuncState *fs, int limit, const char *what) { | ||
72 | const char *msg = (fs->f->linedefined == 0) ? | ||
73 | luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : | ||
74 | luaO_pushfstring(fs->L, "function at line %d has more than %d %s", | ||
75 | fs->f->linedefined, limit, what); | ||
76 | luaX_lexerror(fs->ls, msg, 0); | ||
77 | } | ||
78 | |||
79 | |||
80 | static int testnext (LexState *ls, int c) { | ||
81 | if (ls->t.token == c) { | ||
82 | luaX_next(ls); | ||
83 | return 1; | ||
84 | } | ||
85 | else return 0; | ||
86 | } | ||
87 | |||
88 | |||
89 | static void check (LexState *ls, int c) { | ||
90 | if (ls->t.token != c) | ||
91 | error_expected(ls, c); | ||
92 | } | ||
93 | |||
94 | static void checknext (LexState *ls, int c) { | ||
95 | check(ls, c); | ||
96 | luaX_next(ls); | ||
97 | } | ||
98 | |||
99 | |||
100 | #define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } | ||
101 | |||
102 | |||
103 | |||
104 | static void check_match (LexState *ls, int what, int who, int where) { | ||
105 | if (!testnext(ls, what)) { | ||
106 | if (where == ls->linenumber) | ||
107 | error_expected(ls, what); | ||
108 | else { | ||
109 | luaX_syntaxerror(ls, luaO_pushfstring(ls->L, | ||
110 | LUA_QS " expected (to close " LUA_QS " at line %d)", | ||
111 | luaX_token2str(ls, what), luaX_token2str(ls, who), where)); | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | |||
116 | |||
117 | static TString *str_checkname (LexState *ls) { | ||
118 | TString *ts; | ||
119 | check(ls, TK_NAME); | ||
120 | ts = ls->t.seminfo.ts; | ||
121 | luaX_next(ls); | ||
122 | return ts; | ||
123 | } | ||
124 | |||
125 | |||
126 | static void init_exp (expdesc *e, expkind k, int i) { | ||
127 | e->f = e->t = NO_JUMP; | ||
128 | e->k = k; | ||
129 | e->u.s.info = i; | ||
130 | } | ||
131 | |||
132 | |||
133 | static void codestring (LexState *ls, expdesc *e, TString *s) { | ||
134 | init_exp(e, VK, luaK_stringK(ls->fs, s)); | ||
135 | } | ||
136 | |||
137 | |||
138 | static void checkname(LexState *ls, expdesc *e) { | ||
139 | codestring(ls, e, str_checkname(ls)); | ||
140 | } | ||
141 | |||
142 | |||
143 | static int registerlocalvar (LexState *ls, TString *varname) { | ||
144 | FuncState *fs = ls->fs; | ||
145 | Proto *f = fs->f; | ||
146 | int oldsize = f->sizelocvars; | ||
147 | luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, | ||
148 | LocVar, SHRT_MAX, "too many local variables"); | ||
149 | while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; | ||
150 | f->locvars[fs->nlocvars].varname = varname; | ||
151 | luaC_objbarrier(ls->L, f, varname); | ||
152 | return fs->nlocvars++; | ||
153 | } | ||
154 | |||
155 | |||
156 | #define new_localvarliteral(ls,v,n) \ | ||
157 | new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) | ||
158 | |||
159 | |||
160 | static void new_localvar (LexState *ls, TString *name, int n) { | ||
161 | FuncState *fs = ls->fs; | ||
162 | luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); | ||
163 | fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); | ||
164 | } | ||
165 | |||
166 | |||
167 | static void adjustlocalvars (LexState *ls, int nvars) { | ||
168 | FuncState *fs = ls->fs; | ||
169 | fs->nactvar = cast_byte(fs->nactvar + nvars); | ||
170 | for (; nvars; nvars--) { | ||
171 | getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | |||
176 | static void removevars (LexState *ls, int tolevel) { | ||
177 | FuncState *fs = ls->fs; | ||
178 | while (fs->nactvar > tolevel) | ||
179 | getlocvar(fs, --fs->nactvar).endpc = fs->pc; | ||
180 | } | ||
181 | |||
182 | |||
183 | static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { | ||
184 | int i; | ||
185 | Proto *f = fs->f; | ||
186 | int oldsize = f->sizeupvalues; | ||
187 | for (i=0; i<f->nups; i++) { | ||
188 | if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { | ||
189 | lua_assert(f->upvalues[i] == name); | ||
190 | return i; | ||
191 | } | ||
192 | } | ||
193 | /* new one */ | ||
194 | luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); | ||
195 | luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, | ||
196 | TString *, MAX_INT, ""); | ||
197 | while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; | ||
198 | f->upvalues[f->nups] = name; | ||
199 | luaC_objbarrier(fs->L, f, name); | ||
200 | lua_assert(v->k == VLOCAL || v->k == VUPVAL); | ||
201 | fs->upvalues[f->nups].k = cast_byte(v->k); | ||
202 | fs->upvalues[f->nups].info = cast_byte(v->u.s.info); | ||
203 | return f->nups++; | ||
204 | } | ||
205 | |||
206 | |||
207 | static int searchvar (FuncState *fs, TString *n) { | ||
208 | int i; | ||
209 | for (i=fs->nactvar-1; i >= 0; i--) { | ||
210 | if (n == getlocvar(fs, i).varname) | ||
211 | return i; | ||
212 | } | ||
213 | return -1; /* not found */ | ||
214 | } | ||
215 | |||
216 | |||
217 | static void markupval (FuncState *fs, int level) { | ||
218 | BlockCnt *bl = fs->bl; | ||
219 | while (bl && bl->nactvar > level) bl = bl->previous; | ||
220 | if (bl) bl->upval = 1; | ||
221 | } | ||
222 | |||
223 | |||
224 | static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | ||
225 | if (fs == NULL) { /* no more levels? */ | ||
226 | init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ | ||
227 | return VGLOBAL; | ||
228 | } | ||
229 | else { | ||
230 | int v = searchvar(fs, n); /* look up at current level */ | ||
231 | if (v >= 0) { | ||
232 | init_exp(var, VLOCAL, v); | ||
233 | if (!base) | ||
234 | markupval(fs, v); /* local will be used as an upval */ | ||
235 | return VLOCAL; | ||
236 | } | ||
237 | else { /* not found at current level; try upper one */ | ||
238 | if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) | ||
239 | return VGLOBAL; | ||
240 | var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ | ||
241 | var->k = VUPVAL; /* upvalue in this level */ | ||
242 | return VUPVAL; | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | |||
247 | |||
248 | static void singlevar (LexState *ls, expdesc *var) { | ||
249 | TString *varname = str_checkname(ls); | ||
250 | FuncState *fs = ls->fs; | ||
251 | if (singlevaraux(fs, varname, var, 1) == VGLOBAL) | ||
252 | var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ | ||
253 | } | ||
254 | |||
255 | |||
256 | static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { | ||
257 | FuncState *fs = ls->fs; | ||
258 | int extra = nvars - nexps; | ||
259 | if (hasmultret(e->k)) { | ||
260 | extra++; /* includes call itself */ | ||
261 | if (extra < 0) extra = 0; | ||
262 | luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ | ||
263 | if (extra > 1) luaK_reserveregs(fs, extra-1); | ||
264 | } | ||
265 | else { | ||
266 | if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ | ||
267 | if (extra > 0) { | ||
268 | int reg = fs->freereg; | ||
269 | luaK_reserveregs(fs, extra); | ||
270 | luaK_nil(fs, reg, extra); | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | |||
275 | |||
276 | static void enterlevel (LexState *ls) { | ||
277 | if (++ls->L->nCcalls > LUAI_MAXCCALLS) | ||
278 | luaX_lexerror(ls, "chunk has too many syntax levels", 0); | ||
279 | } | ||
280 | |||
281 | |||
282 | #define leavelevel(ls) ((ls)->L->nCcalls--) | ||
283 | |||
284 | |||
285 | static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { | ||
286 | bl->breaklist = NO_JUMP; | ||
287 | bl->isbreakable = isbreakable; | ||
288 | bl->nactvar = fs->nactvar; | ||
289 | bl->upval = 0; | ||
290 | bl->previous = fs->bl; | ||
291 | fs->bl = bl; | ||
292 | lua_assert(fs->freereg == fs->nactvar); | ||
293 | } | ||
294 | |||
295 | |||
296 | static void leaveblock (FuncState *fs) { | ||
297 | BlockCnt *bl = fs->bl; | ||
298 | fs->bl = bl->previous; | ||
299 | removevars(fs->ls, bl->nactvar); | ||
300 | if (bl->upval) | ||
301 | luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); | ||
302 | /* a block either controls scope or breaks (never both) */ | ||
303 | lua_assert(!bl->isbreakable || !bl->upval); | ||
304 | lua_assert(bl->nactvar == fs->nactvar); | ||
305 | fs->freereg = fs->nactvar; /* free registers */ | ||
306 | luaK_patchtohere(fs, bl->breaklist); | ||
307 | } | ||
308 | |||
309 | |||
310 | static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { | ||
311 | FuncState *fs = ls->fs; | ||
312 | Proto *f = fs->f; | ||
313 | int oldsize = f->sizep; | ||
314 | int i; | ||
315 | luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, | ||
316 | MAXARG_Bx, "constant table overflow"); | ||
317 | while (oldsize < f->sizep) f->p[oldsize++] = NULL; | ||
318 | f->p[fs->np++] = func->f; | ||
319 | luaC_objbarrier(ls->L, f, func->f); | ||
320 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); | ||
321 | for (i=0; i<func->f->nups; i++) { | ||
322 | OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; | ||
323 | luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | |||
328 | static void open_func (LexState *ls, FuncState *fs) { | ||
329 | lua_State *L = ls->L; | ||
330 | Proto *f = luaF_newproto(L); | ||
331 | fs->f = f; | ||
332 | fs->prev = ls->fs; /* linked list of funcstates */ | ||
333 | fs->ls = ls; | ||
334 | fs->L = L; | ||
335 | ls->fs = fs; | ||
336 | fs->pc = 0; | ||
337 | fs->lasttarget = -1; | ||
338 | fs->jpc = NO_JUMP; | ||
339 | fs->freereg = 0; | ||
340 | fs->nk = 0; | ||
341 | fs->np = 0; | ||
342 | fs->nlocvars = 0; | ||
343 | fs->nactvar = 0; | ||
344 | fs->bl = NULL; | ||
345 | f->source = ls->source; | ||
346 | f->maxstacksize = 2; /* registers 0/1 are always valid */ | ||
347 | fs->h = luaH_new(L, 0, 0); | ||
348 | /* anchor table of constants and prototype (to avoid being collected) */ | ||
349 | sethvalue2s(L, L->top, fs->h); | ||
350 | incr_top(L); | ||
351 | setptvalue2s(L, L->top, f); | ||
352 | incr_top(L); | ||
353 | } | ||
354 | |||
355 | |||
356 | static void close_func (LexState *ls) { | ||
357 | lua_State *L = ls->L; | ||
358 | FuncState *fs = ls->fs; | ||
359 | Proto *f = fs->f; | ||
360 | removevars(ls, 0); | ||
361 | luaK_ret(fs, 0, 0); /* final return */ | ||
362 | luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); | ||
363 | f->sizecode = fs->pc; | ||
364 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); | ||
365 | f->sizelineinfo = fs->pc; | ||
366 | luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); | ||
367 | f->sizek = fs->nk; | ||
368 | luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); | ||
369 | f->sizep = fs->np; | ||
370 | luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); | ||
371 | f->sizelocvars = fs->nlocvars; | ||
372 | luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); | ||
373 | f->sizeupvalues = f->nups; | ||
374 | lua_assert(luaG_checkcode(f)); | ||
375 | lua_assert(fs->bl == NULL); | ||
376 | ls->fs = fs->prev; | ||
377 | L->top -= 2; /* remove table and prototype from the stack */ | ||
378 | /* last token read was anchored in defunct function; must reanchor it */ | ||
379 | if (fs) anchor_token(ls); | ||
380 | } | ||
381 | |||
382 | |||
383 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { | ||
384 | struct LexState lexstate; | ||
385 | struct FuncState funcstate; | ||
386 | lexstate.buff = buff; | ||
387 | luaX_setinput(L, &lexstate, z, luaS_new(L, name)); | ||
388 | open_func(&lexstate, &funcstate); | ||
389 | funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ | ||
390 | luaX_next(&lexstate); /* read first token */ | ||
391 | chunk(&lexstate); | ||
392 | check(&lexstate, TK_EOS); | ||
393 | close_func(&lexstate); | ||
394 | lua_assert(funcstate.prev == NULL); | ||
395 | lua_assert(funcstate.f->nups == 0); | ||
396 | lua_assert(lexstate.fs == NULL); | ||
397 | return funcstate.f; | ||
398 | } | ||
399 | |||
400 | |||
401 | |||
402 | /*============================================================*/ | ||
403 | /* GRAMMAR RULES */ | ||
404 | /*============================================================*/ | ||
405 | |||
406 | |||
407 | static void field (LexState *ls, expdesc *v) { | ||
408 | /* field -> ['.' | ':'] NAME */ | ||
409 | FuncState *fs = ls->fs; | ||
410 | expdesc key; | ||
411 | luaK_exp2anyreg(fs, v); | ||
412 | luaX_next(ls); /* skip the dot or colon */ | ||
413 | checkname(ls, &key); | ||
414 | luaK_indexed(fs, v, &key); | ||
415 | } | ||
416 | |||
417 | |||
418 | static void yindex (LexState *ls, expdesc *v) { | ||
419 | /* index -> '[' expr ']' */ | ||
420 | luaX_next(ls); /* skip the '[' */ | ||
421 | expr(ls, v); | ||
422 | luaK_exp2val(ls->fs, v); | ||
423 | checknext(ls, ']'); | ||
424 | } | ||
425 | |||
426 | |||
427 | /* | ||
428 | ** {====================================================================== | ||
429 | ** Rules for Constructors | ||
430 | ** ======================================================================= | ||
431 | */ | ||
432 | |||
433 | |||
434 | struct ConsControl { | ||
435 | expdesc v; /* last list item read */ | ||
436 | expdesc *t; /* table descriptor */ | ||
437 | int nh; /* total number of `record' elements */ | ||
438 | int na; /* total number of array elements */ | ||
439 | int tostore; /* number of array elements pending to be stored */ | ||
440 | }; | ||
441 | |||
442 | |||
443 | static void recfield (LexState *ls, struct ConsControl *cc) { | ||
444 | /* recfield -> (NAME | `['exp1`]') = exp1 */ | ||
445 | FuncState *fs = ls->fs; | ||
446 | int reg = ls->fs->freereg; | ||
447 | expdesc key, val; | ||
448 | int rkkey; | ||
449 | if (ls->t.token == TK_NAME) { | ||
450 | luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); | ||
451 | checkname(ls, &key); | ||
452 | } | ||
453 | else /* ls->t.token == '[' */ | ||
454 | yindex(ls, &key); | ||
455 | cc->nh++; | ||
456 | checknext(ls, '='); | ||
457 | rkkey = luaK_exp2RK(fs, &key); | ||
458 | expr(ls, &val); | ||
459 | luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); | ||
460 | fs->freereg = reg; /* free registers */ | ||
461 | } | ||
462 | |||
463 | |||
464 | static void closelistfield (FuncState *fs, struct ConsControl *cc) { | ||
465 | if (cc->v.k == VVOID) return; /* there is no list item */ | ||
466 | luaK_exp2nextreg(fs, &cc->v); | ||
467 | cc->v.k = VVOID; | ||
468 | if (cc->tostore == LFIELDS_PER_FLUSH) { | ||
469 | luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ | ||
470 | cc->tostore = 0; /* no more items pending */ | ||
471 | } | ||
472 | } | ||
473 | |||
474 | |||
475 | static void lastlistfield (FuncState *fs, struct ConsControl *cc) { | ||
476 | if (cc->tostore == 0) return; | ||
477 | if (hasmultret(cc->v.k)) { | ||
478 | luaK_setmultret(fs, &cc->v); | ||
479 | luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET); | ||
480 | cc->na--; /* do not count last expression (unknown number of elements) */ | ||
481 | } | ||
482 | else { | ||
483 | if (cc->v.k != VVOID) | ||
484 | luaK_exp2nextreg(fs, &cc->v); | ||
485 | luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); | ||
486 | } | ||
487 | } | ||
488 | |||
489 | |||
490 | static void listfield (LexState *ls, struct ConsControl *cc) { | ||
491 | expr(ls, &cc->v); | ||
492 | luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); | ||
493 | cc->na++; | ||
494 | cc->tostore++; | ||
495 | } | ||
496 | |||
497 | |||
498 | static void constructor (LexState *ls, expdesc *t) { | ||
499 | /* constructor -> ?? */ | ||
500 | FuncState *fs = ls->fs; | ||
501 | int line = ls->linenumber; | ||
502 | int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); | ||
503 | struct ConsControl cc; | ||
504 | cc.na = cc.nh = cc.tostore = 0; | ||
505 | cc.t = t; | ||
506 | init_exp(t, VRELOCABLE, pc); | ||
507 | init_exp(&cc.v, VVOID, 0); /* no value (yet) */ | ||
508 | luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ | ||
509 | checknext(ls, '{'); | ||
510 | do { | ||
511 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); | ||
512 | if (ls->t.token == '}') break; | ||
513 | closelistfield(fs, &cc); | ||
514 | switch(ls->t.token) { | ||
515 | case TK_NAME: { /* may be listfields or recfields */ | ||
516 | luaX_lookahead(ls); | ||
517 | if (ls->lookahead.token != '=') /* expression? */ | ||
518 | listfield(ls, &cc); | ||
519 | else | ||
520 | recfield(ls, &cc); | ||
521 | break; | ||
522 | } | ||
523 | case '[': { /* constructor_item -> recfield */ | ||
524 | recfield(ls, &cc); | ||
525 | break; | ||
526 | } | ||
527 | default: { /* constructor_part -> listfield */ | ||
528 | listfield(ls, &cc); | ||
529 | break; | ||
530 | } | ||
531 | } | ||
532 | } while (testnext(ls, ',') || testnext(ls, ';')); | ||
533 | check_match(ls, '}', '{', line); | ||
534 | lastlistfield(fs, &cc); | ||
535 | SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ | ||
536 | SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ | ||
537 | } | ||
538 | |||
539 | /* }====================================================================== */ | ||
540 | |||
541 | |||
542 | |||
543 | static void parlist (LexState *ls) { | ||
544 | /* parlist -> [ param { `,' param } ] */ | ||
545 | FuncState *fs = ls->fs; | ||
546 | Proto *f = fs->f; | ||
547 | int nparams = 0; | ||
548 | f->is_vararg = 0; | ||
549 | if (ls->t.token != ')') { /* is `parlist' not empty? */ | ||
550 | do { | ||
551 | switch (ls->t.token) { | ||
552 | case TK_NAME: { /* param -> NAME */ | ||
553 | new_localvar(ls, str_checkname(ls), nparams++); | ||
554 | break; | ||
555 | } | ||
556 | case TK_DOTS: { /* param -> `...' */ | ||
557 | luaX_next(ls); | ||
558 | #if defined(LUA_COMPAT_VARARG) | ||
559 | /* use `arg' as default name */ | ||
560 | new_localvarliteral(ls, "arg", nparams++); | ||
561 | f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG; | ||
562 | #endif | ||
563 | f->is_vararg |= VARARG_ISVARARG; | ||
564 | break; | ||
565 | } | ||
566 | default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected"); | ||
567 | } | ||
568 | } while (!f->is_vararg && testnext(ls, ',')); | ||
569 | } | ||
570 | adjustlocalvars(ls, nparams); | ||
571 | f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); | ||
572 | luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ | ||
573 | } | ||
574 | |||
575 | |||
576 | static void body (LexState *ls, expdesc *e, int needself, int line) { | ||
577 | /* body -> `(' parlist `)' chunk END */ | ||
578 | FuncState new_fs; | ||
579 | open_func(ls, &new_fs); | ||
580 | new_fs.f->linedefined = line; | ||
581 | checknext(ls, '('); | ||
582 | if (needself) { | ||
583 | new_localvarliteral(ls, "self", 0); | ||
584 | adjustlocalvars(ls, 1); | ||
585 | } | ||
586 | parlist(ls); | ||
587 | checknext(ls, ')'); | ||
588 | chunk(ls); | ||
589 | new_fs.f->lastlinedefined = ls->linenumber; | ||
590 | check_match(ls, TK_END, TK_FUNCTION, line); | ||
591 | close_func(ls); | ||
592 | pushclosure(ls, &new_fs, e); | ||
593 | } | ||
594 | |||
595 | |||
596 | static int explist1 (LexState *ls, expdesc *v) { | ||
597 | /* explist1 -> expr { `,' expr } */ | ||
598 | int n = 1; /* at least one expression */ | ||
599 | expr(ls, v); | ||
600 | while (testnext(ls, ',')) { | ||
601 | luaK_exp2nextreg(ls->fs, v); | ||
602 | expr(ls, v); | ||
603 | n++; | ||
604 | } | ||
605 | return n; | ||
606 | } | ||
607 | |||
608 | |||
609 | static void funcargs (LexState *ls, expdesc *f) { | ||
610 | FuncState *fs = ls->fs; | ||
611 | expdesc args; | ||
612 | int base, nparams; | ||
613 | int line = ls->linenumber; | ||
614 | switch (ls->t.token) { | ||
615 | case '(': { /* funcargs -> `(' [ explist1 ] `)' */ | ||
616 | if (line != ls->lastline) | ||
617 | luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); | ||
618 | luaX_next(ls); | ||
619 | if (ls->t.token == ')') /* arg list is empty? */ | ||
620 | args.k = VVOID; | ||
621 | else { | ||
622 | explist1(ls, &args); | ||
623 | luaK_setmultret(fs, &args); | ||
624 | } | ||
625 | check_match(ls, ')', '(', line); | ||
626 | break; | ||
627 | } | ||
628 | case '{': { /* funcargs -> constructor */ | ||
629 | constructor(ls, &args); | ||
630 | break; | ||
631 | } | ||
632 | case TK_STRING: { /* funcargs -> STRING */ | ||
633 | codestring(ls, &args, ls->t.seminfo.ts); | ||
634 | luaX_next(ls); /* must use `seminfo' before `next' */ | ||
635 | break; | ||
636 | } | ||
637 | default: { | ||
638 | luaX_syntaxerror(ls, "function arguments expected"); | ||
639 | return; | ||
640 | } | ||
641 | } | ||
642 | lua_assert(f->k == VNONRELOC); | ||
643 | base = f->u.s.info; /* base register for call */ | ||
644 | if (hasmultret(args.k)) | ||
645 | nparams = LUA_MULTRET; /* open call */ | ||
646 | else { | ||
647 | if (args.k != VVOID) | ||
648 | luaK_exp2nextreg(fs, &args); /* close last argument */ | ||
649 | nparams = fs->freereg - (base+1); | ||
650 | } | ||
651 | init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); | ||
652 | luaK_fixline(fs, line); | ||
653 | fs->freereg = base+1; /* call remove function and arguments and leaves | ||
654 | (unless changed) one result */ | ||
655 | } | ||
656 | |||
657 | |||
658 | |||
659 | |||
660 | /* | ||
661 | ** {====================================================================== | ||
662 | ** Expression parsing | ||
663 | ** ======================================================================= | ||
664 | */ | ||
665 | |||
666 | |||
667 | static void prefixexp (LexState *ls, expdesc *v) { | ||
668 | /* prefixexp -> NAME | '(' expr ')' */ | ||
669 | switch (ls->t.token) { | ||
670 | case '(': { | ||
671 | int line = ls->linenumber; | ||
672 | luaX_next(ls); | ||
673 | expr(ls, v); | ||
674 | check_match(ls, ')', '(', line); | ||
675 | luaK_dischargevars(ls->fs, v); | ||
676 | return; | ||
677 | } | ||
678 | case TK_NAME: { | ||
679 | singlevar(ls, v); | ||
680 | return; | ||
681 | } | ||
682 | default: { | ||
683 | luaX_syntaxerror(ls, "unexpected symbol"); | ||
684 | return; | ||
685 | } | ||
686 | } | ||
687 | } | ||
688 | |||
689 | |||
690 | static void primaryexp (LexState *ls, expdesc *v) { | ||
691 | /* primaryexp -> | ||
692 | prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ | ||
693 | FuncState *fs = ls->fs; | ||
694 | prefixexp(ls, v); | ||
695 | for (;;) { | ||
696 | switch (ls->t.token) { | ||
697 | case '.': { /* field */ | ||
698 | field(ls, v); | ||
699 | break; | ||
700 | } | ||
701 | case '[': { /* `[' exp1 `]' */ | ||
702 | expdesc key; | ||
703 | luaK_exp2anyreg(fs, v); | ||
704 | yindex(ls, &key); | ||
705 | luaK_indexed(fs, v, &key); | ||
706 | break; | ||
707 | } | ||
708 | case ':': { /* `:' NAME funcargs */ | ||
709 | expdesc key; | ||
710 | luaX_next(ls); | ||
711 | checkname(ls, &key); | ||
712 | luaK_self(fs, v, &key); | ||
713 | funcargs(ls, v); | ||
714 | break; | ||
715 | } | ||
716 | case '(': case TK_STRING: case '{': { /* funcargs */ | ||
717 | luaK_exp2nextreg(fs, v); | ||
718 | funcargs(ls, v); | ||
719 | break; | ||
720 | } | ||
721 | default: return; | ||
722 | } | ||
723 | } | ||
724 | } | ||
725 | |||
726 | |||
727 | static void simpleexp (LexState *ls, expdesc *v) { | ||
728 | /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | | ||
729 | constructor | FUNCTION body | primaryexp */ | ||
730 | switch (ls->t.token) { | ||
731 | case TK_NUMBER: { | ||
732 | init_exp(v, VKNUM, 0); | ||
733 | v->u.nval = ls->t.seminfo.r; | ||
734 | break; | ||
735 | } | ||
736 | case TK_STRING: { | ||
737 | codestring(ls, v, ls->t.seminfo.ts); | ||
738 | break; | ||
739 | } | ||
740 | case TK_NIL: { | ||
741 | init_exp(v, VNIL, 0); | ||
742 | break; | ||
743 | } | ||
744 | case TK_TRUE: { | ||
745 | init_exp(v, VTRUE, 0); | ||
746 | break; | ||
747 | } | ||
748 | case TK_FALSE: { | ||
749 | init_exp(v, VFALSE, 0); | ||
750 | break; | ||
751 | } | ||
752 | case TK_DOTS: { /* vararg */ | ||
753 | FuncState *fs = ls->fs; | ||
754 | check_condition(ls, fs->f->is_vararg, | ||
755 | "cannot use " LUA_QL("...") " outside a vararg function"); | ||
756 | fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ | ||
757 | init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); | ||
758 | break; | ||
759 | } | ||
760 | case '{': { /* constructor */ | ||
761 | constructor(ls, v); | ||
762 | return; | ||
763 | } | ||
764 | case TK_FUNCTION: { | ||
765 | luaX_next(ls); | ||
766 | body(ls, v, 0, ls->linenumber); | ||
767 | return; | ||
768 | } | ||
769 | default: { | ||
770 | primaryexp(ls, v); | ||
771 | return; | ||
772 | } | ||
773 | } | ||
774 | luaX_next(ls); | ||
775 | } | ||
776 | |||
777 | |||
778 | static UnOpr getunopr (int op) { | ||
779 | switch (op) { | ||
780 | case TK_NOT: return OPR_NOT; | ||
781 | case '-': return OPR_MINUS; | ||
782 | case '#': return OPR_LEN; | ||
783 | default: return OPR_NOUNOPR; | ||
784 | } | ||
785 | } | ||
786 | |||
787 | |||
788 | static BinOpr getbinopr (int op) { | ||
789 | switch (op) { | ||
790 | case '+': return OPR_ADD; | ||
791 | case '-': return OPR_SUB; | ||
792 | case '*': return OPR_MUL; | ||
793 | case '/': return OPR_DIV; | ||
794 | case '%': return OPR_MOD; | ||
795 | case '^': return OPR_POW; | ||
796 | case TK_CONCAT: return OPR_CONCAT; | ||
797 | case TK_NE: return OPR_NE; | ||
798 | case TK_EQ: return OPR_EQ; | ||
799 | case '<': return OPR_LT; | ||
800 | case TK_LE: return OPR_LE; | ||
801 | case '>': return OPR_GT; | ||
802 | case TK_GE: return OPR_GE; | ||
803 | case TK_AND: return OPR_AND; | ||
804 | case TK_OR: return OPR_OR; | ||
805 | default: return OPR_NOBINOPR; | ||
806 | } | ||
807 | } | ||
808 | |||
809 | |||
810 | static const struct { | ||
811 | lu_byte left; /* left priority for each binary operator */ | ||
812 | lu_byte right; /* right priority */ | ||
813 | } priority[] = { /* ORDER OPR */ | ||
814 | {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ | ||
815 | {10, 9}, {5, 4}, /* power and concat (right associative) */ | ||
816 | {3, 3}, {3, 3}, /* equality and inequality */ | ||
817 | {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ | ||
818 | {2, 2}, {1, 1} /* logical (and/or) */ | ||
819 | }; | ||
820 | |||
821 | #define UNARY_PRIORITY 8 /* priority for unary operators */ | ||
822 | |||
823 | |||
824 | /* | ||
825 | ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } | ||
826 | ** where `binop' is any binary operator with a priority higher than `limit' | ||
827 | */ | ||
828 | static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { | ||
829 | BinOpr op; | ||
830 | UnOpr uop; | ||
831 | enterlevel(ls); | ||
832 | uop = getunopr(ls->t.token); | ||
833 | if (uop != OPR_NOUNOPR) { | ||
834 | luaX_next(ls); | ||
835 | subexpr(ls, v, UNARY_PRIORITY); | ||
836 | luaK_prefix(ls->fs, uop, v); | ||
837 | } | ||
838 | else simpleexp(ls, v); | ||
839 | /* expand while operators have priorities higher than `limit' */ | ||
840 | op = getbinopr(ls->t.token); | ||
841 | while (op != OPR_NOBINOPR && priority[op].left > limit) { | ||
842 | expdesc v2; | ||
843 | BinOpr nextop; | ||
844 | luaX_next(ls); | ||
845 | luaK_infix(ls->fs, op, v); | ||
846 | /* read sub-expression with higher priority */ | ||
847 | nextop = subexpr(ls, &v2, priority[op].right); | ||
848 | luaK_posfix(ls->fs, op, v, &v2); | ||
849 | op = nextop; | ||
850 | } | ||
851 | leavelevel(ls); | ||
852 | return op; /* return first untreated operator */ | ||
853 | } | ||
854 | |||
855 | |||
856 | static void expr (LexState *ls, expdesc *v) { | ||
857 | subexpr(ls, v, 0); | ||
858 | } | ||
859 | |||
860 | /* }==================================================================== */ | ||
861 | |||
862 | |||
863 | |||
864 | /* | ||
865 | ** {====================================================================== | ||
866 | ** Rules for Statements | ||
867 | ** ======================================================================= | ||
868 | */ | ||
869 | |||
870 | |||
871 | static int block_follow (int token) { | ||
872 | switch (token) { | ||
873 | case TK_ELSE: case TK_ELSEIF: case TK_END: | ||
874 | case TK_UNTIL: case TK_EOS: | ||
875 | return 1; | ||
876 | default: return 0; | ||
877 | } | ||
878 | } | ||
879 | |||
880 | |||
881 | static void block (LexState *ls) { | ||
882 | /* block -> chunk */ | ||
883 | FuncState *fs = ls->fs; | ||
884 | BlockCnt bl; | ||
885 | enterblock(fs, &bl, 0); | ||
886 | chunk(ls); | ||
887 | lua_assert(bl.breaklist == NO_JUMP); | ||
888 | leaveblock(fs); | ||
889 | } | ||
890 | |||
891 | |||
892 | /* | ||
893 | ** structure to chain all variables in the left-hand side of an | ||
894 | ** assignment | ||
895 | */ | ||
896 | struct LHS_assign { | ||
897 | struct LHS_assign *prev; | ||
898 | expdesc v; /* variable (global, local, upvalue, or indexed) */ | ||
899 | }; | ||
900 | |||
901 | |||
902 | /* | ||
903 | ** check whether, in an assignment to a local variable, the local variable | ||
904 | ** is needed in a previous assignment (to a table). If so, save original | ||
905 | ** local value in a safe place and use this safe copy in the previous | ||
906 | ** assignment. | ||
907 | */ | ||
908 | static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { | ||
909 | FuncState *fs = ls->fs; | ||
910 | int extra = fs->freereg; /* eventual position to save local variable */ | ||
911 | int conflict = 0; | ||
912 | for (; lh; lh = lh->prev) { | ||
913 | if (lh->v.k == VINDEXED) { | ||
914 | if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ | ||
915 | conflict = 1; | ||
916 | lh->v.u.s.info = extra; /* previous assignment will use safe copy */ | ||
917 | } | ||
918 | if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ | ||
919 | conflict = 1; | ||
920 | lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ | ||
921 | } | ||
922 | } | ||
923 | } | ||
924 | if (conflict) { | ||
925 | luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ | ||
926 | luaK_reserveregs(fs, 1); | ||
927 | } | ||
928 | } | ||
929 | |||
930 | |||
931 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { | ||
932 | expdesc e; | ||
933 | check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, | ||
934 | "syntax error"); | ||
935 | if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ | ||
936 | struct LHS_assign nv; | ||
937 | nv.prev = lh; | ||
938 | primaryexp(ls, &nv.v); | ||
939 | if (nv.v.k == VLOCAL) | ||
940 | check_conflict(ls, lh, &nv.v); | ||
941 | luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, | ||
942 | "variables in assignment"); | ||
943 | assignment(ls, &nv, nvars+1); | ||
944 | } | ||
945 | else { /* assignment -> `=' explist1 */ | ||
946 | int nexps; | ||
947 | checknext(ls, '='); | ||
948 | nexps = explist1(ls, &e); | ||
949 | if (nexps != nvars) { | ||
950 | adjust_assign(ls, nvars, nexps, &e); | ||
951 | if (nexps > nvars) | ||
952 | ls->fs->freereg -= nexps - nvars; /* remove extra values */ | ||
953 | } | ||
954 | else { | ||
955 | luaK_setoneret(ls->fs, &e); /* close last expression */ | ||
956 | luaK_storevar(ls->fs, &lh->v, &e); | ||
957 | return; /* avoid default */ | ||
958 | } | ||
959 | } | ||
960 | init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ | ||
961 | luaK_storevar(ls->fs, &lh->v, &e); | ||
962 | } | ||
963 | |||
964 | |||
965 | static int cond (LexState *ls) { | ||
966 | /* cond -> exp */ | ||
967 | expdesc v; | ||
968 | expr(ls, &v); /* read condition */ | ||
969 | if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ | ||
970 | luaK_goiftrue(ls->fs, &v); | ||
971 | return v.f; | ||
972 | } | ||
973 | |||
974 | |||
975 | static void breakstat (LexState *ls) { | ||
976 | FuncState *fs = ls->fs; | ||
977 | BlockCnt *bl = fs->bl; | ||
978 | int upval = 0; | ||
979 | while (bl && !bl->isbreakable) { | ||
980 | upval |= bl->upval; | ||
981 | bl = bl->previous; | ||
982 | } | ||
983 | if (!bl) | ||
984 | luaX_syntaxerror(ls, "no loop to break"); | ||
985 | if (upval) | ||
986 | luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); | ||
987 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); | ||
988 | } | ||
989 | |||
990 | |||
991 | static void whilestat (LexState *ls, int line) { | ||
992 | /* whilestat -> WHILE cond DO block END */ | ||
993 | FuncState *fs = ls->fs; | ||
994 | int whileinit; | ||
995 | int condexit; | ||
996 | BlockCnt bl; | ||
997 | luaX_next(ls); /* skip WHILE */ | ||
998 | whileinit = luaK_getlabel(fs); | ||
999 | condexit = cond(ls); | ||
1000 | enterblock(fs, &bl, 1); | ||
1001 | checknext(ls, TK_DO); | ||
1002 | block(ls); | ||
1003 | luaK_patchlist(fs, luaK_jump(fs), whileinit); | ||
1004 | check_match(ls, TK_END, TK_WHILE, line); | ||
1005 | leaveblock(fs); | ||
1006 | luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ | ||
1007 | } | ||
1008 | |||
1009 | |||
1010 | static void repeatstat (LexState *ls, int line) { | ||
1011 | /* repeatstat -> REPEAT block UNTIL cond */ | ||
1012 | int condexit; | ||
1013 | FuncState *fs = ls->fs; | ||
1014 | int repeat_init = luaK_getlabel(fs); | ||
1015 | BlockCnt bl1, bl2; | ||
1016 | enterblock(fs, &bl1, 1); /* loop block */ | ||
1017 | enterblock(fs, &bl2, 0); /* scope block */ | ||
1018 | luaX_next(ls); /* skip REPEAT */ | ||
1019 | chunk(ls); | ||
1020 | check_match(ls, TK_UNTIL, TK_REPEAT, line); | ||
1021 | condexit = cond(ls); /* read condition (inside scope block) */ | ||
1022 | if (!bl2.upval) { /* no upvalues? */ | ||
1023 | leaveblock(fs); /* finish scope */ | ||
1024 | luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */ | ||
1025 | } | ||
1026 | else { /* complete semantics when there are upvalues */ | ||
1027 | breakstat(ls); /* if condition then break */ | ||
1028 | luaK_patchtohere(ls->fs, condexit); /* else... */ | ||
1029 | leaveblock(fs); /* finish scope... */ | ||
1030 | luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */ | ||
1031 | } | ||
1032 | leaveblock(fs); /* finish loop */ | ||
1033 | } | ||
1034 | |||
1035 | |||
1036 | static int exp1 (LexState *ls) { | ||
1037 | expdesc e; | ||
1038 | int k; | ||
1039 | expr(ls, &e); | ||
1040 | k = e.k; | ||
1041 | luaK_exp2nextreg(ls->fs, &e); | ||
1042 | return k; | ||
1043 | } | ||
1044 | |||
1045 | |||
1046 | static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { | ||
1047 | /* forbody -> DO block */ | ||
1048 | BlockCnt bl; | ||
1049 | FuncState *fs = ls->fs; | ||
1050 | int prep, endfor; | ||
1051 | adjustlocalvars(ls, 3); /* control variables */ | ||
1052 | checknext(ls, TK_DO); | ||
1053 | prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); | ||
1054 | enterblock(fs, &bl, 0); /* scope for declared variables */ | ||
1055 | adjustlocalvars(ls, nvars); | ||
1056 | luaK_reserveregs(fs, nvars); | ||
1057 | block(ls); | ||
1058 | leaveblock(fs); /* end of scope for declared variables */ | ||
1059 | luaK_patchtohere(fs, prep); | ||
1060 | endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : | ||
1061 | luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); | ||
1062 | luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ | ||
1063 | luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); | ||
1064 | } | ||
1065 | |||
1066 | |||
1067 | static void fornum (LexState *ls, TString *varname, int line) { | ||
1068 | /* fornum -> NAME = exp1,exp1[,exp1] forbody */ | ||
1069 | FuncState *fs = ls->fs; | ||
1070 | int base = fs->freereg; | ||
1071 | new_localvarliteral(ls, "(for index)", 0); | ||
1072 | new_localvarliteral(ls, "(for limit)", 1); | ||
1073 | new_localvarliteral(ls, "(for step)", 2); | ||
1074 | new_localvar(ls, varname, 3); | ||
1075 | checknext(ls, '='); | ||
1076 | exp1(ls); /* initial value */ | ||
1077 | checknext(ls, ','); | ||
1078 | exp1(ls); /* limit */ | ||
1079 | if (testnext(ls, ',')) | ||
1080 | exp1(ls); /* optional step */ | ||
1081 | else { /* default step = 1 */ | ||
1082 | luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); | ||
1083 | luaK_reserveregs(fs, 1); | ||
1084 | } | ||
1085 | forbody(ls, base, line, 1, 1); | ||
1086 | } | ||
1087 | |||
1088 | |||
1089 | static void forlist (LexState *ls, TString *indexname) { | ||
1090 | /* forlist -> NAME {,NAME} IN explist1 forbody */ | ||
1091 | FuncState *fs = ls->fs; | ||
1092 | expdesc e; | ||
1093 | int nvars = 0; | ||
1094 | int line; | ||
1095 | int base = fs->freereg; | ||
1096 | /* create control variables */ | ||
1097 | new_localvarliteral(ls, "(for generator)", nvars++); | ||
1098 | new_localvarliteral(ls, "(for state)", nvars++); | ||
1099 | new_localvarliteral(ls, "(for control)", nvars++); | ||
1100 | /* create declared variables */ | ||
1101 | new_localvar(ls, indexname, nvars++); | ||
1102 | while (testnext(ls, ',')) | ||
1103 | new_localvar(ls, str_checkname(ls), nvars++); | ||
1104 | checknext(ls, TK_IN); | ||
1105 | line = ls->linenumber; | ||
1106 | adjust_assign(ls, 3, explist1(ls, &e), &e); | ||
1107 | luaK_checkstack(fs, 3); /* extra space to call generator */ | ||
1108 | forbody(ls, base, line, nvars - 3, 0); | ||
1109 | } | ||
1110 | |||
1111 | |||
1112 | static void forstat (LexState *ls, int line) { | ||
1113 | /* forstat -> FOR (fornum | forlist) END */ | ||
1114 | FuncState *fs = ls->fs; | ||
1115 | TString *varname; | ||
1116 | BlockCnt bl; | ||
1117 | enterblock(fs, &bl, 1); /* scope for loop and control variables */ | ||
1118 | luaX_next(ls); /* skip `for' */ | ||
1119 | varname = str_checkname(ls); /* first variable name */ | ||
1120 | switch (ls->t.token) { | ||
1121 | case '=': fornum(ls, varname, line); break; | ||
1122 | case ',': case TK_IN: forlist(ls, varname); break; | ||
1123 | default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); | ||
1124 | } | ||
1125 | check_match(ls, TK_END, TK_FOR, line); | ||
1126 | leaveblock(fs); /* loop scope (`break' jumps to this point) */ | ||
1127 | } | ||
1128 | |||
1129 | |||
1130 | static int test_then_block (LexState *ls) { | ||
1131 | /* test_then_block -> [IF | ELSEIF] cond THEN block */ | ||
1132 | int condexit; | ||
1133 | luaX_next(ls); /* skip IF or ELSEIF */ | ||
1134 | condexit = cond(ls); | ||
1135 | checknext(ls, TK_THEN); | ||
1136 | block(ls); /* `then' part */ | ||
1137 | return condexit; | ||
1138 | } | ||
1139 | |||
1140 | |||
1141 | static void ifstat (LexState *ls, int line) { | ||
1142 | /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ | ||
1143 | FuncState *fs = ls->fs; | ||
1144 | int flist; | ||
1145 | int escapelist = NO_JUMP; | ||
1146 | flist = test_then_block(ls); /* IF cond THEN block */ | ||
1147 | while (ls->t.token == TK_ELSEIF) { | ||
1148 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | ||
1149 | luaK_patchtohere(fs, flist); | ||
1150 | flist = test_then_block(ls); /* ELSEIF cond THEN block */ | ||
1151 | } | ||
1152 | if (ls->t.token == TK_ELSE) { | ||
1153 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | ||
1154 | luaK_patchtohere(fs, flist); | ||
1155 | luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ | ||
1156 | block(ls); /* `else' part */ | ||
1157 | } | ||
1158 | else | ||
1159 | luaK_concat(fs, &escapelist, flist); | ||
1160 | luaK_patchtohere(fs, escapelist); | ||
1161 | check_match(ls, TK_END, TK_IF, line); | ||
1162 | } | ||
1163 | |||
1164 | |||
1165 | static void localfunc (LexState *ls) { | ||
1166 | expdesc v, b; | ||
1167 | FuncState *fs = ls->fs; | ||
1168 | new_localvar(ls, str_checkname(ls), 0); | ||
1169 | init_exp(&v, VLOCAL, fs->freereg); | ||
1170 | luaK_reserveregs(fs, 1); | ||
1171 | adjustlocalvars(ls, 1); | ||
1172 | body(ls, &b, 0, ls->linenumber); | ||
1173 | luaK_storevar(fs, &v, &b); | ||
1174 | /* debug information will only see the variable after this point! */ | ||
1175 | getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; | ||
1176 | } | ||
1177 | |||
1178 | |||
1179 | static void localstat (LexState *ls) { | ||
1180 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ | ||
1181 | int nvars = 0; | ||
1182 | int nexps; | ||
1183 | expdesc e; | ||
1184 | do { | ||
1185 | new_localvar(ls, str_checkname(ls), nvars++); | ||
1186 | } while (testnext(ls, ',')); | ||
1187 | if (testnext(ls, '=')) | ||
1188 | nexps = explist1(ls, &e); | ||
1189 | else { | ||
1190 | e.k = VVOID; | ||
1191 | nexps = 0; | ||
1192 | } | ||
1193 | adjust_assign(ls, nvars, nexps, &e); | ||
1194 | adjustlocalvars(ls, nvars); | ||
1195 | } | ||
1196 | |||
1197 | |||
1198 | static int funcname (LexState *ls, expdesc *v) { | ||
1199 | /* funcname -> NAME {field} [`:' NAME] */ | ||
1200 | int needself = 0; | ||
1201 | singlevar(ls, v); | ||
1202 | while (ls->t.token == '.') | ||
1203 | field(ls, v); | ||
1204 | if (ls->t.token == ':') { | ||
1205 | needself = 1; | ||
1206 | field(ls, v); | ||
1207 | } | ||
1208 | return needself; | ||
1209 | } | ||
1210 | |||
1211 | |||
1212 | static void funcstat (LexState *ls, int line) { | ||
1213 | /* funcstat -> FUNCTION funcname body */ | ||
1214 | int needself; | ||
1215 | expdesc v, b; | ||
1216 | luaX_next(ls); /* skip FUNCTION */ | ||
1217 | needself = funcname(ls, &v); | ||
1218 | body(ls, &b, needself, line); | ||
1219 | luaK_storevar(ls->fs, &v, &b); | ||
1220 | luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ | ||
1221 | } | ||
1222 | |||
1223 | |||
1224 | static void exprstat (LexState *ls) { | ||
1225 | /* stat -> func | assignment */ | ||
1226 | FuncState *fs = ls->fs; | ||
1227 | struct LHS_assign v; | ||
1228 | primaryexp(ls, &v.v); | ||
1229 | if (v.v.k == VCALL) /* stat -> func */ | ||
1230 | SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ | ||
1231 | else { /* stat -> assignment */ | ||
1232 | v.prev = NULL; | ||
1233 | assignment(ls, &v, 1); | ||
1234 | } | ||
1235 | } | ||
1236 | |||
1237 | |||
1238 | static void retstat (LexState *ls) { | ||
1239 | /* stat -> RETURN explist */ | ||
1240 | FuncState *fs = ls->fs; | ||
1241 | expdesc e; | ||
1242 | int first, nret; /* registers with returned values */ | ||
1243 | luaX_next(ls); /* skip RETURN */ | ||
1244 | if (block_follow(ls->t.token) || ls->t.token == ';') | ||
1245 | first = nret = 0; /* return no values */ | ||
1246 | else { | ||
1247 | nret = explist1(ls, &e); /* optional return values */ | ||
1248 | if (hasmultret(e.k)) { | ||
1249 | luaK_setmultret(fs, &e); | ||
1250 | if (e.k == VCALL && nret == 1) { /* tail call? */ | ||
1251 | SET_OPCODE(getcode(fs,&e), OP_TAILCALL); | ||
1252 | lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); | ||
1253 | } | ||
1254 | first = fs->nactvar; | ||
1255 | nret = LUA_MULTRET; /* return all values */ | ||
1256 | } | ||
1257 | else { | ||
1258 | if (nret == 1) /* only one single value? */ | ||
1259 | first = luaK_exp2anyreg(fs, &e); | ||
1260 | else { | ||
1261 | luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ | ||
1262 | first = fs->nactvar; /* return all `active' values */ | ||
1263 | lua_assert(nret == fs->freereg - first); | ||
1264 | } | ||
1265 | } | ||
1266 | } | ||
1267 | luaK_ret(fs, first, nret); | ||
1268 | } | ||
1269 | |||
1270 | |||
1271 | static int statement (LexState *ls) { | ||
1272 | int line = ls->linenumber; /* may be needed for error messages */ | ||
1273 | switch (ls->t.token) { | ||
1274 | case TK_IF: { /* stat -> ifstat */ | ||
1275 | ifstat(ls, line); | ||
1276 | return 0; | ||
1277 | } | ||
1278 | case TK_WHILE: { /* stat -> whilestat */ | ||
1279 | whilestat(ls, line); | ||
1280 | return 0; | ||
1281 | } | ||
1282 | case TK_DO: { /* stat -> DO block END */ | ||
1283 | luaX_next(ls); /* skip DO */ | ||
1284 | block(ls); | ||
1285 | check_match(ls, TK_END, TK_DO, line); | ||
1286 | return 0; | ||
1287 | } | ||
1288 | case TK_FOR: { /* stat -> forstat */ | ||
1289 | forstat(ls, line); | ||
1290 | return 0; | ||
1291 | } | ||
1292 | case TK_REPEAT: { /* stat -> repeatstat */ | ||
1293 | repeatstat(ls, line); | ||
1294 | return 0; | ||
1295 | } | ||
1296 | case TK_FUNCTION: { | ||
1297 | funcstat(ls, line); /* stat -> funcstat */ | ||
1298 | return 0; | ||
1299 | } | ||
1300 | case TK_LOCAL: { /* stat -> localstat */ | ||
1301 | luaX_next(ls); /* skip LOCAL */ | ||
1302 | if (testnext(ls, TK_FUNCTION)) /* local function? */ | ||
1303 | localfunc(ls); | ||
1304 | else | ||
1305 | localstat(ls); | ||
1306 | return 0; | ||
1307 | } | ||
1308 | case TK_RETURN: { /* stat -> retstat */ | ||
1309 | retstat(ls); | ||
1310 | return 1; /* must be last statement */ | ||
1311 | } | ||
1312 | case TK_BREAK: { /* stat -> breakstat */ | ||
1313 | luaX_next(ls); /* skip BREAK */ | ||
1314 | breakstat(ls); | ||
1315 | return 1; /* must be last statement */ | ||
1316 | } | ||
1317 | default: { | ||
1318 | exprstat(ls); | ||
1319 | return 0; /* to avoid warnings */ | ||
1320 | } | ||
1321 | } | ||
1322 | } | ||
1323 | |||
1324 | |||
1325 | static void chunk (LexState *ls) { | ||
1326 | /* chunk -> { stat [`;'] } */ | ||
1327 | int islast = 0; | ||
1328 | enterlevel(ls); | ||
1329 | while (!islast && !block_follow(ls->t.token)) { | ||
1330 | islast = statement(ls); | ||
1331 | testnext(ls, ';'); | ||
1332 | lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && | ||
1333 | ls->fs->freereg >= ls->fs->nactvar); | ||
1334 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ | ||
1335 | } | ||
1336 | leavelevel(ls); | ||
1337 | } | ||
1338 | |||
1339 | /* }====================================================================== */ | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lparser.h b/libraries/LuaJIT-1.1.7/src/lparser.h new file mode 100644 index 0000000..18836af --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lparser.h | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | ** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Lua Parser | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lparser_h | ||
8 | #define lparser_h | ||
9 | |||
10 | #include "llimits.h" | ||
11 | #include "lobject.h" | ||
12 | #include "lzio.h" | ||
13 | |||
14 | |||
15 | /* | ||
16 | ** Expression descriptor | ||
17 | */ | ||
18 | |||
19 | typedef enum { | ||
20 | VVOID, /* no value */ | ||
21 | VNIL, | ||
22 | VTRUE, | ||
23 | VFALSE, | ||
24 | VK, /* info = index of constant in `k' */ | ||
25 | VKNUM, /* nval = numerical value */ | ||
26 | VLOCAL, /* info = local register */ | ||
27 | VUPVAL, /* info = index of upvalue in `upvalues' */ | ||
28 | VGLOBAL, /* info = index of table; aux = index of global name in `k' */ | ||
29 | VINDEXED, /* info = table register; aux = index register (or `k') */ | ||
30 | VJMP, /* info = instruction pc */ | ||
31 | VRELOCABLE, /* info = instruction pc */ | ||
32 | VNONRELOC, /* info = result register */ | ||
33 | VCALL, /* info = instruction pc */ | ||
34 | VVARARG /* info = instruction pc */ | ||
35 | } expkind; | ||
36 | |||
37 | typedef struct expdesc { | ||
38 | expkind k; | ||
39 | union { | ||
40 | struct { int info, aux; } s; | ||
41 | lua_Number nval; | ||
42 | } u; | ||
43 | int t; /* patch list of `exit when true' */ | ||
44 | int f; /* patch list of `exit when false' */ | ||
45 | } expdesc; | ||
46 | |||
47 | |||
48 | typedef struct upvaldesc { | ||
49 | lu_byte k; | ||
50 | lu_byte info; | ||
51 | } upvaldesc; | ||
52 | |||
53 | |||
54 | struct BlockCnt; /* defined in lparser.c */ | ||
55 | |||
56 | |||
57 | /* state needed to generate code for a given function */ | ||
58 | typedef struct FuncState { | ||
59 | Proto *f; /* current function header */ | ||
60 | Table *h; /* table to find (and reuse) elements in `k' */ | ||
61 | struct FuncState *prev; /* enclosing function */ | ||
62 | struct LexState *ls; /* lexical state */ | ||
63 | struct lua_State *L; /* copy of the Lua state */ | ||
64 | struct BlockCnt *bl; /* chain of current blocks */ | ||
65 | int pc; /* next position to code (equivalent to `ncode') */ | ||
66 | int lasttarget; /* `pc' of last `jump target' */ | ||
67 | int jpc; /* list of pending jumps to `pc' */ | ||
68 | int freereg; /* first free register */ | ||
69 | int nk; /* number of elements in `k' */ | ||
70 | int np; /* number of elements in `p' */ | ||
71 | short nlocvars; /* number of elements in `locvars' */ | ||
72 | lu_byte nactvar; /* number of active local variables */ | ||
73 | upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ | ||
74 | unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ | ||
75 | } FuncState; | ||
76 | |||
77 | |||
78 | LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | ||
79 | const char *name); | ||
80 | |||
81 | |||
82 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lstate.c b/libraries/LuaJIT-1.1.7/src/lstate.c new file mode 100644 index 0000000..2bf835b --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lstate.c | |||
@@ -0,0 +1,218 @@ | |||
1 | /* | ||
2 | ** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ | ||
3 | ** Global State | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <stddef.h> | ||
9 | |||
10 | #define lstate_c | ||
11 | #define LUA_CORE | ||
12 | |||
13 | #include "lua.h" | ||
14 | |||
15 | #include "ldebug.h" | ||
16 | #include "ldo.h" | ||
17 | #include "lfunc.h" | ||
18 | #include "lgc.h" | ||
19 | #include "llex.h" | ||
20 | #include "lmem.h" | ||
21 | #include "lstate.h" | ||
22 | #include "lstring.h" | ||
23 | #include "ltable.h" | ||
24 | #include "ltm.h" | ||
25 | #include "ljit.h" | ||
26 | |||
27 | |||
28 | #define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) | ||
29 | #define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) | ||
30 | #define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) | ||
31 | |||
32 | |||
33 | /* | ||
34 | ** Main thread combines a thread state and the global state | ||
35 | */ | ||
36 | typedef struct LG { | ||
37 | lua_State l; | ||
38 | global_State g; | ||
39 | } LG; | ||
40 | |||
41 | |||
42 | |||
43 | static void stack_init (lua_State *L1, lua_State *L) { | ||
44 | /* initialize CallInfo array */ | ||
45 | L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); | ||
46 | L1->ci = L1->base_ci; | ||
47 | L1->size_ci = BASIC_CI_SIZE; | ||
48 | L1->end_ci = L1->base_ci + L1->size_ci - 1; | ||
49 | /* initialize stack array */ | ||
50 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); | ||
51 | L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; | ||
52 | L1->top = L1->stack; | ||
53 | L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; | ||
54 | /* initialize first ci */ | ||
55 | L1->ci->func = L1->top; | ||
56 | setnilvalue(L1->top++); /* `function' entry for this `ci' */ | ||
57 | L1->base = L1->ci->base = L1->top; | ||
58 | L1->ci->top = L1->top + LUA_MINSTACK; | ||
59 | } | ||
60 | |||
61 | |||
62 | static void freestack (lua_State *L, lua_State *L1) { | ||
63 | luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); | ||
64 | luaM_freearray(L, L1->stack, L1->stacksize, TValue); | ||
65 | } | ||
66 | |||
67 | |||
68 | /* | ||
69 | ** open parts that may cause memory-allocation errors | ||
70 | */ | ||
71 | static void f_luaopen (lua_State *L, void *ud) { | ||
72 | global_State *g = G(L); | ||
73 | UNUSED(ud); | ||
74 | stack_init(L, L); /* init stack */ | ||
75 | sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ | ||
76 | sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ | ||
77 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ | ||
78 | luaT_init(L); | ||
79 | luaX_init(L); | ||
80 | luaS_fix(luaS_newliteral(L, MEMERRMSG)); | ||
81 | g->GCthreshold = 4*g->totalbytes; | ||
82 | luaJIT_initstate(L); | ||
83 | } | ||
84 | |||
85 | |||
86 | static void preinit_state (lua_State *L, global_State *g) { | ||
87 | G(L) = g; | ||
88 | L->stack = NULL; | ||
89 | L->stacksize = 0; | ||
90 | L->errorJmp = NULL; | ||
91 | L->hook = NULL; | ||
92 | L->hookmask = 0; | ||
93 | L->basehookcount = 0; | ||
94 | L->allowhook = 1; | ||
95 | resethookcount(L); | ||
96 | L->openupval = NULL; | ||
97 | L->size_ci = 0; | ||
98 | L->nCcalls = 0; | ||
99 | L->status = 0; | ||
100 | L->base_ci = L->ci = NULL; | ||
101 | L->savedpc = NULL; | ||
102 | L->errfunc = 0; | ||
103 | setnilvalue(gt(L)); | ||
104 | } | ||
105 | |||
106 | |||
107 | static void close_state (lua_State *L) { | ||
108 | global_State *g = G(L); | ||
109 | luaF_close(L, L->stack); /* close all upvalues for this thread */ | ||
110 | luaC_freeall(L); /* collect all objects */ | ||
111 | luaJIT_freestate(L); | ||
112 | lua_assert(g->rootgc == obj2gco(L)); | ||
113 | lua_assert(g->strt.nuse == 0); | ||
114 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); | ||
115 | luaZ_freebuffer(L, &g->buff); | ||
116 | freestack(L, L); | ||
117 | lua_assert(g->totalbytes == sizeof(LG)); | ||
118 | (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); | ||
119 | } | ||
120 | |||
121 | |||
122 | lua_State *luaE_newthread (lua_State *L) { | ||
123 | lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); | ||
124 | luaC_link(L, obj2gco(L1), LUA_TTHREAD); | ||
125 | preinit_state(L1, G(L)); | ||
126 | stack_init(L1, L); /* init stack */ | ||
127 | setobj2n(L, gt(L1), gt(L)); /* share table of globals */ | ||
128 | L1->hookmask = L->hookmask; | ||
129 | L1->basehookcount = L->basehookcount; | ||
130 | L1->hook = L->hook; | ||
131 | resethookcount(L1); | ||
132 | lua_assert(iswhite(obj2gco(L1))); | ||
133 | return L1; | ||
134 | } | ||
135 | |||
136 | |||
137 | void luaE_freethread (lua_State *L, lua_State *L1) { | ||
138 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ | ||
139 | lua_assert(L1->openupval == NULL); | ||
140 | luai_userstatefree(L1); | ||
141 | freestack(L, L1); | ||
142 | luaM_freemem(L, fromstate(L1), state_size(lua_State)); | ||
143 | } | ||
144 | |||
145 | |||
146 | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | ||
147 | int i; | ||
148 | lua_State *L; | ||
149 | global_State *g; | ||
150 | void *l = (*f)(ud, NULL, 0, state_size(LG)); | ||
151 | if (l == NULL) return NULL; | ||
152 | L = tostate(l); | ||
153 | g = &((LG *)L)->g; | ||
154 | L->next = NULL; | ||
155 | L->tt = LUA_TTHREAD; | ||
156 | g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); | ||
157 | L->marked = luaC_white(g); | ||
158 | set2bits(L->marked, FIXEDBIT, SFIXEDBIT); | ||
159 | preinit_state(L, g); | ||
160 | g->frealloc = f; | ||
161 | g->ud = ud; | ||
162 | g->mainthread = L; | ||
163 | g->uvhead.u.l.prev = &g->uvhead; | ||
164 | g->uvhead.u.l.next = &g->uvhead; | ||
165 | g->GCthreshold = 0; /* mark it as unfinished state */ | ||
166 | g->strt.size = 0; | ||
167 | g->strt.nuse = 0; | ||
168 | g->strt.hash = NULL; | ||
169 | setnilvalue(registry(L)); | ||
170 | luaZ_initbuffer(L, &g->buff); | ||
171 | g->panic = NULL; | ||
172 | g->gcstate = GCSpause; | ||
173 | g->rootgc = obj2gco(L); | ||
174 | g->sweepstrgc = 0; | ||
175 | g->sweepgc = &g->rootgc; | ||
176 | g->gray = NULL; | ||
177 | g->grayagain = NULL; | ||
178 | g->weak = NULL; | ||
179 | g->tmudata = NULL; | ||
180 | g->totalbytes = sizeof(LG); | ||
181 | g->gcpause = LUAI_GCPAUSE; | ||
182 | g->gcstepmul = LUAI_GCMUL; | ||
183 | g->gcdept = 0; | ||
184 | g->jit_state = NULL; | ||
185 | for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL; | ||
186 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { | ||
187 | /* memory allocation error: free partial state */ | ||
188 | close_state(L); | ||
189 | L = NULL; | ||
190 | } | ||
191 | else | ||
192 | luai_userstateopen(L); | ||
193 | return L; | ||
194 | } | ||
195 | |||
196 | |||
197 | static void callallgcTM (lua_State *L, void *ud) { | ||
198 | UNUSED(ud); | ||
199 | luaC_callGCTM(L); /* call GC metamethods for all udata */ | ||
200 | } | ||
201 | |||
202 | |||
203 | LUA_API void lua_close (lua_State *L) { | ||
204 | L = G(L)->mainthread; /* only the main thread can be closed */ | ||
205 | lua_lock(L); | ||
206 | luaF_close(L, L->stack); /* close all upvalues for this thread */ | ||
207 | luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ | ||
208 | L->errfunc = 0; /* no error function during GC metamethods */ | ||
209 | do { /* repeat until no more errors */ | ||
210 | L->ci = L->base_ci; | ||
211 | L->base = L->top = L->ci->base; | ||
212 | L->nCcalls = 0; | ||
213 | } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); | ||
214 | lua_assert(G(L)->tmudata == NULL); | ||
215 | luai_userstateclose(L); | ||
216 | close_state(L); | ||
217 | } | ||
218 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lstate.h b/libraries/LuaJIT-1.1.7/src/lstate.h new file mode 100644 index 0000000..ddaa554 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lstate.h | |||
@@ -0,0 +1,179 @@ | |||
1 | /* | ||
2 | ** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $ | ||
3 | ** Global State | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lstate_h | ||
8 | #define lstate_h | ||
9 | |||
10 | #include "lua.h" | ||
11 | |||
12 | #include "lobject.h" | ||
13 | #include "ltm.h" | ||
14 | #include "lzio.h" | ||
15 | #ifndef COCO_DISABLE | ||
16 | #include "lcoco.h" | ||
17 | #endif | ||
18 | |||
19 | |||
20 | |||
21 | struct lua_longjmp; /* defined in ldo.c */ | ||
22 | struct jit_State; /* defined in ljit.c */ | ||
23 | typedef int (*luaJIT_GateLJ)(lua_State *L, StkId func, int nresults); | ||
24 | |||
25 | |||
26 | /* table of globals */ | ||
27 | #define gt(L) (&L->l_gt) | ||
28 | |||
29 | /* registry */ | ||
30 | #define registry(L) (&G(L)->l_registry) | ||
31 | |||
32 | |||
33 | /* extra stack space to handle TM calls and some other extras */ | ||
34 | /* LuaJIT uses more than the default (5) to speed up calls (setnil loop) */ | ||
35 | #define EXTRA_STACK 8 | ||
36 | |||
37 | |||
38 | #define BASIC_CI_SIZE 8 | ||
39 | |||
40 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) | ||
41 | |||
42 | |||
43 | |||
44 | typedef struct stringtable { | ||
45 | GCObject **hash; | ||
46 | lu_int32 nuse; /* number of elements */ | ||
47 | int size; | ||
48 | } stringtable; | ||
49 | |||
50 | |||
51 | /* | ||
52 | ** informations about a call | ||
53 | */ | ||
54 | typedef struct CallInfo { | ||
55 | StkId base; /* base for this function */ | ||
56 | StkId func; /* function index in the stack */ | ||
57 | StkId top; /* top for this function */ | ||
58 | const Instruction *savedpc; | ||
59 | int nresults; /* expected number of results from this function */ | ||
60 | int tailcalls; /* number of tail calls lost under this entry */ | ||
61 | } CallInfo; | ||
62 | |||
63 | |||
64 | |||
65 | #define curr_func(L) (clvalue(L->ci->func)) | ||
66 | #define ci_func(ci) (clvalue((ci)->func)) | ||
67 | #define f_isLua(ci) (!ci_func(ci)->c.isC) | ||
68 | #define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) | ||
69 | |||
70 | |||
71 | /* | ||
72 | ** `global state', shared by all threads of this state | ||
73 | */ | ||
74 | typedef struct global_State { | ||
75 | stringtable strt; /* hash table for strings */ | ||
76 | lua_Alloc frealloc; /* function to reallocate memory */ | ||
77 | void *ud; /* auxiliary data to `frealloc' */ | ||
78 | lu_byte currentwhite; | ||
79 | lu_byte gcstate; /* state of garbage collector */ | ||
80 | int sweepstrgc; /* position of sweep in `strt' */ | ||
81 | GCObject *rootgc; /* list of all collectable objects */ | ||
82 | GCObject **sweepgc; /* position of sweep in `rootgc' */ | ||
83 | GCObject *gray; /* list of gray objects */ | ||
84 | GCObject *grayagain; /* list of objects to be traversed atomically */ | ||
85 | GCObject *weak; /* list of weak tables (to be cleared) */ | ||
86 | GCObject *tmudata; /* last element of list of userdata to be GC */ | ||
87 | Mbuffer buff; /* temporary buffer for string concatentation */ | ||
88 | lu_mem GCthreshold; | ||
89 | lu_mem totalbytes; /* number of bytes currently allocated */ | ||
90 | lu_mem estimate; /* an estimate of number of bytes actually in use */ | ||
91 | lu_mem gcdept; /* how much GC is `behind schedule' */ | ||
92 | int gcpause; /* size of pause between successive GCs */ | ||
93 | int gcstepmul; /* GC `granularity' */ | ||
94 | lua_CFunction panic; /* to be called in unprotected errors */ | ||
95 | TValue l_registry; | ||
96 | struct lua_State *mainthread; | ||
97 | UpVal uvhead; /* head of double-linked list of all open upvalues */ | ||
98 | struct Table *mt[NUM_TAGS]; /* metatables for basic types */ | ||
99 | TString *tmname[TM_N]; /* array with tag-method names */ | ||
100 | /* LuaJIT extensions */ | ||
101 | struct jit_State *jit_state; /* JIT state */ | ||
102 | luaJIT_GateLJ jit_gateLJ; /* Lua -> JIT gate */ | ||
103 | lua_CFunction jit_gateJL; /* JIT -> Lua callgate */ | ||
104 | lua_CFunction jit_gateJC; /* JIT -> C callgate */ | ||
105 | } global_State; | ||
106 | |||
107 | |||
108 | /* | ||
109 | ** `per thread' state | ||
110 | */ | ||
111 | struct lua_State { | ||
112 | CommonHeader; | ||
113 | lu_byte status; | ||
114 | StkId top; /* first free slot in the stack */ | ||
115 | StkId base; /* base of current function */ | ||
116 | global_State *l_G; | ||
117 | CallInfo *ci; /* call info for current function */ | ||
118 | const Instruction *savedpc; /* `savedpc' of current function */ | ||
119 | StkId stack_last; /* last free slot in the stack */ | ||
120 | StkId stack; /* stack base */ | ||
121 | CallInfo *end_ci; /* points after end of ci array*/ | ||
122 | CallInfo *base_ci; /* array of CallInfo's */ | ||
123 | int stacksize; | ||
124 | int size_ci; /* size of array `base_ci' */ | ||
125 | unsigned short nCcalls; /* number of nested C calls */ | ||
126 | lu_byte hookmask; | ||
127 | lu_byte allowhook; | ||
128 | int basehookcount; | ||
129 | int hookcount; | ||
130 | lua_Hook hook; | ||
131 | TValue l_gt; /* table of globals */ | ||
132 | TValue env; /* temporary place for environments */ | ||
133 | GCObject *openupval; /* list of open upvalues in this stack */ | ||
134 | GCObject *gclist; | ||
135 | struct lua_longjmp *errorJmp; /* current error recover point */ | ||
136 | ptrdiff_t errfunc; /* current error handling function (stack index) */ | ||
137 | }; | ||
138 | |||
139 | |||
140 | #define G(L) (L->l_G) | ||
141 | |||
142 | |||
143 | /* | ||
144 | ** Union of all collectable objects | ||
145 | */ | ||
146 | union GCObject { | ||
147 | GCheader gch; | ||
148 | union TString ts; | ||
149 | union Udata u; | ||
150 | union Closure cl; | ||
151 | struct Table h; | ||
152 | struct Proto p; | ||
153 | struct UpVal uv; | ||
154 | struct lua_State th; /* thread */ | ||
155 | }; | ||
156 | |||
157 | |||
158 | /* macros to convert a GCObject into a specific value */ | ||
159 | #define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) | ||
160 | #define gco2ts(o) (&rawgco2ts(o)->tsv) | ||
161 | #define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) | ||
162 | #define gco2u(o) (&rawgco2u(o)->uv) | ||
163 | #define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) | ||
164 | #define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) | ||
165 | #define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) | ||
166 | #define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) | ||
167 | #define ngcotouv(o) \ | ||
168 | check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) | ||
169 | #define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) | ||
170 | |||
171 | /* macro to convert any Lua object into a GCObject */ | ||
172 | #define obj2gco(v) (cast(GCObject *, (v))) | ||
173 | |||
174 | |||
175 | LUAI_FUNC lua_State *luaE_newthread (lua_State *L); | ||
176 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); | ||
177 | |||
178 | #endif | ||
179 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lstring.c b/libraries/LuaJIT-1.1.7/src/lstring.c new file mode 100644 index 0000000..4911315 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lstring.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | ** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** String table (keeps all strings handled by Lua) | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <string.h> | ||
9 | |||
10 | #define lstring_c | ||
11 | #define LUA_CORE | ||
12 | |||
13 | #include "lua.h" | ||
14 | |||
15 | #include "lmem.h" | ||
16 | #include "lobject.h" | ||
17 | #include "lstate.h" | ||
18 | #include "lstring.h" | ||
19 | |||
20 | |||
21 | |||
22 | void luaS_resize (lua_State *L, int newsize) { | ||
23 | GCObject **newhash; | ||
24 | stringtable *tb; | ||
25 | int i; | ||
26 | if (G(L)->gcstate == GCSsweepstring) | ||
27 | return; /* cannot resize during GC traverse */ | ||
28 | newhash = luaM_newvector(L, newsize, GCObject *); | ||
29 | tb = &G(L)->strt; | ||
30 | for (i=0; i<newsize; i++) newhash[i] = NULL; | ||
31 | /* rehash */ | ||
32 | for (i=0; i<tb->size; i++) { | ||
33 | GCObject *p = tb->hash[i]; | ||
34 | while (p) { /* for each node in the list */ | ||
35 | GCObject *next = p->gch.next; /* save next */ | ||
36 | unsigned int h = gco2ts(p)->hash; | ||
37 | int h1 = lmod(h, newsize); /* new position */ | ||
38 | lua_assert(cast_int(h%newsize) == lmod(h, newsize)); | ||
39 | p->gch.next = newhash[h1]; /* chain it */ | ||
40 | newhash[h1] = p; | ||
41 | p = next; | ||
42 | } | ||
43 | } | ||
44 | luaM_freearray(L, tb->hash, tb->size, TString *); | ||
45 | tb->size = newsize; | ||
46 | tb->hash = newhash; | ||
47 | } | ||
48 | |||
49 | |||
50 | static TString *newlstr (lua_State *L, const char *str, size_t l, | ||
51 | unsigned int h) { | ||
52 | TString *ts; | ||
53 | stringtable *tb; | ||
54 | if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) | ||
55 | luaM_toobig(L); | ||
56 | ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); | ||
57 | ts->tsv.len = l; | ||
58 | ts->tsv.hash = h; | ||
59 | ts->tsv.marked = luaC_white(G(L)); | ||
60 | ts->tsv.tt = LUA_TSTRING; | ||
61 | ts->tsv.reserved = 0; | ||
62 | memcpy(ts+1, str, l*sizeof(char)); | ||
63 | ((char *)(ts+1))[l] = '\0'; /* ending 0 */ | ||
64 | tb = &G(L)->strt; | ||
65 | h = lmod(h, tb->size); | ||
66 | ts->tsv.next = tb->hash[h]; /* chain new entry */ | ||
67 | tb->hash[h] = obj2gco(ts); | ||
68 | tb->nuse++; | ||
69 | if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) | ||
70 | luaS_resize(L, tb->size*2); /* too crowded */ | ||
71 | return ts; | ||
72 | } | ||
73 | |||
74 | |||
75 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | ||
76 | GCObject *o; | ||
77 | unsigned int h = cast(unsigned int, l); /* seed */ | ||
78 | size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ | ||
79 | size_t l1; | ||
80 | for (l1=l; l1>=step; l1-=step) /* compute hash */ | ||
81 | h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); | ||
82 | for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; | ||
83 | o != NULL; | ||
84 | o = o->gch.next) { | ||
85 | TString *ts = rawgco2ts(o); | ||
86 | if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { | ||
87 | /* string may be dead */ | ||
88 | if (isdead(G(L), o)) changewhite(o); | ||
89 | return ts; | ||
90 | } | ||
91 | } | ||
92 | return newlstr(L, str, l, h); /* not found */ | ||
93 | } | ||
94 | |||
95 | |||
96 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { | ||
97 | Udata *u; | ||
98 | if (s > MAX_SIZET - sizeof(Udata)) | ||
99 | luaM_toobig(L); | ||
100 | u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); | ||
101 | u->uv.marked = luaC_white(G(L)); /* is not finalized */ | ||
102 | u->uv.tt = LUA_TUSERDATA; | ||
103 | u->uv.len = s; | ||
104 | u->uv.metatable = NULL; | ||
105 | u->uv.env = e; | ||
106 | /* chain it on udata list (after main thread) */ | ||
107 | u->uv.next = G(L)->mainthread->next; | ||
108 | G(L)->mainthread->next = obj2gco(u); | ||
109 | return u; | ||
110 | } | ||
111 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lstring.h b/libraries/LuaJIT-1.1.7/src/lstring.h new file mode 100644 index 0000000..73a2ff8 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lstring.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | ** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** String table (keep all strings handled by Lua) | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lstring_h | ||
8 | #define lstring_h | ||
9 | |||
10 | |||
11 | #include "lgc.h" | ||
12 | #include "lobject.h" | ||
13 | #include "lstate.h" | ||
14 | |||
15 | |||
16 | #define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) | ||
17 | |||
18 | #define sizeudata(u) (sizeof(union Udata)+(u)->len) | ||
19 | |||
20 | #define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) | ||
21 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ | ||
22 | (sizeof(s)/sizeof(char))-1)) | ||
23 | |||
24 | #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) | ||
25 | |||
26 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); | ||
27 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); | ||
28 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); | ||
29 | |||
30 | |||
31 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lstrlib.c b/libraries/LuaJIT-1.1.7/src/lstrlib.c new file mode 100644 index 0000000..fe452ce --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lstrlib.c | |||
@@ -0,0 +1,871 @@ | |||
1 | /* | ||
2 | ** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $ | ||
3 | ** Standard library for string operations and pattern-matching | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <ctype.h> | ||
9 | #include <stddef.h> | ||
10 | #include <stdio.h> | ||
11 | #include <stdlib.h> | ||
12 | #include <string.h> | ||
13 | |||
14 | #define lstrlib_c | ||
15 | #define LUA_LIB | ||
16 | |||
17 | #include "lua.h" | ||
18 | |||
19 | #include "lauxlib.h" | ||
20 | #include "lualib.h" | ||
21 | |||
22 | |||
23 | /* macro to `unsign' a character */ | ||
24 | #define uchar(c) ((unsigned char)(c)) | ||
25 | |||
26 | |||
27 | |||
28 | static int str_len (lua_State *L) { | ||
29 | size_t l; | ||
30 | luaL_checklstring(L, 1, &l); | ||
31 | lua_pushinteger(L, l); | ||
32 | return 1; | ||
33 | } | ||
34 | |||
35 | |||
36 | static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { | ||
37 | /* relative string position: negative means back from end */ | ||
38 | if (pos < 0) pos += (ptrdiff_t)len + 1; | ||
39 | return (pos >= 0) ? pos : 0; | ||
40 | } | ||
41 | |||
42 | |||
43 | static int str_sub (lua_State *L) { | ||
44 | size_t l; | ||
45 | const char *s = luaL_checklstring(L, 1, &l); | ||
46 | ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); | ||
47 | ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); | ||
48 | if (start < 1) start = 1; | ||
49 | if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; | ||
50 | if (start <= end) | ||
51 | lua_pushlstring(L, s+start-1, end-start+1); | ||
52 | else lua_pushliteral(L, ""); | ||
53 | return 1; | ||
54 | } | ||
55 | |||
56 | |||
57 | static int str_reverse (lua_State *L) { | ||
58 | size_t l; | ||
59 | luaL_Buffer b; | ||
60 | const char *s = luaL_checklstring(L, 1, &l); | ||
61 | luaL_buffinit(L, &b); | ||
62 | while (l--) luaL_addchar(&b, s[l]); | ||
63 | luaL_pushresult(&b); | ||
64 | return 1; | ||
65 | } | ||
66 | |||
67 | |||
68 | static int str_lower (lua_State *L) { | ||
69 | size_t l; | ||
70 | size_t i; | ||
71 | luaL_Buffer b; | ||
72 | const char *s = luaL_checklstring(L, 1, &l); | ||
73 | luaL_buffinit(L, &b); | ||
74 | for (i=0; i<l; i++) | ||
75 | luaL_addchar(&b, tolower(uchar(s[i]))); | ||
76 | luaL_pushresult(&b); | ||
77 | return 1; | ||
78 | } | ||
79 | |||
80 | |||
81 | static int str_upper (lua_State *L) { | ||
82 | size_t l; | ||
83 | size_t i; | ||
84 | luaL_Buffer b; | ||
85 | const char *s = luaL_checklstring(L, 1, &l); | ||
86 | luaL_buffinit(L, &b); | ||
87 | for (i=0; i<l; i++) | ||
88 | luaL_addchar(&b, toupper(uchar(s[i]))); | ||
89 | luaL_pushresult(&b); | ||
90 | return 1; | ||
91 | } | ||
92 | |||
93 | static int str_rep (lua_State *L) { | ||
94 | size_t l; | ||
95 | luaL_Buffer b; | ||
96 | const char *s = luaL_checklstring(L, 1, &l); | ||
97 | int n = luaL_checkint(L, 2); | ||
98 | luaL_buffinit(L, &b); | ||
99 | while (n-- > 0) | ||
100 | luaL_addlstring(&b, s, l); | ||
101 | luaL_pushresult(&b); | ||
102 | return 1; | ||
103 | } | ||
104 | |||
105 | |||
106 | static int str_byte (lua_State *L) { | ||
107 | size_t l; | ||
108 | const char *s = luaL_checklstring(L, 1, &l); | ||
109 | ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); | ||
110 | ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); | ||
111 | int n, i; | ||
112 | if (posi <= 0) posi = 1; | ||
113 | if ((size_t)pose > l) pose = l; | ||
114 | if (posi > pose) return 0; /* empty interval; return no values */ | ||
115 | n = (int)(pose - posi + 1); | ||
116 | if (posi + n <= pose) /* overflow? */ | ||
117 | luaL_error(L, "string slice too long"); | ||
118 | luaL_checkstack(L, n, "string slice too long"); | ||
119 | for (i=0; i<n; i++) | ||
120 | lua_pushinteger(L, uchar(s[posi+i-1])); | ||
121 | return n; | ||
122 | } | ||
123 | |||
124 | |||
125 | static int str_char (lua_State *L) { | ||
126 | int n = lua_gettop(L); /* number of arguments */ | ||
127 | int i; | ||
128 | luaL_Buffer b; | ||
129 | luaL_buffinit(L, &b); | ||
130 | for (i=1; i<=n; i++) { | ||
131 | int c = luaL_checkint(L, i); | ||
132 | luaL_argcheck(L, uchar(c) == c, i, "invalid value"); | ||
133 | luaL_addchar(&b, uchar(c)); | ||
134 | } | ||
135 | luaL_pushresult(&b); | ||
136 | return 1; | ||
137 | } | ||
138 | |||
139 | |||
140 | static int writer (lua_State *L, const void* b, size_t size, void* B) { | ||
141 | (void)L; | ||
142 | luaL_addlstring((luaL_Buffer*) B, (const char *)b, size); | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | |||
147 | static int str_dump (lua_State *L) { | ||
148 | luaL_Buffer b; | ||
149 | luaL_checktype(L, 1, LUA_TFUNCTION); | ||
150 | lua_settop(L, 1); | ||
151 | luaL_buffinit(L,&b); | ||
152 | if (lua_dump(L, writer, &b) != 0) | ||
153 | luaL_error(L, "unable to dump given function"); | ||
154 | luaL_pushresult(&b); | ||
155 | return 1; | ||
156 | } | ||
157 | |||
158 | |||
159 | |||
160 | /* | ||
161 | ** {====================================================== | ||
162 | ** PATTERN MATCHING | ||
163 | ** ======================================================= | ||
164 | */ | ||
165 | |||
166 | |||
167 | #define CAP_UNFINISHED (-1) | ||
168 | #define CAP_POSITION (-2) | ||
169 | |||
170 | typedef struct MatchState { | ||
171 | const char *src_init; /* init of source string */ | ||
172 | const char *src_end; /* end (`\0') of source string */ | ||
173 | lua_State *L; | ||
174 | int level; /* total number of captures (finished or unfinished) */ | ||
175 | struct { | ||
176 | const char *init; | ||
177 | ptrdiff_t len; | ||
178 | } capture[LUA_MAXCAPTURES]; | ||
179 | } MatchState; | ||
180 | |||
181 | |||
182 | #define L_ESC '%' | ||
183 | #define SPECIALS "^$*+?.([%-" | ||
184 | |||
185 | |||
186 | static int check_capture (MatchState *ms, int l) { | ||
187 | l -= '1'; | ||
188 | if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) | ||
189 | return luaL_error(ms->L, "invalid capture index"); | ||
190 | return l; | ||
191 | } | ||
192 | |||
193 | |||
194 | static int capture_to_close (MatchState *ms) { | ||
195 | int level = ms->level; | ||
196 | for (level--; level>=0; level--) | ||
197 | if (ms->capture[level].len == CAP_UNFINISHED) return level; | ||
198 | return luaL_error(ms->L, "invalid pattern capture"); | ||
199 | } | ||
200 | |||
201 | |||
202 | static const char *classend (MatchState *ms, const char *p) { | ||
203 | switch (*p++) { | ||
204 | case L_ESC: { | ||
205 | if (*p == '\0') | ||
206 | luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); | ||
207 | return p+1; | ||
208 | } | ||
209 | case '[': { | ||
210 | if (*p == '^') p++; | ||
211 | do { /* look for a `]' */ | ||
212 | if (*p == '\0') | ||
213 | luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); | ||
214 | if (*(p++) == L_ESC && *p != '\0') | ||
215 | p++; /* skip escapes (e.g. `%]') */ | ||
216 | } while (*p != ']'); | ||
217 | return p+1; | ||
218 | } | ||
219 | default: { | ||
220 | return p; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
225 | |||
226 | static int match_class (int c, int cl) { | ||
227 | int res; | ||
228 | switch (tolower(cl)) { | ||
229 | case 'a' : res = isalpha(c); break; | ||
230 | case 'c' : res = iscntrl(c); break; | ||
231 | case 'd' : res = isdigit(c); break; | ||
232 | case 'l' : res = islower(c); break; | ||
233 | case 'p' : res = ispunct(c); break; | ||
234 | case 's' : res = isspace(c); break; | ||
235 | case 'u' : res = isupper(c); break; | ||
236 | case 'w' : res = isalnum(c); break; | ||
237 | case 'x' : res = isxdigit(c); break; | ||
238 | case 'z' : res = (c == 0); break; | ||
239 | default: return (cl == c); | ||
240 | } | ||
241 | return (islower(cl) ? res : !res); | ||
242 | } | ||
243 | |||
244 | |||
245 | static int matchbracketclass (int c, const char *p, const char *ec) { | ||
246 | int sig = 1; | ||
247 | if (*(p+1) == '^') { | ||
248 | sig = 0; | ||
249 | p++; /* skip the `^' */ | ||
250 | } | ||
251 | while (++p < ec) { | ||
252 | if (*p == L_ESC) { | ||
253 | p++; | ||
254 | if (match_class(c, uchar(*p))) | ||
255 | return sig; | ||
256 | } | ||
257 | else if ((*(p+1) == '-') && (p+2 < ec)) { | ||
258 | p+=2; | ||
259 | if (uchar(*(p-2)) <= c && c <= uchar(*p)) | ||
260 | return sig; | ||
261 | } | ||
262 | else if (uchar(*p) == c) return sig; | ||
263 | } | ||
264 | return !sig; | ||
265 | } | ||
266 | |||
267 | |||
268 | static int singlematch (int c, const char *p, const char *ep) { | ||
269 | switch (*p) { | ||
270 | case '.': return 1; /* matches any char */ | ||
271 | case L_ESC: return match_class(c, uchar(*(p+1))); | ||
272 | case '[': return matchbracketclass(c, p, ep-1); | ||
273 | default: return (uchar(*p) == c); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | |||
278 | static const char *match (MatchState *ms, const char *s, const char *p); | ||
279 | |||
280 | |||
281 | static const char *matchbalance (MatchState *ms, const char *s, | ||
282 | const char *p) { | ||
283 | if (*p == 0 || *(p+1) == 0) | ||
284 | luaL_error(ms->L, "unbalanced pattern"); | ||
285 | if (*s != *p) return NULL; | ||
286 | else { | ||
287 | int b = *p; | ||
288 | int e = *(p+1); | ||
289 | int cont = 1; | ||
290 | while (++s < ms->src_end) { | ||
291 | if (*s == e) { | ||
292 | if (--cont == 0) return s+1; | ||
293 | } | ||
294 | else if (*s == b) cont++; | ||
295 | } | ||
296 | } | ||
297 | return NULL; /* string ends out of balance */ | ||
298 | } | ||
299 | |||
300 | |||
301 | static const char *max_expand (MatchState *ms, const char *s, | ||
302 | const char *p, const char *ep) { | ||
303 | ptrdiff_t i = 0; /* counts maximum expand for item */ | ||
304 | while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep)) | ||
305 | i++; | ||
306 | /* keeps trying to match with the maximum repetitions */ | ||
307 | while (i>=0) { | ||
308 | const char *res = match(ms, (s+i), ep+1); | ||
309 | if (res) return res; | ||
310 | i--; /* else didn't match; reduce 1 repetition to try again */ | ||
311 | } | ||
312 | return NULL; | ||
313 | } | ||
314 | |||
315 | |||
316 | static const char *min_expand (MatchState *ms, const char *s, | ||
317 | const char *p, const char *ep) { | ||
318 | for (;;) { | ||
319 | const char *res = match(ms, s, ep+1); | ||
320 | if (res != NULL) | ||
321 | return res; | ||
322 | else if (s<ms->src_end && singlematch(uchar(*s), p, ep)) | ||
323 | s++; /* try with one more repetition */ | ||
324 | else return NULL; | ||
325 | } | ||
326 | } | ||
327 | |||
328 | |||
329 | static const char *start_capture (MatchState *ms, const char *s, | ||
330 | const char *p, int what) { | ||
331 | const char *res; | ||
332 | int level = ms->level; | ||
333 | if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); | ||
334 | ms->capture[level].init = s; | ||
335 | ms->capture[level].len = what; | ||
336 | ms->level = level+1; | ||
337 | if ((res=match(ms, s, p)) == NULL) /* match failed? */ | ||
338 | ms->level--; /* undo capture */ | ||
339 | return res; | ||
340 | } | ||
341 | |||
342 | |||
343 | static const char *end_capture (MatchState *ms, const char *s, | ||
344 | const char *p) { | ||
345 | int l = capture_to_close(ms); | ||
346 | const char *res; | ||
347 | ms->capture[l].len = s - ms->capture[l].init; /* close capture */ | ||
348 | if ((res = match(ms, s, p)) == NULL) /* match failed? */ | ||
349 | ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ | ||
350 | return res; | ||
351 | } | ||
352 | |||
353 | |||
354 | static const char *match_capture (MatchState *ms, const char *s, int l) { | ||
355 | size_t len; | ||
356 | l = check_capture(ms, l); | ||
357 | len = ms->capture[l].len; | ||
358 | if ((size_t)(ms->src_end-s) >= len && | ||
359 | memcmp(ms->capture[l].init, s, len) == 0) | ||
360 | return s+len; | ||
361 | else return NULL; | ||
362 | } | ||
363 | |||
364 | |||
365 | static const char *match (MatchState *ms, const char *s, const char *p) { | ||
366 | init: /* using goto's to optimize tail recursion */ | ||
367 | switch (*p) { | ||
368 | case '(': { /* start capture */ | ||
369 | if (*(p+1) == ')') /* position capture? */ | ||
370 | return start_capture(ms, s, p+2, CAP_POSITION); | ||
371 | else | ||
372 | return start_capture(ms, s, p+1, CAP_UNFINISHED); | ||
373 | } | ||
374 | case ')': { /* end capture */ | ||
375 | return end_capture(ms, s, p+1); | ||
376 | } | ||
377 | case L_ESC: { | ||
378 | switch (*(p+1)) { | ||
379 | case 'b': { /* balanced string? */ | ||
380 | s = matchbalance(ms, s, p+2); | ||
381 | if (s == NULL) return NULL; | ||
382 | p+=4; goto init; /* else return match(ms, s, p+4); */ | ||
383 | } | ||
384 | case 'f': { /* frontier? */ | ||
385 | const char *ep; char previous; | ||
386 | p += 2; | ||
387 | if (*p != '[') | ||
388 | luaL_error(ms->L, "missing " LUA_QL("[") " after " | ||
389 | LUA_QL("%%f") " in pattern"); | ||
390 | ep = classend(ms, p); /* points to what is next */ | ||
391 | previous = (s == ms->src_init) ? '\0' : *(s-1); | ||
392 | if (matchbracketclass(uchar(previous), p, ep-1) || | ||
393 | !matchbracketclass(uchar(*s), p, ep-1)) return NULL; | ||
394 | p=ep; goto init; /* else return match(ms, s, ep); */ | ||
395 | } | ||
396 | default: { | ||
397 | if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ | ||
398 | s = match_capture(ms, s, uchar(*(p+1))); | ||
399 | if (s == NULL) return NULL; | ||
400 | p+=2; goto init; /* else return match(ms, s, p+2) */ | ||
401 | } | ||
402 | goto dflt; /* case default */ | ||
403 | } | ||
404 | } | ||
405 | } | ||
406 | case '\0': { /* end of pattern */ | ||
407 | return s; /* match succeeded */ | ||
408 | } | ||
409 | case '$': { | ||
410 | if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ | ||
411 | return (s == ms->src_end) ? s : NULL; /* check end of string */ | ||
412 | else goto dflt; | ||
413 | } | ||
414 | default: dflt: { /* it is a pattern item */ | ||
415 | const char *ep = classend(ms, p); /* points to what is next */ | ||
416 | int m = s<ms->src_end && singlematch(uchar(*s), p, ep); | ||
417 | switch (*ep) { | ||
418 | case '?': { /* optional */ | ||
419 | const char *res; | ||
420 | if (m && ((res=match(ms, s+1, ep+1)) != NULL)) | ||
421 | return res; | ||
422 | p=ep+1; goto init; /* else return match(ms, s, ep+1); */ | ||
423 | } | ||
424 | case '*': { /* 0 or more repetitions */ | ||
425 | return max_expand(ms, s, p, ep); | ||
426 | } | ||
427 | case '+': { /* 1 or more repetitions */ | ||
428 | return (m ? max_expand(ms, s+1, p, ep) : NULL); | ||
429 | } | ||
430 | case '-': { /* 0 or more repetitions (minimum) */ | ||
431 | return min_expand(ms, s, p, ep); | ||
432 | } | ||
433 | default: { | ||
434 | if (!m) return NULL; | ||
435 | s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ | ||
436 | } | ||
437 | } | ||
438 | } | ||
439 | } | ||
440 | } | ||
441 | |||
442 | |||
443 | |||
444 | static const char *lmemfind (const char *s1, size_t l1, | ||
445 | const char *s2, size_t l2) { | ||
446 | if (l2 == 0) return s1; /* empty strings are everywhere */ | ||
447 | else if (l2 > l1) return NULL; /* avoids a negative `l1' */ | ||
448 | else { | ||
449 | const char *init; /* to search for a `*s2' inside `s1' */ | ||
450 | l2--; /* 1st char will be checked by `memchr' */ | ||
451 | l1 = l1-l2; /* `s2' cannot be found after that */ | ||
452 | while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { | ||
453 | init++; /* 1st char is already checked */ | ||
454 | if (memcmp(init, s2+1, l2) == 0) | ||
455 | return init-1; | ||
456 | else { /* correct `l1' and `s1' to try again */ | ||
457 | l1 -= init-s1; | ||
458 | s1 = init; | ||
459 | } | ||
460 | } | ||
461 | return NULL; /* not found */ | ||
462 | } | ||
463 | } | ||
464 | |||
465 | |||
466 | static void push_onecapture (MatchState *ms, int i, const char *s, | ||
467 | const char *e) { | ||
468 | if (i >= ms->level) { | ||
469 | if (i == 0) /* ms->level == 0, too */ | ||
470 | lua_pushlstring(ms->L, s, e - s); /* add whole match */ | ||
471 | else | ||
472 | luaL_error(ms->L, "invalid capture index"); | ||
473 | } | ||
474 | else { | ||
475 | ptrdiff_t l = ms->capture[i].len; | ||
476 | if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); | ||
477 | if (l == CAP_POSITION) | ||
478 | lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); | ||
479 | else | ||
480 | lua_pushlstring(ms->L, ms->capture[i].init, l); | ||
481 | } | ||
482 | } | ||
483 | |||
484 | |||
485 | static int push_captures (MatchState *ms, const char *s, const char *e) { | ||
486 | int i; | ||
487 | int nlevels = (ms->level == 0 && s) ? 1 : ms->level; | ||
488 | luaL_checkstack(ms->L, nlevels, "too many captures"); | ||
489 | for (i = 0; i < nlevels; i++) | ||
490 | push_onecapture(ms, i, s, e); | ||
491 | return nlevels; /* number of strings pushed */ | ||
492 | } | ||
493 | |||
494 | |||
495 | static int str_find_aux (lua_State *L, int find) { | ||
496 | size_t l1, l2; | ||
497 | const char *s = luaL_checklstring(L, 1, &l1); | ||
498 | const char *p = luaL_checklstring(L, 2, &l2); | ||
499 | ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; | ||
500 | if (init < 0) init = 0; | ||
501 | else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; | ||
502 | if (find && (lua_toboolean(L, 4) || /* explicit request? */ | ||
503 | strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ | ||
504 | /* do a plain search */ | ||
505 | const char *s2 = lmemfind(s+init, l1-init, p, l2); | ||
506 | if (s2) { | ||
507 | lua_pushinteger(L, s2-s+1); | ||
508 | lua_pushinteger(L, s2-s+l2); | ||
509 | return 2; | ||
510 | } | ||
511 | } | ||
512 | else { | ||
513 | MatchState ms; | ||
514 | int anchor = (*p == '^') ? (p++, 1) : 0; | ||
515 | const char *s1=s+init; | ||
516 | ms.L = L; | ||
517 | ms.src_init = s; | ||
518 | ms.src_end = s+l1; | ||
519 | do { | ||
520 | const char *res; | ||
521 | ms.level = 0; | ||
522 | if ((res=match(&ms, s1, p)) != NULL) { | ||
523 | if (find) { | ||
524 | lua_pushinteger(L, s1-s+1); /* start */ | ||
525 | lua_pushinteger(L, res-s); /* end */ | ||
526 | return push_captures(&ms, NULL, 0) + 2; | ||
527 | } | ||
528 | else | ||
529 | return push_captures(&ms, s1, res); | ||
530 | } | ||
531 | } while (s1++ < ms.src_end && !anchor); | ||
532 | } | ||
533 | lua_pushnil(L); /* not found */ | ||
534 | return 1; | ||
535 | } | ||
536 | |||
537 | |||
538 | static int str_find (lua_State *L) { | ||
539 | return str_find_aux(L, 1); | ||
540 | } | ||
541 | |||
542 | |||
543 | static int str_match (lua_State *L) { | ||
544 | return str_find_aux(L, 0); | ||
545 | } | ||
546 | |||
547 | |||
548 | static int gmatch_aux (lua_State *L) { | ||
549 | MatchState ms; | ||
550 | size_t ls; | ||
551 | const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); | ||
552 | const char *p = lua_tostring(L, lua_upvalueindex(2)); | ||
553 | const char *src; | ||
554 | ms.L = L; | ||
555 | ms.src_init = s; | ||
556 | ms.src_end = s+ls; | ||
557 | for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); | ||
558 | src <= ms.src_end; | ||
559 | src++) { | ||
560 | const char *e; | ||
561 | ms.level = 0; | ||
562 | if ((e = match(&ms, src, p)) != NULL) { | ||
563 | lua_Integer newstart = e-s; | ||
564 | if (e == src) newstart++; /* empty match? go at least one position */ | ||
565 | lua_pushinteger(L, newstart); | ||
566 | lua_replace(L, lua_upvalueindex(3)); | ||
567 | return push_captures(&ms, src, e); | ||
568 | } | ||
569 | } | ||
570 | return 0; /* not found */ | ||
571 | } | ||
572 | |||
573 | |||
574 | static int gmatch (lua_State *L) { | ||
575 | luaL_checkstring(L, 1); | ||
576 | luaL_checkstring(L, 2); | ||
577 | lua_settop(L, 2); | ||
578 | lua_pushinteger(L, 0); | ||
579 | lua_pushcclosure(L, gmatch_aux, 3); | ||
580 | return 1; | ||
581 | } | ||
582 | |||
583 | |||
584 | static int gfind_nodef (lua_State *L) { | ||
585 | return luaL_error(L, LUA_QL("string.gfind") " was renamed to " | ||
586 | LUA_QL("string.gmatch")); | ||
587 | } | ||
588 | |||
589 | |||
590 | static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, | ||
591 | const char *e) { | ||
592 | size_t l, i; | ||
593 | const char *news = lua_tolstring(ms->L, 3, &l); | ||
594 | for (i = 0; i < l; i++) { | ||
595 | if (news[i] != L_ESC) | ||
596 | luaL_addchar(b, news[i]); | ||
597 | else { | ||
598 | i++; /* skip ESC */ | ||
599 | if (!isdigit(uchar(news[i]))) | ||
600 | luaL_addchar(b, news[i]); | ||
601 | else if (news[i] == '0') | ||
602 | luaL_addlstring(b, s, e - s); | ||
603 | else { | ||
604 | push_onecapture(ms, news[i] - '1', s, e); | ||
605 | luaL_addvalue(b); /* add capture to accumulated result */ | ||
606 | } | ||
607 | } | ||
608 | } | ||
609 | } | ||
610 | |||
611 | |||
612 | static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, | ||
613 | const char *e) { | ||
614 | lua_State *L = ms->L; | ||
615 | switch (lua_type(L, 3)) { | ||
616 | case LUA_TNUMBER: | ||
617 | case LUA_TSTRING: { | ||
618 | add_s(ms, b, s, e); | ||
619 | return; | ||
620 | } | ||
621 | case LUA_TFUNCTION: { | ||
622 | int n; | ||
623 | lua_pushvalue(L, 3); | ||
624 | n = push_captures(ms, s, e); | ||
625 | lua_call(L, n, 1); | ||
626 | break; | ||
627 | } | ||
628 | case LUA_TTABLE: { | ||
629 | push_onecapture(ms, 0, s, e); | ||
630 | lua_gettable(L, 3); | ||
631 | break; | ||
632 | } | ||
633 | } | ||
634 | if (!lua_toboolean(L, -1)) { /* nil or false? */ | ||
635 | lua_pop(L, 1); | ||
636 | lua_pushlstring(L, s, e - s); /* keep original text */ | ||
637 | } | ||
638 | else if (!lua_isstring(L, -1)) | ||
639 | luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); | ||
640 | luaL_addvalue(b); /* add result to accumulator */ | ||
641 | } | ||
642 | |||
643 | |||
644 | static int str_gsub (lua_State *L) { | ||
645 | size_t srcl; | ||
646 | const char *src = luaL_checklstring(L, 1, &srcl); | ||
647 | const char *p = luaL_checkstring(L, 2); | ||
648 | int tr = lua_type(L, 3); | ||
649 | int max_s = luaL_optint(L, 4, srcl+1); | ||
650 | int anchor = (*p == '^') ? (p++, 1) : 0; | ||
651 | int n = 0; | ||
652 | MatchState ms; | ||
653 | luaL_Buffer b; | ||
654 | luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || | ||
655 | tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, | ||
656 | "string/function/table expected"); | ||
657 | luaL_buffinit(L, &b); | ||
658 | ms.L = L; | ||
659 | ms.src_init = src; | ||
660 | ms.src_end = src+srcl; | ||
661 | while (n < max_s) { | ||
662 | const char *e; | ||
663 | ms.level = 0; | ||
664 | e = match(&ms, src, p); | ||
665 | if (e) { | ||
666 | n++; | ||
667 | add_value(&ms, &b, src, e); | ||
668 | } | ||
669 | if (e && e>src) /* non empty match? */ | ||
670 | src = e; /* skip it */ | ||
671 | else if (src < ms.src_end) | ||
672 | luaL_addchar(&b, *src++); | ||
673 | else break; | ||
674 | if (anchor) break; | ||
675 | } | ||
676 | luaL_addlstring(&b, src, ms.src_end-src); | ||
677 | luaL_pushresult(&b); | ||
678 | lua_pushinteger(L, n); /* number of substitutions */ | ||
679 | return 2; | ||
680 | } | ||
681 | |||
682 | /* }====================================================== */ | ||
683 | |||
684 | |||
685 | /* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ | ||
686 | #define MAX_ITEM 512 | ||
687 | /* valid flags in a format specification */ | ||
688 | #define FLAGS "-+ #0" | ||
689 | /* | ||
690 | ** maximum size of each format specification (such as '%-099.99d') | ||
691 | ** (+10 accounts for %99.99x plus margin of error) | ||
692 | */ | ||
693 | #define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) | ||
694 | |||
695 | |||
696 | static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { | ||
697 | size_t l; | ||
698 | const char *s = luaL_checklstring(L, arg, &l); | ||
699 | luaL_addchar(b, '"'); | ||
700 | while (l--) { | ||
701 | switch (*s) { | ||
702 | case '"': case '\\': case '\n': { | ||
703 | luaL_addchar(b, '\\'); | ||
704 | luaL_addchar(b, *s); | ||
705 | break; | ||
706 | } | ||
707 | case '\r': { | ||
708 | luaL_addlstring(b, "\\r", 2); | ||
709 | break; | ||
710 | } | ||
711 | case '\0': { | ||
712 | luaL_addlstring(b, "\\000", 4); | ||
713 | break; | ||
714 | } | ||
715 | default: { | ||
716 | luaL_addchar(b, *s); | ||
717 | break; | ||
718 | } | ||
719 | } | ||
720 | s++; | ||
721 | } | ||
722 | luaL_addchar(b, '"'); | ||
723 | } | ||
724 | |||
725 | static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { | ||
726 | const char *p = strfrmt; | ||
727 | while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ | ||
728 | if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) | ||
729 | luaL_error(L, "invalid format (repeated flags)"); | ||
730 | if (isdigit(uchar(*p))) p++; /* skip width */ | ||
731 | if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ | ||
732 | if (*p == '.') { | ||
733 | p++; | ||
734 | if (isdigit(uchar(*p))) p++; /* skip precision */ | ||
735 | if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ | ||
736 | } | ||
737 | if (isdigit(uchar(*p))) | ||
738 | luaL_error(L, "invalid format (width or precision too long)"); | ||
739 | *(form++) = '%'; | ||
740 | strncpy(form, strfrmt, p - strfrmt + 1); | ||
741 | form += p - strfrmt + 1; | ||
742 | *form = '\0'; | ||
743 | return p; | ||
744 | } | ||
745 | |||
746 | |||
747 | static void addintlen (char *form) { | ||
748 | size_t l = strlen(form); | ||
749 | char spec = form[l - 1]; | ||
750 | strcpy(form + l - 1, LUA_INTFRMLEN); | ||
751 | form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; | ||
752 | form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; | ||
753 | } | ||
754 | |||
755 | |||
756 | static int str_format (lua_State *L) { | ||
757 | int top = lua_gettop(L); | ||
758 | int arg = 1; | ||
759 | size_t sfl; | ||
760 | const char *strfrmt = luaL_checklstring(L, arg, &sfl); | ||
761 | const char *strfrmt_end = strfrmt+sfl; | ||
762 | luaL_Buffer b; | ||
763 | luaL_buffinit(L, &b); | ||
764 | while (strfrmt < strfrmt_end) { | ||
765 | if (*strfrmt != L_ESC) | ||
766 | luaL_addchar(&b, *strfrmt++); | ||
767 | else if (*++strfrmt == L_ESC) | ||
768 | luaL_addchar(&b, *strfrmt++); /* %% */ | ||
769 | else { /* format item */ | ||
770 | char form[MAX_FORMAT]; /* to store the format (`%...') */ | ||
771 | char buff[MAX_ITEM]; /* to store the formatted item */ | ||
772 | if (++arg > top) | ||
773 | luaL_argerror(L, arg, "no value"); | ||
774 | strfrmt = scanformat(L, strfrmt, form); | ||
775 | switch (*strfrmt++) { | ||
776 | case 'c': { | ||
777 | sprintf(buff, form, (int)luaL_checknumber(L, arg)); | ||
778 | break; | ||
779 | } | ||
780 | case 'd': case 'i': { | ||
781 | addintlen(form); | ||
782 | sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); | ||
783 | break; | ||
784 | } | ||
785 | case 'o': case 'u': case 'x': case 'X': { | ||
786 | addintlen(form); | ||
787 | sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); | ||
788 | break; | ||
789 | } | ||
790 | case 'e': case 'E': case 'f': | ||
791 | case 'g': case 'G': { | ||
792 | sprintf(buff, form, (double)luaL_checknumber(L, arg)); | ||
793 | break; | ||
794 | } | ||
795 | case 'q': { | ||
796 | addquoted(L, &b, arg); | ||
797 | continue; /* skip the 'addsize' at the end */ | ||
798 | } | ||
799 | case 's': { | ||
800 | size_t l; | ||
801 | const char *s = luaL_checklstring(L, arg, &l); | ||
802 | if (!strchr(form, '.') && l >= 100) { | ||
803 | /* no precision and string is too long to be formatted; | ||
804 | keep original string */ | ||
805 | lua_pushvalue(L, arg); | ||
806 | luaL_addvalue(&b); | ||
807 | continue; /* skip the `addsize' at the end */ | ||
808 | } | ||
809 | else { | ||
810 | sprintf(buff, form, s); | ||
811 | break; | ||
812 | } | ||
813 | } | ||
814 | default: { /* also treat cases `pnLlh' */ | ||
815 | return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " | ||
816 | LUA_QL("format"), *(strfrmt - 1)); | ||
817 | } | ||
818 | } | ||
819 | luaL_addlstring(&b, buff, strlen(buff)); | ||
820 | } | ||
821 | } | ||
822 | luaL_pushresult(&b); | ||
823 | return 1; | ||
824 | } | ||
825 | |||
826 | |||
827 | static const luaL_Reg strlib[] = { | ||
828 | {"byte", str_byte}, | ||
829 | {"char", str_char}, | ||
830 | {"dump", str_dump}, | ||
831 | {"find", str_find}, | ||
832 | {"format", str_format}, | ||
833 | {"gfind", gfind_nodef}, | ||
834 | {"gmatch", gmatch}, | ||
835 | {"gsub", str_gsub}, | ||
836 | {"len", str_len}, | ||
837 | {"lower", str_lower}, | ||
838 | {"match", str_match}, | ||
839 | {"rep", str_rep}, | ||
840 | {"reverse", str_reverse}, | ||
841 | {"sub", str_sub}, | ||
842 | {"upper", str_upper}, | ||
843 | {NULL, NULL} | ||
844 | }; | ||
845 | |||
846 | |||
847 | static void createmetatable (lua_State *L) { | ||
848 | lua_createtable(L, 0, 1); /* create metatable for strings */ | ||
849 | lua_pushliteral(L, ""); /* dummy string */ | ||
850 | lua_pushvalue(L, -2); | ||
851 | lua_setmetatable(L, -2); /* set string metatable */ | ||
852 | lua_pop(L, 1); /* pop dummy string */ | ||
853 | lua_pushvalue(L, -2); /* string library... */ | ||
854 | lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ | ||
855 | lua_pop(L, 1); /* pop metatable */ | ||
856 | } | ||
857 | |||
858 | |||
859 | /* | ||
860 | ** Open string library | ||
861 | */ | ||
862 | LUALIB_API int luaopen_string (lua_State *L) { | ||
863 | luaL_register(L, LUA_STRLIBNAME, strlib); | ||
864 | #if defined(LUA_COMPAT_GFIND) | ||
865 | lua_getfield(L, -1, "gmatch"); | ||
866 | lua_setfield(L, -2, "gfind"); | ||
867 | #endif | ||
868 | createmetatable(L); | ||
869 | return 1; | ||
870 | } | ||
871 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ltable.c b/libraries/LuaJIT-1.1.7/src/ltable.c new file mode 100644 index 0000000..6b226ad --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ltable.c | |||
@@ -0,0 +1,588 @@ | |||
1 | /* | ||
2 | ** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $ | ||
3 | ** Lua tables (hash) | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | /* | ||
9 | ** Implementation of tables (aka arrays, objects, or hash tables). | ||
10 | ** Tables keep its elements in two parts: an array part and a hash part. | ||
11 | ** Non-negative integer keys are all candidates to be kept in the array | ||
12 | ** part. The actual size of the array is the largest `n' such that at | ||
13 | ** least half the slots between 0 and n are in use. | ||
14 | ** Hash uses a mix of chained scatter table with Brent's variation. | ||
15 | ** A main invariant of these tables is that, if an element is not | ||
16 | ** in its main position (i.e. the `original' position that its hash gives | ||
17 | ** to it), then the colliding element is in its own main position. | ||
18 | ** Hence even when the load factor reaches 100%, performance remains good. | ||
19 | */ | ||
20 | |||
21 | #include <math.h> | ||
22 | #include <string.h> | ||
23 | |||
24 | #define ltable_c | ||
25 | #define LUA_CORE | ||
26 | |||
27 | #include "lua.h" | ||
28 | |||
29 | #include "ldebug.h" | ||
30 | #include "ldo.h" | ||
31 | #include "lgc.h" | ||
32 | #include "lmem.h" | ||
33 | #include "lobject.h" | ||
34 | #include "lstate.h" | ||
35 | #include "ltable.h" | ||
36 | |||
37 | |||
38 | /* | ||
39 | ** max size of array part is 2^MAXBITS | ||
40 | */ | ||
41 | #if LUAI_BITSINT > 26 | ||
42 | #define MAXBITS 26 | ||
43 | #else | ||
44 | #define MAXBITS (LUAI_BITSINT-2) | ||
45 | #endif | ||
46 | |||
47 | #define MAXASIZE (1 << MAXBITS) | ||
48 | |||
49 | |||
50 | #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) | ||
51 | |||
52 | #define hashstr(t,str) hashpow2(t, (str)->tsv.hash) | ||
53 | #define hashboolean(t,p) hashpow2(t, p) | ||
54 | |||
55 | |||
56 | /* | ||
57 | ** for some types, it is better to avoid modulus by power of 2, as | ||
58 | ** they tend to have many 2 factors. | ||
59 | */ | ||
60 | #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) | ||
61 | |||
62 | |||
63 | #define hashpointer(t,p) hashmod(t, IntPoint(p)) | ||
64 | |||
65 | |||
66 | /* | ||
67 | ** number of ints inside a lua_Number | ||
68 | */ | ||
69 | #define numints cast_int(sizeof(lua_Number)/sizeof(int)) | ||
70 | |||
71 | |||
72 | |||
73 | #define dummynode (&dummynode_) | ||
74 | |||
75 | static const Node dummynode_ = { | ||
76 | {{NULL}, LUA_TNIL}, /* value */ | ||
77 | {{{NULL}, LUA_TNIL, NULL}} /* key */ | ||
78 | }; | ||
79 | |||
80 | |||
81 | /* | ||
82 | ** hash for lua_Numbers | ||
83 | */ | ||
84 | static Node *hashnum (const Table *t, lua_Number n) { | ||
85 | unsigned int a[numints]; | ||
86 | int i; | ||
87 | if (luai_numeq(n, 0)) /* avoid problems with -0 */ | ||
88 | return gnode(t, 0); | ||
89 | memcpy(a, &n, sizeof(a)); | ||
90 | for (i = 1; i < numints; i++) a[0] += a[i]; | ||
91 | return hashmod(t, a[0]); | ||
92 | } | ||
93 | |||
94 | |||
95 | |||
96 | /* | ||
97 | ** returns the `main' position of an element in a table (that is, the index | ||
98 | ** of its hash value) | ||
99 | */ | ||
100 | static Node *mainposition (const Table *t, const TValue *key) { | ||
101 | switch (ttype(key)) { | ||
102 | case LUA_TNUMBER: | ||
103 | return hashnum(t, nvalue(key)); | ||
104 | case LUA_TSTRING: | ||
105 | return hashstr(t, rawtsvalue(key)); | ||
106 | case LUA_TBOOLEAN: | ||
107 | return hashboolean(t, bvalue(key)); | ||
108 | case LUA_TLIGHTUSERDATA: | ||
109 | return hashpointer(t, pvalue(key)); | ||
110 | default: | ||
111 | return hashpointer(t, gcvalue(key)); | ||
112 | } | ||
113 | } | ||
114 | |||
115 | |||
116 | /* | ||
117 | ** returns the index for `key' if `key' is an appropriate key to live in | ||
118 | ** the array part of the table, -1 otherwise. | ||
119 | */ | ||
120 | static int arrayindex (const TValue *key) { | ||
121 | if (ttisnumber(key)) { | ||
122 | lua_Number n = nvalue(key); | ||
123 | int k; | ||
124 | lua_number2int(k, n); | ||
125 | if (luai_numeq(cast_num(k), n)) | ||
126 | return k; | ||
127 | } | ||
128 | return -1; /* `key' did not match some condition */ | ||
129 | } | ||
130 | |||
131 | |||
132 | /* | ||
133 | ** returns the index of a `key' for table traversals. First goes all | ||
134 | ** elements in the array part, then elements in the hash part. The | ||
135 | ** beginning of a traversal is signalled by -1. | ||
136 | */ | ||
137 | static int findindex (lua_State *L, Table *t, StkId key) { | ||
138 | int i; | ||
139 | if (ttisnil(key)) return -1; /* first iteration */ | ||
140 | i = arrayindex(key); | ||
141 | if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ | ||
142 | return i-1; /* yes; that's the index (corrected to C) */ | ||
143 | else { | ||
144 | Node *n = mainposition(t, key); | ||
145 | do { /* check whether `key' is somewhere in the chain */ | ||
146 | /* key may be dead already, but it is ok to use it in `next' */ | ||
147 | if (luaO_rawequalObj(key2tval(n), key) || | ||
148 | (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && | ||
149 | gcvalue(gkey(n)) == gcvalue(key))) { | ||
150 | i = cast_int(n - gnode(t, 0)); /* key index in hash table */ | ||
151 | /* hash elements are numbered after array ones */ | ||
152 | return i + t->sizearray; | ||
153 | } | ||
154 | else n = gnext(n); | ||
155 | } while (n); | ||
156 | luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ | ||
157 | return 0; /* to avoid warnings */ | ||
158 | } | ||
159 | } | ||
160 | |||
161 | |||
162 | int luaH_next (lua_State *L, Table *t, StkId key) { | ||
163 | int i = findindex(L, t, key); /* find original element */ | ||
164 | for (i++; i < t->sizearray; i++) { /* try first array part */ | ||
165 | if (!ttisnil(&t->array[i])) { /* a non-nil value? */ | ||
166 | setnvalue(key, cast_num(i+1)); | ||
167 | setobj2s(L, key+1, &t->array[i]); | ||
168 | return 1; | ||
169 | } | ||
170 | } | ||
171 | for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ | ||
172 | if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ | ||
173 | setobj2s(L, key, key2tval(gnode(t, i))); | ||
174 | setobj2s(L, key+1, gval(gnode(t, i))); | ||
175 | return 1; | ||
176 | } | ||
177 | } | ||
178 | return 0; /* no more elements */ | ||
179 | } | ||
180 | |||
181 | |||
182 | /* | ||
183 | ** {============================================================= | ||
184 | ** Rehash | ||
185 | ** ============================================================== | ||
186 | */ | ||
187 | |||
188 | |||
189 | static int computesizes (int nums[], int *narray) { | ||
190 | int i; | ||
191 | int twotoi; /* 2^i */ | ||
192 | int a = 0; /* number of elements smaller than 2^i */ | ||
193 | int na = 0; /* number of elements to go to array part */ | ||
194 | int n = 0; /* optimal size for array part */ | ||
195 | for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { | ||
196 | if (nums[i] > 0) { | ||
197 | a += nums[i]; | ||
198 | if (a > twotoi/2) { /* more than half elements present? */ | ||
199 | n = twotoi; /* optimal size (till now) */ | ||
200 | na = a; /* all elements smaller than n will go to array part */ | ||
201 | } | ||
202 | } | ||
203 | if (a == *narray) break; /* all elements already counted */ | ||
204 | } | ||
205 | *narray = n; | ||
206 | lua_assert(*narray/2 <= na && na <= *narray); | ||
207 | return na; | ||
208 | } | ||
209 | |||
210 | |||
211 | static int countint (const TValue *key, int *nums) { | ||
212 | int k = arrayindex(key); | ||
213 | if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ | ||
214 | nums[ceillog2(k)]++; /* count as such */ | ||
215 | return 1; | ||
216 | } | ||
217 | else | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | |||
222 | static int numusearray (const Table *t, int *nums) { | ||
223 | int lg; | ||
224 | int ttlg; /* 2^lg */ | ||
225 | int ause = 0; /* summation of `nums' */ | ||
226 | int i = 1; /* count to traverse all array keys */ | ||
227 | for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ | ||
228 | int lc = 0; /* counter */ | ||
229 | int lim = ttlg; | ||
230 | if (lim > t->sizearray) { | ||
231 | lim = t->sizearray; /* adjust upper limit */ | ||
232 | if (i > lim) | ||
233 | break; /* no more elements to count */ | ||
234 | } | ||
235 | /* count elements in range (2^(lg-1), 2^lg] */ | ||
236 | for (; i <= lim; i++) { | ||
237 | if (!ttisnil(&t->array[i-1])) | ||
238 | lc++; | ||
239 | } | ||
240 | nums[lg] += lc; | ||
241 | ause += lc; | ||
242 | } | ||
243 | return ause; | ||
244 | } | ||
245 | |||
246 | |||
247 | static int numusehash (const Table *t, int *nums, int *pnasize) { | ||
248 | int totaluse = 0; /* total number of elements */ | ||
249 | int ause = 0; /* summation of `nums' */ | ||
250 | int i = sizenode(t); | ||
251 | while (i--) { | ||
252 | Node *n = &t->node[i]; | ||
253 | if (!ttisnil(gval(n))) { | ||
254 | ause += countint(key2tval(n), nums); | ||
255 | totaluse++; | ||
256 | } | ||
257 | } | ||
258 | *pnasize += ause; | ||
259 | return totaluse; | ||
260 | } | ||
261 | |||
262 | |||
263 | static void setarrayvector (lua_State *L, Table *t, int size) { | ||
264 | int i; | ||
265 | luaM_reallocvector(L, t->array, t->sizearray, size, TValue); | ||
266 | for (i=t->sizearray; i<size; i++) | ||
267 | setnilvalue(&t->array[i]); | ||
268 | t->sizearray = size; | ||
269 | } | ||
270 | |||
271 | |||
272 | static void setnodevector (lua_State *L, Table *t, int size) { | ||
273 | int lsize; | ||
274 | if (size == 0) { /* no elements to hash part? */ | ||
275 | t->node = cast(Node *, dummynode); /* use common `dummynode' */ | ||
276 | lsize = 0; | ||
277 | } | ||
278 | else { | ||
279 | int i; | ||
280 | lsize = ceillog2(size); | ||
281 | if (lsize > MAXBITS) | ||
282 | luaG_runerror(L, "table overflow"); | ||
283 | size = twoto(lsize); | ||
284 | t->node = luaM_newvector(L, size, Node); | ||
285 | for (i=0; i<size; i++) { | ||
286 | Node *n = gnode(t, i); | ||
287 | gnext(n) = NULL; | ||
288 | setnilvalue(gkey(n)); | ||
289 | setnilvalue(gval(n)); | ||
290 | } | ||
291 | } | ||
292 | t->lsizenode = cast_byte(lsize); | ||
293 | t->lastfree = gnode(t, size); /* all positions are free */ | ||
294 | } | ||
295 | |||
296 | |||
297 | static void resize (lua_State *L, Table *t, int nasize, int nhsize) { | ||
298 | int i; | ||
299 | int oldasize = t->sizearray; | ||
300 | int oldhsize = t->lsizenode; | ||
301 | Node *nold = t->node; /* save old hash ... */ | ||
302 | if (nasize > oldasize) /* array part must grow? */ | ||
303 | setarrayvector(L, t, nasize); | ||
304 | /* create new hash part with appropriate size */ | ||
305 | setnodevector(L, t, nhsize); | ||
306 | if (nasize < oldasize) { /* array part must shrink? */ | ||
307 | t->sizearray = nasize; | ||
308 | /* re-insert elements from vanishing slice */ | ||
309 | for (i=nasize; i<oldasize; i++) { | ||
310 | if (!ttisnil(&t->array[i])) | ||
311 | setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]); | ||
312 | } | ||
313 | /* shrink array */ | ||
314 | luaM_reallocvector(L, t->array, oldasize, nasize, TValue); | ||
315 | } | ||
316 | /* re-insert elements from hash part */ | ||
317 | for (i = twoto(oldhsize) - 1; i >= 0; i--) { | ||
318 | Node *old = nold+i; | ||
319 | if (!ttisnil(gval(old))) | ||
320 | setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old)); | ||
321 | } | ||
322 | if (nold != dummynode) | ||
323 | luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ | ||
324 | } | ||
325 | |||
326 | |||
327 | void luaH_resizearray (lua_State *L, Table *t, int nasize) { | ||
328 | int nsize = (t->node == dummynode) ? 0 : sizenode(t); | ||
329 | resize(L, t, nasize, nsize); | ||
330 | } | ||
331 | |||
332 | |||
333 | static void rehash (lua_State *L, Table *t, const TValue *ek) { | ||
334 | int nasize, na; | ||
335 | int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */ | ||
336 | int i; | ||
337 | int totaluse; | ||
338 | for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ | ||
339 | nasize = numusearray(t, nums); /* count keys in array part */ | ||
340 | totaluse = nasize; /* all those keys are integer keys */ | ||
341 | totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ | ||
342 | /* count extra key */ | ||
343 | nasize += countint(ek, nums); | ||
344 | totaluse++; | ||
345 | /* compute new size for array part */ | ||
346 | na = computesizes(nums, &nasize); | ||
347 | /* resize the table to new computed sizes */ | ||
348 | resize(L, t, nasize, totaluse - na); | ||
349 | } | ||
350 | |||
351 | |||
352 | |||
353 | /* | ||
354 | ** }============================================================= | ||
355 | */ | ||
356 | |||
357 | |||
358 | Table *luaH_new (lua_State *L, int narray, int nhash) { | ||
359 | Table *t = luaM_new(L, Table); | ||
360 | luaC_link(L, obj2gco(t), LUA_TTABLE); | ||
361 | t->metatable = NULL; | ||
362 | t->flags = cast_byte(~0); | ||
363 | /* temporary values (kept only if some malloc fails) */ | ||
364 | t->array = NULL; | ||
365 | t->sizearray = 0; | ||
366 | t->lsizenode = 0; | ||
367 | t->node = cast(Node *, dummynode); | ||
368 | setarrayvector(L, t, narray); | ||
369 | setnodevector(L, t, nhash); | ||
370 | return t; | ||
371 | } | ||
372 | |||
373 | |||
374 | void luaH_free (lua_State *L, Table *t) { | ||
375 | if (t->node != dummynode) | ||
376 | luaM_freearray(L, t->node, sizenode(t), Node); | ||
377 | luaM_freearray(L, t->array, t->sizearray, TValue); | ||
378 | luaM_free(L, t); | ||
379 | } | ||
380 | |||
381 | |||
382 | static Node *getfreepos (Table *t) { | ||
383 | while (t->lastfree-- > t->node) { | ||
384 | if (ttisnil(gkey(t->lastfree))) | ||
385 | return t->lastfree; | ||
386 | } | ||
387 | return NULL; /* could not find a free place */ | ||
388 | } | ||
389 | |||
390 | |||
391 | |||
392 | /* | ||
393 | ** inserts a new key into a hash table; first, check whether key's main | ||
394 | ** position is free. If not, check whether colliding node is in its main | ||
395 | ** position or not: if it is not, move colliding node to an empty place and | ||
396 | ** put new key in its main position; otherwise (colliding node is in its main | ||
397 | ** position), new key goes to an empty position. | ||
398 | */ | ||
399 | TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | ||
400 | Node *mp = mainposition(t, key); | ||
401 | if (!ttisnil(gval(mp)) || mp == dummynode) { | ||
402 | Node *othern; | ||
403 | Node *n = getfreepos(t); /* get a free place */ | ||
404 | if (n == NULL) { /* cannot find a free place? */ | ||
405 | rehash(L, t, key); /* grow table */ | ||
406 | return luaH_set(L, t, key); /* re-insert key into grown table */ | ||
407 | } | ||
408 | lua_assert(n != dummynode); | ||
409 | othern = mainposition(t, key2tval(mp)); | ||
410 | if (othern != mp) { /* is colliding node out of its main position? */ | ||
411 | /* yes; move colliding node into free position */ | ||
412 | while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ | ||
413 | gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ | ||
414 | *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ | ||
415 | gnext(mp) = NULL; /* now `mp' is free */ | ||
416 | setnilvalue(gval(mp)); | ||
417 | } | ||
418 | else { /* colliding node is in its own main position */ | ||
419 | /* new node will go into free position */ | ||
420 | gnext(n) = gnext(mp); /* chain new position */ | ||
421 | gnext(mp) = n; | ||
422 | mp = n; | ||
423 | } | ||
424 | } | ||
425 | gkey(mp)->value = key->value; gkey(mp)->tt = key->tt; | ||
426 | luaC_barriert(L, t, key); | ||
427 | lua_assert(ttisnil(gval(mp))); | ||
428 | return gval(mp); | ||
429 | } | ||
430 | |||
431 | |||
432 | /* | ||
433 | ** search function for integers | ||
434 | */ | ||
435 | const TValue *luaH_getnum (Table *t, int key) { | ||
436 | /* (1 <= key && key <= t->sizearray) */ | ||
437 | if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) | ||
438 | return &t->array[key-1]; | ||
439 | else { | ||
440 | lua_Number nk = cast_num(key); | ||
441 | Node *n = hashnum(t, nk); | ||
442 | do { /* check whether `key' is somewhere in the chain */ | ||
443 | if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) | ||
444 | return gval(n); /* that's it */ | ||
445 | else n = gnext(n); | ||
446 | } while (n); | ||
447 | return luaO_nilobject; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | |||
452 | /* | ||
453 | ** search function for strings | ||
454 | */ | ||
455 | const TValue *luaH_getstr (Table *t, TString *key) { | ||
456 | Node *n = hashstr(t, key); | ||
457 | do { /* check whether `key' is somewhere in the chain */ | ||
458 | if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) | ||
459 | return gval(n); /* that's it */ | ||
460 | else n = gnext(n); | ||
461 | } while (n); | ||
462 | return luaO_nilobject; | ||
463 | } | ||
464 | |||
465 | |||
466 | /* | ||
467 | ** main search function | ||
468 | */ | ||
469 | const TValue *luaH_get (Table *t, const TValue *key) { | ||
470 | switch (ttype(key)) { | ||
471 | case LUA_TNIL: return luaO_nilobject; | ||
472 | case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); | ||
473 | case LUA_TNUMBER: { | ||
474 | int k; | ||
475 | lua_Number n = nvalue(key); | ||
476 | lua_number2int(k, n); | ||
477 | if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ | ||
478 | return luaH_getnum(t, k); /* use specialized version */ | ||
479 | /* else go through */ | ||
480 | } | ||
481 | default: { | ||
482 | Node *n = mainposition(t, key); | ||
483 | do { /* check whether `key' is somewhere in the chain */ | ||
484 | if (luaO_rawequalObj(key2tval(n), key)) | ||
485 | return gval(n); /* that's it */ | ||
486 | else n = gnext(n); | ||
487 | } while (n); | ||
488 | return luaO_nilobject; | ||
489 | } | ||
490 | } | ||
491 | } | ||
492 | |||
493 | |||
494 | TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { | ||
495 | const TValue *p = luaH_get(t, key); | ||
496 | t->flags = 0; | ||
497 | if (p != luaO_nilobject) | ||
498 | return cast(TValue *, p); | ||
499 | else { | ||
500 | if (ttisnil(key)) luaG_runerror(L, "table index is nil"); | ||
501 | else if (ttisnumber(key) && luai_numisnan(nvalue(key))) | ||
502 | luaG_runerror(L, "table index is NaN"); | ||
503 | return luaH_newkey(L, t, key); | ||
504 | } | ||
505 | } | ||
506 | |||
507 | |||
508 | TValue *luaH_setnum (lua_State *L, Table *t, int key) { | ||
509 | const TValue *p = luaH_getnum(t, key); | ||
510 | if (p != luaO_nilobject) | ||
511 | return cast(TValue *, p); | ||
512 | else { | ||
513 | TValue k; | ||
514 | setnvalue(&k, cast_num(key)); | ||
515 | return luaH_newkey(L, t, &k); | ||
516 | } | ||
517 | } | ||
518 | |||
519 | |||
520 | TValue *luaH_setstr (lua_State *L, Table *t, TString *key) { | ||
521 | const TValue *p = luaH_getstr(t, key); | ||
522 | if (p != luaO_nilobject) | ||
523 | return cast(TValue *, p); | ||
524 | else { | ||
525 | TValue k; | ||
526 | setsvalue(L, &k, key); | ||
527 | return luaH_newkey(L, t, &k); | ||
528 | } | ||
529 | } | ||
530 | |||
531 | |||
532 | static int unbound_search (Table *t, unsigned int j) { | ||
533 | unsigned int i = j; /* i is zero or a present index */ | ||
534 | j++; | ||
535 | /* find `i' and `j' such that i is present and j is not */ | ||
536 | while (!ttisnil(luaH_getnum(t, j))) { | ||
537 | i = j; | ||
538 | j *= 2; | ||
539 | if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ | ||
540 | /* table was built with bad purposes: resort to linear search */ | ||
541 | i = 1; | ||
542 | while (!ttisnil(luaH_getnum(t, i))) i++; | ||
543 | return i - 1; | ||
544 | } | ||
545 | } | ||
546 | /* now do a binary search between them */ | ||
547 | while (j - i > 1) { | ||
548 | unsigned int m = (i+j)/2; | ||
549 | if (ttisnil(luaH_getnum(t, m))) j = m; | ||
550 | else i = m; | ||
551 | } | ||
552 | return i; | ||
553 | } | ||
554 | |||
555 | |||
556 | /* | ||
557 | ** Try to find a boundary in table `t'. A `boundary' is an integer index | ||
558 | ** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). | ||
559 | */ | ||
560 | int luaH_getn (Table *t) { | ||
561 | unsigned int j = t->sizearray; | ||
562 | if (j > 0 && ttisnil(&t->array[j - 1])) { | ||
563 | /* there is a boundary in the array part: (binary) search for it */ | ||
564 | unsigned int i = 0; | ||
565 | while (j - i > 1) { | ||
566 | unsigned int m = (i+j)/2; | ||
567 | if (ttisnil(&t->array[m - 1])) j = m; | ||
568 | else i = m; | ||
569 | } | ||
570 | return i; | ||
571 | } | ||
572 | /* else must find a boundary in hash part */ | ||
573 | else if (t->node == dummynode) /* hash part is empty? */ | ||
574 | return j; /* that is easy... */ | ||
575 | else return unbound_search(t, j); | ||
576 | } | ||
577 | |||
578 | |||
579 | |||
580 | #if defined(LUA_DEBUG) | ||
581 | |||
582 | Node *luaH_mainposition (const Table *t, const TValue *key) { | ||
583 | return mainposition(t, key); | ||
584 | } | ||
585 | |||
586 | int luaH_isdummy (Node *n) { return n == dummynode; } | ||
587 | |||
588 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/ltable.h b/libraries/LuaJIT-1.1.7/src/ltable.h new file mode 100644 index 0000000..a61c981 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ltable.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | ** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Lua tables (hash) | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef ltable_h | ||
8 | #define ltable_h | ||
9 | |||
10 | #include "lobject.h" | ||
11 | |||
12 | |||
13 | #define gnode(t,i) (&(t)->node[i]) | ||
14 | #define gkey(n) (&(n)->i_key.nk) | ||
15 | #define gval(n) (&(n)->i_val) | ||
16 | #define gnext(n) ((n)->i_key.nk.next) | ||
17 | |||
18 | #define key2tval(n) (&(n)->i_key.tvk) | ||
19 | |||
20 | |||
21 | LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); | ||
22 | LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); | ||
23 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); | ||
24 | LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); | ||
25 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); | ||
26 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); | ||
27 | LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); | ||
28 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); | ||
29 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); | ||
30 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); | ||
31 | LUAI_FUNC int luaH_getn (Table *t); | ||
32 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); | ||
33 | |||
34 | |||
35 | #if defined(LUA_DEBUG) | ||
36 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); | ||
37 | LUAI_FUNC int luaH_isdummy (Node *n); | ||
38 | #endif | ||
39 | |||
40 | |||
41 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/ltablib.c b/libraries/LuaJIT-1.1.7/src/ltablib.c new file mode 100644 index 0000000..b6d9cb4 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ltablib.c | |||
@@ -0,0 +1,287 @@ | |||
1 | /* | ||
2 | ** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $ | ||
3 | ** Library for Table Manipulation | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <stddef.h> | ||
9 | |||
10 | #define ltablib_c | ||
11 | #define LUA_LIB | ||
12 | |||
13 | #include "lua.h" | ||
14 | |||
15 | #include "lauxlib.h" | ||
16 | #include "lualib.h" | ||
17 | |||
18 | |||
19 | #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) | ||
20 | |||
21 | |||
22 | static int foreachi (lua_State *L) { | ||
23 | int i; | ||
24 | int n = aux_getn(L, 1); | ||
25 | luaL_checktype(L, 2, LUA_TFUNCTION); | ||
26 | for (i=1; i <= n; i++) { | ||
27 | lua_pushvalue(L, 2); /* function */ | ||
28 | lua_pushinteger(L, i); /* 1st argument */ | ||
29 | lua_rawgeti(L, 1, i); /* 2nd argument */ | ||
30 | lua_call(L, 2, 1); | ||
31 | if (!lua_isnil(L, -1)) | ||
32 | return 1; | ||
33 | lua_pop(L, 1); /* remove nil result */ | ||
34 | } | ||
35 | return 0; | ||
36 | } | ||
37 | |||
38 | |||
39 | static int foreach (lua_State *L) { | ||
40 | luaL_checktype(L, 1, LUA_TTABLE); | ||
41 | luaL_checktype(L, 2, LUA_TFUNCTION); | ||
42 | lua_pushnil(L); /* first key */ | ||
43 | while (lua_next(L, 1)) { | ||
44 | lua_pushvalue(L, 2); /* function */ | ||
45 | lua_pushvalue(L, -3); /* key */ | ||
46 | lua_pushvalue(L, -3); /* value */ | ||
47 | lua_call(L, 2, 1); | ||
48 | if (!lua_isnil(L, -1)) | ||
49 | return 1; | ||
50 | lua_pop(L, 2); /* remove value and result */ | ||
51 | } | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | |||
56 | static int maxn (lua_State *L) { | ||
57 | lua_Number max = 0; | ||
58 | luaL_checktype(L, 1, LUA_TTABLE); | ||
59 | lua_pushnil(L); /* first key */ | ||
60 | while (lua_next(L, 1)) { | ||
61 | lua_pop(L, 1); /* remove value */ | ||
62 | if (lua_type(L, -1) == LUA_TNUMBER) { | ||
63 | lua_Number v = lua_tonumber(L, -1); | ||
64 | if (v > max) max = v; | ||
65 | } | ||
66 | } | ||
67 | lua_pushnumber(L, max); | ||
68 | return 1; | ||
69 | } | ||
70 | |||
71 | |||
72 | static int getn (lua_State *L) { | ||
73 | lua_pushinteger(L, aux_getn(L, 1)); | ||
74 | return 1; | ||
75 | } | ||
76 | |||
77 | |||
78 | static int setn (lua_State *L) { | ||
79 | luaL_checktype(L, 1, LUA_TTABLE); | ||
80 | #ifndef luaL_setn | ||
81 | luaL_setn(L, 1, luaL_checkint(L, 2)); | ||
82 | #else | ||
83 | luaL_error(L, LUA_QL("setn") " is obsolete"); | ||
84 | #endif | ||
85 | lua_pushvalue(L, 1); | ||
86 | return 1; | ||
87 | } | ||
88 | |||
89 | |||
90 | static int tinsert (lua_State *L) { | ||
91 | int e = aux_getn(L, 1) + 1; /* first empty element */ | ||
92 | int pos; /* where to insert new element */ | ||
93 | switch (lua_gettop(L)) { | ||
94 | case 2: { /* called with only 2 arguments */ | ||
95 | pos = e; /* insert new element at the end */ | ||
96 | break; | ||
97 | } | ||
98 | case 3: { | ||
99 | int i; | ||
100 | pos = luaL_checkint(L, 2); /* 2nd argument is the position */ | ||
101 | if (pos > e) e = pos; /* `grow' array if necessary */ | ||
102 | for (i = e; i > pos; i--) { /* move up elements */ | ||
103 | lua_rawgeti(L, 1, i-1); | ||
104 | lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ | ||
105 | } | ||
106 | break; | ||
107 | } | ||
108 | default: { | ||
109 | return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); | ||
110 | } | ||
111 | } | ||
112 | luaL_setn(L, 1, e); /* new size */ | ||
113 | lua_rawseti(L, 1, pos); /* t[pos] = v */ | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | |||
118 | static int tremove (lua_State *L) { | ||
119 | int e = aux_getn(L, 1); | ||
120 | int pos = luaL_optint(L, 2, e); | ||
121 | if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ | ||
122 | return 0; /* nothing to remove */ | ||
123 | luaL_setn(L, 1, e - 1); /* t.n = n-1 */ | ||
124 | lua_rawgeti(L, 1, pos); /* result = t[pos] */ | ||
125 | for ( ;pos<e; pos++) { | ||
126 | lua_rawgeti(L, 1, pos+1); | ||
127 | lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ | ||
128 | } | ||
129 | lua_pushnil(L); | ||
130 | lua_rawseti(L, 1, e); /* t[e] = nil */ | ||
131 | return 1; | ||
132 | } | ||
133 | |||
134 | |||
135 | static void addfield (lua_State *L, luaL_Buffer *b, int i) { | ||
136 | lua_rawgeti(L, 1, i); | ||
137 | if (!lua_isstring(L, -1)) | ||
138 | luaL_error(L, "invalid value (%s) at index %d in table for " | ||
139 | LUA_QL("concat"), luaL_typename(L, -1), i); | ||
140 | luaL_addvalue(b); | ||
141 | } | ||
142 | |||
143 | |||
144 | static int tconcat (lua_State *L) { | ||
145 | luaL_Buffer b; | ||
146 | size_t lsep; | ||
147 | int i, last; | ||
148 | const char *sep = luaL_optlstring(L, 2, "", &lsep); | ||
149 | luaL_checktype(L, 1, LUA_TTABLE); | ||
150 | i = luaL_optint(L, 3, 1); | ||
151 | last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1)); | ||
152 | luaL_buffinit(L, &b); | ||
153 | for (; i < last; i++) { | ||
154 | addfield(L, &b, i); | ||
155 | luaL_addlstring(&b, sep, lsep); | ||
156 | } | ||
157 | if (i == last) /* add last value (if interval was not empty) */ | ||
158 | addfield(L, &b, i); | ||
159 | luaL_pushresult(&b); | ||
160 | return 1; | ||
161 | } | ||
162 | |||
163 | |||
164 | |||
165 | /* | ||
166 | ** {====================================================== | ||
167 | ** Quicksort | ||
168 | ** (based on `Algorithms in MODULA-3', Robert Sedgewick; | ||
169 | ** Addison-Wesley, 1993.) | ||
170 | */ | ||
171 | |||
172 | |||
173 | static void set2 (lua_State *L, int i, int j) { | ||
174 | lua_rawseti(L, 1, i); | ||
175 | lua_rawseti(L, 1, j); | ||
176 | } | ||
177 | |||
178 | static int sort_comp (lua_State *L, int a, int b) { | ||
179 | if (!lua_isnil(L, 2)) { /* function? */ | ||
180 | int res; | ||
181 | lua_pushvalue(L, 2); | ||
182 | lua_pushvalue(L, a-1); /* -1 to compensate function */ | ||
183 | lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */ | ||
184 | lua_call(L, 2, 1); | ||
185 | res = lua_toboolean(L, -1); | ||
186 | lua_pop(L, 1); | ||
187 | return res; | ||
188 | } | ||
189 | else /* a < b? */ | ||
190 | return lua_lessthan(L, a, b); | ||
191 | } | ||
192 | |||
193 | static void auxsort (lua_State *L, int l, int u) { | ||
194 | while (l < u) { /* for tail recursion */ | ||
195 | int i, j; | ||
196 | /* sort elements a[l], a[(l+u)/2] and a[u] */ | ||
197 | lua_rawgeti(L, 1, l); | ||
198 | lua_rawgeti(L, 1, u); | ||
199 | if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */ | ||
200 | set2(L, l, u); /* swap a[l] - a[u] */ | ||
201 | else | ||
202 | lua_pop(L, 2); | ||
203 | if (u-l == 1) break; /* only 2 elements */ | ||
204 | i = (l+u)/2; | ||
205 | lua_rawgeti(L, 1, i); | ||
206 | lua_rawgeti(L, 1, l); | ||
207 | if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */ | ||
208 | set2(L, i, l); | ||
209 | else { | ||
210 | lua_pop(L, 1); /* remove a[l] */ | ||
211 | lua_rawgeti(L, 1, u); | ||
212 | if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */ | ||
213 | set2(L, i, u); | ||
214 | else | ||
215 | lua_pop(L, 2); | ||
216 | } | ||
217 | if (u-l == 2) break; /* only 3 elements */ | ||
218 | lua_rawgeti(L, 1, i); /* Pivot */ | ||
219 | lua_pushvalue(L, -1); | ||
220 | lua_rawgeti(L, 1, u-1); | ||
221 | set2(L, i, u-1); | ||
222 | /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */ | ||
223 | i = l; j = u-1; | ||
224 | for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ | ||
225 | /* repeat ++i until a[i] >= P */ | ||
226 | while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { | ||
227 | if (i>u) luaL_error(L, "invalid order function for sorting"); | ||
228 | lua_pop(L, 1); /* remove a[i] */ | ||
229 | } | ||
230 | /* repeat --j until a[j] <= P */ | ||
231 | while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { | ||
232 | if (j<l) luaL_error(L, "invalid order function for sorting"); | ||
233 | lua_pop(L, 1); /* remove a[j] */ | ||
234 | } | ||
235 | if (j<i) { | ||
236 | lua_pop(L, 3); /* pop pivot, a[i], a[j] */ | ||
237 | break; | ||
238 | } | ||
239 | set2(L, i, j); | ||
240 | } | ||
241 | lua_rawgeti(L, 1, u-1); | ||
242 | lua_rawgeti(L, 1, i); | ||
243 | set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */ | ||
244 | /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ | ||
245 | /* adjust so that smaller half is in [j..i] and larger one in [l..u] */ | ||
246 | if (i-l < u-i) { | ||
247 | j=l; i=i-1; l=i+2; | ||
248 | } | ||
249 | else { | ||
250 | j=i+1; i=u; u=j-2; | ||
251 | } | ||
252 | auxsort(L, j, i); /* call recursively the smaller one */ | ||
253 | } /* repeat the routine for the larger one */ | ||
254 | } | ||
255 | |||
256 | static int sort (lua_State *L) { | ||
257 | int n = aux_getn(L, 1); | ||
258 | luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ | ||
259 | if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ | ||
260 | luaL_checktype(L, 2, LUA_TFUNCTION); | ||
261 | lua_settop(L, 2); /* make sure there is two arguments */ | ||
262 | auxsort(L, 1, n); | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | /* }====================================================== */ | ||
267 | |||
268 | |||
269 | static const luaL_Reg tab_funcs[] = { | ||
270 | {"concat", tconcat}, | ||
271 | {"foreach", foreach}, | ||
272 | {"foreachi", foreachi}, | ||
273 | {"getn", getn}, | ||
274 | {"maxn", maxn}, | ||
275 | {"insert", tinsert}, | ||
276 | {"remove", tremove}, | ||
277 | {"setn", setn}, | ||
278 | {"sort", sort}, | ||
279 | {NULL, NULL} | ||
280 | }; | ||
281 | |||
282 | |||
283 | LUALIB_API int luaopen_table (lua_State *L) { | ||
284 | luaL_register(L, LUA_TABLIBNAME, tab_funcs); | ||
285 | return 1; | ||
286 | } | ||
287 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ltm.c b/libraries/LuaJIT-1.1.7/src/ltm.c new file mode 100644 index 0000000..c27f0f6 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ltm.c | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | ** $Id: ltm.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Tag methods | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <string.h> | ||
9 | |||
10 | #define ltm_c | ||
11 | #define LUA_CORE | ||
12 | |||
13 | #include "lua.h" | ||
14 | |||
15 | #include "lobject.h" | ||
16 | #include "lstate.h" | ||
17 | #include "lstring.h" | ||
18 | #include "ltable.h" | ||
19 | #include "ltm.h" | ||
20 | |||
21 | |||
22 | |||
23 | const char *const luaT_typenames[] = { | ||
24 | "nil", "boolean", "userdata", "number", | ||
25 | "string", "table", "function", "userdata", "thread", | ||
26 | "proto", "upval" | ||
27 | }; | ||
28 | |||
29 | |||
30 | void luaT_init (lua_State *L) { | ||
31 | static const char *const luaT_eventname[] = { /* ORDER TM */ | ||
32 | "__index", "__newindex", | ||
33 | "__gc", "__mode", "__eq", | ||
34 | "__add", "__sub", "__mul", "__div", "__mod", | ||
35 | "__pow", "__unm", "__len", "__lt", "__le", | ||
36 | "__concat", "__call" | ||
37 | }; | ||
38 | int i; | ||
39 | for (i=0; i<TM_N; i++) { | ||
40 | G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]); | ||
41 | luaS_fix(G(L)->tmname[i]); /* never collect these names */ | ||
42 | } | ||
43 | } | ||
44 | |||
45 | |||
46 | /* | ||
47 | ** function to be used with macro "fasttm": optimized for absence of | ||
48 | ** tag methods | ||
49 | */ | ||
50 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { | ||
51 | const TValue *tm = luaH_getstr(events, ename); | ||
52 | lua_assert(event <= TM_EQ); | ||
53 | if (ttisnil(tm)) { /* no tag method? */ | ||
54 | events->flags |= cast_byte(1u<<event); /* cache this fact */ | ||
55 | return NULL; | ||
56 | } | ||
57 | else return tm; | ||
58 | } | ||
59 | |||
60 | |||
61 | const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { | ||
62 | Table *mt; | ||
63 | switch (ttype(o)) { | ||
64 | case LUA_TTABLE: | ||
65 | mt = hvalue(o)->metatable; | ||
66 | break; | ||
67 | case LUA_TUSERDATA: | ||
68 | mt = uvalue(o)->metatable; | ||
69 | break; | ||
70 | default: | ||
71 | mt = G(L)->mt[ttype(o)]; | ||
72 | } | ||
73 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); | ||
74 | } | ||
75 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/ltm.h b/libraries/LuaJIT-1.1.7/src/ltm.h new file mode 100644 index 0000000..64343b7 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ltm.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | ** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Tag methods | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef ltm_h | ||
8 | #define ltm_h | ||
9 | |||
10 | |||
11 | #include "lobject.h" | ||
12 | |||
13 | |||
14 | /* | ||
15 | * WARNING: if you change the order of this enumeration, | ||
16 | * grep "ORDER TM" | ||
17 | */ | ||
18 | typedef enum { | ||
19 | TM_INDEX, | ||
20 | TM_NEWINDEX, | ||
21 | TM_GC, | ||
22 | TM_MODE, | ||
23 | TM_EQ, /* last tag method with `fast' access */ | ||
24 | TM_ADD, | ||
25 | TM_SUB, | ||
26 | TM_MUL, | ||
27 | TM_DIV, | ||
28 | TM_MOD, | ||
29 | TM_POW, | ||
30 | TM_UNM, | ||
31 | TM_LEN, | ||
32 | TM_LT, | ||
33 | TM_LE, | ||
34 | TM_CONCAT, | ||
35 | TM_CALL, | ||
36 | TM_N /* number of elements in the enum */ | ||
37 | } TMS; | ||
38 | |||
39 | |||
40 | |||
41 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ | ||
42 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) | ||
43 | |||
44 | #define fasttm(l,et,e) gfasttm(G(l), et, e) | ||
45 | |||
46 | LUAI_DATA const char *const luaT_typenames[]; | ||
47 | |||
48 | |||
49 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); | ||
50 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, | ||
51 | TMS event); | ||
52 | LUAI_FUNC void luaT_init (lua_State *L); | ||
53 | |||
54 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lua.c b/libraries/LuaJIT-1.1.7/src/lua.c new file mode 100644 index 0000000..a4b413f --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lua.c | |||
@@ -0,0 +1,463 @@ | |||
1 | /* | ||
2 | ** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $ | ||
3 | ** Lua stand-alone interpreter | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <signal.h> | ||
9 | #include <stdio.h> | ||
10 | #include <stdlib.h> | ||
11 | #include <string.h> | ||
12 | |||
13 | #define lua_c | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "lauxlib.h" | ||
18 | #include "lualib.h" | ||
19 | #include "luajit.h" | ||
20 | |||
21 | |||
22 | |||
23 | static lua_State *globalL = NULL; | ||
24 | |||
25 | static const char *progname = LUA_PROGNAME; | ||
26 | |||
27 | |||
28 | |||
29 | static void lstop (lua_State *L, lua_Debug *ar) { | ||
30 | (void)ar; /* unused arg. */ | ||
31 | lua_sethook(L, NULL, 0, 0); | ||
32 | luaL_error(L, "interrupted!"); | ||
33 | } | ||
34 | |||
35 | |||
36 | static void laction (int i) { | ||
37 | signal(i, SIG_DFL); /* if another SIGINT happens before lstop, | ||
38 | terminate process (default action) */ | ||
39 | lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); | ||
40 | } | ||
41 | |||
42 | |||
43 | static void print_usage (void) { | ||
44 | fprintf(stderr, | ||
45 | "usage: %s [options] [script [args]].\n" | ||
46 | "Available options are:\n" | ||
47 | " -e stat execute string " LUA_QL("stat") "\n" | ||
48 | " -l name require library " LUA_QL("name") "\n" | ||
49 | " -j cmd perform LuaJIT control command\n" | ||
50 | " -O[lvl] set LuaJIT optimization level\n" | ||
51 | " -i enter interactive mode after executing " LUA_QL("script") "\n" | ||
52 | " -v show version information\n" | ||
53 | " -- stop handling options\n" | ||
54 | " - execute stdin and stop handling options\n" | ||
55 | , | ||
56 | progname); | ||
57 | fflush(stderr); | ||
58 | } | ||
59 | |||
60 | |||
61 | static void l_message (const char *pname, const char *msg) { | ||
62 | if (pname) fprintf(stderr, "%s: ", pname); | ||
63 | fprintf(stderr, "%s\n", msg); | ||
64 | fflush(stderr); | ||
65 | } | ||
66 | |||
67 | |||
68 | static int report (lua_State *L, int status) { | ||
69 | if (status && !lua_isnil(L, -1)) { | ||
70 | const char *msg = lua_tostring(L, -1); | ||
71 | if (msg == NULL) msg = "(error object is not a string)"; | ||
72 | l_message(progname, msg); | ||
73 | lua_pop(L, 1); | ||
74 | } | ||
75 | return status; | ||
76 | } | ||
77 | |||
78 | |||
79 | static int traceback (lua_State *L) { | ||
80 | if (!lua_isstring(L, 1)) /* 'message' not a string? */ | ||
81 | return 1; /* keep it intact */ | ||
82 | lua_getfield(L, LUA_GLOBALSINDEX, "debug"); | ||
83 | if (!lua_istable(L, -1)) { | ||
84 | lua_pop(L, 1); | ||
85 | return 1; | ||
86 | } | ||
87 | lua_getfield(L, -1, "traceback"); | ||
88 | if (!lua_isfunction(L, -1)) { | ||
89 | lua_pop(L, 2); | ||
90 | return 1; | ||
91 | } | ||
92 | lua_pushvalue(L, 1); /* pass error message */ | ||
93 | lua_pushinteger(L, 2); /* skip this function and traceback */ | ||
94 | lua_call(L, 2, 1); /* call debug.traceback */ | ||
95 | return 1; | ||
96 | } | ||
97 | |||
98 | |||
99 | static int docall (lua_State *L, int narg, int clear) { | ||
100 | int status; | ||
101 | int base = lua_gettop(L) - narg; /* function index */ | ||
102 | lua_pushcfunction(L, traceback); /* push traceback function */ | ||
103 | lua_insert(L, base); /* put it under chunk and args */ | ||
104 | signal(SIGINT, laction); | ||
105 | status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); | ||
106 | signal(SIGINT, SIG_DFL); | ||
107 | lua_remove(L, base); /* remove traceback function */ | ||
108 | /* force a complete garbage collection in case of errors */ | ||
109 | if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); | ||
110 | return status; | ||
111 | } | ||
112 | |||
113 | |||
114 | static void print_version (void) { | ||
115 | l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT); | ||
116 | l_message(NULL, LUAJIT_VERSION " " LUAJIT_COPYRIGHT ", " LUAJIT_URL); | ||
117 | } | ||
118 | |||
119 | |||
120 | static int getargs (lua_State *L, char **argv, int n) { | ||
121 | int narg; | ||
122 | int i; | ||
123 | int argc = 0; | ||
124 | while (argv[argc]) argc++; /* count total number of arguments */ | ||
125 | narg = argc - (n + 1); /* number of arguments to the script */ | ||
126 | luaL_checkstack(L, narg + 3, "too many arguments to script"); | ||
127 | for (i=n+1; i < argc; i++) | ||
128 | lua_pushstring(L, argv[i]); | ||
129 | lua_createtable(L, narg, n + 1); | ||
130 | for (i=0; i < argc; i++) { | ||
131 | lua_pushstring(L, argv[i]); | ||
132 | lua_rawseti(L, -2, i - n); | ||
133 | } | ||
134 | return narg; | ||
135 | } | ||
136 | |||
137 | |||
138 | static int dofile (lua_State *L, const char *name) { | ||
139 | int status = luaL_loadfile(L, name) || docall(L, 0, 1); | ||
140 | return report(L, status); | ||
141 | } | ||
142 | |||
143 | |||
144 | static int dostring (lua_State *L, const char *s, const char *name) { | ||
145 | int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1); | ||
146 | return report(L, status); | ||
147 | } | ||
148 | |||
149 | |||
150 | static int dolibrary (lua_State *L, const char *name) { | ||
151 | lua_getglobal(L, "require"); | ||
152 | lua_pushstring(L, name); | ||
153 | return report(L, docall(L, 1, 1)); | ||
154 | } | ||
155 | |||
156 | |||
157 | static const char *get_prompt (lua_State *L, int firstline) { | ||
158 | const char *p; | ||
159 | lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2"); | ||
160 | p = lua_tostring(L, -1); | ||
161 | if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); | ||
162 | lua_pop(L, 1); /* remove global */ | ||
163 | return p; | ||
164 | } | ||
165 | |||
166 | |||
167 | static int incomplete (lua_State *L, int status) { | ||
168 | if (status == LUA_ERRSYNTAX) { | ||
169 | size_t lmsg; | ||
170 | const char *msg = lua_tolstring(L, -1, &lmsg); | ||
171 | const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1); | ||
172 | if (strstr(msg, LUA_QL("<eof>")) == tp) { | ||
173 | lua_pop(L, 1); | ||
174 | return 1; | ||
175 | } | ||
176 | } | ||
177 | return 0; /* else... */ | ||
178 | } | ||
179 | |||
180 | |||
181 | static int pushline (lua_State *L, int firstline) { | ||
182 | char buffer[LUA_MAXINPUT]; | ||
183 | char *b = buffer; | ||
184 | size_t l; | ||
185 | const char *prmt = get_prompt(L, firstline); | ||
186 | if (lua_readline(L, b, prmt) == 0) | ||
187 | return 0; /* no input */ | ||
188 | l = strlen(b); | ||
189 | if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ | ||
190 | b[l-1] = '\0'; /* remove it */ | ||
191 | if (firstline && b[0] == '=') /* first line starts with `=' ? */ | ||
192 | lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ | ||
193 | else | ||
194 | lua_pushstring(L, b); | ||
195 | lua_freeline(L, b); | ||
196 | return 1; | ||
197 | } | ||
198 | |||
199 | |||
200 | static int loadline (lua_State *L) { | ||
201 | int status; | ||
202 | lua_settop(L, 0); | ||
203 | if (!pushline(L, 1)) | ||
204 | return -1; /* no input */ | ||
205 | for (;;) { /* repeat until gets a complete line */ | ||
206 | status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); | ||
207 | if (!incomplete(L, status)) break; /* cannot try to add lines? */ | ||
208 | if (!pushline(L, 0)) /* no more input? */ | ||
209 | return -1; | ||
210 | lua_pushliteral(L, "\n"); /* add a new line... */ | ||
211 | lua_insert(L, -2); /* ...between the two lines */ | ||
212 | lua_concat(L, 3); /* join them */ | ||
213 | } | ||
214 | lua_saveline(L, 1); | ||
215 | lua_remove(L, 1); /* remove line */ | ||
216 | return status; | ||
217 | } | ||
218 | |||
219 | |||
220 | static void dotty (lua_State *L) { | ||
221 | int status; | ||
222 | const char *oldprogname = progname; | ||
223 | progname = NULL; | ||
224 | while ((status = loadline(L)) != -1) { | ||
225 | if (status == 0) status = docall(L, 0, 0); | ||
226 | report(L, status); | ||
227 | if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ | ||
228 | lua_getglobal(L, "print"); | ||
229 | lua_insert(L, 1); | ||
230 | if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) | ||
231 | l_message(progname, lua_pushfstring(L, | ||
232 | "error calling " LUA_QL("print") " (%s)", | ||
233 | lua_tostring(L, -1))); | ||
234 | } | ||
235 | } | ||
236 | lua_settop(L, 0); /* clear stack */ | ||
237 | fputs("\n", stdout); | ||
238 | fflush(stdout); | ||
239 | progname = oldprogname; | ||
240 | } | ||
241 | |||
242 | |||
243 | static int handle_script (lua_State *L, char **argv, int n) { | ||
244 | int status; | ||
245 | const char *fname; | ||
246 | int narg = getargs(L, argv, n); /* collect arguments */ | ||
247 | lua_setglobal(L, "arg"); | ||
248 | fname = argv[n]; | ||
249 | if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) | ||
250 | fname = NULL; /* stdin */ | ||
251 | status = luaL_loadfile(L, fname); | ||
252 | lua_insert(L, -(narg+1)); | ||
253 | if (status == 0) | ||
254 | status = docall(L, narg, 0); | ||
255 | else | ||
256 | lua_pop(L, narg); | ||
257 | return report(L, status); | ||
258 | } | ||
259 | |||
260 | /* ---- start of LuaJIT extensions */ | ||
261 | |||
262 | static int loadjitmodule (lua_State *L, const char *notfound) { | ||
263 | lua_getglobal(L, "require"); | ||
264 | lua_pushliteral(L, "jit."); | ||
265 | lua_pushvalue(L, -3); | ||
266 | lua_concat(L, 2); | ||
267 | if (lua_pcall(L, 1, 1, 0)) { | ||
268 | const char *msg = lua_tostring(L, -1); | ||
269 | if (msg && !strncmp(msg, "module ", 7)) { | ||
270 | l_message(progname, notfound); | ||
271 | return 1; | ||
272 | } | ||
273 | else | ||
274 | return report(L, 1); | ||
275 | } | ||
276 | lua_getfield(L, -1, "start"); | ||
277 | lua_remove(L, -2); /* drop module table */ | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | /* JIT engine control command: try jit library first or load add-on module */ | ||
282 | static int dojitcmd (lua_State *L, const char *cmd) { | ||
283 | const char *val = strchr(cmd, '='); | ||
284 | lua_pushlstring(L, cmd, val ? val - cmd : strlen(cmd)); | ||
285 | lua_getglobal(L, "jit"); /* get jit.* table */ | ||
286 | lua_pushvalue(L, -2); | ||
287 | lua_gettable(L, -2); /* lookup library function */ | ||
288 | if (!lua_isfunction(L, -1)) { | ||
289 | lua_pop(L, 2); /* drop non-function and jit.* table, keep module name */ | ||
290 | if (loadjitmodule(L, "unknown luaJIT command")) | ||
291 | return 1; | ||
292 | } | ||
293 | else { | ||
294 | lua_remove(L, -2); /* drop jit.* table */ | ||
295 | } | ||
296 | lua_remove(L, -2); /* drop module name */ | ||
297 | if (val) lua_pushstring(L, val+1); | ||
298 | return report(L, lua_pcall(L, val ? 1 : 0, 0, 0)); | ||
299 | } | ||
300 | |||
301 | /* start optimizer */ | ||
302 | static int dojitopt (lua_State *L, const char *opt) { | ||
303 | lua_pushliteral(L, "opt"); | ||
304 | if (loadjitmodule(L, "LuaJIT optimizer module not installed")) | ||
305 | return 1; | ||
306 | lua_remove(L, -2); /* drop module name */ | ||
307 | if (*opt) lua_pushstring(L, opt); | ||
308 | return report(L, lua_pcall(L, *opt ? 1 : 0, 0, 0)); | ||
309 | } | ||
310 | |||
311 | /* ---- end of LuaJIT extensions */ | ||
312 | |||
313 | /* check that argument has no extra characters at the end */ | ||
314 | #define notail(x) {if ((x)[2] != '\0') return -1;} | ||
315 | |||
316 | |||
317 | static int collectargs (char **argv, int *pi, int *pv, int *pe) { | ||
318 | int i; | ||
319 | for (i = 1; argv[i] != NULL; i++) { | ||
320 | if (argv[i][0] != '-') /* not an option? */ | ||
321 | return i; | ||
322 | switch (argv[i][1]) { /* option */ | ||
323 | case '-': | ||
324 | notail(argv[i]); | ||
325 | return (argv[i+1] != NULL ? i+1 : 0); | ||
326 | case '\0': | ||
327 | return i; | ||
328 | case 'i': | ||
329 | notail(argv[i]); | ||
330 | *pi = 1; /* go through */ | ||
331 | case 'v': | ||
332 | notail(argv[i]); | ||
333 | *pv = 1; | ||
334 | break; | ||
335 | case 'e': | ||
336 | *pe = 1; /* go through */ | ||
337 | case 'j': /* LuaJIT extension */ | ||
338 | case 'l': | ||
339 | if (argv[i][2] == '\0') { | ||
340 | i++; | ||
341 | if (argv[i] == NULL) return -1; | ||
342 | } | ||
343 | break; | ||
344 | case 'O': break; /* LuaJIT extension */ | ||
345 | default: return -1; /* invalid option */ | ||
346 | } | ||
347 | } | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | |||
352 | static int runargs (lua_State *L, char **argv, int n) { | ||
353 | int i; | ||
354 | for (i = 1; i < n; i++) { | ||
355 | if (argv[i] == NULL) continue; | ||
356 | lua_assert(argv[i][0] == '-'); | ||
357 | switch (argv[i][1]) { /* option */ | ||
358 | case 'e': { | ||
359 | const char *chunk = argv[i] + 2; | ||
360 | if (*chunk == '\0') chunk = argv[++i]; | ||
361 | lua_assert(chunk != NULL); | ||
362 | if (dostring(L, chunk, "=(command line)") != 0) | ||
363 | return 1; | ||
364 | break; | ||
365 | } | ||
366 | case 'l': { | ||
367 | const char *filename = argv[i] + 2; | ||
368 | if (*filename == '\0') filename = argv[++i]; | ||
369 | lua_assert(filename != NULL); | ||
370 | if (dolibrary(L, filename)) | ||
371 | return 1; /* stop if file fails */ | ||
372 | break; | ||
373 | } | ||
374 | case 'j': { /* LuaJIT extension */ | ||
375 | const char *cmd = argv[i] + 2; | ||
376 | if (*cmd == '\0') cmd = argv[++i]; | ||
377 | lua_assert(cmd != NULL); | ||
378 | if (dojitcmd(L, cmd)) | ||
379 | return 1; | ||
380 | break; | ||
381 | } | ||
382 | case 'O': /* LuaJIT extension */ | ||
383 | if (dojitopt(L, argv[i] + 2)) | ||
384 | return 1; | ||
385 | break; | ||
386 | default: break; | ||
387 | } | ||
388 | } | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | |||
393 | static int handle_luainit (lua_State *L) { | ||
394 | const char *init = getenv(LUA_INIT); | ||
395 | if (init == NULL) return 0; /* status OK */ | ||
396 | else if (init[0] == '@') | ||
397 | return dofile(L, init+1); | ||
398 | else | ||
399 | return dostring(L, init, "=" LUA_INIT); | ||
400 | } | ||
401 | |||
402 | |||
403 | struct Smain { | ||
404 | int argc; | ||
405 | char **argv; | ||
406 | int status; | ||
407 | }; | ||
408 | |||
409 | |||
410 | static int pmain (lua_State *L) { | ||
411 | struct Smain *s = (struct Smain *)lua_touserdata(L, 1); | ||
412 | char **argv = s->argv; | ||
413 | int script; | ||
414 | int has_i = 0, has_v = 0, has_e = 0; | ||
415 | globalL = L; | ||
416 | if (argv[0] && argv[0][0]) progname = argv[0]; | ||
417 | LUAJIT_VERSION_SYM(); /* linker-enforced version check */ | ||
418 | lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ | ||
419 | luaL_openlibs(L); /* open libraries */ | ||
420 | lua_gc(L, LUA_GCRESTART, 0); | ||
421 | s->status = handle_luainit(L); | ||
422 | if (s->status != 0) return 0; | ||
423 | script = collectargs(argv, &has_i, &has_v, &has_e); | ||
424 | if (script < 0) { /* invalid args? */ | ||
425 | print_usage(); | ||
426 | s->status = 1; | ||
427 | return 0; | ||
428 | } | ||
429 | if (has_v) print_version(); | ||
430 | s->status = runargs(L, argv, (script > 0) ? script : s->argc); | ||
431 | if (s->status != 0) return 0; | ||
432 | if (script) | ||
433 | s->status = handle_script(L, argv, script); | ||
434 | if (s->status != 0) return 0; | ||
435 | if (has_i) | ||
436 | dotty(L); | ||
437 | else if (script == 0 && !has_e && !has_v) { | ||
438 | if (lua_stdin_is_tty()) { | ||
439 | print_version(); | ||
440 | dotty(L); | ||
441 | } | ||
442 | else dofile(L, NULL); /* executes stdin as a file */ | ||
443 | } | ||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | |||
448 | int main (int argc, char **argv) { | ||
449 | int status; | ||
450 | struct Smain s; | ||
451 | lua_State *L = lua_open(); /* create state */ | ||
452 | if (L == NULL) { | ||
453 | l_message(argv[0], "cannot create state: not enough memory"); | ||
454 | return EXIT_FAILURE; | ||
455 | } | ||
456 | s.argc = argc; | ||
457 | s.argv = argv; | ||
458 | status = lua_cpcall(L, &pmain, &s); | ||
459 | report(L, status); | ||
460 | lua_close(L); | ||
461 | return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; | ||
462 | } | ||
463 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lua.h b/libraries/LuaJIT-1.1.7/src/lua.h new file mode 100644 index 0000000..7d6ee45 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lua.h | |||
@@ -0,0 +1,385 @@ | |||
1 | /* | ||
2 | ** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $ | ||
3 | ** Lua - An Extensible Extension Language | ||
4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) | ||
5 | ** See Copyright Notice at the end of this file | ||
6 | */ | ||
7 | |||
8 | |||
9 | #ifndef lua_h | ||
10 | #define lua_h | ||
11 | |||
12 | #include <stdarg.h> | ||
13 | #include <stddef.h> | ||
14 | |||
15 | |||
16 | #include "luaconf.h" | ||
17 | |||
18 | |||
19 | #define LUA_VERSION "Lua 5.1" | ||
20 | #define LUA_RELEASE "Lua 5.1.4" | ||
21 | #define LUA_VERSION_NUM 501 | ||
22 | #define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" | ||
23 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" | ||
24 | |||
25 | |||
26 | /* mark for precompiled code (`<esc>Lua') */ | ||
27 | #define LUA_SIGNATURE "\033Lua" | ||
28 | |||
29 | /* option for multiple returns in `lua_pcall' and `lua_call' */ | ||
30 | #define LUA_MULTRET (-1) | ||
31 | |||
32 | |||
33 | /* | ||
34 | ** pseudo-indices | ||
35 | */ | ||
36 | #define LUA_REGISTRYINDEX (-10000) | ||
37 | #define LUA_ENVIRONINDEX (-10001) | ||
38 | #define LUA_GLOBALSINDEX (-10002) | ||
39 | #define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) | ||
40 | |||
41 | |||
42 | /* thread status; 0 is OK */ | ||
43 | #define LUA_YIELD 1 | ||
44 | #define LUA_ERRRUN 2 | ||
45 | #define LUA_ERRSYNTAX 3 | ||
46 | #define LUA_ERRMEM 4 | ||
47 | #define LUA_ERRERR 5 | ||
48 | |||
49 | |||
50 | typedef struct lua_State lua_State; | ||
51 | |||
52 | typedef int (*lua_CFunction) (lua_State *L); | ||
53 | |||
54 | |||
55 | /* | ||
56 | ** functions that read/write blocks when loading/dumping Lua chunks | ||
57 | */ | ||
58 | typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); | ||
59 | |||
60 | typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); | ||
61 | |||
62 | |||
63 | /* | ||
64 | ** prototype for memory-allocation functions | ||
65 | */ | ||
66 | typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); | ||
67 | |||
68 | |||
69 | /* | ||
70 | ** basic types | ||
71 | */ | ||
72 | #define LUA_TNONE (-1) | ||
73 | |||
74 | #define LUA_TNIL 0 | ||
75 | #define LUA_TBOOLEAN 1 | ||
76 | #define LUA_TLIGHTUSERDATA 2 | ||
77 | #define LUA_TNUMBER 3 | ||
78 | #define LUA_TSTRING 4 | ||
79 | #define LUA_TTABLE 5 | ||
80 | #define LUA_TFUNCTION 6 | ||
81 | #define LUA_TUSERDATA 7 | ||
82 | #define LUA_TTHREAD 8 | ||
83 | |||
84 | |||
85 | |||
86 | /* minimum Lua stack available to a C function */ | ||
87 | #define LUA_MINSTACK 20 | ||
88 | |||
89 | |||
90 | /* | ||
91 | ** generic extra include file | ||
92 | */ | ||
93 | #if defined(LUA_USER_H) | ||
94 | #include LUA_USER_H | ||
95 | #endif | ||
96 | |||
97 | |||
98 | /* type of numbers in Lua */ | ||
99 | typedef LUA_NUMBER lua_Number; | ||
100 | |||
101 | |||
102 | /* type for integer functions */ | ||
103 | typedef LUA_INTEGER lua_Integer; | ||
104 | |||
105 | |||
106 | |||
107 | /* | ||
108 | ** state manipulation | ||
109 | */ | ||
110 | LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); | ||
111 | LUA_API void (lua_close) (lua_State *L); | ||
112 | LUA_API lua_State *(lua_newthread) (lua_State *L); | ||
113 | |||
114 | LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); | ||
115 | |||
116 | |||
117 | /* | ||
118 | ** basic stack manipulation | ||
119 | */ | ||
120 | LUA_API int (lua_gettop) (lua_State *L); | ||
121 | LUA_API void (lua_settop) (lua_State *L, int idx); | ||
122 | LUA_API void (lua_pushvalue) (lua_State *L, int idx); | ||
123 | LUA_API void (lua_remove) (lua_State *L, int idx); | ||
124 | LUA_API void (lua_insert) (lua_State *L, int idx); | ||
125 | LUA_API void (lua_replace) (lua_State *L, int idx); | ||
126 | LUA_API int (lua_checkstack) (lua_State *L, int sz); | ||
127 | |||
128 | LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); | ||
129 | |||
130 | |||
131 | /* | ||
132 | ** access functions (stack -> C) | ||
133 | */ | ||
134 | |||
135 | LUA_API int (lua_isnumber) (lua_State *L, int idx); | ||
136 | LUA_API int (lua_isstring) (lua_State *L, int idx); | ||
137 | LUA_API int (lua_iscfunction) (lua_State *L, int idx); | ||
138 | LUA_API int (lua_isuserdata) (lua_State *L, int idx); | ||
139 | LUA_API int (lua_type) (lua_State *L, int idx); | ||
140 | LUA_API const char *(lua_typename) (lua_State *L, int tp); | ||
141 | |||
142 | LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); | ||
143 | LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); | ||
144 | LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); | ||
145 | |||
146 | LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); | ||
147 | LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); | ||
148 | LUA_API int (lua_toboolean) (lua_State *L, int idx); | ||
149 | LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); | ||
150 | LUA_API size_t (lua_objlen) (lua_State *L, int idx); | ||
151 | LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); | ||
152 | LUA_API void *(lua_touserdata) (lua_State *L, int idx); | ||
153 | LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); | ||
154 | LUA_API const void *(lua_topointer) (lua_State *L, int idx); | ||
155 | |||
156 | |||
157 | /* | ||
158 | ** push functions (C -> stack) | ||
159 | */ | ||
160 | LUA_API void (lua_pushnil) (lua_State *L); | ||
161 | LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); | ||
162 | LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); | ||
163 | LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); | ||
164 | LUA_API void (lua_pushstring) (lua_State *L, const char *s); | ||
165 | LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, | ||
166 | va_list argp); | ||
167 | LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); | ||
168 | LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); | ||
169 | LUA_API void (lua_pushboolean) (lua_State *L, int b); | ||
170 | LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); | ||
171 | LUA_API int (lua_pushthread) (lua_State *L); | ||
172 | |||
173 | |||
174 | /* | ||
175 | ** get functions (Lua -> stack) | ||
176 | */ | ||
177 | LUA_API void (lua_gettable) (lua_State *L, int idx); | ||
178 | LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); | ||
179 | LUA_API void (lua_rawget) (lua_State *L, int idx); | ||
180 | LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); | ||
181 | LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); | ||
182 | LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); | ||
183 | LUA_API int (lua_getmetatable) (lua_State *L, int objindex); | ||
184 | LUA_API void (lua_getfenv) (lua_State *L, int idx); | ||
185 | |||
186 | |||
187 | /* | ||
188 | ** set functions (stack -> Lua) | ||
189 | */ | ||
190 | LUA_API void (lua_settable) (lua_State *L, int idx); | ||
191 | LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); | ||
192 | LUA_API void (lua_rawset) (lua_State *L, int idx); | ||
193 | LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); | ||
194 | LUA_API int (lua_setmetatable) (lua_State *L, int objindex); | ||
195 | LUA_API int (lua_setfenv) (lua_State *L, int idx); | ||
196 | |||
197 | |||
198 | /* | ||
199 | ** `load' and `call' functions (load and run Lua code) | ||
200 | */ | ||
201 | LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); | ||
202 | LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); | ||
203 | LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); | ||
204 | LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, | ||
205 | const char *chunkname); | ||
206 | |||
207 | LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); | ||
208 | |||
209 | |||
210 | /* | ||
211 | ** coroutine functions | ||
212 | */ | ||
213 | LUA_API int (lua_yield) (lua_State *L, int nresults); | ||
214 | LUA_API int (lua_resume) (lua_State *L, int narg); | ||
215 | LUA_API int (lua_status) (lua_State *L); | ||
216 | |||
217 | /* | ||
218 | ** garbage-collection function and options | ||
219 | */ | ||
220 | |||
221 | #define LUA_GCSTOP 0 | ||
222 | #define LUA_GCRESTART 1 | ||
223 | #define LUA_GCCOLLECT 2 | ||
224 | #define LUA_GCCOUNT 3 | ||
225 | #define LUA_GCCOUNTB 4 | ||
226 | #define LUA_GCSTEP 5 | ||
227 | #define LUA_GCSETPAUSE 6 | ||
228 | #define LUA_GCSETSTEPMUL 7 | ||
229 | |||
230 | LUA_API int (lua_gc) (lua_State *L, int what, int data); | ||
231 | |||
232 | |||
233 | /* | ||
234 | ** miscellaneous functions | ||
235 | */ | ||
236 | |||
237 | LUA_API int (lua_error) (lua_State *L); | ||
238 | |||
239 | LUA_API int (lua_next) (lua_State *L, int idx); | ||
240 | |||
241 | LUA_API void (lua_concat) (lua_State *L, int n); | ||
242 | |||
243 | LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); | ||
244 | LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); | ||
245 | |||
246 | |||
247 | |||
248 | /* | ||
249 | ** =============================================================== | ||
250 | ** some useful macros | ||
251 | ** =============================================================== | ||
252 | */ | ||
253 | |||
254 | #define lua_pop(L,n) lua_settop(L, -(n)-1) | ||
255 | |||
256 | #define lua_newtable(L) lua_createtable(L, 0, 0) | ||
257 | |||
258 | #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) | ||
259 | |||
260 | #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) | ||
261 | |||
262 | #define lua_strlen(L,i) lua_objlen(L, (i)) | ||
263 | |||
264 | #define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) | ||
265 | #define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) | ||
266 | #define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) | ||
267 | #define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) | ||
268 | #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) | ||
269 | #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) | ||
270 | #define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) | ||
271 | #define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) | ||
272 | |||
273 | #define lua_pushliteral(L, s) \ | ||
274 | lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) | ||
275 | |||
276 | #define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) | ||
277 | #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) | ||
278 | |||
279 | #define lua_tostring(L,i) lua_tolstring(L, (i), NULL) | ||
280 | |||
281 | |||
282 | |||
283 | /* | ||
284 | ** compatibility macros and functions | ||
285 | */ | ||
286 | |||
287 | #define lua_open() luaL_newstate() | ||
288 | |||
289 | #define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) | ||
290 | |||
291 | #define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) | ||
292 | |||
293 | #define lua_Chunkreader lua_Reader | ||
294 | #define lua_Chunkwriter lua_Writer | ||
295 | |||
296 | |||
297 | |||
298 | /* | ||
299 | ** {====================================================================== | ||
300 | ** Debug API | ||
301 | ** ======================================================================= | ||
302 | */ | ||
303 | |||
304 | |||
305 | /* | ||
306 | ** Event codes | ||
307 | */ | ||
308 | #define LUA_HOOKCALL 0 | ||
309 | #define LUA_HOOKRET 1 | ||
310 | #define LUA_HOOKLINE 2 | ||
311 | #define LUA_HOOKCOUNT 3 | ||
312 | #define LUA_HOOKTAILRET 4 | ||
313 | |||
314 | |||
315 | /* | ||
316 | ** Event masks | ||
317 | */ | ||
318 | #define LUA_MASKCALL (1 << LUA_HOOKCALL) | ||
319 | #define LUA_MASKRET (1 << LUA_HOOKRET) | ||
320 | #define LUA_MASKLINE (1 << LUA_HOOKLINE) | ||
321 | #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) | ||
322 | |||
323 | typedef struct lua_Debug lua_Debug; /* activation record */ | ||
324 | |||
325 | |||
326 | /* Functions to be called by the debuger in specific events */ | ||
327 | typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); | ||
328 | |||
329 | |||
330 | LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); | ||
331 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); | ||
332 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); | ||
333 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); | ||
334 | LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); | ||
335 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); | ||
336 | |||
337 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); | ||
338 | LUA_API lua_Hook lua_gethook (lua_State *L); | ||
339 | LUA_API int lua_gethookmask (lua_State *L); | ||
340 | LUA_API int lua_gethookcount (lua_State *L); | ||
341 | |||
342 | |||
343 | struct lua_Debug { | ||
344 | int event; | ||
345 | const char *name; /* (n) */ | ||
346 | const char *namewhat; /* (n) `global', `local', `field', `method' */ | ||
347 | const char *what; /* (S) `Lua', `C', `main', `tail' */ | ||
348 | const char *source; /* (S) */ | ||
349 | int currentline; /* (l) */ | ||
350 | int nups; /* (u) number of upvalues */ | ||
351 | int linedefined; /* (S) */ | ||
352 | int lastlinedefined; /* (S) */ | ||
353 | char short_src[LUA_IDSIZE]; /* (S) */ | ||
354 | /* private part */ | ||
355 | int i_ci; /* active function */ | ||
356 | }; | ||
357 | |||
358 | /* }====================================================================== */ | ||
359 | |||
360 | |||
361 | /****************************************************************************** | ||
362 | * Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. | ||
363 | * | ||
364 | * Permission is hereby granted, free of charge, to any person obtaining | ||
365 | * a copy of this software and associated documentation files (the | ||
366 | * "Software"), to deal in the Software without restriction, including | ||
367 | * without limitation the rights to use, copy, modify, merge, publish, | ||
368 | * distribute, sublicense, and/or sell copies of the Software, and to | ||
369 | * permit persons to whom the Software is furnished to do so, subject to | ||
370 | * the following conditions: | ||
371 | * | ||
372 | * The above copyright notice and this permission notice shall be | ||
373 | * included in all copies or substantial portions of the Software. | ||
374 | * | ||
375 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
376 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
377 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
378 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
379 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
380 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
381 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
382 | ******************************************************************************/ | ||
383 | |||
384 | |||
385 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/luac.c b/libraries/LuaJIT-1.1.7/src/luac.c new file mode 100644 index 0000000..d070173 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/luac.c | |||
@@ -0,0 +1,200 @@ | |||
1 | /* | ||
2 | ** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $ | ||
3 | ** Lua compiler (saves bytecodes to files; also list bytecodes) | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #include <errno.h> | ||
8 | #include <stdio.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <string.h> | ||
11 | |||
12 | #define luac_c | ||
13 | #define LUA_CORE | ||
14 | |||
15 | #include "lua.h" | ||
16 | #include "lauxlib.h" | ||
17 | |||
18 | #include "ldo.h" | ||
19 | #include "lfunc.h" | ||
20 | #include "lmem.h" | ||
21 | #include "lobject.h" | ||
22 | #include "lopcodes.h" | ||
23 | #include "lstring.h" | ||
24 | #include "lundump.h" | ||
25 | |||
26 | #define PROGNAME "luac" /* default program name */ | ||
27 | #define OUTPUT PROGNAME ".out" /* default output file */ | ||
28 | |||
29 | static int listing=0; /* list bytecodes? */ | ||
30 | static int dumping=1; /* dump bytecodes? */ | ||
31 | static int stripping=0; /* strip debug information? */ | ||
32 | static char Output[]={ OUTPUT }; /* default output file name */ | ||
33 | static const char* output=Output; /* actual output file name */ | ||
34 | static const char* progname=PROGNAME; /* actual program name */ | ||
35 | |||
36 | static void fatal(const char* message) | ||
37 | { | ||
38 | fprintf(stderr,"%s: %s\n",progname,message); | ||
39 | exit(EXIT_FAILURE); | ||
40 | } | ||
41 | |||
42 | static void cannot(const char* what) | ||
43 | { | ||
44 | fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno)); | ||
45 | exit(EXIT_FAILURE); | ||
46 | } | ||
47 | |||
48 | static void usage(const char* message) | ||
49 | { | ||
50 | if (*message=='-') | ||
51 | fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message); | ||
52 | else | ||
53 | fprintf(stderr,"%s: %s\n",progname,message); | ||
54 | fprintf(stderr, | ||
55 | "usage: %s [options] [filenames].\n" | ||
56 | "Available options are:\n" | ||
57 | " - process stdin\n" | ||
58 | " -l list\n" | ||
59 | " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" | ||
60 | " -p parse only\n" | ||
61 | " -s strip debug information\n" | ||
62 | " -v show version information\n" | ||
63 | " -- stop handling options\n", | ||
64 | progname,Output); | ||
65 | exit(EXIT_FAILURE); | ||
66 | } | ||
67 | |||
68 | #define IS(s) (strcmp(argv[i],s)==0) | ||
69 | |||
70 | static int doargs(int argc, char* argv[]) | ||
71 | { | ||
72 | int i; | ||
73 | int version=0; | ||
74 | if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; | ||
75 | for (i=1; i<argc; i++) | ||
76 | { | ||
77 | if (*argv[i]!='-') /* end of options; keep it */ | ||
78 | break; | ||
79 | else if (IS("--")) /* end of options; skip it */ | ||
80 | { | ||
81 | ++i; | ||
82 | if (version) ++version; | ||
83 | break; | ||
84 | } | ||
85 | else if (IS("-")) /* end of options; use stdin */ | ||
86 | break; | ||
87 | else if (IS("-l")) /* list */ | ||
88 | ++listing; | ||
89 | else if (IS("-o")) /* output file */ | ||
90 | { | ||
91 | output=argv[++i]; | ||
92 | if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument"); | ||
93 | if (IS("-")) output=NULL; | ||
94 | } | ||
95 | else if (IS("-p")) /* parse only */ | ||
96 | dumping=0; | ||
97 | else if (IS("-s")) /* strip debug information */ | ||
98 | stripping=1; | ||
99 | else if (IS("-v")) /* show version */ | ||
100 | ++version; | ||
101 | else /* unknown option */ | ||
102 | usage(argv[i]); | ||
103 | } | ||
104 | if (i==argc && (listing || !dumping)) | ||
105 | { | ||
106 | dumping=0; | ||
107 | argv[--i]=Output; | ||
108 | } | ||
109 | if (version) | ||
110 | { | ||
111 | printf("%s %s\n",LUA_RELEASE,LUA_COPYRIGHT); | ||
112 | if (version==argc-1) exit(EXIT_SUCCESS); | ||
113 | } | ||
114 | return i; | ||
115 | } | ||
116 | |||
117 | #define toproto(L,i) (clvalue(L->top+(i))->l.p) | ||
118 | |||
119 | static const Proto* combine(lua_State* L, int n) | ||
120 | { | ||
121 | if (n==1) | ||
122 | return toproto(L,-1); | ||
123 | else | ||
124 | { | ||
125 | int i,pc; | ||
126 | Proto* f=luaF_newproto(L); | ||
127 | setptvalue2s(L,L->top,f); incr_top(L); | ||
128 | f->source=luaS_newliteral(L,"=(" PROGNAME ")"); | ||
129 | f->maxstacksize=1; | ||
130 | pc=2*n+1; | ||
131 | f->code=luaM_newvector(L,pc,Instruction); | ||
132 | f->sizecode=pc; | ||
133 | f->p=luaM_newvector(L,n,Proto*); | ||
134 | f->sizep=n; | ||
135 | pc=0; | ||
136 | for (i=0; i<n; i++) | ||
137 | { | ||
138 | f->p[i]=toproto(L,i-n-1); | ||
139 | f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); | ||
140 | f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1); | ||
141 | } | ||
142 | f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); | ||
143 | return f; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | static int writer(lua_State* L, const void* p, size_t size, void* u) | ||
148 | { | ||
149 | UNUSED(L); | ||
150 | return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); | ||
151 | } | ||
152 | |||
153 | struct Smain { | ||
154 | int argc; | ||
155 | char** argv; | ||
156 | }; | ||
157 | |||
158 | static int pmain(lua_State* L) | ||
159 | { | ||
160 | struct Smain* s = (struct Smain*)lua_touserdata(L, 1); | ||
161 | int argc=s->argc; | ||
162 | char** argv=s->argv; | ||
163 | const Proto* f; | ||
164 | int i; | ||
165 | if (!lua_checkstack(L,argc)) fatal("too many input files"); | ||
166 | for (i=0; i<argc; i++) | ||
167 | { | ||
168 | const char* filename=IS("-") ? NULL : argv[i]; | ||
169 | if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1)); | ||
170 | } | ||
171 | f=combine(L,argc); | ||
172 | if (listing) luaU_print(f,listing>1); | ||
173 | if (dumping) | ||
174 | { | ||
175 | FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); | ||
176 | if (D==NULL) cannot("open"); | ||
177 | lua_lock(L); | ||
178 | luaU_dump(L,f,writer,D,stripping); | ||
179 | lua_unlock(L); | ||
180 | if (ferror(D)) cannot("write"); | ||
181 | if (fclose(D)) cannot("close"); | ||
182 | } | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | int main(int argc, char* argv[]) | ||
187 | { | ||
188 | lua_State* L; | ||
189 | struct Smain s; | ||
190 | int i=doargs(argc,argv); | ||
191 | argc-=i; argv+=i; | ||
192 | if (argc<=0) usage("no input files given"); | ||
193 | L=lua_open(); | ||
194 | if (L==NULL) fatal("not enough memory for state"); | ||
195 | s.argc=argc; | ||
196 | s.argv=argv; | ||
197 | if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1)); | ||
198 | lua_close(L); | ||
199 | return EXIT_SUCCESS; | ||
200 | } | ||
diff --git a/libraries/LuaJIT-1.1.7/src/luaconf.h b/libraries/LuaJIT-1.1.7/src/luaconf.h new file mode 100644 index 0000000..35a6bd1 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/luaconf.h | |||
@@ -0,0 +1,786 @@ | |||
1 | /* | ||
2 | ** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $ | ||
3 | ** Configuration file for Lua | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #ifndef lconfig_h | ||
9 | #define lconfig_h | ||
10 | |||
11 | #include <limits.h> | ||
12 | #include <stddef.h> | ||
13 | |||
14 | |||
15 | /* | ||
16 | ** ================================================================== | ||
17 | ** Search for "@@" to find all configurable definitions. | ||
18 | ** =================================================================== | ||
19 | */ | ||
20 | |||
21 | |||
22 | /* | ||
23 | @@ LUA_ANSI controls the use of non-ansi features. | ||
24 | ** CHANGE it (define it) if you want Lua to avoid the use of any | ||
25 | ** non-ansi feature or library. | ||
26 | */ | ||
27 | #if defined(__STRICT_ANSI__) | ||
28 | #define LUA_ANSI | ||
29 | #endif | ||
30 | |||
31 | |||
32 | #if !defined(LUA_ANSI) && defined(_WIN32) | ||
33 | #define LUA_WIN | ||
34 | #endif | ||
35 | |||
36 | #if defined(LUA_USE_LINUX) | ||
37 | #define LUA_USE_POSIX | ||
38 | #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ | ||
39 | /* #define LUA_USE_READLINE */ /* needs some extra libraries */ | ||
40 | #endif | ||
41 | |||
42 | #if defined(LUA_USE_MACOSX) | ||
43 | #define LUA_USE_POSIX | ||
44 | #define LUA_DL_DYLD /* does not need extra library */ | ||
45 | #endif | ||
46 | |||
47 | |||
48 | |||
49 | /* | ||
50 | @@ LUA_USE_POSIX includes all functionallity listed as X/Open System | ||
51 | @* Interfaces Extension (XSI). | ||
52 | ** CHANGE it (define it) if your system is XSI compatible. | ||
53 | */ | ||
54 | #if defined(LUA_USE_POSIX) | ||
55 | #define LUA_USE_MKSTEMP | ||
56 | #define LUA_USE_ISATTY | ||
57 | #define LUA_USE_POPEN | ||
58 | #define LUA_USE_ULONGJMP | ||
59 | #endif | ||
60 | |||
61 | |||
62 | /* | ||
63 | @@ LUA_PATH and LUA_CPATH are the names of the environment variables that | ||
64 | @* Lua check to set its paths. | ||
65 | @@ LUA_INIT is the name of the environment variable that Lua | ||
66 | @* checks for initialization code. | ||
67 | ** CHANGE them if you want different names. | ||
68 | */ | ||
69 | #define LUA_PATH "LUA_PATH" | ||
70 | #define LUA_CPATH "LUA_CPATH" | ||
71 | #define LUA_INIT "LUA_INIT" | ||
72 | |||
73 | |||
74 | /* | ||
75 | @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for | ||
76 | @* Lua libraries. | ||
77 | @@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for | ||
78 | @* C libraries. | ||
79 | ** CHANGE them if your machine has a non-conventional directory | ||
80 | ** hierarchy or if you want to install your libraries in | ||
81 | ** non-conventional directories. | ||
82 | */ | ||
83 | #if defined(_WIN32) | ||
84 | /* | ||
85 | ** In Windows, any exclamation mark ('!') in the path is replaced by the | ||
86 | ** path of the directory of the executable file of the current process. | ||
87 | */ | ||
88 | #define LUA_LDIR "!\\lua\\" | ||
89 | #define LUA_CDIR "!\\" | ||
90 | #define LUA_PATH_DEFAULT \ | ||
91 | ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ | ||
92 | LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" | ||
93 | #define LUA_CPATH_DEFAULT \ | ||
94 | ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" | ||
95 | |||
96 | #else | ||
97 | #define LUA_ROOT "/usr/local/" | ||
98 | #define LUA_LDIR LUA_ROOT "share/lua/5.1/" | ||
99 | #define LUA_CDIR LUA_ROOT "lib/lua/5.1/" | ||
100 | #define LUA_PATH_DEFAULT \ | ||
101 | "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ | ||
102 | LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" | ||
103 | #define LUA_CPATH_DEFAULT \ | ||
104 | "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" | ||
105 | #endif | ||
106 | |||
107 | |||
108 | /* | ||
109 | @@ LUA_DIRSEP is the directory separator (for submodules). | ||
110 | ** CHANGE it if your machine does not use "/" as the directory separator | ||
111 | ** and is not Windows. (On Windows Lua automatically uses "\".) | ||
112 | */ | ||
113 | #if defined(_WIN32) | ||
114 | #define LUA_DIRSEP "\\" | ||
115 | #else | ||
116 | #define LUA_DIRSEP "/" | ||
117 | #endif | ||
118 | |||
119 | |||
120 | /* | ||
121 | @@ LUA_PATHSEP is the character that separates templates in a path. | ||
122 | @@ LUA_PATH_MARK is the string that marks the substitution points in a | ||
123 | @* template. | ||
124 | @@ LUA_EXECDIR in a Windows path is replaced by the executable's | ||
125 | @* directory. | ||
126 | @@ LUA_IGMARK is a mark to ignore all before it when bulding the | ||
127 | @* luaopen_ function name. | ||
128 | ** CHANGE them if for some reason your system cannot use those | ||
129 | ** characters. (E.g., if one of those characters is a common character | ||
130 | ** in file/directory names.) Probably you do not need to change them. | ||
131 | */ | ||
132 | #define LUA_PATHSEP ";" | ||
133 | #define LUA_PATH_MARK "?" | ||
134 | #define LUA_EXECDIR "!" | ||
135 | #define LUA_IGMARK "-" | ||
136 | |||
137 | |||
138 | /* | ||
139 | @@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. | ||
140 | ** CHANGE that if ptrdiff_t is not adequate on your machine. (On most | ||
141 | ** machines, ptrdiff_t gives a good choice between int or long.) | ||
142 | */ | ||
143 | #define LUA_INTEGER ptrdiff_t | ||
144 | |||
145 | |||
146 | /* | ||
147 | @@ LUA_API is a mark for all core API functions. | ||
148 | @@ LUALIB_API is a mark for all standard library functions. | ||
149 | ** CHANGE them if you need to define those functions in some special way. | ||
150 | ** For instance, if you want to create one Windows DLL with the core and | ||
151 | ** the libraries, you may want to use the following definition (define | ||
152 | ** LUA_BUILD_AS_DLL to get it). | ||
153 | */ | ||
154 | #if defined(LUA_BUILD_AS_DLL) | ||
155 | |||
156 | #if defined(LUA_CORE) || defined(LUA_LIB) | ||
157 | #define LUA_API __declspec(dllexport) | ||
158 | #else | ||
159 | #define LUA_API __declspec(dllimport) | ||
160 | #endif | ||
161 | |||
162 | #else | ||
163 | |||
164 | #define LUA_API extern | ||
165 | |||
166 | #endif | ||
167 | |||
168 | /* more often than not the libs go together with the core */ | ||
169 | #define LUALIB_API LUA_API | ||
170 | |||
171 | |||
172 | /* | ||
173 | @@ LUAI_FUNC is a mark for all extern functions that are not to be | ||
174 | @* exported to outside modules. | ||
175 | @@ LUAI_DATA is a mark for all extern (const) variables that are not to | ||
176 | @* be exported to outside modules. | ||
177 | ** CHANGE them if you need to mark them in some special way. Elf/gcc | ||
178 | ** (versions 3.2 and later) mark them as "hidden" to optimize access | ||
179 | ** when Lua is compiled as a shared library. | ||
180 | */ | ||
181 | #if defined(luaall_c) | ||
182 | #define LUAI_FUNC static | ||
183 | #define LUAI_DATA /* empty */ | ||
184 | |||
185 | #elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ | ||
186 | defined(__ELF__) | ||
187 | #define LUAI_FUNC __attribute__((visibility("hidden"))) extern | ||
188 | #define LUAI_DATA LUAI_FUNC | ||
189 | |||
190 | #else | ||
191 | #define LUAI_FUNC extern | ||
192 | #define LUAI_DATA extern | ||
193 | #endif | ||
194 | |||
195 | |||
196 | |||
197 | /* | ||
198 | @@ LUA_QL describes how error messages quote program elements. | ||
199 | ** CHANGE it if you want a different appearance. | ||
200 | */ | ||
201 | #define LUA_QL(x) "'" x "'" | ||
202 | #define LUA_QS LUA_QL("%s") | ||
203 | |||
204 | |||
205 | /* | ||
206 | @@ LUA_IDSIZE gives the maximum size for the description of the source | ||
207 | @* of a function in debug information. | ||
208 | ** CHANGE it if you want a different size. | ||
209 | */ | ||
210 | #define LUA_IDSIZE 60 | ||
211 | |||
212 | |||
213 | /* | ||
214 | ** {================================================================== | ||
215 | ** Stand-alone configuration | ||
216 | ** =================================================================== | ||
217 | */ | ||
218 | |||
219 | #if defined(lua_c) || defined(luaall_c) | ||
220 | |||
221 | /* | ||
222 | @@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that | ||
223 | @* is, whether we're running lua interactively). | ||
224 | ** CHANGE it if you have a better definition for non-POSIX/non-Windows | ||
225 | ** systems. | ||
226 | */ | ||
227 | #if defined(LUA_USE_ISATTY) | ||
228 | #include <unistd.h> | ||
229 | #define lua_stdin_is_tty() isatty(0) | ||
230 | #elif defined(LUA_WIN) | ||
231 | #include <io.h> | ||
232 | #include <stdio.h> | ||
233 | #define lua_stdin_is_tty() _isatty(_fileno(stdin)) | ||
234 | #else | ||
235 | #define lua_stdin_is_tty() 1 /* assume stdin is a tty */ | ||
236 | #endif | ||
237 | |||
238 | |||
239 | /* | ||
240 | @@ LUA_PROMPT is the default prompt used by stand-alone Lua. | ||
241 | @@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. | ||
242 | ** CHANGE them if you want different prompts. (You can also change the | ||
243 | ** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) | ||
244 | */ | ||
245 | #define LUA_PROMPT "> " | ||
246 | #define LUA_PROMPT2 ">> " | ||
247 | |||
248 | |||
249 | /* | ||
250 | @@ LUA_PROGNAME is the default name for the stand-alone Lua program. | ||
251 | ** CHANGE it if your stand-alone interpreter has a different name and | ||
252 | ** your system is not able to detect that name automatically. | ||
253 | */ | ||
254 | #define LUA_PROGNAME "luajit" | ||
255 | |||
256 | |||
257 | /* | ||
258 | @@ LUA_MAXINPUT is the maximum length for an input line in the | ||
259 | @* stand-alone interpreter. | ||
260 | ** CHANGE it if you need longer lines. | ||
261 | */ | ||
262 | #define LUA_MAXINPUT 512 | ||
263 | |||
264 | |||
265 | /* | ||
266 | @@ lua_readline defines how to show a prompt and then read a line from | ||
267 | @* the standard input. | ||
268 | @@ lua_saveline defines how to "save" a read line in a "history". | ||
269 | @@ lua_freeline defines how to free a line read by lua_readline. | ||
270 | ** CHANGE them if you want to improve this functionality (e.g., by using | ||
271 | ** GNU readline and history facilities). | ||
272 | */ | ||
273 | #if defined(LUA_USE_READLINE) | ||
274 | #include <stdio.h> | ||
275 | #include <readline/readline.h> | ||
276 | #include <readline/history.h> | ||
277 | #define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) | ||
278 | #define lua_saveline(L,idx) \ | ||
279 | if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ | ||
280 | add_history(lua_tostring(L, idx)); /* add it to history */ | ||
281 | #define lua_freeline(L,b) ((void)L, free(b)) | ||
282 | #else | ||
283 | #define lua_readline(L,b,p) \ | ||
284 | ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ | ||
285 | fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ | ||
286 | #define lua_saveline(L,idx) { (void)L; (void)idx; } | ||
287 | #define lua_freeline(L,b) { (void)L; (void)b; } | ||
288 | #endif | ||
289 | |||
290 | #endif | ||
291 | |||
292 | /* }================================================================== */ | ||
293 | |||
294 | |||
295 | /* | ||
296 | @@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles | ||
297 | @* as a percentage. | ||
298 | ** CHANGE it if you want the GC to run faster or slower (higher values | ||
299 | ** mean larger pauses which mean slower collection.) You can also change | ||
300 | ** this value dynamically. | ||
301 | */ | ||
302 | #define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ | ||
303 | |||
304 | |||
305 | /* | ||
306 | @@ LUAI_GCMUL defines the default speed of garbage collection relative to | ||
307 | @* memory allocation as a percentage. | ||
308 | ** CHANGE it if you want to change the granularity of the garbage | ||
309 | ** collection. (Higher values mean coarser collections. 0 represents | ||
310 | ** infinity, where each step performs a full collection.) You can also | ||
311 | ** change this value dynamically. | ||
312 | */ | ||
313 | #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ | ||
314 | |||
315 | |||
316 | |||
317 | /* | ||
318 | @@ LUA_COMPAT_GETN controls compatibility with old getn behavior. | ||
319 | ** CHANGE it (define it) if you want exact compatibility with the | ||
320 | ** behavior of setn/getn in Lua 5.0. | ||
321 | ** | ||
322 | ** Note: this is not supported by LuaJIT. Leave it undefined. | ||
323 | */ | ||
324 | #undef LUA_COMPAT_GETN | ||
325 | |||
326 | /* | ||
327 | @@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. | ||
328 | ** CHANGE it to undefined as soon as you do not need a global 'loadlib' | ||
329 | ** function (the function is still available as 'package.loadlib'). | ||
330 | */ | ||
331 | #undef LUA_COMPAT_LOADLIB | ||
332 | |||
333 | /* | ||
334 | @@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. | ||
335 | ** CHANGE it to undefined as soon as your programs use only '...' to | ||
336 | ** access vararg parameters (instead of the old 'arg' table). | ||
337 | ** | ||
338 | ** Note: this has a slightly negative performance impact with LuaJIT | ||
339 | ** for all vararg functions. Leave it off if possible and upgrade your | ||
340 | ** code (replace unpack(arg) with ... and/or add local arg = {...}). | ||
341 | */ | ||
342 | #undef LUA_COMPAT_VARARG | ||
343 | |||
344 | /* | ||
345 | @@ LUA_COMPAT_MOD controls compatibility with old math.mod function. | ||
346 | ** CHANGE it to undefined as soon as your programs use 'math.fmod' or | ||
347 | ** the new '%' operator instead of 'math.mod'. | ||
348 | */ | ||
349 | #define LUA_COMPAT_MOD | ||
350 | |||
351 | /* | ||
352 | @@ LUA_COMPAT_LSTR controls compatibility with old long string nesting | ||
353 | @* facility. | ||
354 | ** CHANGE it to 2 if you want the old behaviour, or undefine it to turn | ||
355 | ** off the advisory error when nesting [[...]]. | ||
356 | */ | ||
357 | #define LUA_COMPAT_LSTR 1 | ||
358 | |||
359 | /* | ||
360 | @@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. | ||
361 | ** CHANGE it to undefined as soon as you rename 'string.gfind' to | ||
362 | ** 'string.gmatch'. | ||
363 | */ | ||
364 | #define LUA_COMPAT_GFIND | ||
365 | |||
366 | /* | ||
367 | @@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' | ||
368 | @* behavior. | ||
369 | ** CHANGE it to undefined as soon as you replace to 'luaL_register' | ||
370 | ** your uses of 'luaL_openlib' | ||
371 | */ | ||
372 | #define LUA_COMPAT_OPENLIB | ||
373 | |||
374 | |||
375 | |||
376 | /* | ||
377 | @@ luai_apicheck is the assert macro used by the Lua-C API. | ||
378 | ** CHANGE luai_apicheck if you want Lua to perform some checks in the | ||
379 | ** parameters it gets from API calls. This may slow down the interpreter | ||
380 | ** a bit, but may be quite useful when debugging C code that interfaces | ||
381 | ** with Lua. A useful redefinition is to use assert.h. | ||
382 | */ | ||
383 | #if defined(LUA_USE_APICHECK) | ||
384 | #include <assert.h> | ||
385 | #define luai_apicheck(L,o) { (void)L; assert(o); } | ||
386 | #else | ||
387 | #define luai_apicheck(L,o) { (void)L; } | ||
388 | #endif | ||
389 | |||
390 | |||
391 | /* | ||
392 | @@ LUAI_BITSINT defines the number of bits in an int. | ||
393 | ** CHANGE here if Lua cannot automatically detect the number of bits of | ||
394 | ** your machine. Probably you do not need to change this. | ||
395 | */ | ||
396 | /* avoid overflows in comparison */ | ||
397 | #if INT_MAX-20 < 32760 | ||
398 | #define LUAI_BITSINT 16 | ||
399 | #elif INT_MAX > 2147483640L | ||
400 | /* int has at least 32 bits */ | ||
401 | #define LUAI_BITSINT 32 | ||
402 | #else | ||
403 | #error "you must define LUA_BITSINT with number of bits in an integer" | ||
404 | #endif | ||
405 | |||
406 | |||
407 | /* | ||
408 | @@ LUAI_UINT32 is an unsigned integer with at least 32 bits. | ||
409 | @@ LUAI_INT32 is an signed integer with at least 32 bits. | ||
410 | @@ LUAI_UMEM is an unsigned integer big enough to count the total | ||
411 | @* memory used by Lua. | ||
412 | @@ LUAI_MEM is a signed integer big enough to count the total memory | ||
413 | @* used by Lua. | ||
414 | ** CHANGE here if for some weird reason the default definitions are not | ||
415 | ** good enough for your machine. (The definitions in the 'else' | ||
416 | ** part always works, but may waste space on machines with 64-bit | ||
417 | ** longs.) Probably you do not need to change this. | ||
418 | */ | ||
419 | #if LUAI_BITSINT >= 32 | ||
420 | #define LUAI_UINT32 unsigned int | ||
421 | #define LUAI_INT32 int | ||
422 | #define LUAI_MAXINT32 INT_MAX | ||
423 | #define LUAI_UMEM size_t | ||
424 | #define LUAI_MEM ptrdiff_t | ||
425 | #else | ||
426 | /* 16-bit ints */ | ||
427 | #define LUAI_UINT32 unsigned long | ||
428 | #define LUAI_INT32 long | ||
429 | #define LUAI_MAXINT32 LONG_MAX | ||
430 | #define LUAI_UMEM unsigned long | ||
431 | #define LUAI_MEM long | ||
432 | #endif | ||
433 | |||
434 | |||
435 | /* | ||
436 | @@ LUAI_MAXCALLS limits the number of nested calls. | ||
437 | ** CHANGE it if you need really deep recursive calls. This limit is | ||
438 | ** arbitrary; its only purpose is to stop infinite recursion before | ||
439 | ** exhausting memory. | ||
440 | */ | ||
441 | #define LUAI_MAXCALLS 20000 | ||
442 | |||
443 | |||
444 | /* | ||
445 | @@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function | ||
446 | @* can use. | ||
447 | ** CHANGE it if you need lots of (Lua) stack space for your C | ||
448 | ** functions. This limit is arbitrary; its only purpose is to stop C | ||
449 | ** functions to consume unlimited stack space. (must be smaller than | ||
450 | ** -LUA_REGISTRYINDEX) | ||
451 | */ | ||
452 | #define LUAI_MAXCSTACK 8000 | ||
453 | |||
454 | |||
455 | /* | ||
456 | ** {================================================================== | ||
457 | ** CHANGE (to smaller values) the following definitions if your system | ||
458 | ** has a small C stack. (Or you may want to change them to larger | ||
459 | ** values if your system has a large C stack and these limits are | ||
460 | ** too rigid for you.) Some of these constants control the size of | ||
461 | ** stack-allocated arrays used by the compiler or the interpreter, while | ||
462 | ** others limit the maximum number of recursive calls that the compiler | ||
463 | ** or the interpreter can perform. Values too large may cause a C stack | ||
464 | ** overflow for some forms of deep constructs. | ||
465 | ** =================================================================== | ||
466 | */ | ||
467 | |||
468 | |||
469 | /* | ||
470 | @@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and | ||
471 | @* syntactical nested non-terminals in a program. | ||
472 | */ | ||
473 | #define LUAI_MAXCCALLS 200 | ||
474 | |||
475 | |||
476 | /* | ||
477 | @@ LUAI_MAXVARS is the maximum number of local variables per function | ||
478 | @* (must be smaller than 250). | ||
479 | */ | ||
480 | #define LUAI_MAXVARS 200 | ||
481 | |||
482 | |||
483 | /* | ||
484 | @@ LUAI_MAXUPVALUES is the maximum number of upvalues per function | ||
485 | @* (must be smaller than 250). | ||
486 | */ | ||
487 | #define LUAI_MAXUPVALUES 60 | ||
488 | |||
489 | |||
490 | /* | ||
491 | @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. | ||
492 | */ | ||
493 | #define LUAL_BUFFERSIZE BUFSIZ | ||
494 | |||
495 | /* }================================================================== */ | ||
496 | |||
497 | |||
498 | |||
499 | |||
500 | /* | ||
501 | ** {================================================================== | ||
502 | @@ LUA_NUMBER is the type of numbers in Lua. | ||
503 | ** CHANGE the following definitions only if you want to build Lua | ||
504 | ** with a number type different from double. You may also need to | ||
505 | ** change lua_number2int & lua_number2integer. | ||
506 | ** =================================================================== | ||
507 | */ | ||
508 | |||
509 | #define LUA_NUMBER_DOUBLE | ||
510 | #define LUA_NUMBER double | ||
511 | |||
512 | /* | ||
513 | @@ LUAI_UACNUMBER is the result of an 'usual argument conversion' | ||
514 | @* over a number. | ||
515 | */ | ||
516 | #define LUAI_UACNUMBER double | ||
517 | |||
518 | |||
519 | /* | ||
520 | @@ LUA_NUMBER_SCAN is the format for reading numbers. | ||
521 | @@ LUA_NUMBER_FMT is the format for writing numbers. | ||
522 | @@ lua_number2str converts a number to a string. | ||
523 | @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. | ||
524 | @@ lua_str2number converts a string to a number. | ||
525 | */ | ||
526 | #define LUA_NUMBER_SCAN "%lf" | ||
527 | #define LUA_NUMBER_FMT "%.14g" | ||
528 | #define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) | ||
529 | #define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ | ||
530 | #define lua_str2number(s,p) strtod((s), (p)) | ||
531 | |||
532 | |||
533 | /* | ||
534 | @@ The luai_num* macros define the primitive operations over numbers. | ||
535 | */ | ||
536 | #if defined(LUA_CORE) | ||
537 | #include <math.h> | ||
538 | #define luai_numadd(a,b) ((a)+(b)) | ||
539 | #define luai_numsub(a,b) ((a)-(b)) | ||
540 | #define luai_nummul(a,b) ((a)*(b)) | ||
541 | #define luai_numdiv(a,b) ((a)/(b)) | ||
542 | #define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) | ||
543 | #define luai_numpow(a,b) (pow(a,b)) | ||
544 | #define luai_numunm(a) (-(a)) | ||
545 | #define luai_numeq(a,b) ((a)==(b)) | ||
546 | #define luai_numlt(a,b) ((a)<(b)) | ||
547 | #define luai_numle(a,b) ((a)<=(b)) | ||
548 | #define luai_numisnan(a) (!luai_numeq((a), (a))) | ||
549 | #endif | ||
550 | |||
551 | |||
552 | /* | ||
553 | @@ lua_number2int is a macro to convert lua_Number to int. | ||
554 | @@ lua_number2integer is a macro to convert lua_Number to lua_Integer. | ||
555 | ** CHANGE them if you know a faster way to convert a lua_Number to | ||
556 | ** int (with any rounding method and without throwing errors) in your | ||
557 | ** system. In Pentium machines, a naive typecast from double to int | ||
558 | ** in C is extremely slow, so any alternative is worth trying. | ||
559 | */ | ||
560 | |||
561 | /* On a Pentium, resort to a trick */ | ||
562 | #if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ | ||
563 | (defined(__i386) || defined (_M_IX86) || defined(__i386__)) | ||
564 | |||
565 | /* On a Microsoft compiler, use assembler */ | ||
566 | #if defined(_MSC_VER) | ||
567 | |||
568 | #define lua_number2int(i,d) __asm fld d __asm fistp i | ||
569 | #define lua_number2integer(i,n) lua_number2int(i, n) | ||
570 | |||
571 | /* the next trick should work on any Pentium, but sometimes clashes | ||
572 | with a DirectX idiosyncrasy */ | ||
573 | #else | ||
574 | |||
575 | union luai_Cast { double l_d; long l_l; }; | ||
576 | #define lua_number2int(i,d) \ | ||
577 | { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } | ||
578 | #define lua_number2integer(i,n) lua_number2int(i, n) | ||
579 | |||
580 | #endif | ||
581 | |||
582 | |||
583 | /* this option always works, but may be slow */ | ||
584 | #else | ||
585 | #define lua_number2int(i,d) ((i)=(int)(d)) | ||
586 | #define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) | ||
587 | |||
588 | #endif | ||
589 | |||
590 | |||
591 | /* | ||
592 | @@ LUA_TVALUE_ALIGN specifies extra alignment constraints for the | ||
593 | @@ tagged value structure to get better lua_Number alignment. | ||
594 | ** CHANGE it to an empty define if you want to save some space | ||
595 | ** at the cost of execution time. Note that this is only needed | ||
596 | ** for the x86 ABI on most POSIX systems, but not on Windows and | ||
597 | ** not for most other CPUs. If you change it then you need to follow | ||
598 | ** the instructions in ljit_x86.dash, too (look for TVALUE_SIZE). | ||
599 | */ | ||
600 | |||
601 | #if defined(LUA_NUMBER_DOUBLE) && defined(__GNUC__) && \ | ||
602 | (defined(__i386) || defined(__i386__)) && !defined(_WIN32) | ||
603 | #define LUA_TVALUE_ALIGN __attribute__ ((aligned(8))) | ||
604 | #else | ||
605 | #define LUA_TVALUE_ALIGN | ||
606 | #endif | ||
607 | |||
608 | /* }================================================================== */ | ||
609 | |||
610 | |||
611 | /* | ||
612 | @@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. | ||
613 | ** CHANGE it if your system requires alignments larger than double. (For | ||
614 | ** instance, if your system supports long doubles and they must be | ||
615 | ** aligned in 16-byte boundaries, then you should add long double in the | ||
616 | ** union.) Probably you do not need to change this. | ||
617 | */ | ||
618 | #define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } | ||
619 | |||
620 | |||
621 | /* | ||
622 | @@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. | ||
623 | ** CHANGE them if you prefer to use longjmp/setjmp even with C++ | ||
624 | ** or if want/don't to use _longjmp/_setjmp instead of regular | ||
625 | ** longjmp/setjmp. By default, Lua handles errors with exceptions when | ||
626 | ** compiling as C++ code, with _longjmp/_setjmp when asked to use them, | ||
627 | ** and with longjmp/setjmp otherwise. | ||
628 | */ | ||
629 | #if defined(__cplusplus) | ||
630 | /* C++ exceptions */ | ||
631 | #define LUAI_THROW(L,c) throw(c) | ||
632 | #define LUAI_TRY(L,c,a) try { a } catch(...) \ | ||
633 | { if ((c)->status == 0) (c)->status = -1; } | ||
634 | #define luai_jmpbuf int /* dummy variable */ | ||
635 | |||
636 | #elif defined(LUA_USE_ULONGJMP) | ||
637 | /* in Unix, try _longjmp/_setjmp (more efficient) */ | ||
638 | #define LUAI_THROW(L,c) _longjmp((c)->b, 1) | ||
639 | #define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } | ||
640 | #define luai_jmpbuf jmp_buf | ||
641 | |||
642 | #else | ||
643 | /* default handling with long jumps */ | ||
644 | #define LUAI_THROW(L,c) longjmp((c)->b, 1) | ||
645 | #define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } | ||
646 | #define luai_jmpbuf jmp_buf | ||
647 | |||
648 | #endif | ||
649 | |||
650 | |||
651 | /* | ||
652 | @@ LUA_MAXCAPTURES is the maximum number of captures that a pattern | ||
653 | @* can do during pattern-matching. | ||
654 | ** CHANGE it if you need more captures. This limit is arbitrary. | ||
655 | */ | ||
656 | #define LUA_MAXCAPTURES 32 | ||
657 | |||
658 | |||
659 | /* | ||
660 | @@ lua_tmpnam is the function that the OS library uses to create a | ||
661 | @* temporary name. | ||
662 | @@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. | ||
663 | ** CHANGE them if you have an alternative to tmpnam (which is considered | ||
664 | ** insecure) or if you want the original tmpnam anyway. By default, Lua | ||
665 | ** uses tmpnam except when POSIX is available, where it uses mkstemp. | ||
666 | */ | ||
667 | #if defined(loslib_c) || defined(luaall_c) | ||
668 | |||
669 | #if defined(LUA_USE_MKSTEMP) | ||
670 | #include <unistd.h> | ||
671 | #define LUA_TMPNAMBUFSIZE 32 | ||
672 | #define lua_tmpnam(b,e) { \ | ||
673 | strcpy(b, "/tmp/lua_XXXXXX"); \ | ||
674 | e = mkstemp(b); \ | ||
675 | if (e != -1) close(e); \ | ||
676 | e = (e == -1); } | ||
677 | |||
678 | #else | ||
679 | #define LUA_TMPNAMBUFSIZE L_tmpnam | ||
680 | #define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } | ||
681 | #endif | ||
682 | |||
683 | #endif | ||
684 | |||
685 | |||
686 | /* | ||
687 | @@ lua_popen spawns a new process connected to the current one through | ||
688 | @* the file streams. | ||
689 | ** CHANGE it if you have a way to implement it in your system. | ||
690 | */ | ||
691 | #if defined(LUA_USE_POPEN) | ||
692 | |||
693 | #define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) | ||
694 | #define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) | ||
695 | |||
696 | #elif defined(LUA_WIN) | ||
697 | |||
698 | #define lua_popen(L,c,m) ((void)L, _popen(c,m)) | ||
699 | #define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) | ||
700 | |||
701 | #else | ||
702 | |||
703 | #define lua_popen(L,c,m) ((void)((void)c, m), \ | ||
704 | luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) | ||
705 | #define lua_pclose(L,file) ((void)((void)L, file), 0) | ||
706 | |||
707 | #endif | ||
708 | |||
709 | /* | ||
710 | @@ LUA_DL_* define which dynamic-library system Lua should use. | ||
711 | ** CHANGE here if Lua has problems choosing the appropriate | ||
712 | ** dynamic-library system for your platform (either Windows' DLL, Mac's | ||
713 | ** dyld, or Unix's dlopen). If your system is some kind of Unix, there | ||
714 | ** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for | ||
715 | ** it. To use dlopen you also need to adapt the src/Makefile (probably | ||
716 | ** adding -ldl to the linker options), so Lua does not select it | ||
717 | ** automatically. (When you change the makefile to add -ldl, you must | ||
718 | ** also add -DLUA_USE_DLOPEN.) | ||
719 | ** If you do not want any kind of dynamic library, undefine all these | ||
720 | ** options. | ||
721 | ** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. | ||
722 | */ | ||
723 | #if defined(LUA_USE_DLOPEN) | ||
724 | #define LUA_DL_DLOPEN | ||
725 | #endif | ||
726 | |||
727 | #if defined(LUA_WIN) | ||
728 | #define LUA_DL_DLL | ||
729 | #endif | ||
730 | |||
731 | |||
732 | /* | ||
733 | @@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State | ||
734 | @* (the data goes just *before* the lua_State pointer). | ||
735 | ** CHANGE (define) this if you really need that. This value must be | ||
736 | ** a multiple of the maximum alignment required for your machine. | ||
737 | */ | ||
738 | #define LUAI_EXTRASPACE 0 | ||
739 | |||
740 | |||
741 | /* | ||
742 | @@ luai_userstate* allow user-specific actions on threads. | ||
743 | ** CHANGE them if you defined LUAI_EXTRASPACE and need to do something | ||
744 | ** extra when a thread is created/deleted/resumed/yielded. | ||
745 | */ | ||
746 | #define luai_userstateopen(L) ((void)L) | ||
747 | #define luai_userstateclose(L) ((void)L) | ||
748 | #define luai_userstatethread(L,L1) ((void)L) | ||
749 | #define luai_userstatefree(L) ((void)L) | ||
750 | #define luai_userstateresume(L,n) ((void)L) | ||
751 | #define luai_userstateyield(L,n) ((void)L) | ||
752 | |||
753 | |||
754 | /* | ||
755 | @@ LUA_INTFRMLEN is the length modifier for integer conversions | ||
756 | @* in 'string.format'. | ||
757 | @@ LUA_INTFRM_T is the integer type correspoding to the previous length | ||
758 | @* modifier. | ||
759 | ** CHANGE them if your system supports long long or does not support long. | ||
760 | */ | ||
761 | |||
762 | #if defined(LUA_USELONGLONG) | ||
763 | |||
764 | #define LUA_INTFRMLEN "ll" | ||
765 | #define LUA_INTFRM_T long long | ||
766 | |||
767 | #else | ||
768 | |||
769 | #define LUA_INTFRMLEN "l" | ||
770 | #define LUA_INTFRM_T long | ||
771 | |||
772 | #endif | ||
773 | |||
774 | |||
775 | |||
776 | /* =================================================================== */ | ||
777 | |||
778 | /* | ||
779 | ** Local configuration. You can use this space to add your redefinitions | ||
780 | ** without modifying the main part of the file. | ||
781 | */ | ||
782 | |||
783 | |||
784 | |||
785 | #endif | ||
786 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/luajit.h b/libraries/LuaJIT-1.1.7/src/luajit.h new file mode 100644 index 0000000..fa32e17 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/luajit.h | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | ** Copyright (C) 2005-2011 Mike Pall. All rights reserved. | ||
3 | ** | ||
4 | ** Permission is hereby granted, free of charge, to any person obtaining | ||
5 | ** a copy of this software and associated documentation files (the | ||
6 | ** "Software"), to deal in the Software without restriction, including | ||
7 | ** without limitation the rights to use, copy, modify, merge, publish, | ||
8 | ** distribute, sublicense, and/or sell copies of the Software, and to | ||
9 | ** permit persons to whom the Software is furnished to do so, subject to | ||
10 | ** the following conditions: | ||
11 | ** | ||
12 | ** The above copyright notice and this permission notice shall be | ||
13 | ** included in all copies or substantial portions of the Software. | ||
14 | ** | ||
15 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
16 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
17 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
18 | ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
19 | ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
20 | ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
21 | ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
22 | ** | ||
23 | ** [ MIT license: http://www.opensource.org/licenses/mit-license.php ] | ||
24 | */ | ||
25 | |||
26 | /* LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/ */ | ||
27 | |||
28 | /* LuaJIT public C API. */ | ||
29 | #ifndef luajit_h | ||
30 | #define luajit_h | ||
31 | |||
32 | #include "lua.h" | ||
33 | |||
34 | |||
35 | #define LUAJIT_VERSION "LuaJIT 1.1.7" | ||
36 | #define LUAJIT_VERSION_NUM 10107 /* Version 1.1.7 = 01.01.07. */ | ||
37 | #define LUAJIT_VERSION_SYM luaJIT_version_1_1_7 | ||
38 | #define LUAJIT_COPYRIGHT "Copyright (C) 2005-2011 Mike Pall" | ||
39 | #define LUAJIT_URL "http://luajit.org/" | ||
40 | |||
41 | /* Modes for luaJIT_setmode. */ | ||
42 | #define LUAJIT_MODE_MASK 0x00ff | ||
43 | |||
44 | enum { | ||
45 | LUAJIT_MODE_ENGINE, /* Set mode for whole JIT engine. */ | ||
46 | LUAJIT_MODE_DEBUG, /* Set debug mode (idx = level). */ | ||
47 | |||
48 | LUAJIT_MODE_FUNC, /* Change mode for a function. */ | ||
49 | LUAJIT_MODE_ALLFUNC, /* Recurse into subroutine protos. */ | ||
50 | LUAJIT_MODE_ALLSUBFUNC, /* Change only the subroutines. */ | ||
51 | LUAJIT_MODE_MAX | ||
52 | }; | ||
53 | |||
54 | /* Flags or'ed in to the mode. */ | ||
55 | #define LUAJIT_MODE_OFF 0x0000 /* Disable JIT compilation. */ | ||
56 | #define LUAJIT_MODE_ON 0x0100 /* (Re-)enable JIT compilation. */ | ||
57 | |||
58 | |||
59 | /* Compile a Lua function. Pass arguments as hints. */ | ||
60 | LUA_API int luaJIT_compile(lua_State *L, int nargs); | ||
61 | |||
62 | /* Set the JIT mode for the whole engine or a function (idx = 0: self). */ | ||
63 | LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode); | ||
64 | |||
65 | /* Enforce (dynamic) linker error for version mismatches. Call from main. */ | ||
66 | LUA_API void LUAJIT_VERSION_SYM(void); | ||
67 | |||
68 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lualib.h b/libraries/LuaJIT-1.1.7/src/lualib.h new file mode 100644 index 0000000..c4567e9 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lualib.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | ** $Id: lualib.h,v 1.36 2005/12/27 17:12:00 roberto Exp $ | ||
3 | ** Lua standard libraries | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #ifndef lualib_h | ||
9 | #define lualib_h | ||
10 | |||
11 | #include "lua.h" | ||
12 | |||
13 | |||
14 | /* Key to file-handle type */ | ||
15 | #define LUA_FILEHANDLE "FILE*" | ||
16 | |||
17 | |||
18 | #define LUA_COLIBNAME "coroutine" | ||
19 | LUALIB_API int (luaopen_base) (lua_State *L); | ||
20 | |||
21 | #define LUA_TABLIBNAME "table" | ||
22 | LUALIB_API int (luaopen_table) (lua_State *L); | ||
23 | |||
24 | #define LUA_IOLIBNAME "io" | ||
25 | LUALIB_API int (luaopen_io) (lua_State *L); | ||
26 | |||
27 | #define LUA_OSLIBNAME "os" | ||
28 | LUALIB_API int (luaopen_os) (lua_State *L); | ||
29 | |||
30 | #define LUA_STRLIBNAME "string" | ||
31 | LUALIB_API int (luaopen_string) (lua_State *L); | ||
32 | |||
33 | #define LUA_MATHLIBNAME "math" | ||
34 | LUALIB_API int (luaopen_math) (lua_State *L); | ||
35 | |||
36 | #define LUA_DBLIBNAME "debug" | ||
37 | LUALIB_API int (luaopen_debug) (lua_State *L); | ||
38 | |||
39 | #define LUA_LOADLIBNAME "package" | ||
40 | LUALIB_API int (luaopen_package) (lua_State *L); | ||
41 | |||
42 | #define LUA_JITLIBNAME "jit" | ||
43 | LUALIB_API int (luaopen_jit) (lua_State *L); | ||
44 | |||
45 | |||
46 | /* open all previous libraries */ | ||
47 | LUALIB_API void (luaL_openlibs) (lua_State *L); | ||
48 | |||
49 | |||
50 | |||
51 | #ifndef lua_assert | ||
52 | #define lua_assert(x) ((void)0) | ||
53 | #endif | ||
54 | |||
55 | |||
56 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lundump.c b/libraries/LuaJIT-1.1.7/src/lundump.c new file mode 100644 index 0000000..8010a45 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lundump.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* | ||
2 | ** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $ | ||
3 | ** load precompiled Lua chunks | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #include <string.h> | ||
8 | |||
9 | #define lundump_c | ||
10 | #define LUA_CORE | ||
11 | |||
12 | #include "lua.h" | ||
13 | |||
14 | #include "ldebug.h" | ||
15 | #include "ldo.h" | ||
16 | #include "lfunc.h" | ||
17 | #include "lmem.h" | ||
18 | #include "lobject.h" | ||
19 | #include "lstring.h" | ||
20 | #include "lundump.h" | ||
21 | #include "lzio.h" | ||
22 | |||
23 | typedef struct { | ||
24 | lua_State* L; | ||
25 | ZIO* Z; | ||
26 | Mbuffer* b; | ||
27 | const char* name; | ||
28 | } LoadState; | ||
29 | |||
30 | #ifdef LUAC_TRUST_BINARIES | ||
31 | #define IF(c,s) | ||
32 | #define error(S,s) | ||
33 | #else | ||
34 | #define IF(c,s) if (c) error(S,s) | ||
35 | |||
36 | static void error(LoadState* S, const char* why) | ||
37 | { | ||
38 | luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); | ||
39 | luaD_throw(S->L,LUA_ERRSYNTAX); | ||
40 | } | ||
41 | #endif | ||
42 | |||
43 | #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) | ||
44 | #define LoadByte(S) (lu_byte)LoadChar(S) | ||
45 | #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) | ||
46 | #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) | ||
47 | |||
48 | static void LoadBlock(LoadState* S, void* b, size_t size) | ||
49 | { | ||
50 | size_t r=luaZ_read(S->Z,b,size); | ||
51 | IF (r!=0, "unexpected end"); | ||
52 | } | ||
53 | |||
54 | static int LoadChar(LoadState* S) | ||
55 | { | ||
56 | char x; | ||
57 | LoadVar(S,x); | ||
58 | return x; | ||
59 | } | ||
60 | |||
61 | static int LoadInt(LoadState* S) | ||
62 | { | ||
63 | int x; | ||
64 | LoadVar(S,x); | ||
65 | IF (x<0, "bad integer"); | ||
66 | return x; | ||
67 | } | ||
68 | |||
69 | static lua_Number LoadNumber(LoadState* S) | ||
70 | { | ||
71 | lua_Number x; | ||
72 | LoadVar(S,x); | ||
73 | return x; | ||
74 | } | ||
75 | |||
76 | static TString* LoadString(LoadState* S) | ||
77 | { | ||
78 | size_t size; | ||
79 | LoadVar(S,size); | ||
80 | if (size==0) | ||
81 | return NULL; | ||
82 | else | ||
83 | { | ||
84 | char* s=luaZ_openspace(S->L,S->b,size); | ||
85 | LoadBlock(S,s,size); | ||
86 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ | ||
87 | } | ||
88 | } | ||
89 | |||
90 | static void LoadCode(LoadState* S, Proto* f) | ||
91 | { | ||
92 | int n=LoadInt(S); | ||
93 | f->code=luaM_newvector(S->L,n,Instruction); | ||
94 | f->sizecode=n; | ||
95 | LoadVector(S,f->code,n,sizeof(Instruction)); | ||
96 | } | ||
97 | |||
98 | static Proto* LoadFunction(LoadState* S, TString* p); | ||
99 | |||
100 | static void LoadConstants(LoadState* S, Proto* f) | ||
101 | { | ||
102 | int i,n; | ||
103 | n=LoadInt(S); | ||
104 | f->k=luaM_newvector(S->L,n,TValue); | ||
105 | f->sizek=n; | ||
106 | for (i=0; i<n; i++) setnilvalue(&f->k[i]); | ||
107 | for (i=0; i<n; i++) | ||
108 | { | ||
109 | TValue* o=&f->k[i]; | ||
110 | int t=LoadChar(S); | ||
111 | switch (t) | ||
112 | { | ||
113 | case LUA_TNIL: | ||
114 | setnilvalue(o); | ||
115 | break; | ||
116 | case LUA_TBOOLEAN: | ||
117 | setbvalue(o,LoadChar(S)!=0); | ||
118 | break; | ||
119 | case LUA_TNUMBER: | ||
120 | setnvalue(o,LoadNumber(S)); | ||
121 | break; | ||
122 | case LUA_TSTRING: | ||
123 | setsvalue2n(S->L,o,LoadString(S)); | ||
124 | break; | ||
125 | default: | ||
126 | error(S,"bad constant"); | ||
127 | break; | ||
128 | } | ||
129 | } | ||
130 | n=LoadInt(S); | ||
131 | f->p=luaM_newvector(S->L,n,Proto*); | ||
132 | f->sizep=n; | ||
133 | for (i=0; i<n; i++) f->p[i]=NULL; | ||
134 | for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source); | ||
135 | } | ||
136 | |||
137 | static void LoadDebug(LoadState* S, Proto* f) | ||
138 | { | ||
139 | int i,n; | ||
140 | n=LoadInt(S); | ||
141 | f->lineinfo=luaM_newvector(S->L,n,int); | ||
142 | f->sizelineinfo=n; | ||
143 | LoadVector(S,f->lineinfo,n,sizeof(int)); | ||
144 | n=LoadInt(S); | ||
145 | f->locvars=luaM_newvector(S->L,n,LocVar); | ||
146 | f->sizelocvars=n; | ||
147 | for (i=0; i<n; i++) f->locvars[i].varname=NULL; | ||
148 | for (i=0; i<n; i++) | ||
149 | { | ||
150 | f->locvars[i].varname=LoadString(S); | ||
151 | f->locvars[i].startpc=LoadInt(S); | ||
152 | f->locvars[i].endpc=LoadInt(S); | ||
153 | } | ||
154 | n=LoadInt(S); | ||
155 | f->upvalues=luaM_newvector(S->L,n,TString*); | ||
156 | f->sizeupvalues=n; | ||
157 | for (i=0; i<n; i++) f->upvalues[i]=NULL; | ||
158 | for (i=0; i<n; i++) f->upvalues[i]=LoadString(S); | ||
159 | } | ||
160 | |||
161 | static Proto* LoadFunction(LoadState* S, TString* p) | ||
162 | { | ||
163 | Proto* f; | ||
164 | if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); | ||
165 | f=luaF_newproto(S->L); | ||
166 | setptvalue2s(S->L,S->L->top,f); incr_top(S->L); | ||
167 | f->source=LoadString(S); if (f->source==NULL) f->source=p; | ||
168 | f->linedefined=LoadInt(S); | ||
169 | f->lastlinedefined=LoadInt(S); | ||
170 | f->nups=LoadByte(S); | ||
171 | f->numparams=LoadByte(S); | ||
172 | f->is_vararg=LoadByte(S); | ||
173 | f->maxstacksize=LoadByte(S); | ||
174 | LoadCode(S,f); | ||
175 | LoadConstants(S,f); | ||
176 | LoadDebug(S,f); | ||
177 | IF (!luaG_checkcode(f), "bad code"); | ||
178 | S->L->top--; | ||
179 | S->L->nCcalls--; | ||
180 | return f; | ||
181 | } | ||
182 | |||
183 | static void LoadHeader(LoadState* S) | ||
184 | { | ||
185 | char h[LUAC_HEADERSIZE]; | ||
186 | char s[LUAC_HEADERSIZE]; | ||
187 | luaU_header(h); | ||
188 | LoadBlock(S,s,LUAC_HEADERSIZE); | ||
189 | IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); | ||
190 | } | ||
191 | |||
192 | /* | ||
193 | ** load precompiled chunk | ||
194 | */ | ||
195 | Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) | ||
196 | { | ||
197 | LoadState S; | ||
198 | if (*name=='@' || *name=='=') | ||
199 | S.name=name+1; | ||
200 | else if (*name==LUA_SIGNATURE[0]) | ||
201 | S.name="binary string"; | ||
202 | else | ||
203 | S.name=name; | ||
204 | S.L=L; | ||
205 | S.Z=Z; | ||
206 | S.b=buff; | ||
207 | LoadHeader(&S); | ||
208 | return LoadFunction(&S,luaS_newliteral(L,"=?")); | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * make header | ||
213 | */ | ||
214 | void luaU_header (char* h) | ||
215 | { | ||
216 | int x=1; | ||
217 | memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); | ||
218 | h+=sizeof(LUA_SIGNATURE)-1; | ||
219 | *h++=(char)LUAC_VERSION; | ||
220 | *h++=(char)LUAC_FORMAT; | ||
221 | *h++=(char)*(char*)&x; /* endianness */ | ||
222 | *h++=(char)sizeof(int); | ||
223 | *h++=(char)sizeof(size_t); | ||
224 | *h++=(char)sizeof(Instruction); | ||
225 | *h++=(char)sizeof(lua_Number); | ||
226 | *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ | ||
227 | } | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lundump.h b/libraries/LuaJIT-1.1.7/src/lundump.h new file mode 100644 index 0000000..c80189d --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lundump.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | ** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** load precompiled Lua chunks | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lundump_h | ||
8 | #define lundump_h | ||
9 | |||
10 | #include "lobject.h" | ||
11 | #include "lzio.h" | ||
12 | |||
13 | /* load one chunk; from lundump.c */ | ||
14 | LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); | ||
15 | |||
16 | /* make header; from lundump.c */ | ||
17 | LUAI_FUNC void luaU_header (char* h); | ||
18 | |||
19 | /* dump one chunk; from ldump.c */ | ||
20 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); | ||
21 | |||
22 | #ifdef luac_c | ||
23 | /* print one chunk; from print.c */ | ||
24 | LUAI_FUNC void luaU_print (const Proto* f, int full); | ||
25 | #endif | ||
26 | |||
27 | /* for header of binary files -- this is Lua 5.1 */ | ||
28 | #define LUAC_VERSION 0x51 | ||
29 | |||
30 | /* for header of binary files -- this is the official format */ | ||
31 | #define LUAC_FORMAT 0 | ||
32 | |||
33 | /* size of header of binary files */ | ||
34 | #define LUAC_HEADERSIZE 12 | ||
35 | |||
36 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lvm.c b/libraries/LuaJIT-1.1.7/src/lvm.c new file mode 100644 index 0000000..d24f43c --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lvm.c | |||
@@ -0,0 +1,766 @@ | |||
1 | /* | ||
2 | ** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $ | ||
3 | ** Lua virtual machine | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <stdio.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <string.h> | ||
11 | |||
12 | #define lvm_c | ||
13 | #define LUA_CORE | ||
14 | |||
15 | #include "lua.h" | ||
16 | |||
17 | #include "ldebug.h" | ||
18 | #include "ldo.h" | ||
19 | #include "lfunc.h" | ||
20 | #include "lgc.h" | ||
21 | #include "lobject.h" | ||
22 | #include "lopcodes.h" | ||
23 | #include "lstate.h" | ||
24 | #include "lstring.h" | ||
25 | #include "ltable.h" | ||
26 | #include "ltm.h" | ||
27 | #include "lvm.h" | ||
28 | |||
29 | |||
30 | |||
31 | /* limit for table tag-method chains (to avoid loops) */ | ||
32 | #define MAXTAGLOOP 100 | ||
33 | |||
34 | |||
35 | const TValue *luaV_tonumber (const TValue *obj, TValue *n) { | ||
36 | lua_Number num; | ||
37 | if (ttisnumber(obj)) return obj; | ||
38 | if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { | ||
39 | setnvalue(n, num); | ||
40 | return n; | ||
41 | } | ||
42 | else | ||
43 | return NULL; | ||
44 | } | ||
45 | |||
46 | |||
47 | int luaV_tostring (lua_State *L, StkId obj) { | ||
48 | if (!ttisnumber(obj)) | ||
49 | return 0; | ||
50 | else { | ||
51 | char s[LUAI_MAXNUMBER2STR]; | ||
52 | lua_Number n = nvalue(obj); | ||
53 | lua_number2str(s, n); | ||
54 | setsvalue2s(L, obj, luaS_new(L, s)); | ||
55 | return 1; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | |||
60 | static void traceexec (lua_State *L, const Instruction *pc) { | ||
61 | lu_byte mask = L->hookmask; | ||
62 | const Instruction *oldpc = L->savedpc; | ||
63 | L->savedpc = pc; | ||
64 | if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { | ||
65 | resethookcount(L); | ||
66 | luaD_callhook(L, LUA_HOOKCOUNT, -1); | ||
67 | } | ||
68 | if (mask & LUA_MASKLINE) { | ||
69 | Proto *p = ci_func(L->ci)->l.p; | ||
70 | int npc = pcRel(pc, p); | ||
71 | int newline = getline(p, npc); | ||
72 | /* call linehook when enter a new function, when jump back (loop), | ||
73 | or when enter a new line */ | ||
74 | if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) | ||
75 | luaD_callhook(L, LUA_HOOKLINE, newline); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | |||
80 | static void callTMres (lua_State *L, StkId res, const TValue *f, | ||
81 | const TValue *p1, const TValue *p2) { | ||
82 | ptrdiff_t result = savestack(L, res); | ||
83 | setobj2s(L, L->top, f); /* push function */ | ||
84 | setobj2s(L, L->top+1, p1); /* 1st argument */ | ||
85 | setobj2s(L, L->top+2, p2); /* 2nd argument */ | ||
86 | luaD_checkstack(L, 3); | ||
87 | L->top += 3; | ||
88 | luaD_call(L, L->top - 3, 1); | ||
89 | res = restorestack(L, result); | ||
90 | L->top--; | ||
91 | setobjs2s(L, res, L->top); | ||
92 | } | ||
93 | |||
94 | |||
95 | |||
96 | static void callTM (lua_State *L, const TValue *f, const TValue *p1, | ||
97 | const TValue *p2, const TValue *p3) { | ||
98 | setobj2s(L, L->top, f); /* push function */ | ||
99 | setobj2s(L, L->top+1, p1); /* 1st argument */ | ||
100 | setobj2s(L, L->top+2, p2); /* 2nd argument */ | ||
101 | setobj2s(L, L->top+3, p3); /* 3th argument */ | ||
102 | luaD_checkstack(L, 4); | ||
103 | L->top += 4; | ||
104 | luaD_call(L, L->top - 4, 0); | ||
105 | } | ||
106 | |||
107 | |||
108 | void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { | ||
109 | int loop; | ||
110 | for (loop = 0; loop < MAXTAGLOOP; loop++) { | ||
111 | const TValue *tm; | ||
112 | if (ttistable(t)) { /* `t' is a table? */ | ||
113 | Table *h = hvalue(t); | ||
114 | const TValue *res = luaH_get(h, key); /* do a primitive get */ | ||
115 | if (!ttisnil(res) || /* result is no nil? */ | ||
116 | (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ | ||
117 | setobj2s(L, val, res); | ||
118 | return; | ||
119 | } | ||
120 | /* else will try the tag method */ | ||
121 | } | ||
122 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) | ||
123 | luaG_typeerror(L, t, "index"); | ||
124 | if (ttisfunction(tm)) { | ||
125 | callTMres(L, val, tm, t, key); | ||
126 | return; | ||
127 | } | ||
128 | t = tm; /* else repeat with `tm' */ | ||
129 | } | ||
130 | luaG_runerror(L, "loop in gettable"); | ||
131 | } | ||
132 | |||
133 | |||
134 | void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { | ||
135 | int loop; | ||
136 | TValue temp; | ||
137 | for (loop = 0; loop < MAXTAGLOOP; loop++) { | ||
138 | const TValue *tm; | ||
139 | if (ttistable(t)) { /* `t' is a table? */ | ||
140 | Table *h = hvalue(t); | ||
141 | TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ | ||
142 | if (!ttisnil(oldval) || /* result is no nil? */ | ||
143 | (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ | ||
144 | setobj2t(L, oldval, val); | ||
145 | luaC_barriert(L, h, val); | ||
146 | return; | ||
147 | } | ||
148 | /* else will try the tag method */ | ||
149 | } | ||
150 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) | ||
151 | luaG_typeerror(L, t, "index"); | ||
152 | if (ttisfunction(tm)) { | ||
153 | callTM(L, tm, t, key, val); | ||
154 | return; | ||
155 | } | ||
156 | /* else repeat with `tm' */ | ||
157 | setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ | ||
158 | t = &temp; | ||
159 | } | ||
160 | luaG_runerror(L, "loop in settable"); | ||
161 | } | ||
162 | |||
163 | |||
164 | static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, | ||
165 | StkId res, TMS event) { | ||
166 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ | ||
167 | if (ttisnil(tm)) | ||
168 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | ||
169 | if (ttisnil(tm)) return 0; | ||
170 | callTMres(L, res, tm, p1, p2); | ||
171 | return 1; | ||
172 | } | ||
173 | |||
174 | |||
175 | static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, | ||
176 | TMS event) { | ||
177 | const TValue *tm1 = fasttm(L, mt1, event); | ||
178 | const TValue *tm2; | ||
179 | if (tm1 == NULL) return NULL; /* no metamethod */ | ||
180 | if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ | ||
181 | tm2 = fasttm(L, mt2, event); | ||
182 | if (tm2 == NULL) return NULL; /* no metamethod */ | ||
183 | if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ | ||
184 | return tm1; | ||
185 | return NULL; | ||
186 | } | ||
187 | |||
188 | |||
189 | static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, | ||
190 | TMS event) { | ||
191 | const TValue *tm1 = luaT_gettmbyobj(L, p1, event); | ||
192 | const TValue *tm2; | ||
193 | if (ttisnil(tm1)) return -1; /* no metamethod? */ | ||
194 | tm2 = luaT_gettmbyobj(L, p2, event); | ||
195 | if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ | ||
196 | return -1; | ||
197 | callTMres(L, L->top, tm1, p1, p2); | ||
198 | return !l_isfalse(L->top); | ||
199 | } | ||
200 | |||
201 | |||
202 | static int l_strcmp (const TString *ls, const TString *rs) { | ||
203 | const char *l = getstr(ls); | ||
204 | size_t ll = ls->tsv.len; | ||
205 | const char *r = getstr(rs); | ||
206 | size_t lr = rs->tsv.len; | ||
207 | for (;;) { | ||
208 | int temp = strcoll(l, r); | ||
209 | if (temp != 0) return temp; | ||
210 | else { /* strings are equal up to a `\0' */ | ||
211 | size_t len = strlen(l); /* index of first `\0' in both strings */ | ||
212 | if (len == lr) /* r is finished? */ | ||
213 | return (len == ll) ? 0 : 1; | ||
214 | else if (len == ll) /* l is finished? */ | ||
215 | return -1; /* l is smaller than r (because r is not finished) */ | ||
216 | /* both strings longer than `len'; go on comparing (after the `\0') */ | ||
217 | len++; | ||
218 | l += len; ll -= len; r += len; lr -= len; | ||
219 | } | ||
220 | } | ||
221 | } | ||
222 | |||
223 | |||
224 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { | ||
225 | int res; | ||
226 | if (ttype(l) != ttype(r)) | ||
227 | return luaG_ordererror(L, l, r); | ||
228 | else if (ttisnumber(l)) | ||
229 | return luai_numlt(nvalue(l), nvalue(r)); | ||
230 | else if (ttisstring(l)) | ||
231 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; | ||
232 | else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) | ||
233 | return res; | ||
234 | return luaG_ordererror(L, l, r); | ||
235 | } | ||
236 | |||
237 | |||
238 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { | ||
239 | int res; | ||
240 | if (ttype(l) != ttype(r)) | ||
241 | return luaG_ordererror(L, l, r); | ||
242 | else if (ttisnumber(l)) | ||
243 | return luai_numle(nvalue(l), nvalue(r)); | ||
244 | else if (ttisstring(l)) | ||
245 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; | ||
246 | else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ | ||
247 | return res; | ||
248 | else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ | ||
249 | return !res; | ||
250 | return luaG_ordererror(L, l, r); | ||
251 | } | ||
252 | |||
253 | |||
254 | int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { | ||
255 | const TValue *tm; | ||
256 | lua_assert(ttype(t1) == ttype(t2)); | ||
257 | switch (ttype(t1)) { | ||
258 | case LUA_TNIL: return 1; | ||
259 | case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); | ||
260 | case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ | ||
261 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); | ||
262 | case LUA_TUSERDATA: { | ||
263 | if (uvalue(t1) == uvalue(t2)) return 1; | ||
264 | tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, | ||
265 | TM_EQ); | ||
266 | break; /* will try TM */ | ||
267 | } | ||
268 | case LUA_TTABLE: { | ||
269 | if (hvalue(t1) == hvalue(t2)) return 1; | ||
270 | tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); | ||
271 | break; /* will try TM */ | ||
272 | } | ||
273 | default: return gcvalue(t1) == gcvalue(t2); | ||
274 | } | ||
275 | if (tm == NULL) return 0; /* no TM? */ | ||
276 | callTMres(L, L->top, tm, t1, t2); /* call TM */ | ||
277 | return !l_isfalse(L->top); | ||
278 | } | ||
279 | |||
280 | |||
281 | void luaV_concat (lua_State *L, int total, int last) { | ||
282 | do { | ||
283 | StkId top = L->base + last + 1; | ||
284 | int n = 2; /* number of elements handled in this pass (at least 2) */ | ||
285 | if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { | ||
286 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) | ||
287 | luaG_concaterror(L, top-2, top-1); | ||
288 | } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ | ||
289 | (void)tostring(L, top - 2); /* result is first op (as string) */ | ||
290 | else { | ||
291 | /* at least two string values; get as many as possible */ | ||
292 | size_t tl = tsvalue(top-1)->len; | ||
293 | char *buffer; | ||
294 | int i; | ||
295 | /* collect total length */ | ||
296 | for (n = 1; n < total && tostring(L, top-n-1); n++) { | ||
297 | size_t l = tsvalue(top-n-1)->len; | ||
298 | if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); | ||
299 | tl += l; | ||
300 | } | ||
301 | buffer = luaZ_openspace(L, &G(L)->buff, tl); | ||
302 | tl = 0; | ||
303 | for (i=n; i>0; i--) { /* concat all strings */ | ||
304 | size_t l = tsvalue(top-i)->len; | ||
305 | memcpy(buffer+tl, svalue(top-i), l); | ||
306 | tl += l; | ||
307 | } | ||
308 | setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); | ||
309 | } | ||
310 | total -= n-1; /* got `n' strings to create 1 new */ | ||
311 | last -= n-1; | ||
312 | } while (total > 1); /* repeat until only 1 result left */ | ||
313 | } | ||
314 | |||
315 | |||
316 | void luaV_arith (lua_State *L, StkId ra, const TValue *rb, | ||
317 | const TValue *rc, TMS op) { | ||
318 | TValue tempb, tempc; | ||
319 | const TValue *b, *c; | ||
320 | if ((b = luaV_tonumber(rb, &tempb)) != NULL && | ||
321 | (c = luaV_tonumber(rc, &tempc)) != NULL) { | ||
322 | lua_Number nb = nvalue(b), nc = nvalue(c); | ||
323 | switch (op) { | ||
324 | case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; | ||
325 | case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; | ||
326 | case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; | ||
327 | case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break; | ||
328 | case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break; | ||
329 | case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; | ||
330 | case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; | ||
331 | default: lua_assert(0); break; | ||
332 | } | ||
333 | } | ||
334 | else if (!call_binTM(L, rb, rc, ra, op)) | ||
335 | luaG_aritherror(L, rb, rc); | ||
336 | } | ||
337 | |||
338 | |||
339 | |||
340 | /* | ||
341 | ** some macros for common tasks in `luaV_execute' | ||
342 | */ | ||
343 | |||
344 | #define runtime_check(L, c) { if (!(c)) break; } | ||
345 | |||
346 | #define RA(i) (base+GETARG_A(i)) | ||
347 | /* to be used after possible stack reallocation */ | ||
348 | #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) | ||
349 | #define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) | ||
350 | #define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ | ||
351 | ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) | ||
352 | #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ | ||
353 | ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) | ||
354 | #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) | ||
355 | |||
356 | |||
357 | #define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} | ||
358 | |||
359 | |||
360 | #define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } | ||
361 | |||
362 | |||
363 | #define arith_op(op,tm) { \ | ||
364 | TValue *rb = RKB(i); \ | ||
365 | TValue *rc = RKC(i); \ | ||
366 | if (ttisnumber(rb) && ttisnumber(rc)) { \ | ||
367 | lua_Number nb = nvalue(rb), nc = nvalue(rc); \ | ||
368 | setnvalue(ra, op(nb, nc)); \ | ||
369 | } \ | ||
370 | else \ | ||
371 | Protect(luaV_arith(L, ra, rb, rc, tm)); \ | ||
372 | } | ||
373 | |||
374 | |||
375 | |||
376 | void luaV_execute (lua_State *L, int nexeccalls) { | ||
377 | LClosure *cl; | ||
378 | StkId base; | ||
379 | TValue *k; | ||
380 | const Instruction *pc; | ||
381 | reentry: /* entry point */ | ||
382 | lua_assert(isLua(L->ci)); | ||
383 | pc = L->savedpc; | ||
384 | cl = &clvalue(L->ci->func)->l; | ||
385 | base = L->base; | ||
386 | k = cl->p->k; | ||
387 | /* main loop of interpreter */ | ||
388 | for (;;) { | ||
389 | const Instruction i = *pc++; | ||
390 | StkId ra; | ||
391 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && | ||
392 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { | ||
393 | traceexec(L, pc); | ||
394 | if (L->status == LUA_YIELD) { /* did hook yield? */ | ||
395 | L->savedpc = pc - 1; | ||
396 | return; | ||
397 | } | ||
398 | base = L->base; | ||
399 | } | ||
400 | /* warning!! several calls may realloc the stack and invalidate `ra' */ | ||
401 | ra = RA(i); | ||
402 | lua_assert(base == L->base && L->base == L->ci->base); | ||
403 | lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); | ||
404 | lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); | ||
405 | switch (GET_OPCODE(i)) { | ||
406 | case OP_MOVE: { | ||
407 | setobjs2s(L, ra, RB(i)); | ||
408 | continue; | ||
409 | } | ||
410 | case OP_LOADK: { | ||
411 | setobj2s(L, ra, KBx(i)); | ||
412 | continue; | ||
413 | } | ||
414 | case OP_LOADBOOL: { | ||
415 | setbvalue(ra, GETARG_B(i)); | ||
416 | if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ | ||
417 | continue; | ||
418 | } | ||
419 | case OP_LOADNIL: { | ||
420 | TValue *rb = RB(i); | ||
421 | do { | ||
422 | setnilvalue(rb--); | ||
423 | } while (rb >= ra); | ||
424 | continue; | ||
425 | } | ||
426 | case OP_GETUPVAL: { | ||
427 | int b = GETARG_B(i); | ||
428 | setobj2s(L, ra, cl->upvals[b]->v); | ||
429 | continue; | ||
430 | } | ||
431 | case OP_GETGLOBAL: { | ||
432 | TValue g; | ||
433 | TValue *rb = KBx(i); | ||
434 | sethvalue(L, &g, cl->env); | ||
435 | lua_assert(ttisstring(rb)); | ||
436 | Protect(luaV_gettable(L, &g, rb, ra)); | ||
437 | continue; | ||
438 | } | ||
439 | case OP_GETTABLE: { | ||
440 | Protect(luaV_gettable(L, RB(i), RKC(i), ra)); | ||
441 | continue; | ||
442 | } | ||
443 | case OP_SETGLOBAL: { | ||
444 | TValue g; | ||
445 | sethvalue(L, &g, cl->env); | ||
446 | lua_assert(ttisstring(KBx(i))); | ||
447 | Protect(luaV_settable(L, &g, KBx(i), ra)); | ||
448 | continue; | ||
449 | } | ||
450 | case OP_SETUPVAL: { | ||
451 | UpVal *uv = cl->upvals[GETARG_B(i)]; | ||
452 | setobj(L, uv->v, ra); | ||
453 | luaC_barrier(L, uv, ra); | ||
454 | continue; | ||
455 | } | ||
456 | case OP_SETTABLE: { | ||
457 | Protect(luaV_settable(L, ra, RKB(i), RKC(i))); | ||
458 | continue; | ||
459 | } | ||
460 | case OP_NEWTABLE: { | ||
461 | int b = GETARG_B(i); | ||
462 | int c = GETARG_C(i); | ||
463 | sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); | ||
464 | Protect(luaC_checkGC(L)); | ||
465 | continue; | ||
466 | } | ||
467 | case OP_SELF: { | ||
468 | StkId rb = RB(i); | ||
469 | setobjs2s(L, ra+1, rb); | ||
470 | Protect(luaV_gettable(L, rb, RKC(i), ra)); | ||
471 | continue; | ||
472 | } | ||
473 | case OP_ADD: { | ||
474 | arith_op(luai_numadd, TM_ADD); | ||
475 | continue; | ||
476 | } | ||
477 | case OP_SUB: { | ||
478 | arith_op(luai_numsub, TM_SUB); | ||
479 | continue; | ||
480 | } | ||
481 | case OP_MUL: { | ||
482 | arith_op(luai_nummul, TM_MUL); | ||
483 | continue; | ||
484 | } | ||
485 | case OP_DIV: { | ||
486 | arith_op(luai_numdiv, TM_DIV); | ||
487 | continue; | ||
488 | } | ||
489 | case OP_MOD: { | ||
490 | arith_op(luai_nummod, TM_MOD); | ||
491 | continue; | ||
492 | } | ||
493 | case OP_POW: { | ||
494 | arith_op(luai_numpow, TM_POW); | ||
495 | continue; | ||
496 | } | ||
497 | case OP_UNM: { | ||
498 | TValue *rb = RB(i); | ||
499 | if (ttisnumber(rb)) { | ||
500 | lua_Number nb = nvalue(rb); | ||
501 | setnvalue(ra, luai_numunm(nb)); | ||
502 | } | ||
503 | else { | ||
504 | Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); | ||
505 | } | ||
506 | continue; | ||
507 | } | ||
508 | case OP_NOT: { | ||
509 | int res = l_isfalse(RB(i)); /* next assignment may change this value */ | ||
510 | setbvalue(ra, res); | ||
511 | continue; | ||
512 | } | ||
513 | case OP_LEN: { | ||
514 | const TValue *rb = RB(i); | ||
515 | switch (ttype(rb)) { | ||
516 | case LUA_TTABLE: { | ||
517 | setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); | ||
518 | break; | ||
519 | } | ||
520 | case LUA_TSTRING: { | ||
521 | setnvalue(ra, cast_num(tsvalue(rb)->len)); | ||
522 | break; | ||
523 | } | ||
524 | default: { /* try metamethod */ | ||
525 | Protect( | ||
526 | if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) | ||
527 | luaG_typeerror(L, rb, "get length of"); | ||
528 | ) | ||
529 | } | ||
530 | } | ||
531 | continue; | ||
532 | } | ||
533 | case OP_CONCAT: { | ||
534 | int b = GETARG_B(i); | ||
535 | int c = GETARG_C(i); | ||
536 | Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L)); | ||
537 | setobjs2s(L, RA(i), base+b); | ||
538 | continue; | ||
539 | } | ||
540 | case OP_JMP: { | ||
541 | dojump(L, pc, GETARG_sBx(i)); | ||
542 | continue; | ||
543 | } | ||
544 | case OP_EQ: { | ||
545 | TValue *rb = RKB(i); | ||
546 | TValue *rc = RKC(i); | ||
547 | Protect( | ||
548 | if (equalobj(L, rb, rc) == GETARG_A(i)) | ||
549 | dojump(L, pc, GETARG_sBx(*pc)); | ||
550 | ) | ||
551 | pc++; | ||
552 | continue; | ||
553 | } | ||
554 | case OP_LT: { | ||
555 | Protect( | ||
556 | if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) | ||
557 | dojump(L, pc, GETARG_sBx(*pc)); | ||
558 | ) | ||
559 | pc++; | ||
560 | continue; | ||
561 | } | ||
562 | case OP_LE: { | ||
563 | Protect( | ||
564 | if (luaV_lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) | ||
565 | dojump(L, pc, GETARG_sBx(*pc)); | ||
566 | ) | ||
567 | pc++; | ||
568 | continue; | ||
569 | } | ||
570 | case OP_TEST: { | ||
571 | if (l_isfalse(ra) != GETARG_C(i)) | ||
572 | dojump(L, pc, GETARG_sBx(*pc)); | ||
573 | pc++; | ||
574 | continue; | ||
575 | } | ||
576 | case OP_TESTSET: { | ||
577 | TValue *rb = RB(i); | ||
578 | if (l_isfalse(rb) != GETARG_C(i)) { | ||
579 | setobjs2s(L, ra, rb); | ||
580 | dojump(L, pc, GETARG_sBx(*pc)); | ||
581 | } | ||
582 | pc++; | ||
583 | continue; | ||
584 | } | ||
585 | case OP_CALL: { | ||
586 | int b = GETARG_B(i); | ||
587 | int nresults = GETARG_C(i) - 1; | ||
588 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | ||
589 | L->savedpc = pc; | ||
590 | switch (luaD_precall(L, ra, nresults)) { | ||
591 | case PCRLUA: { | ||
592 | nexeccalls++; | ||
593 | goto reentry; /* restart luaV_execute over new Lua function */ | ||
594 | } | ||
595 | case PCRC: { | ||
596 | /* it was a C function (`precall' called it); adjust results */ | ||
597 | if (nresults >= 0) L->top = L->ci->top; | ||
598 | base = L->base; | ||
599 | continue; | ||
600 | } | ||
601 | default: { | ||
602 | return; /* yield */ | ||
603 | } | ||
604 | } | ||
605 | } | ||
606 | case OP_TAILCALL: { | ||
607 | int b = GETARG_B(i); | ||
608 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | ||
609 | L->savedpc = pc; | ||
610 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); | ||
611 | switch (luaD_precall(L, ra, LUA_MULTRET)) { | ||
612 | case PCRLUA: { | ||
613 | /* tail call: put new frame in place of previous one */ | ||
614 | CallInfo *ci = L->ci - 1; /* previous frame */ | ||
615 | int aux; | ||
616 | StkId func = ci->func; | ||
617 | StkId pfunc = (ci+1)->func; /* previous function index */ | ||
618 | if (L->openupval) luaF_close(L, ci->base); | ||
619 | L->base = ci->base = ci->func + ((ci+1)->base - pfunc); | ||
620 | for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ | ||
621 | setobjs2s(L, func+aux, pfunc+aux); | ||
622 | ci->top = L->top = func+aux; /* correct top */ | ||
623 | lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); | ||
624 | ci->savedpc = L->savedpc; | ||
625 | ci->tailcalls++; /* one more call lost */ | ||
626 | L->ci--; /* remove new frame */ | ||
627 | goto reentry; | ||
628 | } | ||
629 | case PCRC: { /* it was a C function (`precall' called it) */ | ||
630 | base = L->base; | ||
631 | continue; | ||
632 | } | ||
633 | default: { | ||
634 | return; /* yield */ | ||
635 | } | ||
636 | } | ||
637 | } | ||
638 | case OP_RETURN: { | ||
639 | int b = GETARG_B(i); | ||
640 | if (b != 0) L->top = ra+b-1; | ||
641 | if (L->openupval) luaF_close(L, base); | ||
642 | L->savedpc = pc; | ||
643 | b = luaD_poscall(L, ra); | ||
644 | if (--nexeccalls == 0) /* was previous function running `here'? */ | ||
645 | return; /* no: return */ | ||
646 | else { /* yes: continue its execution */ | ||
647 | if (b) L->top = L->ci->top; | ||
648 | lua_assert(isLua(L->ci)); | ||
649 | lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); | ||
650 | goto reentry; | ||
651 | } | ||
652 | } | ||
653 | case OP_FORLOOP: { | ||
654 | lua_Number step = nvalue(ra+2); | ||
655 | lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ | ||
656 | lua_Number limit = nvalue(ra+1); | ||
657 | if (luai_numlt(0, step) ? luai_numle(idx, limit) | ||
658 | : luai_numle(limit, idx)) { | ||
659 | dojump(L, pc, GETARG_sBx(i)); /* jump back */ | ||
660 | setnvalue(ra, idx); /* update internal index... */ | ||
661 | setnvalue(ra+3, idx); /* ...and external index */ | ||
662 | } | ||
663 | continue; | ||
664 | } | ||
665 | case OP_FORPREP: { | ||
666 | const TValue *init = ra; | ||
667 | const TValue *plimit = ra+1; | ||
668 | const TValue *pstep = ra+2; | ||
669 | L->savedpc = pc; /* next steps may throw errors */ | ||
670 | if (!tonumber(init, ra)) | ||
671 | luaG_runerror(L, LUA_QL("for") " initial value must be a number"); | ||
672 | else if (!tonumber(plimit, ra+1)) | ||
673 | luaG_runerror(L, LUA_QL("for") " limit must be a number"); | ||
674 | else if (!tonumber(pstep, ra+2)) | ||
675 | luaG_runerror(L, LUA_QL("for") " step must be a number"); | ||
676 | setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); | ||
677 | dojump(L, pc, GETARG_sBx(i)); | ||
678 | continue; | ||
679 | } | ||
680 | case OP_TFORLOOP: { | ||
681 | StkId cb = ra + 3; /* call base */ | ||
682 | setobjs2s(L, cb+2, ra+2); | ||
683 | setobjs2s(L, cb+1, ra+1); | ||
684 | setobjs2s(L, cb, ra); | ||
685 | L->top = cb+3; /* func. + 2 args (state and index) */ | ||
686 | Protect(luaD_call(L, cb, GETARG_C(i))); | ||
687 | L->top = L->ci->top; | ||
688 | cb = RA(i) + 3; /* previous call may change the stack */ | ||
689 | if (!ttisnil(cb)) { /* continue loop? */ | ||
690 | setobjs2s(L, cb-1, cb); /* save control variable */ | ||
691 | dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ | ||
692 | } | ||
693 | pc++; | ||
694 | continue; | ||
695 | } | ||
696 | case OP_SETLIST: { | ||
697 | int n = GETARG_B(i); | ||
698 | int c = GETARG_C(i); | ||
699 | int last; | ||
700 | Table *h; | ||
701 | if (n == 0) { | ||
702 | n = cast_int(L->top - ra) - 1; | ||
703 | L->top = L->ci->top; | ||
704 | } | ||
705 | if (c == 0) c = cast_int(*pc++); | ||
706 | runtime_check(L, ttistable(ra)); | ||
707 | h = hvalue(ra); | ||
708 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; | ||
709 | if (last > h->sizearray) /* needs more space? */ | ||
710 | luaH_resizearray(L, h, last); /* pre-alloc it at once */ | ||
711 | for (; n > 0; n--) { | ||
712 | TValue *val = ra+n; | ||
713 | setobj2t(L, luaH_setnum(L, h, last--), val); | ||
714 | luaC_barriert(L, h, val); | ||
715 | } | ||
716 | continue; | ||
717 | } | ||
718 | case OP_CLOSE: { | ||
719 | luaF_close(L, ra); | ||
720 | continue; | ||
721 | } | ||
722 | case OP_CLOSURE: { | ||
723 | Proto *p; | ||
724 | Closure *ncl; | ||
725 | int nup, j; | ||
726 | p = cl->p->p[GETARG_Bx(i)]; | ||
727 | nup = p->nups; | ||
728 | ncl = luaF_newLclosure(L, nup, cl->env); | ||
729 | ncl->l.p = p; | ||
730 | for (j=0; j<nup; j++, pc++) { | ||
731 | if (GET_OPCODE(*pc) == OP_GETUPVAL) | ||
732 | ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)]; | ||
733 | else { | ||
734 | lua_assert(GET_OPCODE(*pc) == OP_MOVE); | ||
735 | ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); | ||
736 | } | ||
737 | } | ||
738 | setclvalue(L, ra, ncl); | ||
739 | Protect(luaC_checkGC(L)); | ||
740 | continue; | ||
741 | } | ||
742 | case OP_VARARG: { | ||
743 | int b = GETARG_B(i) - 1; | ||
744 | int j; | ||
745 | CallInfo *ci = L->ci; | ||
746 | int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; | ||
747 | if (b == LUA_MULTRET) { | ||
748 | Protect(luaD_checkstack(L, n)); | ||
749 | ra = RA(i); /* previous call may change the stack */ | ||
750 | b = n; | ||
751 | L->top = ra + n; | ||
752 | } | ||
753 | for (j = 0; j < b; j++) { | ||
754 | if (j < n) { | ||
755 | setobjs2s(L, ra + j, ci->base - n + j); | ||
756 | } | ||
757 | else { | ||
758 | setnilvalue(ra + j); | ||
759 | } | ||
760 | } | ||
761 | continue; | ||
762 | } | ||
763 | } | ||
764 | } | ||
765 | } | ||
766 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lvm.h b/libraries/LuaJIT-1.1.7/src/lvm.h new file mode 100644 index 0000000..506a294 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lvm.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | ** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Lua virtual machine | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef lvm_h | ||
8 | #define lvm_h | ||
9 | |||
10 | |||
11 | #include "ldo.h" | ||
12 | #include "lobject.h" | ||
13 | #include "ltm.h" | ||
14 | |||
15 | |||
16 | #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) | ||
17 | |||
18 | #define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ | ||
19 | (((o) = luaV_tonumber(o,n)) != NULL)) | ||
20 | |||
21 | #define equalobj(L,o1,o2) \ | ||
22 | (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) | ||
23 | |||
24 | |||
25 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); | ||
26 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); | ||
27 | LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); | ||
28 | LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); | ||
29 | LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); | ||
30 | LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, | ||
31 | StkId val); | ||
32 | LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, | ||
33 | StkId val); | ||
34 | LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb, | ||
35 | const TValue *rc, TMS op); | ||
36 | |||
37 | LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); | ||
38 | LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); | ||
39 | |||
40 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/lzio.c b/libraries/LuaJIT-1.1.7/src/lzio.c new file mode 100644 index 0000000..293edd5 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lzio.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | ** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** a generic input stream interface | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <string.h> | ||
9 | |||
10 | #define lzio_c | ||
11 | #define LUA_CORE | ||
12 | |||
13 | #include "lua.h" | ||
14 | |||
15 | #include "llimits.h" | ||
16 | #include "lmem.h" | ||
17 | #include "lstate.h" | ||
18 | #include "lzio.h" | ||
19 | |||
20 | |||
21 | int luaZ_fill (ZIO *z) { | ||
22 | size_t size; | ||
23 | lua_State *L = z->L; | ||
24 | const char *buff; | ||
25 | lua_unlock(L); | ||
26 | buff = z->reader(L, z->data, &size); | ||
27 | lua_lock(L); | ||
28 | if (buff == NULL || size == 0) return EOZ; | ||
29 | z->n = size - 1; | ||
30 | z->p = buff; | ||
31 | return char2int(*(z->p++)); | ||
32 | } | ||
33 | |||
34 | |||
35 | int luaZ_lookahead (ZIO *z) { | ||
36 | if (z->n == 0) { | ||
37 | if (luaZ_fill(z) == EOZ) | ||
38 | return EOZ; | ||
39 | else { | ||
40 | z->n++; /* luaZ_fill removed first byte; put back it */ | ||
41 | z->p--; | ||
42 | } | ||
43 | } | ||
44 | return char2int(*z->p); | ||
45 | } | ||
46 | |||
47 | |||
48 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { | ||
49 | z->L = L; | ||
50 | z->reader = reader; | ||
51 | z->data = data; | ||
52 | z->n = 0; | ||
53 | z->p = NULL; | ||
54 | } | ||
55 | |||
56 | |||
57 | /* --------------------------------------------------------------- read --- */ | ||
58 | size_t luaZ_read (ZIO *z, void *b, size_t n) { | ||
59 | while (n) { | ||
60 | size_t m; | ||
61 | if (luaZ_lookahead(z) == EOZ) | ||
62 | return n; /* return number of missing bytes */ | ||
63 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ | ||
64 | memcpy(b, z->p, m); | ||
65 | z->n -= m; | ||
66 | z->p += m; | ||
67 | b = (char *)b + m; | ||
68 | n -= m; | ||
69 | } | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | /* ------------------------------------------------------------------------ */ | ||
74 | char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { | ||
75 | if (n > buff->buffsize) { | ||
76 | if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; | ||
77 | luaZ_resizebuffer(L, buff, n); | ||
78 | } | ||
79 | return buff->buffer; | ||
80 | } | ||
81 | |||
82 | |||
diff --git a/libraries/LuaJIT-1.1.7/src/lzio.h b/libraries/LuaJIT-1.1.7/src/lzio.h new file mode 100644 index 0000000..51d695d --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/lzio.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | ** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $ | ||
3 | ** Buffered streams | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #ifndef lzio_h | ||
9 | #define lzio_h | ||
10 | |||
11 | #include "lua.h" | ||
12 | |||
13 | #include "lmem.h" | ||
14 | |||
15 | |||
16 | #define EOZ (-1) /* end of stream */ | ||
17 | |||
18 | typedef struct Zio ZIO; | ||
19 | |||
20 | #define char2int(c) cast(int, cast(unsigned char, (c))) | ||
21 | |||
22 | #define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) | ||
23 | |||
24 | typedef struct Mbuffer { | ||
25 | char *buffer; | ||
26 | size_t n; | ||
27 | size_t buffsize; | ||
28 | } Mbuffer; | ||
29 | |||
30 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) | ||
31 | |||
32 | #define luaZ_buffer(buff) ((buff)->buffer) | ||
33 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) | ||
34 | #define luaZ_bufflen(buff) ((buff)->n) | ||
35 | |||
36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) | ||
37 | |||
38 | |||
39 | #define luaZ_resizebuffer(L, buff, size) \ | ||
40 | (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ | ||
41 | (buff)->buffsize = size) | ||
42 | |||
43 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) | ||
44 | |||
45 | |||
46 | LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); | ||
47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, | ||
48 | void *data); | ||
49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ | ||
50 | LUAI_FUNC int luaZ_lookahead (ZIO *z); | ||
51 | |||
52 | |||
53 | |||
54 | /* --------- Private Part ------------------ */ | ||
55 | |||
56 | struct Zio { | ||
57 | size_t n; /* bytes still unread */ | ||
58 | const char *p; /* current position in buffer */ | ||
59 | lua_Reader reader; | ||
60 | void* data; /* additional data */ | ||
61 | lua_State *L; /* Lua state (for reader) */ | ||
62 | }; | ||
63 | |||
64 | |||
65 | LUAI_FUNC int luaZ_fill (ZIO *z); | ||
66 | |||
67 | #endif | ||
diff --git a/libraries/LuaJIT-1.1.7/src/print.c b/libraries/LuaJIT-1.1.7/src/print.c new file mode 100644 index 0000000..e240cfc --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/print.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* | ||
2 | ** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $ | ||
3 | ** print bytecodes | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #include <ctype.h> | ||
8 | #include <stdio.h> | ||
9 | |||
10 | #define luac_c | ||
11 | #define LUA_CORE | ||
12 | |||
13 | #include "ldebug.h" | ||
14 | #include "lobject.h" | ||
15 | #include "lopcodes.h" | ||
16 | #include "lundump.h" | ||
17 | |||
18 | #define PrintFunction luaU_print | ||
19 | |||
20 | #define Sizeof(x) ((int)sizeof(x)) | ||
21 | #define VOID(p) ((const void*)(p)) | ||
22 | |||
23 | static void PrintString(const TString* ts) | ||
24 | { | ||
25 | const char* s=getstr(ts); | ||
26 | size_t i,n=ts->tsv.len; | ||
27 | putchar('"'); | ||
28 | for (i=0; i<n; i++) | ||
29 | { | ||
30 | int c=s[i]; | ||
31 | switch (c) | ||
32 | { | ||
33 | case '"': printf("\\\""); break; | ||
34 | case '\\': printf("\\\\"); break; | ||
35 | case '\a': printf("\\a"); break; | ||
36 | case '\b': printf("\\b"); break; | ||
37 | case '\f': printf("\\f"); break; | ||
38 | case '\n': printf("\\n"); break; | ||
39 | case '\r': printf("\\r"); break; | ||
40 | case '\t': printf("\\t"); break; | ||
41 | case '\v': printf("\\v"); break; | ||
42 | default: if (isprint((unsigned char)c)) | ||
43 | putchar(c); | ||
44 | else | ||
45 | printf("\\%03u",(unsigned char)c); | ||
46 | } | ||
47 | } | ||
48 | putchar('"'); | ||
49 | } | ||
50 | |||
51 | static void PrintConstant(const Proto* f, int i) | ||
52 | { | ||
53 | const TValue* o=&f->k[i]; | ||
54 | switch (ttype(o)) | ||
55 | { | ||
56 | case LUA_TNIL: | ||
57 | printf("nil"); | ||
58 | break; | ||
59 | case LUA_TBOOLEAN: | ||
60 | printf(bvalue(o) ? "true" : "false"); | ||
61 | break; | ||
62 | case LUA_TNUMBER: | ||
63 | printf(LUA_NUMBER_FMT,nvalue(o)); | ||
64 | break; | ||
65 | case LUA_TSTRING: | ||
66 | PrintString(rawtsvalue(o)); | ||
67 | break; | ||
68 | default: /* cannot happen */ | ||
69 | printf("? type=%d",ttype(o)); | ||
70 | break; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | static void PrintCode(const Proto* f) | ||
75 | { | ||
76 | const Instruction* code=f->code; | ||
77 | int pc,n=f->sizecode; | ||
78 | for (pc=0; pc<n; pc++) | ||
79 | { | ||
80 | Instruction i=code[pc]; | ||
81 | OpCode o=GET_OPCODE(i); | ||
82 | int a=GETARG_A(i); | ||
83 | int b=GETARG_B(i); | ||
84 | int c=GETARG_C(i); | ||
85 | int bx=GETARG_Bx(i); | ||
86 | int sbx=GETARG_sBx(i); | ||
87 | int line=getline(f,pc); | ||
88 | printf("\t%d\t",pc+1); | ||
89 | if (line>0) printf("[%d]\t",line); else printf("[-]\t"); | ||
90 | printf("%-9s\t",luaP_opnames[o]); | ||
91 | switch (getOpMode(o)) | ||
92 | { | ||
93 | case iABC: | ||
94 | printf("%d",a); | ||
95 | if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); | ||
96 | if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); | ||
97 | break; | ||
98 | case iABx: | ||
99 | if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); | ||
100 | break; | ||
101 | case iAsBx: | ||
102 | if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); | ||
103 | break; | ||
104 | } | ||
105 | switch (o) | ||
106 | { | ||
107 | case OP_LOADK: | ||
108 | printf("\t; "); PrintConstant(f,bx); | ||
109 | break; | ||
110 | case OP_GETUPVAL: | ||
111 | case OP_SETUPVAL: | ||
112 | printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-"); | ||
113 | break; | ||
114 | case OP_GETGLOBAL: | ||
115 | case OP_SETGLOBAL: | ||
116 | printf("\t; %s",svalue(&f->k[bx])); | ||
117 | break; | ||
118 | case OP_GETTABLE: | ||
119 | case OP_SELF: | ||
120 | if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } | ||
121 | break; | ||
122 | case OP_SETTABLE: | ||
123 | case OP_ADD: | ||
124 | case OP_SUB: | ||
125 | case OP_MUL: | ||
126 | case OP_DIV: | ||
127 | case OP_POW: | ||
128 | case OP_EQ: | ||
129 | case OP_LT: | ||
130 | case OP_LE: | ||
131 | if (ISK(b) || ISK(c)) | ||
132 | { | ||
133 | printf("\t; "); | ||
134 | if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); | ||
135 | printf(" "); | ||
136 | if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); | ||
137 | } | ||
138 | break; | ||
139 | case OP_JMP: | ||
140 | case OP_FORLOOP: | ||
141 | case OP_FORPREP: | ||
142 | printf("\t; to %d",sbx+pc+2); | ||
143 | break; | ||
144 | case OP_CLOSURE: | ||
145 | printf("\t; %p",VOID(f->p[bx])); | ||
146 | break; | ||
147 | case OP_SETLIST: | ||
148 | if (c==0) printf("\t; %d",(int)code[++pc]); | ||
149 | else printf("\t; %d",c); | ||
150 | break; | ||
151 | default: | ||
152 | break; | ||
153 | } | ||
154 | printf("\n"); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | #define SS(x) (x==1)?"":"s" | ||
159 | #define S(x) x,SS(x) | ||
160 | |||
161 | static void PrintHeader(const Proto* f) | ||
162 | { | ||
163 | const char* s=getstr(f->source); | ||
164 | if (*s=='@' || *s=='=') | ||
165 | s++; | ||
166 | else if (*s==LUA_SIGNATURE[0]) | ||
167 | s="(bstring)"; | ||
168 | else | ||
169 | s="(string)"; | ||
170 | printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", | ||
171 | (f->linedefined==0)?"main":"function",s, | ||
172 | f->linedefined,f->lastlinedefined, | ||
173 | S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); | ||
174 | printf("%d%s param%s, %d slot%s, %d upvalue%s, ", | ||
175 | f->numparams,f->is_vararg?"+":"",SS(f->numparams), | ||
176 | S(f->maxstacksize),S(f->nups)); | ||
177 | printf("%d local%s, %d constant%s, %d function%s\n", | ||
178 | S(f->sizelocvars),S(f->sizek),S(f->sizep)); | ||
179 | } | ||
180 | |||
181 | static void PrintConstants(const Proto* f) | ||
182 | { | ||
183 | int i,n=f->sizek; | ||
184 | printf("constants (%d) for %p:\n",n,VOID(f)); | ||
185 | for (i=0; i<n; i++) | ||
186 | { | ||
187 | printf("\t%d\t",i+1); | ||
188 | PrintConstant(f,i); | ||
189 | printf("\n"); | ||
190 | } | ||
191 | } | ||
192 | |||
193 | static void PrintLocals(const Proto* f) | ||
194 | { | ||
195 | int i,n=f->sizelocvars; | ||
196 | printf("locals (%d) for %p:\n",n,VOID(f)); | ||
197 | for (i=0; i<n; i++) | ||
198 | { | ||
199 | printf("\t%d\t%s\t%d\t%d\n", | ||
200 | i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | static void PrintUpvalues(const Proto* f) | ||
205 | { | ||
206 | int i,n=f->sizeupvalues; | ||
207 | printf("upvalues (%d) for %p:\n",n,VOID(f)); | ||
208 | if (f->upvalues==NULL) return; | ||
209 | for (i=0; i<n; i++) | ||
210 | { | ||
211 | printf("\t%d\t%s\n",i,getstr(f->upvalues[i])); | ||
212 | } | ||
213 | } | ||
214 | |||
215 | void PrintFunction(const Proto* f, int full) | ||
216 | { | ||
217 | int i,n=f->sizep; | ||
218 | PrintHeader(f); | ||
219 | PrintCode(f); | ||
220 | if (full) | ||
221 | { | ||
222 | PrintConstants(f); | ||
223 | PrintLocals(f); | ||
224 | PrintUpvalues(f); | ||
225 | } | ||
226 | for (i=0; i<n; i++) PrintFunction(f->p[i],full); | ||
227 | } | ||