aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2009-12-08 19:49:20 +0100
committerMike Pall <mike>2009-12-08 19:49:20 +0100
commit1d1fed48a002dfc0919135911057ebc255a53e0a (patch)
treec5c6643908374bb8f02f4c7691332d32f6645986
parent55b16959717084884fd4a0cbae6d19e3786c20c7 (diff)
downloadluajit-1d1fed48a002dfc0919135911057ebc255a53e0a.tar.gz
luajit-1d1fed48a002dfc0919135911057ebc255a53e0a.tar.bz2
luajit-1d1fed48a002dfc0919135911057ebc255a53e0a.zip
RELEASE LuaJIT-2.0.0-beta2v2.0.0-beta2
-rw-r--r--COPYRIGHT56
-rw-r--r--Makefile96
-rw-r--r--README4
-rw-r--r--doc/api.html147
-rw-r--r--doc/changes.html32
-rw-r--r--doc/faq.html23
-rw-r--r--doc/install.html59
-rw-r--r--doc/running.html6
-rw-r--r--doc/status.html21
-rw-r--r--etc/luajit.182
-rw-r--r--etc/luajit.pc24
-rw-r--r--src/Makefile322
-rw-r--r--src/Makefile.dep4
-rw-r--r--src/buildvm_asm.c7
-rw-r--r--src/buildvm_fold.c7
-rw-r--r--src/buildvm_peobj.c3
-rw-r--r--src/buildvm_x86.dasc111
-rw-r--r--src/lib_aux.c96
-rw-r--r--src/lib_io.c9
-rw-r--r--src/lib_jit.c5
-rw-r--r--src/lib_math.c19
-rw-r--r--src/lib_package.c1
-rw-r--r--src/lib_string.c7
-rw-r--r--src/lib_table.c24
-rw-r--r--src/lj_api.c136
-rw-r--r--src/lj_asm.c11
-rw-r--r--src/lj_dispatch.c17
-rw-r--r--src/lj_err.c46
-rw-r--r--src/lj_errmsg.h4
-rw-r--r--src/lj_func.c2
-rw-r--r--src/lj_gc.c3
-rw-r--r--src/lj_ir.c1
-rw-r--r--src/lj_lib.h9
-rw-r--r--src/lj_obj.h3
-rw-r--r--src/lj_opt_fold.c8
-rw-r--r--src/lj_opt_loop.c2
-rw-r--r--src/lj_opt_mem.c4
-rw-r--r--src/lj_record.c70
-rw-r--r--src/lj_tab.c4
-rw-r--r--src/lj_trace.c82
-rw-r--r--src/lj_trace.h2
-rw-r--r--src/lj_vm.h6
-rw-r--r--src/lua.hpp8
-rw-r--r--src/luaconf.h15
-rw-r--r--src/luajit.c20
-rw-r--r--src/luajit.h10
46 files changed, 1238 insertions, 390 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644
index 00000000..2a2db3dc
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,56 @@
1===============================================================================
2LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
3
4Copyright (C) 2005-2009 Mike Pall. All rights reserved.
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in
14all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22THE SOFTWARE.
23
24[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
25
26===============================================================================
27[ LuaJIT includes code from Lua 5.1, which has this license statement: ]
28
29Copyright (C) 1994-2008 Lua.org, PUC-Rio.
30
31Permission is hereby granted, free of charge, to any person obtaining a copy
32of this software and associated documentation files (the "Software"), to deal
33in the Software without restriction, including without limitation the rights
34to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35copies of the Software, and to permit persons to whom the Software is
36furnished to do so, subject to the following conditions:
37
38The above copyright notice and this permission notice shall be included in
39all copies or substantial portions of the Software.
40
41THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47THE SOFTWARE.
48
49===============================================================================
50[ LuaJIT includes code from dlmalloc, which has this license statement: ]
51
52This is a version (aka dlmalloc) of malloc/free/realloc written by
53Doug Lea and released to the public domain, as explained at
54http://creativecommons.org/licenses/publicdomain
55
56===============================================================================
diff --git a/Makefile b/Makefile
index 67347041..1dd0c132 100644
--- a/Makefile
+++ b/Makefile
@@ -12,46 +12,104 @@
12# Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h 12# Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h
13############################################################################## 13##############################################################################
14 14
15BASEVER= 2.0.0 15MAJVER= 2
16VERSION= 2.0.0-beta1 16MINVER= 0
17RELVER= 0
18PREREL= -beta2
19VERSION= $(MAJVER).$(MINVER).$(RELVER)$(PREREL)
20ABIVER= 5.1
21NODOTABIVER= 51
17 22
18############################################################################## 23##############################################################################
19# 24#
20# Change the installation path as needed and modify src/luaconf.h accordingly. 25# Change the installation path as needed and modify src/luaconf.h accordingly.
21# Note: PREFIX must be an absolute path! 26# Note: PREFIX must be an absolute path!
22# 27#
23PREFIX= /usr/local 28export PREFIX= /usr/local
24############################################################################## 29##############################################################################
25 30
26INSTALL_BIN= $(PREFIX)/bin 31DPREFIX= $(DESTDIR)$(PREFIX)
27INSTALL_NAME= luajit-$(VERSION) 32INSTALL_BIN= $(DPREFIX)/bin
28INSTALL_T= $(INSTALL_BIN)/$(INSTALL_NAME) 33INSTALL_LIB= $(DPREFIX)/lib
29INSTALL_TSYM= $(INSTALL_BIN)/luajit 34INSTALL_SHARE= $(DPREFIX)/share
30INSTALL_INC= $(PREFIX)/include/luajit-$(BASEVER) 35INSTALL_INC= $(DPREFIX)/include/luajit-$(MAJVER).$(MINVER)
31INSTALL_JITLIB= $(PREFIX)/share/luajit-$(VERSION)/jit 36
32 37INSTALL_JITLIB= $(INSTALL_SHARE)/luajit-$(VERSION)/jit
38INSTALL_LMOD= $(INSTALL_SHARE)/lua/$(ABIVER)
39INSTALL_CMOD= $(INSTALL_LIB)/lua/$(ABIVER)
40INSTALL_MAN= $(INSTALL_SHARE)/man/man1
41INSTALL_PKGCONFIG= $(INSTALL_LIB)/pkgconfig
42
43INSTALL_TNAME= luajit-$(VERSION)
44INSTALL_TSYMNAME= luajit
45INSTALL_ANAME= libluajit-$(ABIVER).a
46INSTALL_SONAME= libluajit-$(ABIVER).so.$(MAJVER).$(MINVER).$(RELVER)
47INSTALL_SOSHORT= libluajit-$(ABIVER).so
48INSTALL_DYLIBNAME= libluajit-$(NODOTABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib
49INSTALL_DYLIBSHORT1= libluajit-$(NODOTABIVER).dylib
50INSTALL_DYLIBSHORT2= libluajit-$(NODOTABIVER).$(MAJVER).dylib
51INSTALL_PCNAME= luajit.pc
52
53INSTALL_STATIC= $(INSTALL_LIB)/$(INSTALL_ANAME)
54INSTALL_DYN= $(INSTALL_LIB)/$(INSTALL_SONAME)
55INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_SOSHORT)
56INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_SOSHORT)
57INSTALL_T= $(INSTALL_BIN)/$(INSTALL_TNAME)
58INSTALL_TSYM= $(INSTALL_BIN)/$(INSTALL_TSYMNAME)
59INSTALL_PC= $(INSTALL_PKGCONFIG)/$(INSTALL_PCNAME)
60
61INSTALL_DIRS= $(INSTALL_BIN) $(INSTALL_LIB) $(INSTALL_INC) $(INSTALL_MAN) \
62 $(INSTALL_PKGCONFIG) $(INSTALL_JITLIB) $(INSTALL_LMOD) $(INSTALL_CMOD)
63
64RM= rm -f
33MKDIR= mkdir -p 65MKDIR= mkdir -p
34SYMLINK= ln -f -s 66SYMLINK= ln -sf
35INSTALL_X= install -m 0755 67INSTALL_X= install -m 0755
36INSTALL_F= install -m 0644 68INSTALL_F= install -m 0644
37 69LDCONFIG= ldconfig -n
38FILES_T= luajit 70SED_PC= sed -e "s|^prefix=.*|prefix=$(PREFIX)|"
71
72FILE_T= luajit
73FILE_A= libluajit.a
74FILE_SO= libluajit.so
75FILE_MAN= luajit.1
76FILE_PC= luajit.pc
39FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h 77FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h
40FILES_JITLIB= bc.lua v.lua dump.lua dis_x86.lua dis_x64.lua vmdef.lua 78FILES_JITLIB= bc.lua v.lua dump.lua dis_x86.lua dis_x64.lua vmdef.lua
41 79
80ifeq (,$(findstring Windows,$(OS)))
81 ifeq (Darwin,$(shell uname -s))
82 INSTALL_SONAME= $(INSTALL_DYLIBNAME)
83 INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_DYLIBSHORT1)
84 INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_DYLIBSHORT2)
85 LDCONFIG= :
86 endif
87endif
88
42############################################################################## 89##############################################################################
43 90
44INSTALL_DEP= src/luajit 91INSTALL_DEP= src/luajit
45 92
46all $(INSTALL_DEP): 93default all $(INSTALL_DEP):
47 @echo "==== Building LuaJIT $(VERSION) ====" 94 @echo "==== Building LuaJIT $(VERSION) ===="
48 $(MAKE) -C src 95 $(MAKE) -C src
49 @echo "==== Successfully built LuaJIT $(VERSION) ====" 96 @echo "==== Successfully built LuaJIT $(VERSION) ===="
50 97
51install: $(INSTALL_DEP) 98install: $(INSTALL_DEP)
52 @echo "==== Installing LuaJIT $(VERSION) to $(PREFIX) ====" 99 @echo "==== Installing LuaJIT $(VERSION) to $(PREFIX) ===="
53 $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_JITLIB) 100 $(MKDIR) $(INSTALL_DIRS)
54 cd src && $(INSTALL_X) $(FILES_T) $(INSTALL_T) 101 cd src && $(INSTALL_X) $(FILE_T) $(INSTALL_T)
102 cd src && test -f $(FILE_A) && $(INSTALL_F) $(FILE_A) $(INSTALL_STATIC) || :
103 $(RM) $(INSTALL_DYN) $(INSTALL_SHORT1) $(INSTALL_SHORT2)
104 cd src && test -f $(FILE_SO) && \
105 $(INSTALL_F) $(FILE_SO) $(INSTALL_DYN) && \
106 $(LDCONFIG) $(INSTALL_LIB) && \
107 $(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT1) && \
108 $(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT2) || :
109 cd etc && $(INSTALL_F) $(FILE_MAN) $(INSTALL_MAN)
110 cd etc && $(SED_PC) $(FILE_PC) > $(FILE_PC).tmp && \
111 $(INSTALL_F) $(FILE_PC).tmp $(INSTALL_PC) && \
112 $(RM) $(FILE_PC).tmp
55 cd src && $(INSTALL_F) $(FILES_INC) $(INSTALL_INC) 113 cd src && $(INSTALL_F) $(FILES_INC) $(INSTALL_INC)
56 cd lib && $(INSTALL_F) $(FILES_JITLIB) $(INSTALL_JITLIB) 114 cd lib && $(INSTALL_F) $(FILES_JITLIB) $(INSTALL_JITLIB)
57 @echo "==== Successfully installed LuaJIT $(VERSION) to $(PREFIX) ====" 115 @echo "==== Successfully installed LuaJIT $(VERSION) to $(PREFIX) ===="
@@ -59,7 +117,7 @@ install: $(INSTALL_DEP)
59 @echo "Note: the beta releases deliberately do NOT install a symlink for luajit" 117 @echo "Note: the beta releases deliberately do NOT install a symlink for luajit"
60 @echo "You can do this now by running this command (with sudo):" 118 @echo "You can do this now by running this command (with sudo):"
61 @echo "" 119 @echo ""
62 @echo " $(SYMLINK) $(INSTALL_NAME) $(INSTALL_TSYM)" 120 @echo " $(SYMLINK) $(INSTALL_TNAME) $(INSTALL_TSYM)"
63 @echo "" 121 @echo ""
64 122
65############################################################################## 123##############################################################################
@@ -77,8 +135,6 @@ cleaner:
77distclean: 135distclean:
78 $(MAKE) -C src distclean 136 $(MAKE) -C src distclean
79 137
80SUB_TARGETS= amalg clean cleaner distclean 138.PHONY: all install amalg clean cleaner distclean
81
82.PHONY: all install $(SUB_TARGETS)
83 139
84############################################################################## 140##############################################################################
diff --git a/README b/README
index 43caf78e..98df99af 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
1README for LuaJIT 2.0.0-beta1 1README for LuaJIT 2.0.0-beta2
2----------------------------- 2-----------------------------
3 3
4LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language. 4LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
@@ -7,7 +7,7 @@ Project Homepage: http://luajit.org/
7 7
8LuaJIT is Copyright (C) 2005-2009 Mike Pall. 8LuaJIT is Copyright (C) 2005-2009 Mike Pall.
9LuaJIT is free software, released under the MIT/X license. 9LuaJIT is free software, released under the MIT/X license.
10See full Copyright Notice in src/luajit.h 10See full Copyright Notice in the COPYRIGHT file or in luajit.h.
11 11
12Documentation for LuaJIT is available in HTML format. 12Documentation for LuaJIT is available in HTML format.
13Please point your favorite browser to: 13Please point your favorite browser to:
diff --git a/doc/api.html b/doc/api.html
index 79788d95..3bb10967 100644
--- a/doc/api.html
+++ b/doc/api.html
@@ -100,12 +100,6 @@ These functions are typically used with the command line options
100Flushes the whole cache of compiled code. 100Flushes the whole cache of compiled code.
101</p> 101</p>
102 102
103<h3 id="jit_flush_tr"><tt>jit.flush(tr)</tt></h3>
104<p>
105Flushes the code for the specified root trace and all of its
106side traces from the cache.
107</p>
108
109<h3 id="jit_onoff_func"><tt>jit.on(func|true [,true|false])<br> 103<h3 id="jit_onoff_func"><tt>jit.on(func|true [,true|false])<br>
110jit.off(func|true [,true|false])<br> 104jit.off(func|true [,true|false])<br>
111jit.flush(func|true [,true|false])</tt></h3> 105jit.flush(func|true [,true|false])</tt></h3>
@@ -142,6 +136,13 @@ of a module to turn off JIT compilation for the whole module for
142debugging purposes. 136debugging purposes.
143</p> 137</p>
144 138
139<h3 id="jit_flush_tr"><tt>status = jit.flush(tr)</tt></h3>
140<p>
141Tries to flush the code for the specified trace and all of its
142side traces from the cache. Returns <tt>true</tt> on success.
143Returns <tt>false</tt> if there are still links to this trace.
144</p>
145
145<h3 id="jit_version"><tt>jit.version</tt></h3> 146<h3 id="jit_version"><tt>jit.version</tt></h3>
146<p> 147<p>
147Contains the LuaJIT version string. 148Contains the LuaJIT version string.
@@ -189,6 +190,140 @@ The debug modules <tt>-jbc</tt>, <tt>-jv</tt> and <tt>-jdump</tt> make
189extensive use of these functions. Please check out their source code, 190extensive use of these functions. Please check out their source code,
190if you want to know more. 191if you want to know more.
191</p> 192</p>
193
194<h2 id="c_api">C API extensions</h2>
195<p>
196LuaJIT adds some extensions to the Lua/C API. The LuaJIT include
197directory must be in the compiler search path (<tt>-I<i>path</i></tt>)
198to be able to include the required header for C code:
199</p>
200<pre class="code">
201#include "luajit.h"
202</pre>
203<p>
204Or for C++ code:
205</p>
206<pre class="code">
207#include "lua.hpp"
208</pre>
209
210<h2 id="luaJIT_setmode"><tt>luaJIT_setmode(L, idx, mode)</tt>
211&mdash; Control VM</h2>
212<p>
213This is a C API extension to allow control of the VM from C code. The
214full prototype of <tt>LuaJIT_setmode</tt> is:
215</p>
216<pre class="code">
217LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
218</pre>
219<p>
220The returned status is either success (<tt>1</tt>) or failure (<tt>0</tt>).
221The second argument is either <tt>0</tt> or a stack index (similar to the
222other Lua/C API functions).
223</p>
224<p>
225The third argument specifies the mode, which is 'or'ed with a flag.
226The flag can be <tt>LUAJIT_MODE_OFF</tt> to turn a feature on,
227<tt>LUAJIT_MODE_ON</tt> to turn a feature off, or
228<tt>LUAJIT_MODE_FLUSH</tt> to flush cached code.
229</p>
230<p>
231The following modes are defined:
232</p>
233
234<h3 id="mode_engine"><tt>luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|flag)</tt></h3>
235<p>
236Turn the whole JIT compiler on or off or flush the whole cache of compiled code.
237</p>
238
239<h3 id="mode_func"><tt>luaJIT_setmode(L, idx, LUAJIT_MODE_FUNC|flag)</tt><br>
240<tt>luaJIT_setmode(L, idx, LUAJIT_MODE_ALLFUNC|flag)</tt><br>
241<tt>luaJIT_setmode(L, idx, LUAJIT_MODE_ALLSUBFUNC|flag)</tt></h3>
242<p>
243This sets the mode for the function at the stack index <tt>idx</tt> or
244the parent of the calling function (<tt>idx = 0</tt>). It either
245enables JIT compilation for a function, disables it and flushes any
246already compiled code or only flushes already compiled code. This
247applies recursively to all subfunctions of the function with
248<tt>LUAJIT_MODE_ALLFUNC</tt> or only to the subfunctions with
249<tt>LUAJIT_MODE_ALLSUBFUNC</tt>.
250</p>
251
252<h3 id="mode_engine"><tt>luaJIT_setmode(L, trace,<br>
253&nbsp;&nbsp;LUAJIT_MODE_TRACE|LUAJIT_MODE_FLUSH)</tt></h3>
254<p>
255Tries to flush the code for the specified trace and all of its
256side traces from the cache.
257</p>
258
259<h3 id="mode_engine"><tt>luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|flag)</tt></h3>
260<p>
261This mode defines a wrapper function for calls to C functions. The
262first time this is called with <tt>LUAJIT_MODE_ON</tt>, the stack
263index at <tt>idx</tt> must be a <tt>lightuserdata</tt> object holding
264a pointer to the wrapper function. All <b>subsequently created C
265functions</b> are called through the wrapper functions. After the initial
266definition <tt>idx</tt> can be left at <tt>0</tt> when turning the mode
267on or off.
268</p>
269<p>
270The wrapper function can be used for debugging purposes or to catch
271and convert foreign exceptions. Recommended usage can be seen in this
272C++ code excerpt:
273</p>
274<pre class="code">
275#include &lt;exception&gt;
276#include "lua.hpp"
277
278// Catch C++ exceptions and convert them to Lua error messages.
279// Customize as needed for your own exception classes.
280static int wrap_exceptions(lua_State *L, lua_CFunction f)
281{
282 try {
283 return f(L); // Call wrapped function and return result.
284 } catch (const char *s) { // Catch and convert exceptions.
285 lua_pushstring(L, s);
286 } catch (std::exception& e) {
287 lua_pushstring(L, e.what());
288 } catch (...) {
289 lua_pushliteral(L, "caught (...)");
290 }
291 return lua_error(L); // Rethrow as a Lua error.
292}
293
294static int myregister(lua_State *L)
295{
296 ...
297 // Define wrapper function and enable it.
298 lua_pushlightuserdata(L, (void *)wrap_exceptions);
299 luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
300 lua_pop(L, 1);
301 luaL_register(L, "mymodule", myfuncs); // Pass luaL_Reg list.
302 luaJIT_setmode(L, 0, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_OFF);
303 ...
304 // Wrap some more C++ functions which might throw an exception.
305 luaJIT_setmode(L, 0, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
306 lua_pushcfunction(L, mythrowingfunc1);
307 lua_pushcclosure(L, mythrowingfunc2, 1);
308 luaJIT_setmode(L, 0, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_OFF);
309 ...
310}
311</pre>
312<p>
313Note that you can only define <b>a single global wrapper function</b>,
314so be careful when using this mechanism from multiple C++ modules.
315Also note that this mechanism is not without overhead. It should only
316be enabled for definitions of C++ functions that can actually throw
317exceptions. If you're embedding LuaJIT into an application, only
318enable it <b>after</b> running <tt>luaL_openlibs</tt>.
319</p>
320<p>
321LuaJIT already intercepts exception handling for systems using
322ELF/DWARF2 stack unwinding (e.g. Linux). This is a zero-cost mechanism
323and always enabled. You don't need to use any wrapper functions,
324except when you want to get a more specific error message than
325<tt>"C++&nbsp;exception"</tt>.
326</p>
192<br class="flush"> 327<br class="flush">
193</div> 328</div>
194<div id="foot"> 329<div id="foot">
diff --git a/doc/changes.html b/doc/changes.html
index 6c34b8be..641f1e28 100644
--- a/doc/changes.html
+++ b/doc/changes.html
@@ -43,7 +43,7 @@ div.major { max-width: 600px; padding: 1em; margin: 1em 0 1em 0; }
43<div id="main"> 43<div id="main">
44<p> 44<p>
45This is a list of changes between the released versions of LuaJIT.<br> 45This is a list of changes between the released versions of LuaJIT.<br>
46The current <span style="color: #c00000;">development version</span> is <strong>LuaJIT&nbsp;2.0.0-beta1</strong>.<br> 46The current <span style="color: #c00000;">development version</span> is <strong>LuaJIT&nbsp;2.0.0-beta2</strong>.<br>
47The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT&nbsp;1.1.5</strong>. 47The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT&nbsp;1.1.5</strong>.
48</p> 48</p>
49<p> 49<p>
@@ -53,6 +53,36 @@ to see whether newer versions are available.
53</p> 53</p>
54 54
55<div class="major" style="background: #ffd0d0;"> 55<div class="major" style="background: #ffd0d0;">
56<h2 id="LuaJIT-2.0.0-beta2">LuaJIT 2.0.0-beta2 &mdash; 2009-11-09</h2>
57<ul>
58<li>Reorganize build system. Build static+shared library on POSIX.</li>
59<li>Allow C++ exception conversion on all platforms
60using a wrapper function.</li>
61<li>Automatically catch C++ exceptions and rethrow Lua error
62(ELF/DWARF2 only).</li>
63<li>Check for the correct x87 FPU precision at strategic points.</li>
64<li>Always use wrappers for libm functions.</li>
65<li>Resurrect metamethod name strings before copying them.</li>
66<li>Mark current trace, even if compiler is idle.</li>
67<li>Ensure FILE metatable is created only once.</li>
68<li>Fix type comparisons when different integer types are involved.</li>
69<li>Fix getmetatable() recording.</li>
70<li>Fix TDUP with dead keys in template table.</li>
71<li><tt>jit.flush(tr)</tt> returns status.
72Prevent manual flush of a trace that's still linked.</li>
73<li>Improve register allocation heuristics for invariant references.</li>
74<li>Compile the push/pop variants of <tt>table.insert()</tt> and
75<tt>table.remove()</tt>.</li>
76<li>Compatibility with MSVC <tt>link&nbsp/debug</tt>.</li>
77<li>Fix <tt>lua_iscfunction()</tt>.</li>
78<li>Fix <tt>math.random()</tt> when compiled with <tt>-fpic</tt> (OSX).</li>
79<li>Fix <tt>table.maxn()</tt>.</li>
80<li>Bump <tt>MACOSX_DEPLOYMENT_TARGET</tt> to <tt>10.4</tt></li>
81<li><tt>luaL_check*()</tt> and <tt>luaL_opt*()</tt> now support
82negative arguments, too.<br>
83This matches the behavior of Lua 5.1, but not the specification.</li>
84</ul>
85
56<h2 id="LuaJIT-2.0.0-beta1">LuaJIT 2.0.0-beta1 &mdash; 2009-10-31</h2> 86<h2 id="LuaJIT-2.0.0-beta1">LuaJIT 2.0.0-beta1 &mdash; 2009-10-31</h2>
57<ul> 87<ul>
58<li>This is the first public release of LuaJIT 2.0.</li> 88<li>This is the first public release of LuaJIT 2.0.</li>
diff --git a/doc/faq.html b/doc/faq.html
index 6f62e1eb..f76308a1 100644
--- a/doc/faq.html
+++ b/doc/faq.html
@@ -72,6 +72,7 @@ Search for: <a href="http://scholar.google.com/scholar?q=JIT+Compiler"><span cla
72Search for: <a href="http://scholar.google.com/scholar?q=Dynamic+Language+Optimizations"><span class="ext">&raquo;</span>&nbsp;Dynamic Language Optimizations</a><br> 72Search for: <a href="http://scholar.google.com/scholar?q=Dynamic+Language+Optimizations"><span class="ext">&raquo;</span>&nbsp;Dynamic Language Optimizations</a><br>
73Search for: <a href="http://scholar.google.com/scholar?q=SSA+Form"><span class="ext">&raquo;</span>&nbsp;SSA Form</a><br> 73Search for: <a href="http://scholar.google.com/scholar?q=SSA+Form"><span class="ext">&raquo;</span>&nbsp;SSA Form</a><br>
74Search for: <a href="http://scholar.google.com/scholar?q=Linear+Scan+Register+Allocation"><span class="ext">&raquo;</span>&nbsp;Linear Scan Register Allocation</a><br> 74Search for: <a href="http://scholar.google.com/scholar?q=Linear+Scan+Register+Allocation"><span class="ext">&raquo;</span>&nbsp;Linear Scan Register Allocation</a><br>
75Here is a list of the <a href="http://article.gmane.org/gmane.comp.lang.lua.general/58908"><span class="ext">&raquo;</span>&nbsp;innovative features in LuaJIT</a>.<br>
75And, you know, reading the source is of course the only way to enlightenment. :-) 76And, you know, reading the source is of course the only way to enlightenment. :-)
76</dd> 77</dd>
77</dl> 78</dl>
@@ -87,6 +88,28 @@ vararg syntax</a>.</dd>
87</dl> 88</dl>
88 89
89<dl> 90<dl>
91<dt>Q: Why do I get this error: "bad FPU precision"?<br>
92<dt>Q: I get weird behavior after initializing Direct3D.<br>
93<dt>Q: Some FPU operations crash after I load a Delphi DLL.<br>
94</dt>
95<dd>
96
97DirectX/Direct3D (up to version 9) sets the x87 FPU to single-precision
98mode by default. This violates the Windows ABI and interferes with the
99operation of many programs &mdash; LuaJIT is affected, too. Please make
100sure you always use the <tt>D3DCREATE_FPU_PRESERVE</tt> flag when
101initializing Direct3D.<br>
102
103Direct3D version 10 or higher do not show this behavior anymore.
104Consider testing your application with older versions, too.<br>
105
106Similarly, the Borland/Delphi runtime modifies the FPU control word and
107enables FP exceptions. Of course this violates the Windows ABI, too.
108Please check the Delphi docs for the Set8087CW method.
109
110</dl>
111
112<dl>
90<dt>Q: Sometimes Ctrl-C fails to stop my Lua program. Why?</dt> 113<dt>Q: Sometimes Ctrl-C fails to stop my Lua program. Why?</dt>
91<dd>The interrupt signal handler sets a Lua debug hook. But this is 114<dd>The interrupt signal handler sets a Lua debug hook. But this is
92currently ignored by compiled code (this will eventually be fixed). If 115currently ignored by compiled code (this will eventually be fixed). If
diff --git a/doc/install.html b/doc/install.html
index b7211d21..3aa60f1c 100644
--- a/doc/install.html
+++ b/doc/install.html
@@ -58,17 +58,15 @@ application under x64-based systems, too.
58<h2>Configuring LuaJIT</h2> 58<h2>Configuring LuaJIT</h2>
59<p> 59<p>
60The standard configuration should work fine for most installations. 60The standard configuration should work fine for most installations.
61Usually there is no need to tweak the settings, except when you want to 61Usually there is no need to tweak the settings. The following files
62install to a non-standard path. The following three files hold all 62hold all user-configurable settings:
63user-configurable settings:
64</p> 63</p>
65<ul> 64<ul>
66<li><tt>src/luaconf.h</tt> sets some configuration variables, in 65<li><tt>src/luaconf.h</tt> sets some configuration variables.</li>
67particular the default paths for loading modules.</li> 66<li><tt>Makefile</tt> has settings for <b>installing</b> LuaJIT (POSIX
68<li><tt>Makefile</tt> has settings for installing LuaJIT (POSIX
69only).</li> 67only).</li>
70<li><tt>src/Makefile</tt> has settings for compiling LuaJIT under POSIX, 68<li><tt>src/Makefile</tt> has settings for <b>compiling</b> LuaJIT
71MinGW and Cygwin.</li> 69under POSIX, MinGW and Cygwin.</li>
72<li><tt>src/msvcbuild.bat</tt> has settings for compiling LuaJIT with 70<li><tt>src/msvcbuild.bat</tt> has settings for compiling LuaJIT with
73MSVC.</li> 71MSVC.</li>
74</ul> 72</ul>
@@ -97,9 +95,8 @@ terminal window and change to this directory. Now unpack the archive
97and change to the newly created directory: 95and change to the newly created directory:
98</p> 96</p>
99<pre class="code"> 97<pre class="code">
100tar zxf LuaJIT-2.0.0-beta1.tar.gz 98tar zxf LuaJIT-2.0.0-beta2.tar.gz
101cd LuaJIT-2.0.0-beta1 99cd LuaJIT-2.0.0-beta2</pre>
102</pre>
103<h3>Building LuaJIT</h3> 100<h3>Building LuaJIT</h3>
104<p> 101<p>
105The supplied Makefiles try to auto-detect the settings needed for your 102The supplied Makefiles try to auto-detect the settings needed for your
@@ -109,6 +106,18 @@ which is probably the default on your system, anyway. Simply run:
109<pre class="code"> 106<pre class="code">
110make 107make
111</pre> 108</pre>
109<p>
110By default modules are only searched under the prefix <tt>/usr/local</tt>.
111You can add an extra prefix to the search paths by appending the
112<tt>PREFIX</tt> option, e.g.:
113</p>
114<pre class="code">
115make PREFIX=/home/myself/lj2
116</pre>
117<p>
118Note for OSX: <tt>MACOSX_DEPLOYMENT_TARGET</tt> is set to <tt>10.4</tt>
119in <tt>src/Makefile</tt>. Change it, if you want to build on an older version.
120</p>
112<h3>Installing LuaJIT</h3> 121<h3>Installing LuaJIT</h3>
113<p> 122<p>
114The top-level Makefile installs LuaJIT by default under 123The top-level Makefile installs LuaJIT by default under
@@ -124,20 +133,19 @@ sudo make install
124Otherwise specify the directory prefix as an absolute path, e.g.: 133Otherwise specify the directory prefix as an absolute path, e.g.:
125</p> 134</p>
126<pre class="code"> 135<pre class="code">
127sudo make install PREFIX=/opt/lj2 136make install PREFIX=/home/myself/lj2
128</pre> 137</pre>
129<p> 138<p>
130But note that the installation prefix and the prefix for the module paths 139Obviously the prefixes given during build and installation need to be the same.
131(configured in <tt>src/luaconf.h</tt>) must match.
132</p> 140</p>
133<p style="color: #c00000;"> 141<p style="color: #c00000;">
134Note: to avoid overwriting a previous version, the beta test releases 142Note: to avoid overwriting a previous version, the beta test releases
135only install the LuaJIT executable under the versioned name (i.e. 143only install the LuaJIT executable under the versioned name (i.e.
136<tt>luajit-2.0.0-beta1</tt>). You probably want to create a symlink 144<tt>luajit-2.0.0-beta2</tt>). You probably want to create a symlink
137for convenience, with a command like this: 145for convenience, with a command like this:
138</p> 146</p>
139<pre class="code" style="color: #c00000;"> 147<pre class="code" style="color: #c00000;">
140sudo ln -sf luajit-2.0.0-beta1 /usr/local/bin/luajit 148sudo ln -sf luajit-2.0.0-beta2&nbsp;/usr/local/bin/luajit
141</pre> 149</pre>
142 150
143<h2 id="windows">Windows Systems</h2> 151<h2 id="windows">Windows Systems</h2>
@@ -145,8 +153,8 @@ sudo ln -sf luajit-2.0.0-beta1 /usr/local/bin/luajit
145<p> 153<p>
146Either install one of the open source SDKs 154Either install one of the open source SDKs
147(<a href="http://mingw.org/"><span class="ext">&raquo;</span>&nbsp;MinGW</a> or 155(<a href="http://mingw.org/"><span class="ext">&raquo;</span>&nbsp;MinGW</a> or
148<a href="http://www.cygwin.com/"><span class="ext">&raquo;</span>&nbsp;Cygwin</a>) which come with modified 156<a href="http://www.cygwin.com/"><span class="ext">&raquo;</span>&nbsp;Cygwin</a>), which come with a modified
149versions of GCC plus the required development headers. 157GCC plus the required development headers.
150</p> 158</p>
151<p> 159<p>
152Or install Microsoft's Visual C++ (MSVC) &mdash; the freely downloadable 160Or install Microsoft's Visual C++ (MSVC) &mdash; the freely downloadable
@@ -159,8 +167,8 @@ Next, download the source package and unpack it using an archive manager
159</p> 167</p>
160<h3>Building with MSVC</h3> 168<h3>Building with MSVC</h3>
161<p> 169<p>
162Open a "Visual Studio .NET Command Prompt" and <tt>cd</tt> to the 170Open a "Visual Studio .NET Command Prompt", <tt>cd</tt> to the
163directory where you've unpacked the sources. Then run this command: 171directory where you've unpacked the sources and run these commands:
164</p> 172</p>
165<pre class="code"> 173<pre class="code">
166cd src 174cd src
@@ -176,14 +184,12 @@ are in your path. Then <tt>cd</tt> to the directory where
176you've unpacked the sources and run this command for MinGW: 184you've unpacked the sources and run this command for MinGW:
177</p> 185</p>
178<pre class="code"> 186<pre class="code">
179cd src
180mingw32-make 187mingw32-make
181</pre> 188</pre>
182<p> 189<p>
183Or this command for Cygwin: 190Or this command for Cygwin:
184</p> 191</p>
185<pre class="code"> 192<pre class="code">
186cd src
187make 193make
188</pre> 194</pre>
189<p> 195<p>
@@ -191,10 +197,11 @@ Then follow the installation instructions below.
191</p> 197</p>
192<h3>Installing LuaJIT</h3> 198<h3>Installing LuaJIT</h3>
193<p> 199<p>
194Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt> 200Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt> (built in the <tt>src</tt>
195to a newly created directory (any location is ok). Add <tt>lua</tt> 201directory) to a newly created directory (any location is ok).
196and <tt>lua\jit</tt> directories below it and copy all Lua files 202Add <tt>lua</tt> and <tt>lua\jit</tt> directories below it and copy
197from the <tt>lib</tt> directory of the distribution to the latter directory. 203all Lua files from the <tt>lib</tt> directory of the distribution
204to the latter directory.
198</p> 205</p>
199<p> 206<p>
200There are no hardcoded 207There are no hardcoded
diff --git a/doc/running.html b/doc/running.html
index db69578c..fcb28e85 100644
--- a/doc/running.html
+++ b/doc/running.html
@@ -69,11 +69,11 @@ interactive mode, too.
69<p class="indent" style="color: #c00000;"> 69<p class="indent" style="color: #c00000;">
70Note: the beta test releases only install under the versioned name on 70Note: the beta test releases only install under the versioned name on
71POSIX systems (to avoid overwriting a previous version). You either need 71POSIX systems (to avoid overwriting a previous version). You either need
72to type <tt>luajit-2.0.0-beta1</tt> to start it or create a symlink 72to type <tt>luajit-2.0.0-beta2</tt> to start it or create a symlink
73with a command like this: 73with a command like this:
74</p> 74</p>
75<pre class="code" style="color: #c00000;"> 75<pre class="code" style="color: #c00000;">
76sudo ln -sf luajit-2.0.0-beta1 /usr/local/bin/luajit 76sudo ln -sf luajit-2.0.0-beta2&nbsp;/usr/local/bin/luajit
77</pre> 77</pre>
78<p> 78<p>
79Unlike previous versions <b>optimization is turned on by default</b> in 79Unlike previous versions <b>optimization is turned on by default</b> in
@@ -119,7 +119,7 @@ itself. For a description of their options and output format, please
119read the comment block at the start of their source. 119read the comment block at the start of their source.
120They can be found in the <tt>lib</tt> directory of the source 120They can be found in the <tt>lib</tt> directory of the source
121distribution or installed under the <tt>jit</tt> directory. By default 121distribution or installed under the <tt>jit</tt> directory. By default
122this is <tt>/usr/local/share/luajit-2.0.0-beta1/jit</tt> on POSIX 122this is <tt>/usr/local/share/luajit-2.0.0-beta2/jit</tt> on POSIX
123systems. 123systems.
124</p> 124</p>
125 125
diff --git a/doc/status.html b/doc/status.html
index 23c14c76..aa4a1e26 100644
--- a/doc/status.html
+++ b/doc/status.html
@@ -90,7 +90,22 @@ known incompatibilities with standard Lua:
90<ul> 90<ul>
91<li> 91<li>
92The Lua <b>debug API</b> is missing a couple of features (call/return 92The Lua <b>debug API</b> is missing a couple of features (call/return
93hooks) and shows slightly different behavior (no per-coroutine hooks). 93hooks) and shows slightly different behavior (no per-coroutine hooks,
94no tail call counting).
95</li>
96<li>
97<b>Bytecode</b> currently cannot be loaded or dumped. Note that
98the bytecode format differs from Lua&nbsp;5.1 &mdash; loading foreign
99bytecode is not supported at all.
100</li>
101<li>
102Some of the <b>configuration options</b> of Lua&nbsp;5.1 are not supported:
103<ul>
104<li>The <b>number type</b> cannot be changed (it's always a <tt>double</tt>).</li>
105<li>The stand-alone executable cannot be linked with <b>readline</b>
106to enable line editing. It's planned to add support for loading it
107on-demand.</li>
108</ul>
94</li> 109</li>
95<li> 110<li>
96Most other issues you're likely to find (e.g. with the existing test 111Most other issues you're likely to find (e.g. with the existing test
@@ -105,7 +120,7 @@ demonstrable need is shown.
105<li> 120<li>
106The <b>JIT compiler</b> is not complete (yet) and falls back to the 121The <b>JIT compiler</b> is not complete (yet) and falls back to the
107interpreter in some cases. All of this works transparently, so unless 122interpreter in some cases. All of this works transparently, so unless
108you use -jv, you'll probably never notice (the interpreter is quite 123you use <tt>-jv</tt>, you'll probably never notice (the interpreter is quite
109fast, too). Here are the known issues: 124fast, too). Here are the known issues:
110<ul> 125<ul>
111<li> 126<li>
@@ -119,7 +134,7 @@ effort.
119</li> 134</li>
120<li> 135<li>
121<b>Recursion</b> is not traced yet. Often no trace will be generated at 136<b>Recursion</b> is not traced yet. Often no trace will be generated at
122all or some unroll limit will catch it and aborts the trace. 137all or some unroll limit will catch it and abort the trace.
123</li> 138</li>
124<li> 139<li>
125The trace compiler currently does not back off specialization for 140The trace compiler currently does not back off specialization for
diff --git a/etc/luajit.1 b/etc/luajit.1
new file mode 100644
index 00000000..fab65803
--- /dev/null
+++ b/etc/luajit.1
@@ -0,0 +1,82 @@
1.TH luajit 1 "" "" "LuaJIT documentation"
2.SH NAME
3luajit \- Just-In-Time Compiler for the Lua Language
4\fB
5.SH SYNOPSIS
6.B luajit
7[\fIoptions\fR]... [\fIscript\fR [\fIargs\fR]...]
8.SH "WEB SITE"
9.IR http://luajit.org
10.SH DESCRIPTION
11.PP
12This is the command-line program to run Lua programs with \fBLuaJIT\fR.
13.PP
14\fBLuaJIT\fR is a just-in-time (JIT) compiler for the Lua language.
15The virtual machine (VM) is based on a fast interpreter combined with
16a trace compiler. It can significantly improve the performance of Lua programs.
17.PP
18\fBLuaJIT\fR is API\- and ABI-compatible with the VM of the standard
19Lua\ 5.1 interpreter. When embedding the VM into an application,
20the built library can be used as a drop-in replacement.
21.SH OPTIONS
22.TP
23.BI "\-e " chunk
24Run the given chunk of Lua code.
25.TP
26.BI "\-l " library
27Load the named library, just like \fBrequire("\fR\fIlibrary\fR\fB")\fR.
28.TP
29.BI "\-j " command
30Perform LuaJIT control command (optional space after \fB\-j\fR).
31.TP
32.BI "\-O" [opt]
33Control LuaJIT optimizations.
34.TP
35.B "\-i"
36Run in interactive mode.
37.TP
38.B "\-v"
39Show \fBLuaJIT\fR version.
40.TP
41.B "\-\-"
42Stop processing options.
43.TP
44.B "\-"
45Read script from stdin instead.
46.PP
47After all options are processed, the given \fIscript\fR is run.
48The arguments are passed in the global \fIarg\fR table.
49.PP
50Interactive mode is only entered, if no \fIscript\fR and no \fB\-e\fR
51option is given. Interactive mode can be left with EOF (\fICtrl\-Z\fB).
52.SH EXAMPLES
53.TP
54luajit hello.lua world
55
56Prints "Hello world", assuming \fIhello.lua\fR contains:
57.br
58 print("Hello", arg[1])
59.TP
60luajit \-e "local x=0; for i=1,1e9 do x=x+i end; print(x)"
61
62Calculates the sum of the numbers from 1 to 1000000000.
63.br
64And finishes in a reasonable amount of time, too.
65.TP
66luajit \-jv \-e "for i=1,10 do for j=1,10 do for k=1,100 do end end end"
67
68Runs some nested loops and shows the resulting traces.
69.SH COPYRIGHT
70.PP
71\fBLuaJIT\fR is Copyright \(co 2005-2009 Mike Pall.
72.br
73\fBLuaJIT\fR is open source software, released under the MIT/X license.
74.SH SEE ALSO
75.PP
76More details in the provided HTML docs or at:
77.IR http://luajit.org
78.br
79More about the Lua language can be found at:
80.IR http://lua.org/docs.html
81.PP
82lua(1)
diff --git a/etc/luajit.pc b/etc/luajit.pc
new file mode 100644
index 00000000..f0490097
--- /dev/null
+++ b/etc/luajit.pc
@@ -0,0 +1,24 @@
1# Package information for LuaJIT to be used by pkg-config.
2majver=2
3minver=0
4relver=0
5version=${majver}.${minver}.${relver}-beta2
6abiver=5.1
7
8prefix=/usr/local
9exec_prefix=${prefix}
10libdir=${exec_prefix}/lib
11libname=luajit-${abiver}
12includedir=${prefix}/include/luajit-${majver}.${minver}
13
14INSTALL_LMOD=${prefix}/share/lua/${abiver}
15INSTALL_CMOD=${prefix}/lib/lua/${abiver}
16
17Name: LuaJIT
18Description: Just-in-time compiler for Lua
19URL: http://luajit.org
20Version: ${version}
21Requires:
22Libs: -L${libdir} -l${libname}
23Libs.private: -Wl,-E -lm -ldl
24Cflags: -I${includedir}
diff --git a/src/Makefile b/src/Makefile
index bb1839d1..c0deb774 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -8,10 +8,17 @@
8# Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h 8# Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h
9############################################################################## 9##############################################################################
10 10
11MAJVER= 2
12MINVER= 0
13RELVER= 0
14ABIVER= 5.1
15NODOTABIVER= 51
16
11############################################################################## 17##############################################################################
12# Compiler options: change them as needed. This mainly affects the speed of 18# Compiler options: change them as needed. This mainly affects the speed of
13# the JIT compiler itself, not the speed of the JIT compiled code. 19# the JIT compiler itself, not the speed of the JIT compiled code.
14# Turn any of the optional settings on by removing the '#' in front of them. 20# Turn any of the optional settings on by removing the '#' in front of them.
21# You need to 'make clean' and 'make' again, if you change any options.
15# 22#
16# Note: LuaJIT can only be compiled for x86, and not for x64 (yet)! 23# Note: LuaJIT can only be compiled for x86, and not for x64 (yet)!
17# In the meantime, the x86 binary runs fine under a x64 OS. 24# In the meantime, the x86 binary runs fine under a x64 OS.
@@ -81,89 +88,142 @@ XCFLAGS=
81#XCFLAGS+= -DLUA_USE_ASSERT 88#XCFLAGS+= -DLUA_USE_ASSERT
82# 89#
83############################################################################## 90##############################################################################
91
92##############################################################################
93# Build mode: override the mode as needed. Default is mixed mode on POSIX.
94# On Windows this is the same as dynamic mode.
95#
96# Mixed mode creates a static + dynamic library and a statically linked luajit.
97BUILDMODE= mixed
98#
99# Static mode creates a static library and a statically linked luajit.
100#BUILDMODE= static
101#
102# Dynamic mode creates a dynamic library and a dynamically linked luajit.
103# Note: this executable will only run when the library is installed!
104#BUILDMODE= dynamic
105##############################################################################
84# You probably don't need to change anything below this line. 106# You probably don't need to change anything below this line.
85############################################################################## 107##############################################################################
86 108
109##############################################################################
110# Flags and options for host and target.
111##############################################################################
112
87CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(CFLAGS) $(XCFLAGS) 113CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(CFLAGS) $(XCFLAGS)
88LDOPTIONS= $(CCDEBUG) $(LDFLAGS) 114LDOPTIONS= $(CCDEBUG) $(LDFLAGS)
89 115
90HOST_CC= $(CC) 116HOST_CC= $(CC)
91HOST_RM= rm -f 117HOST_RM= rm -f
118# NOTE: The LuaJIT distribution comes with a pre-generated buildvm_*.h.
119# You DO NOT NEED an installed copy of (plain) Lua 5.1 to run DynASM unless
120# you want to MODIFY the corresponding *.dasc file. You can also use LuaJIT
121# itself (bootstrapped from the pre-generated file) to run DynASM of course.
122HOST_LUA= lua
123
92HOST_XCFLAGS= 124HOST_XCFLAGS=
93HOST_XLDFLAGS= 125HOST_XLDFLAGS=
94HOST_XLIBS= 126HOST_XLIBS=
127HOST_CFLAGS= $(CCOPTIONS) $(HOST_XCFLAGS) $(TARGET_ARCH)
128HOST_LDFLAGS= $(LDOPTIONS) $(HOST_XLDFLAGS)
129HOST_LIBS= $(HOST_XLIBS)
130
131# Cross-compilation example: make CROSS=i586-mingw32msvc- TARGET_SYS=Windows
132CROSS=
133STATIC_CC = $(CROSS)$(CC)
134DYNAMIC_CC = $(CROSS)$(CC) -fPIC
135TARGET_CC= $(STATIC_CC)
136TARGET_STCC= $(STATIC_CC)
137TARGET_DYNCC= $(DYNAMIC_CC)
138TARGET_LD= $(CROSS)$(CC)
139TARGET_AR= $(CROSS)ar rcus
140TARGET_STRIP= $(CROSS)strip
141
142TARGET_SONAME= libluajit-$(ABIVER).so.$(MAJVER)
143TARGET_DYLIBNAME= libluajit-$(NODOTABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib
144TARGET_DLLNAME= lua$(NODOTABIVER).dll
145TARGET_XSHLDFLAGS= -shared -fPIC -Wl,-soname,$(TARGET_SONAME)
146TARGET_DYNXLDOPTS=
95 147
96TARGET_CC= $(CC)
97TARGET_STRIP= strip
98TARGET_XCFLAGS= -D_FILE_OFFSET_BITS=64
99TARGET_XLDFLAGS=
100TARGET_XSHLDFLAGS= -shared
101TARGET_XLIBS=
102TARGET_ARCH= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET)) 148TARGET_ARCH= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET))
103TARGET_DISABLE= -U_FORTIFY_SOURCE 149TARGET_DISABLE= -U_FORTIFY_SOURCE
104ifneq (,$(findstring stack-protector,$(shell $(CC) -dumpspecs))) 150ifneq (,$(findstring stack-protector,$(shell $(TARGET_CC) -dumpspecs)))
105 TARGET_DISABLE+= -fno-stack-protector 151 TARGET_DISABLE+= -fno-stack-protector
106endif 152endif
107 153
154TARGET_XCFLAGS= -D_FILE_OFFSET_BITS=64
155TARGET_XLDFLAGS=
156TARGET_XLDOPTS=
157TARGET_XLIBS=
158TARGET_CFLAGS= $(CCOPTIONS) $(TARGET_DISABLE) $(TARGET_XCFLAGS)
159TARGET_LDFLAGS= $(LDOPTIONS) $(TARGET_XLDFLAGS) $(TARGET_XLDOPTS)
160TARGET_SHLDFLAGS= $(LDOPTIONS) $(TARGET_XSHLDFLAGS)
161TARGET_LIBS= -lm $(TARGET_XLIBS)
162
163ifneq (,$(PREFIX))
164ifneq (/usr/local,$(PREFIX))
165 TARGET_XCFLAGS+= -DLUA_XROOT=\"$(PREFIX)/\"
166 ifneq (/usr,$(PREFIX))
167 TARGET_DYNXLDOPTS= -Wl,-rpath,$(PREFIX)/lib
168 endif
169endif
170endif
171
172##############################################################################
173# System detection.
174##############################################################################
175
108ifneq (,$(findstring Windows,$(OS))) 176ifneq (,$(findstring Windows,$(OS)))
109 TARGET_SYS= Windows 177 HOST_SYS= Windows
110else 178else
111 TARGET_SYS:= $(shell uname -s) 179 HOST_SYS:= $(shell uname -s)
112 ifneq (,$(findstring CYGWIN,$(TARGET_SYS))) 180 ifneq (,$(findstring CYGWIN,$(TARGET_SYS)))
113 TARGET_SYS= Windows 181 HOST_SYS= Windows
114 endif 182 endif
115endif 183endif
184ifeq (Windows,$(HOST_SYS))
185 HOST_RM= del
186endif
116 187
117ifeq (Linux,$(TARGET_SYS)) 188TARGET_SYS= $(HOST_SYS)
118 TARGET_XLIBS= -ldl
119 TARGET_XLDFLAGS= -Wl,-E
120else
121ifeq (Windows,$(TARGET_SYS)) 189ifeq (Windows,$(TARGET_SYS))
122 HOST_RM= del 190 TARGET_STRIP+= --strip-unneeded
123 TARGET_STRIP= strip --strip-unneeded 191 TARGET_XSHLDFLAGS= -shared
192 TARGET_DYNXLDOPTS=
124else 193else
125ifeq (Darwin,$(TARGET_SYS)) 194ifeq (Darwin,$(TARGET_SYS))
126 TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup 195 export MACOSX_DEPLOYMENT_TARGET=10.4
127 TARGET_STRIP= strip -x 196 TARGET_STRIP+= -x
128 export MACOSX_DEPLOYMENT_TARGET=10.3 197 TARGET_AR+= 2>/dev/null
198 TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
199 ifneq (,$(TARGET_DYNXLDOPTS))
200 TARGET_DYNXLDOPTS=
201 TARGET_XSHLDFLAGS+= -install_name $(PREFIX)/lib/$(TARGET_DYLIBNAME)
202 endif
129else 203else
130 TARGET_XLDFLAGS= -Wl,-E 204 TARGET_XLDFLAGS= -Wl,-E
205 ifeq (Linux,$(TARGET_SYS))
206 TARGET_XLIBS= -ldl
207 endif
131endif 208endif
132endif 209endif
133endif
134
135# NOTE: The LuaJIT distribution comes with a pre-generated buildvm_*.h.
136# You DO NOT NEED an installed copy of (plain) Lua 5.1 to run DynASM unless
137# you want to MODIFY the corresponding *.dasc file. You can also use LuaJIT
138# itself (bootstrapped from the pre-generated file) to run DynASM of course.
139DASM_LUA= lua
140
141Q= @
142E= @echo
143#Q=
144#E= @:
145
146##############################################################################
147 210
148TARGET_CFLAGS= $(CCOPTIONS) $(TARGET_DISABLE) $(TARGET_XCFLAGS)
149TARGET_LDFLAGS= $(LDOPTIONS) $(TARGET_XLDFLAGS)
150TARGET_SHLDFLAGS= $(LDOPTIONS) $(TARGET_XSHLDFLAGS)
151TARGET_LIBS= -lm $(TARGET_XLIBS)
152ifneq (,$(CCDEBUG)) 211ifneq (,$(CCDEBUG))
153 TARGET_STRIP= @: 212 TARGET_STRIP= @:
154endif 213endif
155 214
156HOST_CFLAGS= $(CCOPTIONS) $(HOST_XCFLAGS) $(TARGET_ARCH) 215##############################################################################
157HOST_LDFLAGS= $(LDOPTIONS) $(HOST_XLDFLAGS) 216# Files and pathnames.
158HOST_LIBS= $(HOST_XLIBS) 217##############################################################################
159 218
160DASM_DIR= ../dynasm 219DASM_DIR= ../dynasm
161DASM= $(DASM_LUA) $(DASM_DIR)/dynasm.lua 220DASM= $(HOST_LUA) $(DASM_DIR)/dynasm.lua
162DASM_FLAGS= 221DASM_FLAGS=
163DASM_DISTFLAGS= -LN 222DASM_DISTFLAGS= -LN
164 223
165BUILDVM_O= buildvm.o buildvm_asm.o buildvm_peobj.o buildvm_lib.o buildvm_fold.o 224BUILDVM_O= buildvm.o buildvm_asm.o buildvm_peobj.o buildvm_lib.o buildvm_fold.o
166BUILDVM_T= buildvm 225BUILDVM_T= buildvm
226BUILDVM_X= ./$(BUILDVM_T)
167 227
168HOST_O= $(BUILDVM_O) 228HOST_O= $(BUILDVM_O)
169HOST_T= $(BUILDVM_T) 229HOST_T= $(BUILDVM_T)
@@ -188,54 +248,114 @@ LJCORE_O= lj_gc.o lj_err.o lj_ctype.o lj_bc.o lj_obj.o \
188 $(LJLIB_O) lib_init.o 248 $(LJLIB_O) lib_init.o
189 249
190LJVMCORE_O= $(LJVM_O) $(LJCORE_O) 250LJVMCORE_O= $(LJVM_O) $(LJCORE_O)
251LJVMCORE_DYNO= $(LJVMCORE_O:.o=_dyn.o)
252
253LIB_VMDEF= ../lib/vmdef.lua
254LIB_VMDEFP= $(LIB_VMDEF)
191 255
192# NYI: Need complete support for building as a shared library on POSIX.
193# This is currently *only* suitable for MinGW and Cygwin, see below.
194LUAJIT_O= luajit.o 256LUAJIT_O= luajit.o
195LUAJIT_SO= luajit.so 257LUAJIT_A= libluajit.a
258LUAJIT_SO= libluajit.so
196LUAJIT_T= luajit 259LUAJIT_T= luajit
197 260
198LIB_VMDEF= ../lib/vmdef.lua 261ALL_T= $(LUAJIT_T) $(LUAJIT_A) $(LUAJIT_SO) $(BUILDVM_T)
262ALL_GEN= $(LJVM_S) lj_ffdef.h lj_libdef.h lj_recdef.h $(LIB_VMDEFP) lj_folddef.h
263ALL_DYNGEN= buildvm_x86.h
264WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest *.pdb *.ilk
265ALL_RM= $(ALL_T) $(ALL_GEN) *.o $(WIN_RM)
199 266
200TARGET_DEP= $(LIB_VMDEF) 267##############################################################################
201TARGET_O= $(LJVMCORE_O) $(LUAJIT_O) 268# Build mode handling.
202TARGET_T= $(LUAJIT_T) 269##############################################################################
203 270
204ALL_GEN= $(LJVM_S) lj_ffdef.h lj_libdef.h lj_recdef.h $(LIB_VMDEF) lj_folddef.h 271# Mixed mode defaults.
205ALL_DYNGEN= buildvm_x86.h 272TARGET_O= $(LUAJIT_A)
206WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest 273TARGET_T= $(LUAJIT_T) $(LUAJIT_SO)
207ALL_RM= $(LUAJIT_T) $(LUAJIT_SO) $(HOST_T) $(ALL_GEN) *.o $(WIN_RM) 274TARGET_DEP= $(LIB_VMDEF) $(LUAJIT_SO)
208 275
276ifeq (Windows,$(HOST_SYS))
277 BUILDVM_T= buildvm.exe
278 LIB_VMDEFP= $(subst /,\\,$(LIB_VMDEF))
279endif
209ifeq (Windows,$(TARGET_SYS)) 280ifeq (Windows,$(TARGET_SYS))
281 DYNAMIC_CC= $(STATIC_CC)
210 LJVM_BOUT= $(LJVM_O) 282 LJVM_BOUT= $(LJVM_O)
211 LJVM_MODE= peobj 283 LJVM_MODE= peobj
212 LIB_VMDEF= ..\lib\vmdef.lua 284 LUAJIT_SO= $(TARGET_DLLNAME)
213 # Imported symbols are bound to a specific DLL name under Windows.
214 LUAJIT_SO= lua51.dll
215 LUAJIT_T= luajit.exe 285 LUAJIT_T= luajit.exe
216 BUILDVM_T= buildvm.exe 286 ifneq ($(HOST_SYS),$(TARGET_SYS))
217 # 287 HOST_XCFLAGS+= -malign-double
218 # You can comment out the following two lines to build a static executable. 288 endif
219 # But then you won't be able to dynamically load any C modules, because 289 # Mixed mode is not supported on Windows. And static mode doesn't work well.
220 # they bind to lua51.dll. 290 # C modules cannot be loaded, because they bind to lua51.dll.
221 # 291 ifneq (static,$(BUILDMODE))
222 TARGET_XCFLAGS+= -DLUA_BUILD_AS_DLL 292 BUILDMODE= dynamic
223 TARGET_O= $(LUAJIT_SO) $(LUAJIT_O) 293 TARGET_XCFLAGS+= -DLUA_BUILD_AS_DLL
294 endif
224endif 295endif
225 296
226############################################################################## 297ifeq (static,$(BUILDMODE))
298 TARGET_DYNCC= @:
299 TARGET_T= $(LUAJIT_T)
300 TARGET_DEP= $(LIB_VMDEF)
301else
302ifeq (dynamic,$(BUILDMODE))
303 TARGET_CC= $(DYNAMIC_CC)
304 TARGET_DYNCC= @:
305 LJVMCORE_DYNO= $(LJVMCORE_O)
306 TARGET_O= $(LUAJIT_SO)
307 TARGET_XLDOPTS= $(TARGET_DYNXLDOPTS)
308else
309ifeq (Darwin,$(TARGET_SYS))
310 TARGET_DYNCC= @:
311 LJVMCORE_DYNO= $(LJVMCORE_O)
312endif
313endif
314endif
227 315
228default: $(TARGET_T) 316Q= @
317E= @echo
318#Q=
319#E= @:
229 320
230all: $(TARGET_T) 321##############################################################################
322# Make targets.
323##############################################################################
324
325default all: $(TARGET_T)
231 326
232amalg: 327amalg:
233 @grep "^[+|]" ljamalg.c 328 @grep "^[+|]" ljamalg.c
234 $(MAKE) all "LJCORE_O=ljamalg.o" 329 $(MAKE) all "LJCORE_O=ljamalg.o"
235 330
236MAKE_TARGETS= amalg 331clean:
332 $(HOST_RM) $(ALL_RM)
333
334cleaner:
335 $(HOST_RM) $(ALL_RM) $(ALL_DYNGEN)
336
337distclean: clean
338 $(E) "DYNASM $@"
339 $(Q)$(DASM) $(DASM_DISTFLAGS) -o buildvm_x86.h buildvm_x86.dasc
340
341depend:
342 @test -f lj_ffdef.h || touch lj_ffdef.h
343 @test -f lj_libdef.h || touch lj_libdef.h
344 @test -f lj_recdef.h || touch lj_recdef.h
345 @test -f lj_folddef.h || touch lj_folddef.h
346 @test -f buildvm_x86.h || touch buildvm_x86.h
347 @$(HOST_CC) $(HOST_CFLAGS) -MM *.c | sed "s|$(DASM_DIR)|\$$(DASM_DIR)|g" >Makefile.dep
348 @test -s lj_ffdef.h || $(HOST_RM) lj_ffdef.h
349 @test -s lj_libdef.h || $(HOST_RM) lj_libdef.h
350 @test -s lj_recdef.h || $(HOST_RM) lj_recdef.h
351 @test -s lj_folddef.h || $(HOST_RM) lj_folddef.h
352 @test -s buildvm_x86.h || $(HOST_RM) buildvm_x86.h
353
354.PHONY: default all amalg clean cleaner distclean depend
237 355
238############################################################################## 356##############################################################################
357# Rules for generated files.
358##############################################################################
239 359
240buildvm_x86.h: buildvm_x86.dasc 360buildvm_x86.h: buildvm_x86.dasc
241 $(E) "DYNASM $@" 361 $(E) "DYNASM $@"
@@ -247,49 +367,46 @@ $(BUILDVM_T): $(BUILDVM_O)
247 367
248$(LJVM_BOUT): $(BUILDVM_T) 368$(LJVM_BOUT): $(BUILDVM_T)
249 $(E) "BUILDVM $@" 369 $(E) "BUILDVM $@"
250 $(Q)./$(BUILDVM_T) -m $(LJVM_MODE) -o $@ 370 $(Q)$(BUILDVM_X) -m $(LJVM_MODE) -o $@
251 371
252lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C) 372lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C)
253 $(E) "BUILDVM $@" 373 $(E) "BUILDVM $@"
254 $(Q)./$(BUILDVM_T) -m ffdef -o $@ $(LJLIB_C) 374 $(Q)$(BUILDVM_X) -m ffdef -o $@ $(LJLIB_C)
255 375
256lj_libdef.h: $(BUILDVM_T) $(LJLIB_C) 376lj_libdef.h: $(BUILDVM_T) $(LJLIB_C)
257 $(E) "BUILDVM $@" 377 $(E) "BUILDVM $@"
258 $(Q)./$(BUILDVM_T) -m libdef -o $@ $(LJLIB_C) 378 $(Q)$(BUILDVM_X) -m libdef -o $@ $(LJLIB_C)
259 379
260lj_recdef.h: $(BUILDVM_T) $(LJLIB_C) 380lj_recdef.h: $(BUILDVM_T) $(LJLIB_C)
261 $(E) "BUILDVM $@" 381 $(E) "BUILDVM $@"
262 $(Q)./$(BUILDVM_T) -m recdef -o $@ $(LJLIB_C) 382 $(Q)$(BUILDVM_X) -m recdef -o $@ $(LJLIB_C)
263 383
264$(LIB_VMDEF): $(BUILDVM_T) $(LJLIB_C) 384$(LIB_VMDEF): $(BUILDVM_T) $(LJLIB_C)
265 $(E) "BUILDVM $@" 385 $(E) "BUILDVM $@"
266 $(Q)./$(BUILDVM_T) -m vmdef -o $@ $(LJLIB_C) 386 $(Q)$(BUILDVM_X) -m vmdef -o $(LIB_VMDEFP) $(LJLIB_C)
267 387
268lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c 388lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c
269 $(E) "BUILDVM $@" 389 $(E) "BUILDVM $@"
270 $(Q)./$(BUILDVM_T) -m folddef -o $@ lj_opt_fold.c 390 $(Q)$(BUILDVM_X) -m folddef -o $@ lj_opt_fold.c
271
272$(LUAJIT_SO): $(LJVMCORE_O)
273 $(E) "LINK $@"
274 $(Q)$(TARGET_CC) $(TARGET_SHLDFLAGS) -o $@ $(LJVMCORE_O) $(TARGET_LIBS)
275 $(Q)$(TARGET_STRIP) $@
276
277$(LUAJIT_T): $(TARGET_O) $(TARGET_DEP)
278 $(E) "LINK $@"
279 $(Q)$(TARGET_CC) $(TARGET_LDFLAGS) -o $@ $(TARGET_O) $(TARGET_LIBS)
280 $(Q)$(TARGET_STRIP) $@
281 $(E) "OK Successfully built LuaJIT"
282 391
283############################################################################## 392##############################################################################
393# Object file rules.
394##############################################################################
284 395
285%.o: %.c 396%.o: %.c
286 $(E) "CC $@" 397 $(E) "CC $@"
398 $(Q)$(TARGET_DYNCC) $(TARGET_CFLAGS) -c -o $(@:.o=_dyn.o) $<
287 $(Q)$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $< 399 $(Q)$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
288 400
289%.o: %.s 401%.o: %.s
290 $(E) "ASM $@" 402 $(E) "ASM $@"
403 $(Q)$(TARGET_DYNCC) $(TARGET_CFLAGS) -c -o $(@:.o=_dyn.o) $<
291 $(Q)$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $< 404 $(Q)$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
292 405
406$(LUAJIT_O):
407 $(E) "CC $@"
408 $(Q)$(TARGET_STCC) $(TARGET_CFLAGS) -c -o $@ $<
409
293$(HOST_O): %.o: %.c 410$(HOST_O): %.o: %.c
294 $(E) "HOSTCC $@" 411 $(E) "HOSTCC $@"
295 $(Q)$(HOST_CC) $(HOST_CFLAGS) -c -o $@ $< 412 $(Q)$(HOST_CC) $(HOST_CFLAGS) -c -o $@ $<
@@ -297,30 +414,23 @@ $(HOST_O): %.o: %.c
297include Makefile.dep 414include Makefile.dep
298 415
299############################################################################## 416##############################################################################
417# Target file rules.
418##############################################################################
300 419
301clean: 420$(LUAJIT_A): $(LJVMCORE_O)
302 $(HOST_RM) $(ALL_RM) 421 $(E) "AR $@"
303 422 $(Q)$(TARGET_AR) $@ $(LJVMCORE_O)
304cleaner: clean
305 $(HOST_RM) $(ALL_DYNGEN)
306 423
307distclean: clean 424# The dependency on _O, but linking with _DYNO is intentional.
308 $(E) "DYNASM $@" 425$(LUAJIT_SO): $(LJVMCORE_O)
309 $(Q)$(DASM) $(DASM_DISTFLAGS) -o buildvm_x86.h buildvm_x86.dasc 426 $(E) "DYNLINK $@"
310 427 $(Q)$(TARGET_LD) $(TARGET_SHLDFLAGS) -o $@ $(LJVMCORE_DYNO) $(TARGET_LIBS)
311depend: 428 $(Q)$(TARGET_STRIP) $@
312 @test -f lj_ffdef.h || touch lj_ffdef.h
313 @test -f lj_libdef.h || touch lj_libdef.h
314 @test -f lj_recdef.h || touch lj_recdef.h
315 @test -f lj_folddef.h || touch lj_folddef.h
316 @test -f buildvm_x86.h || touch buildvm_x86.h
317 @$(HOST_CC) $(HOST_CFLAGS) -MM *.c | sed "s|$(DASM_DIR)|\$$(DASM_DIR)|g" >Makefile.dep
318 @test -s lj_ffdef.h || $(HOST_RM) lj_ffdef.h
319 @test -s lj_libdef.h || $(HOST_RM) lj_libdef.h
320 @test -s lj_recdef.h || $(HOST_RM) lj_recdef.h
321 @test -s lj_folddef.h || $(HOST_RM) lj_folddef.h
322 @test -s buildvm_x86.h || $(HOST_RM) buildvm_x86.h
323 429
324.PHONY: default all $(MAKE_TARGETS) clean cleaner distclean depend 430$(LUAJIT_T): $(TARGET_O) $(LUAJIT_O) $(TARGET_DEP)
431 $(E) "LINK $@"
432 $(Q)$(TARGET_LD) $(TARGET_LDFLAGS) -o $@ $(LUAJIT_O) $(TARGET_O) $(TARGET_LIBS)
433 $(Q)$(TARGET_STRIP) $@
434 $(E) "OK Successfully built LuaJIT"
325 435
326############################################################################## 436##############################################################################
diff --git a/src/Makefile.dep b/src/Makefile.dep
index b1cdd93b..1fb81e27 100644
--- a/src/Makefile.dep
+++ b/src/Makefile.dep
@@ -34,8 +34,8 @@ lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
34lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ 34lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
35 lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h 35 lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h
36lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ 36lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
37 lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_state.h \ 37 lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h \
38 lj_ff.h lj_ffdef.h lj_ctype.h lj_lib.h lj_libdef.h 38 lj_state.h lj_ff.h lj_ffdef.h lj_ctype.h lj_lib.h lj_libdef.h
39lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ 39lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
40 lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \ 40 lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \
41 lj_libdef.h 41 lj_libdef.h
diff --git a/src/buildvm_asm.c b/src/buildvm_asm.c
index e6972bd5..5daab13b 100644
--- a/src/buildvm_asm.c
+++ b/src/buildvm_asm.c
@@ -71,10 +71,7 @@ err:
71 exit(1); 71 exit(1);
72 } 72 }
73 emit_asm_bytes(ctx, cp, n); 73 emit_asm_bytes(ctx, cp, n);
74 if (!strncmp(sym, LABEL_PREFIX, sizeof(LABEL_PREFIX)-1)) 74 fprintf(ctx->fp, "\t%s _%s\n", opname, sym);
75 fprintf(ctx->fp, "\t%s _%s\n", opname, sym);
76 else
77 fprintf(ctx->fp, "\t%s _" LABEL_PREFIX "wrapper_%s\n", opname, sym);
78} 75}
79 76
80/* Emit an assembler label. */ 77/* Emit an assembler label. */
@@ -135,7 +132,7 @@ void emit_asm(BuildCtx *ctx)
135 fprintf(ctx->fp, "\t.text\n"); 132 fprintf(ctx->fp, "\t.text\n");
136 emit_asm_align(ctx, 4); 133 emit_asm_align(ctx, 4);
137 134
138 emit_asm_label(ctx, LABEL_ASM_BEGIN, 0, 1); 135 emit_asm_label(ctx, LABEL_ASM_BEGIN, 0, 0);
139 if (ctx->mode == BUILD_elfasm) 136 if (ctx->mode == BUILD_elfasm)
140 fprintf(ctx->fp, ".Lbegin:\n"); 137 fprintf(ctx->fp, ".Lbegin:\n");
141 138
diff --git a/src/buildvm_fold.c b/src/buildvm_fold.c
index 5f065643..271118e0 100644
--- a/src/buildvm_fold.c
+++ b/src/buildvm_fold.c
@@ -188,7 +188,12 @@ void emit_fold(BuildCtx *ctx)
188 } else if ((p[0] == 'F' || p[0] == 'X') && p[1] == '(' && q) { 188 } else if ((p[0] == 'F' || p[0] == 'X') && p[1] == '(' && q) {
189 p += 2; 189 p += 2;
190 *q = '\0'; 190 *q = '\0';
191 fprintf(ctx->fp, funcidx ? ",\n %s" : " %s", p); 191 if (funcidx)
192 fprintf(ctx->fp, ",\n");
193 if (p[-2] == 'X')
194 fprintf(ctx->fp, " %s", p);
195 else
196 fprintf(ctx->fp, " fold_%s", p);
192 funcidx++; 197 funcidx++;
193 } else { 198 } else {
194 buf[strlen(buf)-1] = '\0'; 199 buf[strlen(buf)-1] = '\0';
diff --git a/src/buildvm_peobj.c b/src/buildvm_peobj.c
index 9acf6b76..1a8661bf 100644
--- a/src/buildvm_peobj.c
+++ b/src/buildvm_peobj.c
@@ -264,7 +264,8 @@ void emit_peobj(BuildCtx *ctx)
264 emit_peobj_sym(ctx, name, 0, 264 emit_peobj_sym(ctx, name, 0,
265 PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN); 265 PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
266 } 266 }
267 emit_peobj_sym_func(ctx, PEOBJ_SYM_PREFIX LABEL_ASM_BEGIN, 0); 267 emit_peobj_sym(ctx, PEOBJ_SYM_PREFIX LABEL_ASM_BEGIN, 0,
268 PEOBJ_SECT_TEXT, PEOBJ_TYPE_NULL, PEOBJ_SCL_EXTERN);
268 for (i = nzsym; i < ctx->nsym; i++) { 269 for (i = nzsym; i < ctx->nsym; i++) {
269 int pi = ctx->perm[i]; 270 int pi = ctx->perm[i];
270 if (pi >= ctx->npc) { 271 if (pi >= ctx->npc) {
diff --git a/src/buildvm_x86.dasc b/src/buildvm_x86.dasc
index add00c9d..f6add4d0 100644
--- a/src/buildvm_x86.dasc
+++ b/src/buildvm_x86.dasc
@@ -287,6 +287,35 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
287 | lea RA, [BASE+RA*8] 287 | lea RA, [BASE+RA*8]
288 | jmp <9 288 | jmp <9
289 | 289 |
290 |->gate_cwrap: // Call gate for wrapped C functions.
291 | // RA = new base, RB = CFUNC, RC = nargs+1, (BASE = old base), PC = return
292 | mov [RA-4], PC
293 | mov KBASE, CFUNC:RB->f
294 | mov L:RB, SAVE_L
295 | lea RC, [RA+NARGS:RC*8-8]
296 | mov L:RB->base, RA
297 | lea RA, [RC+8*LUA_MINSTACK]
298 | mov ARG2, KBASE
299 | mov ARG1, L:RB
300 | mov L:RB->top, RC
301 | cmp RA, L:RB->maxstack
302 | ja ->gate_c_growstack // Need to grow stack.
303 | set_vmstate C
304 | // (lua_State *L, lua_CFunction f)
305 | call aword [DISPATCH+DISPATCH_GL(wrapf)]
306 | set_vmstate INTERP
307 | // nresults returned in eax (RD).
308 | mov BASE, L:RB->base
309 | lea RA, [BASE+RD*8]
310 | neg RA
311 | add RA, L:RB->top // RA = (L->top-(L->base+nresults))*8
312 |->vm_returnc:
313 | add RD, 1 // RD = nresults+1
314 | mov NRESULTS, RD
315 | test PC, FRAME_TYPE
316 | jz ->BC_RET_Z // Handle regular return to Lua.
317 | jmp ->vm_return
318 |
290 |->gate_c: // Call gate for C functions. 319 |->gate_c: // Call gate for C functions.
291 | // RA = new base, RB = CFUNC, RC = nargs+1, (BASE = old base), PC = return 320 | // RA = new base, RB = CFUNC, RC = nargs+1, (BASE = old base), PC = return
292 | mov [RA-4], PC 321 | mov [RA-4], PC
@@ -312,6 +341,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
312 | mov NRESULTS, RD 341 | mov NRESULTS, RD
313 | test PC, FRAME_TYPE 342 | test PC, FRAME_TYPE
314 | jz ->BC_RET_Z // Handle regular return to Lua. 343 | jz ->BC_RET_Z // Handle regular return to Lua.
344 | // Fallthrough.
315 | 345 |
316 |//-- Return handling (non-inline) --------------------------------------- 346 |//-- Return handling (non-inline) ---------------------------------------
317 | 347 |
@@ -1455,7 +1485,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1455 | mov ARG5, RA 1485 | mov ARG5, RA
1456 | fstp FPARG1 1486 | fstp FPARG1
1457 | mov RB, BASE 1487 | mov RB, BASE
1458 | call extern func 1488 | call extern lj_wrapper_ .. func
1459 | mov RA, ARG5 1489 | mov RA, ARG5
1460 | mov BASE, RB 1490 | mov BASE, RB
1461 | jmp ->fff_resn 1491 | jmp ->fff_resn
@@ -3584,6 +3614,85 @@ static void emit_asm_debug(BuildCtx *ctx)
3584 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */ 3614 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
3585 "\t.align 4\n" 3615 "\t.align 4\n"
3586 ".LEFDE0:\n\n", (int)ctx->codesz); 3616 ".LEFDE0:\n\n", (int)ctx->codesz);
3617 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
3618 fprintf(ctx->fp,
3619 ".Lframe1:\n"
3620 "\t.long .LECIE1-.LSCIE1\n"
3621 ".LSCIE1:\n"
3622 "\t.long 0\n"
3623 "\t.byte 0x1\n"
3624 "\t.string \"zPR\"\n"
3625 "\t.uleb128 0x1\n"
3626 "\t.sleb128 -4\n"
3627 "\t.byte 0x8\n"
3628 "\t.uleb128 6\n" /* augmentation length */
3629 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3630 "\t.long lj_err_unwind_dwarf-.\n"
3631 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3632 "\t.byte 0xc\n\t.uleb128 0x4\n\t.uleb128 0x4\n"
3633 "\t.byte 0x88\n\t.uleb128 0x1\n"
3634 "\t.align 4\n"
3635 ".LECIE1:\n\n");
3636 fprintf(ctx->fp,
3637 ".LSFDE1:\n"
3638 "\t.long .LEFDE1-.LASFDE1\n"
3639 ".LASFDE1:\n"
3640 "\t.long .LASFDE1-.Lframe1\n"
3641 "\t.long .Lbegin-.\n"
3642 "\t.long %d\n"
3643 "\t.uleb128 0\n" /* augmentation length */
3644 "\t.byte 0xe\n\t.uleb128 0x30\n" /* def_cfa_offset */
3645 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
3646 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
3647 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
3648 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
3649 "\t.align 4\n"
3650 ".LEFDE1:\n\n", (int)ctx->codesz);
3651 break;
3652 case BUILD_machasm:
3653 /* NYI: OSX ignores it. Something must be missing. */
3654 fprintf(ctx->fp, "\t.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n");
3655 fprintf(ctx->fp,
3656 "EH_frame1:\n"
3657 "\t.set L$set$0,LECIE1-LSCIE1\n"
3658 "\t.long L$set$0\n"
3659 "LSCIE1:\n"
3660 "\t.long 0\n"
3661 "\t.byte 0x1\n"
3662 "\t.ascii \"zPR\"\n"
3663 "\t.byte 0x1\n"
3664 "\t.byte 128-4\n"
3665 "\t.byte 0x8\n"
3666 "\t.byte 6\n" /* augmentation length */
3667 "\t.byte 0x9b\n" /* indirect|pcrel|sdata4 */
3668 "\t.long L_lj_err_unwind_dwarf$non_lazy_ptr-.\n"
3669 "\t.byte 0x1b\n" /* pcrel|sdata4 */
3670 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH-O. */
3671 "\t.byte 0x88\n\t.byte 0x1\n"
3672 "\t.align 2\n"
3673 "LECIE1:\n\n");
3674 fprintf(ctx->fp,
3675 "_lj_vm_asm_begin.eh:\n"
3676 "LSFDE1:\n"
3677 "\t.set L$set$1,LEFDE1-LASFDE1\n"
3678 "\t.long L$set$1\n"
3679 "LASFDE1:\n"
3680 "\t.long LASFDE1-EH_frame1\n"
3681 "\t.long _lj_vm_asm_begin-.\n"
3682 "\t.long %d\n"
3683 "\t.byte 0\n" /* augmentation length */
3684 "\t.byte 0xe\n\t.byte 0x30\n" /* def_cfa_offset */
3685 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
3686 "\t.byte 0x87\n\t.byte 0x3\n" /* offset edi */
3687 "\t.byte 0x86\n\t.byte 0x4\n" /* offset esi */
3688 "\t.byte 0x83\n\t.byte 0x5\n" /* offset ebx */
3689 "\t.align 2\n"
3690 "LEFDE1:\n\n", (int)ctx->codesz);
3691 fprintf(ctx->fp,
3692 "\t.non_lazy_symbol_pointer\n"
3693 "L_lj_err_unwind_dwarf$non_lazy_ptr:\n"
3694 ".indirect_symbol _lj_err_unwind_dwarf\n"
3695 ".long 0\n");
3587 break; 3696 break;
3588 default: /* Difficult for other modes. */ 3697 default: /* Difficult for other modes. */
3589 break; 3698 break;
diff --git a/src/lib_aux.c b/src/lib_aux.c
index 1ae32dbc..2bd06fbb 100644
--- a/src/lib_aux.c
+++ b/src/lib_aux.c
@@ -20,97 +20,6 @@
20#include "lj_err.h" 20#include "lj_err.h"
21#include "lj_lib.h" 21#include "lj_lib.h"
22 22
23/* convert a stack index to positive */
24#define abs_index(L, i) \
25 ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1)
26
27/* -- Type checks --------------------------------------------------------- */
28
29LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
30{
31 if (!lua_checkstack(L, size))
32 lj_err_callerv(L, LJ_ERR_STKOVM, msg);
33}
34
35LUALIB_API void luaL_checktype(lua_State *L, int narg, int tt)
36{
37 if (lua_type(L, narg) != tt)
38 lj_err_argt(L, narg, tt);
39}
40
41LUALIB_API void luaL_checkany(lua_State *L, int narg)
42{
43 lj_lib_checkany(L, narg);
44}
45
46LUALIB_API const char *luaL_checklstring(lua_State *L, int narg, size_t *len)
47{
48 GCstr *s = lj_lib_checkstr(L, narg);
49 if (len != NULL) *len = s->len;
50 return strdata(s);
51}
52
53LUALIB_API const char *luaL_optlstring(lua_State *L, int narg,
54 const char *def, size_t *len)
55{
56 GCstr *s = lj_lib_optstr(L, narg);
57 if (s) {
58 if (len != NULL) *len = s->len;
59 return strdata(s);
60 }
61 if (len != NULL) *len = def ? strlen(def) : 0;
62 return def;
63}
64
65LUALIB_API lua_Number luaL_checknumber(lua_State *L, int narg)
66{
67 return lj_lib_checknum(L, narg);
68}
69
70LUALIB_API lua_Number luaL_optnumber(lua_State *L, int narg, lua_Number def)
71{
72 lj_lib_opt(L, narg,
73 return lj_lib_checknum(L, narg);
74 ,
75 return def;
76 )
77}
78
79LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int narg)
80{
81#if LJ_64
82 return (lua_Integer)lj_lib_checknum(L, narg);
83#else
84 return lj_lib_checkint(L, narg);
85#endif
86}
87
88LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int narg, lua_Integer def)
89{
90#if LJ_64
91 lj_lib_opt(L, narg,
92 return (lua_Integer)lj_lib_checknum(L, narg);
93 ,
94 return def;
95 )
96#else
97 return lj_lib_optint(L, narg, def);
98#endif
99}
100
101LUALIB_API int luaL_checkoption(lua_State *L, int narg, const char *def,
102 const char *const lst[])
103{
104 GCstr *s = lj_lib_optstr(L, narg);
105 const char *opt = s ? strdata(s) : def;
106 uint32_t i;
107 if (!opt) lj_err_argt(L, narg, LUA_TSTRING);
108 for (i = 0; lst[i]; i++)
109 if (strcmp(lst[i], opt) == 0)
110 return (int)i;
111 lj_err_argv(L, narg, LJ_ERR_INVOPTM, opt);
112}
113
114/* -- Module registration ------------------------------------------------- */ 23/* -- Module registration ------------------------------------------------- */
115 24
116LUALIB_API const char *luaL_findtable(lua_State *L, int idx, 25LUALIB_API const char *luaL_findtable(lua_State *L, int idx,
@@ -149,6 +58,7 @@ static int libsize(const luaL_Reg *l)
149LUALIB_API void luaL_openlib(lua_State *L, const char *libname, 58LUALIB_API void luaL_openlib(lua_State *L, const char *libname,
150 const luaL_Reg *l, int nup) 59 const luaL_Reg *l, int nup)
151{ 60{
61 lj_lib_checkfpu(L);
152 if (libname) { 62 if (libname) {
153 int size = libsize(l); 63 int size = libsize(l);
154 /* check whether lib already exists */ 64 /* check whether lib already exists */
@@ -285,6 +195,10 @@ LUALIB_API void luaL_buffinit(lua_State *L, luaL_Buffer *B)
285 195
286#define FREELIST_REF 0 196#define FREELIST_REF 0
287 197
198/* Convert a stack index to an absolute index. */
199#define abs_index(L, i) \
200 ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1)
201
288LUALIB_API int luaL_ref(lua_State *L, int t) 202LUALIB_API int luaL_ref(lua_State *L, int t)
289{ 203{
290 int ref; 204 int ref;
diff --git a/src/lib_io.c b/src/lib_io.c
index 01623258..aefe4213 100644
--- a/src/lib_io.c
+++ b/src/lib_io.c
@@ -523,8 +523,11 @@ static void io_fenv_new(lua_State *L, int narr, lua_CFunction cls)
523 523
524LUALIB_API int luaopen_io(lua_State *L) 524LUALIB_API int luaopen_io(lua_State *L)
525{ 525{
526 LJ_LIB_REG_(L, NULL, io_method); 526 lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
527 lua_setfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); 527 if (tvisnil(L->top-1)) {
528 LJ_LIB_REG_(L, NULL, io_method);
529 lua_setfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
530 }
528 io_fenv_new(L, 0, lj_cf_io_pipe_close); /* top-3 */ 531 io_fenv_new(L, 0, lj_cf_io_pipe_close); /* top-3 */
529 io_fenv_new(L, 2, lj_cf_io_file_close); /* top-2 */ 532 io_fenv_new(L, 2, lj_cf_io_file_close); /* top-2 */
530 LJ_LIB_REG(L, io); 533 LJ_LIB_REG(L, io);
@@ -532,7 +535,7 @@ LUALIB_API int luaopen_io(lua_State *L)
532 io_std_new(L, stdin, IO_INPUT, "stdin"); 535 io_std_new(L, stdin, IO_INPUT, "stdin");
533 io_std_new(L, stdout, IO_OUTPUT, "stdout"); 536 io_std_new(L, stdout, IO_OUTPUT, "stdout");
534 io_std_new(L, stderr, 0, "stderr"); 537 io_std_new(L, stderr, 0, "stderr");
535 lua_pop(L, 1); 538 L->top--;
536 return 1; 539 return 1;
537} 540}
538 541
diff --git a/src/lib_jit.c b/src/lib_jit.c
index 4a57f3b4..6cd0d0b6 100644
--- a/src/lib_jit.c
+++ b/src/lib_jit.c
@@ -73,8 +73,9 @@ LJLIB_CF(jit_flush)
73#if LJ_HASJIT 73#if LJ_HASJIT
74 if (L->base < L->top && (tvisnum(L->base) || tvisstr(L->base))) { 74 if (L->base < L->top && (tvisnum(L->base) || tvisstr(L->base))) {
75 int traceno = lj_lib_checkint(L, 1); 75 int traceno = lj_lib_checkint(L, 1);
76 luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE); 76 setboolV(L->top-1,
77 return 0; 77 luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE));
78 return 1;
78 } 79 }
79#endif 80#endif
80 return setjitmode(L, LUAJIT_MODE_FLUSH); 81 return setjitmode(L, LUAJIT_MODE_FLUSH);
diff --git a/src/lib_math.c b/src/lib_math.c
index ec8b0c2b..adc77c9d 100644
--- a/src/lib_math.c
+++ b/src/lib_math.c
@@ -69,11 +69,9 @@ LJLIB_ASM_(math_max) LJLIB_REC(math_minmax IR_MAX)
69LJLIB_PUSH(3.14159265358979323846) LJLIB_SET(pi) 69LJLIB_PUSH(3.14159265358979323846) LJLIB_SET(pi)
70LJLIB_PUSH(1e310) LJLIB_SET(huge) 70LJLIB_PUSH(1e310) LJLIB_SET(huge)
71 71
72#ifdef __MACH__
73LJ_FUNCA double lj_wrapper_sinh(double x) { return sinh(x); } 72LJ_FUNCA double lj_wrapper_sinh(double x) { return sinh(x); }
74LJ_FUNCA double lj_wrapper_cosh(double x) { return cosh(x); } 73LJ_FUNCA double lj_wrapper_cosh(double x) { return cosh(x); }
75LJ_FUNCA double lj_wrapper_tanh(double x) { return tanh(x); } 74LJ_FUNCA double lj_wrapper_tanh(double x) { return tanh(x); }
76#endif
77 75
78/* ------------------------------------------------------------------------ */ 76/* ------------------------------------------------------------------------ */
79 77
@@ -98,8 +96,8 @@ typedef union { uint64_t u64; double d; } U64double;
98 z = (((z<<q)^z) >> (k-s)) ^ ((z&((uint64_t)(int64_t)-1 << (64-k)))<<s); \ 96 z = (((z<<q)^z) >> (k-s)) ^ ((z&((uint64_t)(int64_t)-1 << (64-k)))<<s); \
99 r ^= z; tw->gen[i] = z; 97 r ^= z; tw->gen[i] = z;
100 98
101/* PRNG step function. Returns a double in the range 0.0 <= d < 1.0. */ 99/* PRNG step function. Returns a double in the range 1.0 <= d < 2.0. */
102static double tw223_step(TW223State *tw) 100static LJ_NOINLINE double tw223_step(TW223State *tw)
103{ 101{
104 uint64_t z, r = 0; 102 uint64_t z, r = 0;
105 U64double u; 103 U64double u;
@@ -108,16 +106,7 @@ static double tw223_step(TW223State *tw)
108 TW223_GEN(2, 55, 24, 7) 106 TW223_GEN(2, 55, 24, 7)
109 TW223_GEN(3, 47, 21, 8) 107 TW223_GEN(3, 47, 21, 8)
110 u.u64 = (r & (((uint64_t)1 << 52)-1)) | ((uint64_t)0x3ff << 52); 108 u.u64 = (r & (((uint64_t)1 << 52)-1)) | ((uint64_t)0x3ff << 52);
111#if defined(__GNUC__) && LJ_TARGET_X86 && __pic__ 109 return u.d;
112 /* Compensate for unbelievable GCC pessimization. */
113 {
114 volatile U64double u1;
115 u1.u64 = (uint64_t)0x3f8 << 52;
116 return u.d - u1.d;
117 }
118#else
119 return u.d - 1.0;
120#endif
121} 110}
122 111
123/* PRNG initialization function. */ 112/* PRNG initialization function. */
@@ -146,7 +135,7 @@ LJLIB_CF(math_random)
146 TW223State *tw = (TW223State *)(uddata(udataV(lj_lib_upvalue(L, 1)))); 135 TW223State *tw = (TW223State *)(uddata(udataV(lj_lib_upvalue(L, 1))));
147 double d; 136 double d;
148 if (LJ_UNLIKELY(!tw->valid)) tw223_init(tw, 0.0); 137 if (LJ_UNLIKELY(!tw->valid)) tw223_init(tw, 0.0);
149 d = tw223_step(tw); 138 d = tw223_step(tw) - 1.0;
150 if (n > 0) { 139 if (n > 0) {
151 double r1 = lj_lib_checknum(L, 1); 140 double r1 = lj_lib_checknum(L, 1);
152 if (n == 1) { 141 if (n == 1) {
diff --git a/src/lib_package.c b/src/lib_package.c
index 69fa1db9..4ede0659 100644
--- a/src/lib_package.c
+++ b/src/lib_package.c
@@ -354,6 +354,7 @@ static int lj_cf_package_require(lua_State *L)
354 lua_pushvalue(L, -1); /* extra copy to be returned */ 354 lua_pushvalue(L, -1); /* extra copy to be returned */
355 lua_setfield(L, 2, name); /* _LOADED[name] = true */ 355 lua_setfield(L, 2, name); /* _LOADED[name] = true */
356 } 356 }
357 lj_lib_checkfpu(L);
357 return 1; 358 return 1;
358} 359}
359 360
diff --git a/src/lib_string.c b/src/lib_string.c
index fdd7fbcb..6c857328 100644
--- a/src/lib_string.c
+++ b/src/lib_string.c
@@ -16,6 +16,7 @@
16#include "lualib.h" 16#include "lualib.h"
17 17
18#include "lj_obj.h" 18#include "lj_obj.h"
19#include "lj_gc.h"
19#include "lj_err.h" 20#include "lj_err.h"
20#include "lj_str.h" 21#include "lj_str.h"
21#include "lj_tab.h" 22#include "lj_tab.h"
@@ -774,6 +775,7 @@ LJLIB_CF(string_format)
774LUALIB_API int luaopen_string(lua_State *L) 775LUALIB_API int luaopen_string(lua_State *L)
775{ 776{
776 GCtab *mt; 777 GCtab *mt;
778 GCstr *mmstr;
777 LJ_LIB_REG(L, string); 779 LJ_LIB_REG(L, string);
778#if defined(LUA_COMPAT_GFIND) 780#if defined(LUA_COMPAT_GFIND)
779 lua_getfield(L, -1, "gmatch"); 781 lua_getfield(L, -1, "gmatch");
@@ -782,8 +784,9 @@ LUALIB_API int luaopen_string(lua_State *L)
782 mt = lj_tab_new(L, 0, 1); 784 mt = lj_tab_new(L, 0, 1);
783 /* NOBARRIER: G(L)->mmname[] is a GC root. */ 785 /* NOBARRIER: G(L)->mmname[] is a GC root. */
784 setgcref(G(L)->basemt[~LJ_TSTR], obj2gco(mt)); 786 setgcref(G(L)->basemt[~LJ_TSTR], obj2gco(mt));
785 settabV(L, lj_tab_setstr(L, mt, strref(G(L)->mmname[MM_index])), 787 mmstr = strref(G(L)->mmname[MM_index]);
786 tabV(L->top-1)); 788 if (isdead(G(L), obj2gco(mmstr))) flipwhite(obj2gco(mmstr));
789 settabV(L, lj_tab_setstr(L, mt, mmstr), tabV(L->top-1));
787 mt->nomm = cast_byte(~(1u<<MM_index)); 790 mt->nomm = cast_byte(~(1u<<MM_index));
788 return 1; 791 return 1;
789} 792}
diff --git a/src/lib_table.c b/src/lib_table.c
index 68dc825b..df9007c8 100644
--- a/src/lib_table.c
+++ b/src/lib_table.c
@@ -74,21 +74,21 @@ LJLIB_CF(table_maxn)
74 TValue *array = tvref(t->array); 74 TValue *array = tvref(t->array);
75 Node *node; 75 Node *node;
76 lua_Number m = 0; 76 lua_Number m = 0;
77 uint32_t i; 77 ptrdiff_t i;
78 for (i = 0; i < t->asize; i++) 78 for (i = (ptrdiff_t)t->asize - 1; i >= 0; i--)
79 if (!tvisnil(&array[i])) { 79 if (!tvisnil(&array[i])) {
80 m = (lua_Number)i; 80 m = (lua_Number)(int32_t)i;
81 break; 81 break;
82 } 82 }
83 node = noderef(t->node); 83 node = noderef(t->node);
84 for (i = 0; i <= t->hmask; i++) 84 for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
85 if (tvisnum(&node[i].key) && numV(&node[i].key) > m) 85 if (tvisnum(&node[i].key) && numV(&node[i].key) > m)
86 m = numV(&node[i].key); 86 m = numV(&node[i].key);
87 setnumV(L->top-1, m); 87 setnumV(L->top-1, m);
88 return 1; 88 return 1;
89} 89}
90 90
91LJLIB_CF(table_insert) 91LJLIB_CF(table_insert) LJLIB_REC(.)
92{ 92{
93 GCtab *t = lj_lib_checktab(L, 1); 93 GCtab *t = lj_lib_checktab(L, 1);
94 int32_t n, i = (int32_t)lj_tab_len(t) + 1; 94 int32_t n, i = (int32_t)lj_tab_len(t) + 1;
@@ -111,20 +111,20 @@ LJLIB_CF(table_insert)
111 } 111 }
112 { 112 {
113 TValue *dst = lj_tab_setint(L, t, i); 113 TValue *dst = lj_tab_setint(L, t, i);
114 copyTV(L, dst, L->top-1); 114 copyTV(L, dst, L->top-1); /* Set new value. */
115 lj_gc_barriert(L, t, dst); 115 lj_gc_barriert(L, t, dst);
116 } 116 }
117 return 0; 117 return 0;
118} 118}
119 119
120LJLIB_CF(table_remove) 120LJLIB_CF(table_remove) LJLIB_REC(.)
121{ 121{
122 GCtab *t = lj_lib_checktab(L, 1); 122 GCtab *t = lj_lib_checktab(L, 1);
123 int32_t e = (int32_t)lj_tab_len(t); 123 int32_t e = (int32_t)lj_tab_len(t);
124 int32_t pos = lj_lib_optint(L, 2, e); 124 int32_t pos = lj_lib_optint(L, 2, e);
125 if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ 125 if (!(1 <= pos && pos <= e)) /* Nothing to remove? */
126 return 0; /* nothing to remove */ 126 return 0;
127 lua_rawgeti(L, 1, pos); 127 lua_rawgeti(L, 1, pos); /* Get previous value. */
128 /* NOBARRIER: This just moves existing elements around. */ 128 /* NOBARRIER: This just moves existing elements around. */
129 for (; pos < e; pos++) { 129 for (; pos < e; pos++) {
130 cTValue *src = lj_tab_getint(t, pos+1); 130 cTValue *src = lj_tab_getint(t, pos+1);
@@ -135,8 +135,8 @@ LJLIB_CF(table_remove)
135 setnilV(dst); 135 setnilV(dst);
136 } 136 }
137 } 137 }
138 setnilV(lj_tab_setint(L, t, e)); 138 setnilV(lj_tab_setint(L, t, e)); /* Remove (last) value. */
139 return 1; 139 return 1; /* Return previous value. */
140} 140}
141 141
142LJLIB_CF(table_concat) 142LJLIB_CF(table_concat)
diff --git a/src/lj_api.c b/src/lj_api.c
index ea4eaf66..db48e3a6 100644
--- a/src/lj_api.c
+++ b/src/lj_api.c
@@ -91,6 +91,12 @@ LUA_API int lua_checkstack(lua_State *L, int size)
91 return 1; 91 return 1;
92} 92}
93 93
94LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
95{
96 if (!lua_checkstack(L, size))
97 lj_err_callerv(L, LJ_ERR_STKOVM, msg);
98}
99
94LUA_API void lua_xmove(lua_State *from, lua_State *to, int n) 100LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
95{ 101{
96 TValue *f, *t; 102 TValue *f, *t;
@@ -193,6 +199,18 @@ LUA_API int lua_type(lua_State *L, int idx)
193 } 199 }
194} 200}
195 201
202LUALIB_API void luaL_checktype(lua_State *L, int idx, int tt)
203{
204 if (lua_type(L, idx) != tt)
205 lj_err_argt(L, idx, tt);
206}
207
208LUALIB_API void luaL_checkany(lua_State *L, int idx)
209{
210 if (index2adr(L, idx) == niltv(L))
211 lj_err_arg(L, idx, LJ_ERR_NOVAL);
212}
213
196LUA_API const char *lua_typename(lua_State *L, int t) 214LUA_API const char *lua_typename(lua_State *L, int t)
197{ 215{
198 UNUSED(L); 216 UNUSED(L);
@@ -202,7 +220,7 @@ LUA_API const char *lua_typename(lua_State *L, int t)
202LUA_API int lua_iscfunction(lua_State *L, int idx) 220LUA_API int lua_iscfunction(lua_State *L, int idx)
203{ 221{
204 cTValue *o = index2adr(L, idx); 222 cTValue *o = index2adr(L, idx);
205 return !isluafunc(funcV(o)); 223 return tvisfunc(o) && !isluafunc(funcV(o));
206} 224}
207 225
208LUA_API int lua_isnumber(lua_State *L, int idx) 226LUA_API int lua_isnumber(lua_State *L, int idx)
@@ -295,6 +313,30 @@ LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
295 return 0; 313 return 0;
296} 314}
297 315
316LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
317{
318 cTValue *o = index2adr(L, idx);
319 TValue tmp;
320 if (tvisnum(o))
321 return numV(o);
322 else if (!(tvisstr(o) && lj_str_numconv(strVdata(o), &tmp)))
323 lj_err_argt(L, idx, LUA_TNUMBER);
324 return numV(&tmp);
325}
326
327LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def)
328{
329 cTValue *o = index2adr(L, idx);
330 TValue tmp;
331 if (tvisnum(o))
332 return numV(o);
333 else if (tvisnil(o))
334 return def;
335 else if (!(tvisstr(o) && lj_str_numconv(strVdata(o), &tmp)))
336 lj_err_argt(L, idx, LUA_TNUMBER);
337 return numV(&tmp);
338}
339
298LUA_API lua_Integer lua_tointeger(lua_State *L, int idx) 340LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
299{ 341{
300 cTValue *o = index2adr(L, idx); 342 cTValue *o = index2adr(L, idx);
@@ -313,6 +355,44 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
313#endif 355#endif
314} 356}
315 357
358LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
359{
360 cTValue *o = index2adr(L, idx);
361 TValue tmp;
362 lua_Number n;
363 if (LJ_LIKELY(tvisnum(o)))
364 n = numV(o);
365 else if (tvisstr(o) && lj_str_numconv(strVdata(o), &tmp))
366 n = numV(&tmp);
367 else
368 lj_err_argt(L, idx, LUA_TNUMBER);
369#if LJ_64
370 return (lua_Integer)n;
371#else
372 return lj_num2int(n);
373#endif
374}
375
376LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
377{
378 cTValue *o = index2adr(L, idx);
379 TValue tmp;
380 lua_Number n;
381 if (LJ_LIKELY(tvisnum(o)))
382 n = numV(o);
383 else if (tvisnil(o))
384 return def;
385 else if (tvisstr(o) && lj_str_numconv(strVdata(o), &tmp))
386 n = numV(&tmp);
387 else
388 lj_err_argt(L, idx, LUA_TNUMBER);
389#if LJ_64
390 return (lua_Integer)n;
391#else
392 return lj_num2int(n);
393#endif
394}
395
316LUA_API int lua_toboolean(lua_State *L, int idx) 396LUA_API int lua_toboolean(lua_State *L, int idx)
317{ 397{
318 cTValue *o = index2adr(L, idx); 398 cTValue *o = index2adr(L, idx);
@@ -337,6 +417,57 @@ LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
337 return strdata(s); 417 return strdata(s);
338} 418}
339 419
420LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
421{
422 TValue *o = index2adr(L, idx);
423 GCstr *s;
424 if (LJ_LIKELY(tvisstr(o))) {
425 s = strV(o);
426 } else if (tvisnum(o)) {
427 lj_gc_check(L);
428 o = index2adr(L, idx); /* GC may move the stack. */
429 s = lj_str_fromnum(L, &o->n);
430 } else {
431 lj_err_argt(L, idx, LUA_TSTRING);
432 }
433 if (len != NULL) *len = s->len;
434 return strdata(s);
435}
436
437LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
438 const char *def, size_t *len)
439{
440 TValue *o = index2adr(L, idx);
441 GCstr *s;
442 if (LJ_LIKELY(tvisstr(o))) {
443 s = strV(o);
444 } else if (tvisnil(o)) {
445 if (len != NULL) *len = def ? strlen(def) : 0;
446 return def;
447 } else if (tvisnum(o)) {
448 lj_gc_check(L);
449 o = index2adr(L, idx); /* GC may move the stack. */
450 s = lj_str_fromnum(L, &o->n);
451 } else {
452 lj_err_argt(L, idx, LUA_TSTRING);
453 }
454 if (len != NULL) *len = s->len;
455 return strdata(s);
456}
457
458LUALIB_API int luaL_checkoption(lua_State *L, int idx, const char *def,
459 const char *const lst[])
460{
461 ptrdiff_t i;
462 const char *s = lua_tolstring(L, idx, NULL);
463 if (s == NULL && (s = def) == NULL)
464 lj_err_argt(L, idx, LUA_TSTRING);
465 for (i = 0; lst[i]; i++)
466 if (strcmp(lst[i], s) == 0)
467 return (int)i;
468 lj_err_argv(L, idx, LJ_ERR_INVOPTM, s);
469}
470
340LUA_API size_t lua_objlen(lua_State *L, int idx) 471LUA_API size_t lua_objlen(lua_State *L, int idx)
341{ 472{
342 TValue *o = index2adr(L, idx); 473 TValue *o = index2adr(L, idx);
@@ -355,7 +486,8 @@ LUA_API size_t lua_objlen(lua_State *L, int idx)
355LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx) 486LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx)
356{ 487{
357 cTValue *o = index2adr(L, idx); 488 cTValue *o = index2adr(L, idx);
358 return funcV(o)->c.gate == lj_gate_c ? funcV(o)->c.f : NULL; 489 ASMFunction gate = funcV(o)->c.gate;
490 return (gate == lj_gate_c || gate == lj_gate_cwrap) ? funcV(o)->c.f : NULL;
359} 491}
360 492
361LUA_API void *lua_touserdata(lua_State *L, int idx) 493LUA_API void *lua_touserdata(lua_State *L, int idx)
diff --git a/src/lj_asm.c b/src/lj_asm.c
index b89b8543..a4d0c606 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -738,11 +738,14 @@ static Reg ra_allocref(ASMState *as, IRRef ref, RegSet allow)
738 } 738 }
739 RA_DBGX((as, "hintmiss $f $r", ref, r)); 739 RA_DBGX((as, "hintmiss $f $r", ref, r));
740 } 740 }
741 /* Invariants should preferably get unused registers. */ 741 /* Invariants should preferably get unmodified registers. */
742 if (ref < as->loopref && !irt_isphi(ir->t)) 742 if (ref < as->loopref && !irt_isphi(ir->t)) {
743 r = rset_pickbot(pick); 743 if ((pick & ~as->modset))
744 else 744 pick &= ~as->modset;
745 r = rset_pickbot(pick); /* Reduce conflicts with inverse allocation. */
746 } else {
745 r = rset_picktop(pick); 747 r = rset_picktop(pick);
748 }
746 } else { 749 } else {
747 r = ra_evict(as, allow); 750 r = ra_evict(as, allow);
748 } 751 }
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c
index d2fce2e0..b427a06e 100644
--- a/src/lj_dispatch.c
+++ b/src/lj_dispatch.c
@@ -153,8 +153,7 @@ int luaJIT_setmode(lua_State *L, int idx, int mode)
153 case LUAJIT_MODE_TRACE: 153 case LUAJIT_MODE_TRACE:
154 if (!(mode & LUAJIT_MODE_FLUSH)) 154 if (!(mode & LUAJIT_MODE_FLUSH))
155 return 0; /* Failed. */ 155 return 0; /* Failed. */
156 lj_trace_flush(G2J(g), idx); 156 return lj_trace_flush(G2J(g), idx);
157 break;
158#else 157#else
159 case LUAJIT_MODE_ENGINE: 158 case LUAJIT_MODE_ENGINE:
160 case LUAJIT_MODE_FUNC: 159 case LUAJIT_MODE_FUNC:
@@ -165,6 +164,20 @@ int luaJIT_setmode(lua_State *L, int idx, int mode)
165 return 0; /* Failed. */ 164 return 0; /* Failed. */
166 break; 165 break;
167#endif 166#endif
167 case LUAJIT_MODE_WRAPCFUNC:
168 if ((mode & LUAJIT_MODE_ON)) {
169 if (idx != 0) {
170 cTValue *tv = idx > 0 ? L->base + (idx-1) : L->top + idx;
171 if (tvislightud(tv) && lightudV(tv) != NULL)
172 g->wrapf = (lua_CFunction)lightudV(tv);
173 else
174 return 0; /* Failed. */
175 }
176 g->wrapmode = 1;
177 } else {
178 g->wrapmode = 0;
179 }
180 break;
168 default: 181 default:
169 return 0; /* Failed. */ 182 return 0; /* Failed. */
170 } 183 }
diff --git a/src/lj_err.c b/src/lj_err.c
index a723af48..71c561b1 100644
--- a/src/lj_err.c
+++ b/src/lj_err.c
@@ -676,6 +676,8 @@ LJ_NORET LJ_NOINLINE static void err_argmsg(lua_State *L, int narg,
676{ 676{
677 const char *fname = "?"; 677 const char *fname = "?";
678 const char *ftype = getfuncname(L, L->base - 1, &fname); 678 const char *ftype = getfuncname(L, L->base - 1, &fname);
679 if (narg < 0 && narg > LUA_REGISTRYINDEX)
680 narg = (L->top - L->base) + narg + 1;
679 if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */ 681 if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */
680 msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg); 682 msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg);
681 else 683 else
@@ -761,3 +763,47 @@ LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...)
761 return 0; /* unreachable */ 763 return 0; /* unreachable */
762} 764}
763 765
766/* -- C++ exception support ----------------------------------------------- */
767
768#if defined(__ELF__) || defined(__MACH__)
769typedef enum
770{
771 _URC_NO_REASON,
772 _URC_FOREIGN_EXCEPTION_CAUGHT,
773 _URC_FATAL_PHASE2_ERROR,
774 _URC_FATAL_PHASE1_ERROR,
775 _URC_NORMAL_STOP,
776 _URC_END_OF_STACK,
777 _URC_HANDLER_FOUND,
778 _URC_INSTALL_CONTEXT,
779 _URC_CONTINUE_UNWIND
780} _Unwind_Reason_Code;
781
782#define _UA_SEARCH_PHASE 1
783#define _UA_CLEANUP_PHASE 2
784#define _UA_HANDLER_FRAME 4
785#define _UA_FORCE_UNWIND 8
786#define _UA_END_OF_STACK 16
787
788extern void *_Unwind_GetCFA(void *ctx);
789extern void _Unwind_DeleteException(void *uex);
790
791/* DWARF2 personality handler referenced from .eh_frame. */
792LJ_FUNCA int lj_err_unwind_dwarf(int version, int actions, uint64_t uexclass,
793 void *uex, void *ctx)
794{
795 if (version != 1)
796 return _URC_FATAL_PHASE1_ERROR;
797 UNUSED(uexclass);
798 if ((actions & _UA_SEARCH_PHASE))
799 return _URC_HANDLER_FOUND;
800 if ((actions & _UA_HANDLER_FRAME)) {
801 void *cf = _Unwind_GetCFA(ctx);
802 lua_State *L = cframe_L(cf);
803 _Unwind_DeleteException(uex);
804 lj_err_msg(L, LJ_ERR_ERRCPP);
805 }
806 return _URC_CONTINUE_UNWIND;
807}
808#endif
809
diff --git a/src/lj_errmsg.h b/src/lj_errmsg.h
index 03abd59b..3c79eaa4 100644
--- a/src/lj_errmsg.h
+++ b/src/lj_errmsg.h
@@ -8,6 +8,7 @@
8/* Basic error handling. */ 8/* Basic error handling. */
9ERRDEF(ERRMEM, "not enough memory") 9ERRDEF(ERRMEM, "not enough memory")
10ERRDEF(ERRERR, "error in error handling") 10ERRDEF(ERRERR, "error in error handling")
11ERRDEF(ERRCPP, "C++ exception")
11 12
12/* Allocations. */ 13/* Allocations. */
13ERRDEF(STROV, "string length overflow") 14ERRDEF(STROV, "string length overflow")
@@ -56,6 +57,9 @@ ERRDEF(NOENV, "no calling environment")
56ERRDEF(CYIELD, "attempt to yield across C-call boundary") 57ERRDEF(CYIELD, "attempt to yield across C-call boundary")
57ERRDEF(BADLU, "bad light userdata pointer") 58ERRDEF(BADLU, "bad light userdata pointer")
58ERRDEF(NOGCMM, "bad action while in __gc metamethod") 59ERRDEF(NOGCMM, "bad action while in __gc metamethod")
60#ifdef LUA_USE_WIN
61ERRDEF(BADFPU, "bad FPU precision (use D3DCREATE_FPU_PRESERVE with DirectX)")
62#endif
59 63
60/* Standard library function errors. */ 64/* Standard library function errors. */
61ERRDEF(ASSERT, "assertion failed!") 65ERRDEF(ASSERT, "assertion failed!")
diff --git a/src/lj_func.c b/src/lj_func.c
index 92cdeda2..6616eff6 100644
--- a/src/lj_func.c
+++ b/src/lj_func.c
@@ -138,7 +138,7 @@ GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env)
138 fn->c.nupvalues = cast_byte(nelems); 138 fn->c.nupvalues = cast_byte(nelems);
139 /* NOBARRIER: The GCfunc is new (marked white). */ 139 /* NOBARRIER: The GCfunc is new (marked white). */
140 setgcref(fn->c.env, obj2gco(env)); 140 setgcref(fn->c.env, obj2gco(env));
141 fn->c.gate = lj_gate_c; 141 fn->c.gate = G(L)->wrapmode ? lj_gate_cwrap : lj_gate_c;
142 return fn; 142 return fn;
143} 143}
144 144
diff --git a/src/lj_gc.c b/src/lj_gc.c
index e479b567..0d8a03ec 100644
--- a/src/lj_gc.c
+++ b/src/lj_gc.c
@@ -230,8 +230,7 @@ static void gc_traverse_trace(global_State *g, Trace *T)
230 230
231/* The current trace is a GC root while not anchored in the prototype (yet). */ 231/* The current trace is a GC root while not anchored in the prototype (yet). */
232#define gc_mark_curtrace(g) \ 232#define gc_mark_curtrace(g) \
233 { if (G2J(g)->state != LJ_TRACE_IDLE && G2J(g)->curtrace != 0) \ 233 { if (G2J(g)->curtrace != 0) gc_traverse_trace(g, &G2J(g)->cur); }
234 gc_traverse_trace(g, &G2J(g)->cur); }
235#else 234#else
236#define gc_mark_curtrace(g) UNUSED(g) 235#define gc_mark_curtrace(g) UNUSED(g)
237#endif 236#endif
diff --git a/src/lj_ir.c b/src/lj_ir.c
index 2ff54821..1efb12f0 100644
--- a/src/lj_ir.c
+++ b/src/lj_ir.c
@@ -252,6 +252,7 @@ TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t)
252{ 252{
253 IRIns *ir, *cir = J->cur.ir; 253 IRIns *ir, *cir = J->cur.ir;
254 IRRef ref; 254 IRRef ref;
255 lua_assert(!isdead(J2G(J), o));
255 for (ref = J->chain[IR_KGC]; ref; ref = cir[ref].prev) 256 for (ref = J->chain[IR_KGC]; ref; ref = cir[ref].prev)
256 if (ir_kgc(&cir[ref]) == o) 257 if (ir_kgc(&cir[ref]) == o)
257 goto found; 258 goto found;
diff --git a/src/lj_lib.h b/src/lj_lib.h
index 1cba3778..59a0f2be 100644
--- a/src/lj_lib.h
+++ b/src/lj_lib.h
@@ -48,6 +48,15 @@ LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst);
48#define lj_lib_upvalue(L, n) \ 48#define lj_lib_upvalue(L, n) \
49 (&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1]) 49 (&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1])
50 50
51#ifdef LUA_USE_WIN
52#define lj_lib_checkfpu(L) \
53 do { setnumV(L->top++, (lua_Number)1437217655); \
54 if (lua_tointeger(L, -1) != 1437217655) lj_err_caller(L, LJ_ERR_BADFPU); \
55 L->top--; } while (0)
56#else
57#define lj_lib_checkfpu(L) UNUSED(L)
58#endif
59
51/* Library function declarations. Scanned by buildvm. */ 60/* Library function declarations. Scanned by buildvm. */
52#define LJLIB_CF(name) static int lj_cf_##name(lua_State *L) 61#define LJLIB_CF(name) static int lj_cf_##name(lua_State *L)
53#define LJLIB_ASM(name) static int lj_ffh_##name(lua_State *L) 62#define LJLIB_ASM(name) static int lj_ffh_##name(lua_State *L)
diff --git a/src/lj_obj.h b/src/lj_obj.h
index e5ea713d..9101f053 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -531,7 +531,7 @@ typedef struct global_State {
531 uint8_t hookmask; /* Hook mask. */ 531 uint8_t hookmask; /* Hook mask. */
532 uint8_t dispatchmode; /* Dispatch mode. */ 532 uint8_t dispatchmode; /* Dispatch mode. */
533 uint8_t vmevmask; /* VM event mask. */ 533 uint8_t vmevmask; /* VM event mask. */
534 uint8_t unused1; 534 uint8_t wrapmode; /* Wrap mode. */
535 GCRef mainthref; /* Link to main thread. */ 535 GCRef mainthref; /* Link to main thread. */
536 TValue registrytv; /* Anchor for registry. */ 536 TValue registrytv; /* Anchor for registry. */
537 TValue tmptv; /* Temporary TValue. */ 537 TValue tmptv; /* Temporary TValue. */
@@ -539,6 +539,7 @@ typedef struct global_State {
539 int32_t hookcount; /* Instruction hook countdown. */ 539 int32_t hookcount; /* Instruction hook countdown. */
540 int32_t hookcstart; /* Start count for instruction hook counter. */ 540 int32_t hookcstart; /* Start count for instruction hook counter. */
541 lua_Hook hookf; /* Hook function. */ 541 lua_Hook hookf; /* Hook function. */
542 lua_CFunction wrapf; /* Wrapper for C function calls. */
542 lua_CFunction panic; /* Called as a last resort for errors. */ 543 lua_CFunction panic; /* Called as a last resort for errors. */
543 volatile int32_t vmstate; /* VM state or current JIT code trace number. */ 544 volatile int32_t vmstate; /* VM state or current JIT code trace number. */
544 GCRef jit_L; /* Current JIT code lua_State or NULL. */ 545 GCRef jit_L; /* Current JIT code lua_State or NULL. */
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index e5d98162..2102561d 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -138,7 +138,7 @@ typedef IRRef (LJ_FASTCALL *FoldFunc)(jit_State *J);
138/* Macros for the fold specs, so buildvm can recognize them. */ 138/* Macros for the fold specs, so buildvm can recognize them. */
139#define LJFOLD(x) 139#define LJFOLD(x)
140#define LJFOLDX(x) 140#define LJFOLDX(x)
141#define LJFOLDF(name) static TRef LJ_FASTCALL name(jit_State *J) 141#define LJFOLDF(name) static TRef LJ_FASTCALL fold_##name(jit_State *J)
142/* Note: They must be at the start of a line or buildvm ignores them! */ 142/* Note: They must be at the start of a line or buildvm ignores them! */
143 143
144/* Barrier to prevent using operands across PHIs. */ 144/* Barrier to prevent using operands across PHIs. */
@@ -979,7 +979,7 @@ LJFOLDF(comm_equal)
979 /* For non-numbers only: x == x ==> drop; x ~= x ==> fail */ 979 /* For non-numbers only: x == x ==> drop; x ~= x ==> fail */
980 if (fins->op1 == fins->op2 && !irt_isnum(fins->t)) 980 if (fins->op1 == fins->op2 && !irt_isnum(fins->t))
981 return CONDFOLD(fins->o == IR_EQ); 981 return CONDFOLD(fins->o == IR_EQ);
982 return comm_swap(J); 982 return fold_comm_swap(J);
983} 983}
984 984
985LJFOLD(LT any any) 985LJFOLD(LT any any)
@@ -1013,7 +1013,7 @@ LJFOLDF(comm_dup)
1013{ 1013{
1014 if (fins->op1 == fins->op2) /* x o x ==> x */ 1014 if (fins->op1 == fins->op2) /* x o x ==> x */
1015 return LEFTFOLD; 1015 return LEFTFOLD;
1016 return comm_swap(J); 1016 return fold_comm_swap(J);
1017} 1017}
1018 1018
1019LJFOLD(BXOR any any) 1019LJFOLD(BXOR any any)
@@ -1021,7 +1021,7 @@ LJFOLDF(comm_bxor)
1021{ 1021{
1022 if (fins->op1 == fins->op2) /* i xor i ==> 0 */ 1022 if (fins->op1 == fins->op2) /* i xor i ==> 0 */
1023 return INTFOLD(0); 1023 return INTFOLD(0);
1024 return comm_swap(J); 1024 return fold_comm_swap(J);
1025} 1025}
1026 1026
1027/* -- Simplification of compound expressions ------------------------------ */ 1027/* -- Simplification of compound expressions ------------------------------ */
diff --git a/src/lj_opt_loop.c b/src/lj_opt_loop.c
index adc0c476..05e9409e 100644
--- a/src/lj_opt_loop.c
+++ b/src/lj_opt_loop.c
@@ -286,7 +286,7 @@ static void loop_unroll(jit_State *J)
286 if (!irt_sametype(t, irr->t)) { 286 if (!irt_sametype(t, irr->t)) {
287 if (irt_isnum(t) && irt_isinteger(irr->t)) /* Fix int->num case. */ 287 if (irt_isnum(t) && irt_isinteger(irr->t)) /* Fix int->num case. */
288 subst[ins] = tref_ref(emitir(IRTN(IR_TONUM), ref, 0)); 288 subst[ins] = tref_ref(emitir(IRTN(IR_TONUM), ref, 0));
289 else 289 else if (!(irt_isinteger(t) && irt_isinteger(irr->t)))
290 lj_trace_err(J, LJ_TRERR_TYPEINS); 290 lj_trace_err(J, LJ_TRERR_TYPEINS);
291 } 291 }
292 } 292 }
diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c
index 77a9c0e7..94fc4ad8 100644
--- a/src/lj_opt_mem.c
+++ b/src/lj_opt_mem.c
@@ -519,8 +519,8 @@ int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref)
519 } else if (irt_isnil(store->t)) { /* Must check any nil store. */ 519 } else if (irt_isnil(store->t)) { /* Must check any nil store. */
520 IRRef skref = IR(store->op1)->op2; 520 IRRef skref = IR(store->op1)->op2;
521 IRRef xkref = IR(xref)->op2; 521 IRRef xkref = IR(xref)->op2;
522 /* Same key type MAY alias. */ 522 /* Same key type MAY alias. Need ALOAD check due to multiple int types. */
523 if (irt_sametype(IR(skref)->t, IR(xkref)->t)) { 523 if (loadop == IR_ALOAD || irt_sametype(IR(skref)->t, IR(xkref)->t)) {
524 if (skref == xkref || !irref_isk(skref) || !irref_isk(xkref)) 524 if (skref == xkref || !irref_isk(skref) || !irref_isk(xkref))
525 return 0; /* A nil store with same const key or var key MAY alias. */ 525 return 0; /* A nil store with same const key or var key MAY alias. */
526 /* Different const keys CANNOT alias. */ 526 /* Different const keys CANNOT alias. */
diff --git a/src/lj_record.c b/src/lj_record.c
index e101ba23..68a233b9 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -168,8 +168,8 @@ static int rec_objcmp(jit_State *J, TRef a, TRef b, cTValue *av, cTValue *bv)
168{ 168{
169 int diff = !lj_obj_equal(av, bv); 169 int diff = !lj_obj_equal(av, bv);
170 if (!tref_isk2(a, b)) { /* Shortcut, also handles primitives. */ 170 if (!tref_isk2(a, b)) { /* Shortcut, also handles primitives. */
171 IRType ta = tref_type(a); 171 IRType ta = tref_isinteger(a) ? IRT_INT : tref_type(a);
172 IRType tb = tref_type(b); 172 IRType tb = tref_isinteger(b) ? IRT_INT : tref_type(b);
173 if (ta != tb) { 173 if (ta != tb) {
174 /* Widen mixed number/int comparisons to number/number comparison. */ 174 /* Widen mixed number/int comparisons to number/number comparison. */
175 if (ta == IRT_INT && tb == IRT_NUM) { 175 if (ta == IRT_INT && tb == IRT_NUM) {
@@ -447,7 +447,7 @@ static int rec_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
447 mix.tab = lj_ir_ktab(J, mt); 447 mix.tab = lj_ir_ktab(J, mt);
448 goto nocheck; 448 goto nocheck;
449 } 449 }
450 ix->mt = mix.tab; 450 ix->mt = mt ? mix.tab : TREF_NIL;
451 emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB)); 451 emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB));
452nocheck: 452nocheck:
453 if (mt) { 453 if (mt) {
@@ -457,6 +457,8 @@ nocheck:
457 copyTV(J->L, &ix->mobjv, mo); 457 copyTV(J->L, &ix->mobjv, mo);
458 ix->mtv = mt; 458 ix->mtv = mt;
459 settabV(J->L, &mix.tabv, mt); 459 settabV(J->L, &mix.tabv, mt);
460 if (isdead(J2G(J), obj2gco(mmstr)))
461 flipwhite(obj2gco(mmstr)); /* Need same logic as lj_str_new(). */
460 setstrV(J->L, &mix.keyv, mmstr); 462 setstrV(J->L, &mix.keyv, mmstr);
461 mix.key = lj_ir_kstr(J, mmstr); 463 mix.key = lj_ir_kstr(J, mmstr);
462 mix.val = 0; 464 mix.val = 0;
@@ -880,7 +882,7 @@ static void recff_nyi(jit_State *J, TRef *res, RecordFFData *rd)
880 lj_trace_err_info(J, LJ_TRERR_NYIFF); 882 lj_trace_err_info(J, LJ_TRERR_NYIFF);
881} 883}
882 884
883LJ_NORET static void recff_err_ffu(jit_State *J, RecordFFData *rd) 885LJ_NORET static void recff_err_nyi(jit_State *J, RecordFFData *rd)
884{ 886{
885 setfuncV(J->L, &J->errinfo, rd->fn); 887 setfuncV(J->L, &J->errinfo, rd->fn);
886 lj_trace_err_info(J, LJ_TRERR_NYIFFU); 888 lj_trace_err_info(J, LJ_TRERR_NYIFFU);
@@ -986,7 +988,7 @@ static void recff_tonumber(jit_State *J, TRef *res, RecordFFData *rd)
986 if (arg[1]) { 988 if (arg[1]) {
987 TRef base = lj_ir_toint(J, arg[1]); 989 TRef base = lj_ir_toint(J, arg[1]);
988 if (!tref_isk(base) || IR(tref_ref(base))->i != 10) 990 if (!tref_isk(base) || IR(tref_ref(base))->i != 10)
989 recff_err_ffu(J, rd); 991 recff_err_nyi(J, rd);
990 } 992 }
991 if (tref_isstr(tr)) 993 if (tref_isstr(tr))
992 tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0); 994 tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
@@ -1016,7 +1018,7 @@ static void recff_tostring(jit_State *J, TRef *res, RecordFFData *rd)
1016 } else if (tref_isnumber(tr)) { 1018 } else if (tref_isnumber(tr)) {
1017 res[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0); 1019 res[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0);
1018 } else { 1020 } else {
1019 recff_err_ffu(J, rd); 1021 recff_err_nyi(J, rd);
1020 } 1022 }
1021 } 1023 }
1022} 1024}
@@ -1338,6 +1340,58 @@ static void recff_table_getn(jit_State *J, TRef *res, RecordFFData *rd)
1338 UNUSED(rd); 1340 UNUSED(rd);
1339} 1341}
1340 1342
1343static void recff_table_remove(jit_State *J, TRef *res, RecordFFData *rd)
1344{
1345 if (tref_istab(arg[0])) {
1346 if (!arg[1] || tref_isnil(arg[1])) { /* Simple pop: t[#t] = nil */
1347 TRef trlen = emitir(IRTI(IR_TLEN), arg[0], 0);
1348 GCtab *t = tabV(&rd->argv[0]);
1349 MSize len = lj_tab_len(t);
1350 emitir(IRTGI(len ? IR_NE : IR_EQ), trlen, lj_ir_kint(J, 0));
1351 if (len) {
1352 RecordIndex ix;
1353 ix.tab = arg[0];
1354 ix.key = trlen;
1355 settabV(J->L, &ix.tabv, t);
1356 setintV(&ix.keyv, len);
1357 ix.idxchain = 0;
1358 if (rd->cres != 0) { /* Specialize load only if result needed. */
1359 ix.val = 0;
1360 res[0] = rec_idx(J, &ix); /* Load previous value. */
1361 /* Assumes ix.key/ix.tab is not modified for raw rec_idx(). */
1362 }
1363 ix.val = TREF_NIL;
1364 rec_idx(J, &ix); /* Remove value. */
1365 } else {
1366 rd->nres = 0;
1367 }
1368 } else { /* Complex case: remove in the middle. */
1369 recff_err_nyi(J, rd);
1370 }
1371 } /* else: Interpreter will throw. */
1372}
1373
1374static void recff_table_insert(jit_State *J, TRef *res, RecordFFData *rd)
1375{
1376 rd->nres = 0;
1377 if (tref_istab(arg[0]) && arg[1]) {
1378 if (!arg[2]) { /* Simple push: t[#t+1] = v */
1379 TRef trlen = emitir(IRTI(IR_TLEN), arg[0], 0);
1380 GCtab *t = tabV(&rd->argv[0]);
1381 RecordIndex ix;
1382 ix.tab = arg[0];
1383 ix.val = arg[1];
1384 ix.key = emitir(IRTI(IR_ADD), trlen, lj_ir_kint(J, 1));
1385 settabV(J->L, &ix.tabv, t);
1386 setintV(&ix.keyv, lj_tab_len(t) + 1);
1387 ix.idxchain = 0;
1388 rec_idx(J, &ix); /* Set new value. */
1389 } else { /* Complex case: insert in the middle. */
1390 recff_err_nyi(J, rd);
1391 }
1392 } /* else: Interpreter will throw. */
1393}
1394
1341/* -- Record calls and returns -------------------------------------------- */ 1395/* -- Record calls and returns -------------------------------------------- */
1342 1396
1343#undef arg 1397#undef arg
@@ -1618,8 +1672,8 @@ void lj_record_ins(jit_State *J)
1618 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: 1672 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
1619 /* Emit nothing for two numeric or string consts. */ 1673 /* Emit nothing for two numeric or string consts. */
1620 if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) { 1674 if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) {
1621 IRType ta = tref_type(ra); 1675 IRType ta = tref_isinteger(ra) ? IRT_INT : tref_type(ra);
1622 IRType tc = tref_type(rc); 1676 IRType tc = tref_isinteger(rc) ? IRT_INT : tref_type(rc);
1623 int irop; 1677 int irop;
1624 if (ta != tc) { 1678 if (ta != tc) {
1625 /* Widen mixed number/int comparisons to number/number comparison. */ 1679 /* Widen mixed number/int comparisons to number/number comparison. */
diff --git a/src/lj_tab.c b/src/lj_tab.c
index 633ea20c..9af51027 100644
--- a/src/lj_tab.c
+++ b/src/lj_tab.c
@@ -191,8 +191,8 @@ GCtab *lj_tab_dup(lua_State *L, const GCtab *kt)
191 Node *kn = &knode[i]; 191 Node *kn = &knode[i];
192 Node *n = &node[i]; 192 Node *n = &node[i];
193 Node *next = nextnode(kn); 193 Node *next = nextnode(kn);
194 copyTV(L, &n->val, &kn->val); 194 /* Don't use copyTV here, since it asserts on a copy of a DEADKEY. */
195 copyTV(L, &n->key, &kn->key); 195 n->val = kn->val; n->key = kn->key;
196 setmref(n->next, next == NULL? next : (Node *)((char *)next + d)); 196 setmref(n->next, next == NULL? next : (Node *)((char *)next + d));
197 } 197 }
198 } 198 }
diff --git a/src/lj_trace.c b/src/lj_trace.c
index 6ceb5633..a0748b40 100644
--- a/src/lj_trace.c
+++ b/src/lj_trace.c
@@ -191,47 +191,58 @@ static void trace_unpatch(jit_State *J, Trace *T)
191 } 191 }
192} 192}
193 193
194/* Flush a root trace and any attached side traces. */ 194/* Free a root trace and any attached side traces. */
195void lj_trace_flush(jit_State *J, TraceNo traceno) 195static void trace_freeroot(jit_State *J, Trace *T, TraceNo traceno)
196{ 196{
197 Trace *T = NULL; 197 GCproto *pt = &gcref(T->startpt)->pt;
198 GCproto *pt; 198 TraceNo side;
199 if (traceno > 0 && traceno <= J->sizetrace) 199 lua_assert(T->root == 0 && pt != NULL);
200 T = J->trace[traceno]; 200 /* First unpatch any modified bytecode. */
201 if (T == NULL) 201 trace_unpatch(J, T);
202 return; 202 /* Unlink root trace from chain anchored in prototype. */
203 pt = &gcref(T->startpt)->pt; 203 if (pt->trace == traceno) { /* Trace is first in chain. Easy. */
204 if (T->root == 0 && pt != NULL) { 204 pt->trace = T->nextroot;
205 TraceNo side; 205 } else { /* Otherwise search in chain of root traces. */
206 /* First unpatch any modified bytecode. */ 206 Trace *T2 = J->trace[pt->trace];
207 trace_unpatch(J, T); 207 while (T2->nextroot != traceno) {
208 /* Unlink root trace from chain anchored in prototype. */ 208 lua_assert(T2->nextroot != 0);
209 if (pt->trace == traceno) { /* Trace is first in chain. Easy. */ 209 T2 = J->trace[T2->nextroot];
210 pt->trace = T->nextroot;
211 } else { /* Otherwise search in chain of root traces. */
212 Trace *T2 = J->trace[pt->trace];
213 while (T2->nextroot != traceno) {
214 lua_assert(T2->nextroot != 0);
215 T2 = J->trace[T2->nextroot];
216 }
217 T2->nextroot = T->nextroot; /* Unlink from chain. */
218 } 210 }
219 /* Free all side traces. */ 211 T2->nextroot = T->nextroot; /* Unlink from chain. */
220 for (side = T->nextside; side != 0; ) { 212 }
221 TraceNo next = J->trace[side]->nextside; 213 /* Free all side traces. */
222 trace_free(J, side); 214 for (side = T->nextside; side != 0; ) {
223 side = next; 215 TraceNo next = J->trace[side]->nextside;
216 trace_free(J, side);
217 side = next;
218 }
219 /* Now free the trace itself. */
220 trace_free(J, traceno);
221}
222
223/* Flush a root trace + side traces, if there are no links to it. */
224int lj_trace_flush(jit_State *J, TraceNo traceno)
225{
226 if (traceno > 0 && traceno < J->sizetrace) {
227 Trace *T = J->trace[traceno];
228 if (T && T->root == 0) {
229 ptrdiff_t i;
230 for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--)
231 if (i != (ptrdiff_t)traceno && J->trace[i] &&
232 J->trace[i]->root != traceno && J->trace[i]->link == traceno)
233 return 0; /* Failed: existing link to trace. */
234 trace_freeroot(J, T, traceno);
235 return 1; /* Ok. */
224 } 236 }
225 /* Now free the trace itself. */ 237 }
226 trace_free(J, traceno); 238 return 0; /* Failed. */
227 } /* Flush for non-root traces is currently ignored. */
228} 239}
229 240
230/* Flush all traces associated with a prototype. */ 241/* Flush all traces associated with a prototype. */
231void lj_trace_flushproto(global_State *g, GCproto *pt) 242void lj_trace_flushproto(global_State *g, GCproto *pt)
232{ 243{
233 while (pt->trace != 0) 244 while (pt->trace != 0)
234 lj_trace_flush(G2J(g), pt->trace); 245 trace_freeroot(G2J(g), G2J(g)->trace[pt->trace], pt->trace);
235} 246}
236 247
237/* Flush all traces. */ 248/* Flush all traces. */
@@ -241,8 +252,11 @@ int lj_trace_flushall(lua_State *L)
241 ptrdiff_t i; 252 ptrdiff_t i;
242 if ((J2G(J)->hookmask & HOOK_GC)) 253 if ((J2G(J)->hookmask & HOOK_GC))
243 return 1; 254 return 1;
244 for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) 255 for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) {
245 lj_trace_flush(J, (TraceNo)i); 256 Trace *T = J->trace[i];
257 if (T && T->root == 0)
258 trace_freeroot(J, T, (TraceNo)i);
259 }
246#ifdef LUA_USE_ASSERT 260#ifdef LUA_USE_ASSERT
247 for (i = 0; i < (ptrdiff_t)J->sizetrace; i++) 261 for (i = 0; i < (ptrdiff_t)J->sizetrace; i++)
248 lua_assert(J->trace[i] == NULL); 262 lua_assert(J->trace[i] == NULL);
diff --git a/src/lj_trace.h b/src/lj_trace.h
index 9d8eb790..466ecc00 100644
--- a/src/lj_trace.h
+++ b/src/lj_trace.h
@@ -26,7 +26,7 @@ LJ_FUNC_NORET void lj_trace_err_info(jit_State *J, TraceError e);
26LJ_FUNC void lj_trace_freeproto(global_State *g, GCproto *pt); 26LJ_FUNC void lj_trace_freeproto(global_State *g, GCproto *pt);
27LJ_FUNC void lj_trace_reenableproto(GCproto *pt); 27LJ_FUNC void lj_trace_reenableproto(GCproto *pt);
28LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt); 28LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt);
29LJ_FUNC void lj_trace_flush(jit_State *J, TraceNo traceno); 29LJ_FUNC int lj_trace_flush(jit_State *J, TraceNo traceno);
30LJ_FUNC int lj_trace_flushall(lua_State *L); 30LJ_FUNC int lj_trace_flushall(lua_State *L);
31LJ_FUNC void lj_trace_freestate(global_State *g); 31LJ_FUNC void lj_trace_freestate(global_State *g);
32 32
diff --git a/src/lj_vm.h b/src/lj_vm.h
index f50614bb..095f284a 100644
--- a/src/lj_vm.h
+++ b/src/lj_vm.h
@@ -46,6 +46,7 @@ LJ_ASMF void lj_vm_powi(void);
46LJ_ASMF void lj_gate_lf(void); 46LJ_ASMF void lj_gate_lf(void);
47LJ_ASMF void lj_gate_lv(void); 47LJ_ASMF void lj_gate_lv(void);
48LJ_ASMF void lj_gate_c(void); 48LJ_ASMF void lj_gate_c(void);
49LJ_ASMF void lj_gate_cwrap(void);
49 50
50/* Continuations for metamethods. */ 51/* Continuations for metamethods. */
51LJ_ASMF void lj_cont_cat(void); /* Continue with concatenation. */ 52LJ_ASMF void lj_cont_cat(void); /* Continue with concatenation. */
@@ -55,12 +56,11 @@ LJ_ASMF void lj_cont_condt(void); /* Branch if result is true. */
55LJ_ASMF void lj_cont_condf(void); /* Branch if result is false. */ 56LJ_ASMF void lj_cont_condf(void); /* Branch if result is false. */
56 57
57/* Start of the ASM code. */ 58/* Start of the ASM code. */
58LJ_ASMF void lj_vm_asm_begin(void); 59LJ_ASMF char lj_vm_asm_begin[];
59 60
60/* Opcode handler offsets, relative to lj_vm_asm_begin. */ 61/* Opcode handler offsets, relative to lj_vm_asm_begin. */
61LJ_ASMF const uint16_t lj_vm_op_ofs[]; 62LJ_ASMF const uint16_t lj_vm_op_ofs[];
62 63
63#define makeasmfunc(ofs) \ 64#define makeasmfunc(ofs) ((ASMFunction)(lj_vm_asm_begin + (ofs)))
64 ((ASMFunction)((char *)lj_vm_asm_begin + (ofs)))
65 65
66#endif 66#endif
diff --git a/src/lua.hpp b/src/lua.hpp
index ec417f59..07e9002d 100644
--- a/src/lua.hpp
+++ b/src/lua.hpp
@@ -1,9 +1,9 @@
1// lua.hpp 1// C++ wrapper for LuaJIT header files.
2// Lua header files for C++
3// <<extern "C">> not supplied automatically because Lua also compiles as C++
4 2
5extern "C" { 3extern "C" {
6#include "lua.h" 4#include "lua.h"
7#include "lualib.h"
8#include "lauxlib.h" 5#include "lauxlib.h"
6#include "lualib.h"
7#include "luajit.h"
9} 8}
9
diff --git a/src/luaconf.h b/src/luaconf.h
index 4d4f1099..dfa0f1d5 100644
--- a/src/luaconf.h
+++ b/src/luaconf.h
@@ -34,13 +34,22 @@
34 ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" 34 ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
35#else 35#else
36#define LUA_ROOT "/usr/local/" 36#define LUA_ROOT "/usr/local/"
37#define LUA_JDIR LUA_ROOT "share/luajit-2.0.0-beta1/"
38#define LUA_LDIR LUA_ROOT "share/lua/5.1/" 37#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
39#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" 38#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
39#ifdef LUA_XROOT
40#define LUA_JDIR LUA_XROOT "share/luajit-2.0.0-beta2/"
41#define LUA_XPATH \
42 ";" LUA_XROOT "share/lua/5.1/?.lua;" LUA_XROOT "share/lua/5.1/?/init.lua"
43#define LUA_XCPATH LUA_XROOT "lib/lua/5.1/?.lua;"
44#else
45#define LUA_JDIR LUA_ROOT "share/luajit-2.0.0-beta2/"
46#define LUA_XPATH
47#define LUA_XCPATH
48#endif
40#define LUA_PATH_DEFAULT \ 49#define LUA_PATH_DEFAULT \
41 "./?.lua;" LUA_JDIR"?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" 50 "./?.lua;" LUA_JDIR"?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua" LUA_XPATH
42#define LUA_CPATH_DEFAULT \ 51#define LUA_CPATH_DEFAULT \
43 "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" 52 "./?.so;" LUA_CDIR"?.so;" LUA_XCPATH LUA_CDIR"loadall.so"
44#endif 53#endif
45 54
46/* Environment variable names for path overrides and initialization code. */ 55/* Environment variable names for path overrides and initialization code. */
diff --git a/src/luajit.c b/src/luajit.c
index 9153975b..eec2c0ca 100644
--- a/src/luajit.c
+++ b/src/luajit.c
@@ -55,16 +55,16 @@ static void laction(int i)
55static void print_usage(void) 55static void print_usage(void)
56{ 56{
57 fprintf(stderr, 57 fprintf(stderr,
58 "usage: %s [options] [script [args]].\n" 58 "usage: %s [options]... [script [args]...].\n"
59 "Available options are:\n" 59 "Available options are:\n"
60 " -e stat execute string " LUA_QL("stat") "\n" 60 " -e chunk Execute string " LUA_QL("chunk") ".\n"
61 " -l name require library " LUA_QL("name") "\n" 61 " -l name Require library " LUA_QL("name") ".\n"
62 " -j cmd perform LuaJIT control command\n" 62 " -j cmd Perform LuaJIT control command.\n"
63 " -O[lvl] set LuaJIT optimization level\n" 63 " -O[opt] Control LuaJIT optimizations.\n"
64 " -i enter interactive mode after executing " LUA_QL("script") "\n" 64 " -i Enter interactive mode after executing " LUA_QL("script") ".\n"
65 " -v show version information\n" 65 " -v Show version information.\n"
66 " -- stop handling options\n" 66 " -- Stop handling options.\n"
67 " - execute stdin and stop handling options\n" 67 " - Execute stdin and stop handling options.\n"
68 , 68 ,
69 progname); 69 progname);
70 fflush(stderr); 70 fflush(stderr);
@@ -143,7 +143,7 @@ static void print_jit_status(lua_State *L)
143 fputs(lua_toboolean(L, n) ? "JIT: ON" : "JIT: OFF", stderr); 143 fputs(lua_toboolean(L, n) ? "JIT: ON" : "JIT: OFF", stderr);
144 for (n++; (s = lua_tostring(L, n)); n++) 144 for (n++; (s = lua_tostring(L, n)); n++)
145 fprintf(stderr, " %s", s); 145 fprintf(stderr, " %s", s);
146 fputs("\n", stdout); 146 fputs("\n", stderr);
147} 147}
148 148
149static int getargs(lua_State *L, char **argv, int n) 149static int getargs(lua_State *L, char **argv, int n)
diff --git a/src/luajit.h b/src/luajit.h
index 01913755..b3617f49 100644
--- a/src/luajit.h
+++ b/src/luajit.h
@@ -30,9 +30,9 @@
30 30
31#include "lua.h" 31#include "lua.h"
32 32
33#define LUAJIT_VERSION "LuaJIT 2.0.0-beta1" 33#define LUAJIT_VERSION "LuaJIT 2.0.0-beta2"
34#define LUAJIT_VERSION_NUM 20000 /* Version 2.0.0 = 02.00.00. */ 34#define LUAJIT_VERSION_NUM 20000 /* Version 2.0.0 = 02.00.00. */
35#define LUAJIT_VERSION_SYM luaJIT_version_2_0_0_beta1 35#define LUAJIT_VERSION_SYM luaJIT_version_2_0_0_beta2
36#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2009 Mike Pall" 36#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2009 Mike Pall"
37#define LUAJIT_URL "http://luajit.org/" 37#define LUAJIT_URL "http://luajit.org/"
38 38
@@ -49,12 +49,14 @@ enum {
49 49
50 LUAJIT_MODE_TRACE, /* Flush a compiled trace. */ 50 LUAJIT_MODE_TRACE, /* Flush a compiled trace. */
51 51
52 LUAJIT_MODE_WRAPCFUNC = 0x10, /* Set wrapper mode for C function calls. */
53
52 LUAJIT_MODE_MAX 54 LUAJIT_MODE_MAX
53}; 55};
54 56
55/* Flags or'ed in to the mode. */ 57/* Flags or'ed in to the mode. */
56#define LUAJIT_MODE_OFF 0x0000 /* Disable JIT compilation. */ 58#define LUAJIT_MODE_OFF 0x0000 /* Turn feature off. */
57#define LUAJIT_MODE_ON 0x0100 /* (Re-)enable JIT compilation. */ 59#define LUAJIT_MODE_ON 0x0100 /* Turn feature on. */
58#define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */ 60#define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */
59 61
60/* LuaJIT public C API. */ 62/* LuaJIT public C API. */