diff options
author | Mike Pall <mike> | 2009-12-08 19:49:20 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2009-12-08 19:49:20 +0100 |
commit | 1d1fed48a002dfc0919135911057ebc255a53e0a (patch) | |
tree | c5c6643908374bb8f02f4c7691332d32f6645986 | |
parent | 55b16959717084884fd4a0cbae6d19e3786c20c7 (diff) | |
download | luajit-1d1fed48a002dfc0919135911057ebc255a53e0a.tar.gz luajit-1d1fed48a002dfc0919135911057ebc255a53e0a.tar.bz2 luajit-1d1fed48a002dfc0919135911057ebc255a53e0a.zip |
RELEASE LuaJIT-2.0.0-beta2v2.0.0-beta2
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 | =============================================================================== | ||
2 | LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/ | ||
3 | |||
4 | Copyright (C) 2005-2009 Mike Pall. All rights reserved. | ||
5 | |||
6 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
7 | of this software and associated documentation files (the "Software"), to deal | ||
8 | in the Software without restriction, including without limitation the rights | ||
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
10 | copies of the Software, and to permit persons to whom the Software is | ||
11 | furnished to do so, subject to the following conditions: | ||
12 | |||
13 | The above copyright notice and this permission notice shall be included in | ||
14 | all copies or substantial portions of the Software. | ||
15 | |||
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
22 | THE 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 | |||
29 | Copyright (C) 1994-2008 Lua.org, PUC-Rio. | ||
30 | |||
31 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
32 | of this software and associated documentation files (the "Software"), to deal | ||
33 | in the Software without restriction, including without limitation the rights | ||
34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
35 | copies of the Software, and to permit persons to whom the Software is | ||
36 | furnished to do so, subject to the following conditions: | ||
37 | |||
38 | The above copyright notice and this permission notice shall be included in | ||
39 | all copies or substantial portions of the Software. | ||
40 | |||
41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
47 | THE SOFTWARE. | ||
48 | |||
49 | =============================================================================== | ||
50 | [ LuaJIT includes code from dlmalloc, which has this license statement: ] | ||
51 | |||
52 | This is a version (aka dlmalloc) of malloc/free/realloc written by | ||
53 | Doug Lea and released to the public domain, as explained at | ||
54 | http://creativecommons.org/licenses/publicdomain | ||
55 | |||
56 | =============================================================================== | ||
@@ -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 | ||
15 | BASEVER= 2.0.0 | 15 | MAJVER= 2 |
16 | VERSION= 2.0.0-beta1 | 16 | MINVER= 0 |
17 | RELVER= 0 | ||
18 | PREREL= -beta2 | ||
19 | VERSION= $(MAJVER).$(MINVER).$(RELVER)$(PREREL) | ||
20 | ABIVER= 5.1 | ||
21 | NODOTABIVER= 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 | # |
23 | PREFIX= /usr/local | 28 | export PREFIX= /usr/local |
24 | ############################################################################## | 29 | ############################################################################## |
25 | 30 | ||
26 | INSTALL_BIN= $(PREFIX)/bin | 31 | DPREFIX= $(DESTDIR)$(PREFIX) |
27 | INSTALL_NAME= luajit-$(VERSION) | 32 | INSTALL_BIN= $(DPREFIX)/bin |
28 | INSTALL_T= $(INSTALL_BIN)/$(INSTALL_NAME) | 33 | INSTALL_LIB= $(DPREFIX)/lib |
29 | INSTALL_TSYM= $(INSTALL_BIN)/luajit | 34 | INSTALL_SHARE= $(DPREFIX)/share |
30 | INSTALL_INC= $(PREFIX)/include/luajit-$(BASEVER) | 35 | INSTALL_INC= $(DPREFIX)/include/luajit-$(MAJVER).$(MINVER) |
31 | INSTALL_JITLIB= $(PREFIX)/share/luajit-$(VERSION)/jit | 36 | |
32 | 37 | INSTALL_JITLIB= $(INSTALL_SHARE)/luajit-$(VERSION)/jit | |
38 | INSTALL_LMOD= $(INSTALL_SHARE)/lua/$(ABIVER) | ||
39 | INSTALL_CMOD= $(INSTALL_LIB)/lua/$(ABIVER) | ||
40 | INSTALL_MAN= $(INSTALL_SHARE)/man/man1 | ||
41 | INSTALL_PKGCONFIG= $(INSTALL_LIB)/pkgconfig | ||
42 | |||
43 | INSTALL_TNAME= luajit-$(VERSION) | ||
44 | INSTALL_TSYMNAME= luajit | ||
45 | INSTALL_ANAME= libluajit-$(ABIVER).a | ||
46 | INSTALL_SONAME= libluajit-$(ABIVER).so.$(MAJVER).$(MINVER).$(RELVER) | ||
47 | INSTALL_SOSHORT= libluajit-$(ABIVER).so | ||
48 | INSTALL_DYLIBNAME= libluajit-$(NODOTABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib | ||
49 | INSTALL_DYLIBSHORT1= libluajit-$(NODOTABIVER).dylib | ||
50 | INSTALL_DYLIBSHORT2= libluajit-$(NODOTABIVER).$(MAJVER).dylib | ||
51 | INSTALL_PCNAME= luajit.pc | ||
52 | |||
53 | INSTALL_STATIC= $(INSTALL_LIB)/$(INSTALL_ANAME) | ||
54 | INSTALL_DYN= $(INSTALL_LIB)/$(INSTALL_SONAME) | ||
55 | INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_SOSHORT) | ||
56 | INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_SOSHORT) | ||
57 | INSTALL_T= $(INSTALL_BIN)/$(INSTALL_TNAME) | ||
58 | INSTALL_TSYM= $(INSTALL_BIN)/$(INSTALL_TSYMNAME) | ||
59 | INSTALL_PC= $(INSTALL_PKGCONFIG)/$(INSTALL_PCNAME) | ||
60 | |||
61 | INSTALL_DIRS= $(INSTALL_BIN) $(INSTALL_LIB) $(INSTALL_INC) $(INSTALL_MAN) \ | ||
62 | $(INSTALL_PKGCONFIG) $(INSTALL_JITLIB) $(INSTALL_LMOD) $(INSTALL_CMOD) | ||
63 | |||
64 | RM= rm -f | ||
33 | MKDIR= mkdir -p | 65 | MKDIR= mkdir -p |
34 | SYMLINK= ln -f -s | 66 | SYMLINK= ln -sf |
35 | INSTALL_X= install -m 0755 | 67 | INSTALL_X= install -m 0755 |
36 | INSTALL_F= install -m 0644 | 68 | INSTALL_F= install -m 0644 |
37 | 69 | LDCONFIG= ldconfig -n | |
38 | FILES_T= luajit | 70 | SED_PC= sed -e "s|^prefix=.*|prefix=$(PREFIX)|" |
71 | |||
72 | FILE_T= luajit | ||
73 | FILE_A= libluajit.a | ||
74 | FILE_SO= libluajit.so | ||
75 | FILE_MAN= luajit.1 | ||
76 | FILE_PC= luajit.pc | ||
39 | FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h | 77 | FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h |
40 | FILES_JITLIB= bc.lua v.lua dump.lua dis_x86.lua dis_x64.lua vmdef.lua | 78 | FILES_JITLIB= bc.lua v.lua dump.lua dis_x86.lua dis_x64.lua vmdef.lua |
41 | 79 | ||
80 | ifeq (,$(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 | ||
87 | endif | ||
88 | |||
42 | ############################################################################## | 89 | ############################################################################## |
43 | 90 | ||
44 | INSTALL_DEP= src/luajit | 91 | INSTALL_DEP= src/luajit |
45 | 92 | ||
46 | all $(INSTALL_DEP): | 93 | default 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 | ||
51 | install: $(INSTALL_DEP) | 98 | install: $(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: | |||
77 | distclean: | 135 | distclean: |
78 | $(MAKE) -C src distclean | 136 | $(MAKE) -C src distclean |
79 | 137 | ||
80 | SUB_TARGETS= amalg clean cleaner distclean | 138 | .PHONY: all install amalg clean cleaner distclean |
81 | |||
82 | .PHONY: all install $(SUB_TARGETS) | ||
83 | 139 | ||
84 | ############################################################################## | 140 | ############################################################################## |
@@ -1,4 +1,4 @@ | |||
1 | README for LuaJIT 2.0.0-beta1 | 1 | README for LuaJIT 2.0.0-beta2 |
2 | ----------------------------- | 2 | ----------------------------- |
3 | 3 | ||
4 | LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language. | 4 | LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language. |
@@ -7,7 +7,7 @@ Project Homepage: http://luajit.org/ | |||
7 | 7 | ||
8 | LuaJIT is Copyright (C) 2005-2009 Mike Pall. | 8 | LuaJIT is Copyright (C) 2005-2009 Mike Pall. |
9 | LuaJIT is free software, released under the MIT/X license. | 9 | LuaJIT is free software, released under the MIT/X license. |
10 | See full Copyright Notice in src/luajit.h | 10 | See full Copyright Notice in the COPYRIGHT file or in luajit.h. |
11 | 11 | ||
12 | Documentation for LuaJIT is available in HTML format. | 12 | Documentation for LuaJIT is available in HTML format. |
13 | Please point your favorite browser to: | 13 | Please 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 | |||
100 | Flushes the whole cache of compiled code. | 100 | Flushes 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> | ||
105 | Flushes the code for the specified root trace and all of its | ||
106 | side 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> |
110 | jit.off(func|true [,true|false])<br> | 104 | jit.off(func|true [,true|false])<br> |
111 | jit.flush(func|true [,true|false])</tt></h3> | 105 | jit.flush(func|true [,true|false])</tt></h3> |
@@ -142,6 +136,13 @@ of a module to turn off JIT compilation for the whole module for | |||
142 | debugging purposes. | 136 | debugging purposes. |
143 | </p> | 137 | </p> |
144 | 138 | ||
139 | <h3 id="jit_flush_tr"><tt>status = jit.flush(tr)</tt></h3> | ||
140 | <p> | ||
141 | Tries to flush the code for the specified trace and all of its | ||
142 | side traces from the cache. Returns <tt>true</tt> on success. | ||
143 | Returns <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> |
147 | Contains the LuaJIT version string. | 148 | Contains the LuaJIT version string. |
@@ -189,6 +190,140 @@ The debug modules <tt>-jbc</tt>, <tt>-jv</tt> and <tt>-jdump</tt> make | |||
189 | extensive use of these functions. Please check out their source code, | 190 | extensive use of these functions. Please check out their source code, |
190 | if you want to know more. | 191 | if you want to know more. |
191 | </p> | 192 | </p> |
193 | |||
194 | <h2 id="c_api">C API extensions</h2> | ||
195 | <p> | ||
196 | LuaJIT adds some extensions to the Lua/C API. The LuaJIT include | ||
197 | directory must be in the compiler search path (<tt>-I<i>path</i></tt>) | ||
198 | to be able to include the required header for C code: | ||
199 | </p> | ||
200 | <pre class="code"> | ||
201 | #include "luajit.h" | ||
202 | </pre> | ||
203 | <p> | ||
204 | Or 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 | — Control VM</h2> | ||
212 | <p> | ||
213 | This is a C API extension to allow control of the VM from C code. The | ||
214 | full prototype of <tt>LuaJIT_setmode</tt> is: | ||
215 | </p> | ||
216 | <pre class="code"> | ||
217 | LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode); | ||
218 | </pre> | ||
219 | <p> | ||
220 | The returned status is either success (<tt>1</tt>) or failure (<tt>0</tt>). | ||
221 | The second argument is either <tt>0</tt> or a stack index (similar to the | ||
222 | other Lua/C API functions). | ||
223 | </p> | ||
224 | <p> | ||
225 | The third argument specifies the mode, which is 'or'ed with a flag. | ||
226 | The 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> | ||
231 | The 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> | ||
236 | Turn 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> | ||
243 | This sets the mode for the function at the stack index <tt>idx</tt> or | ||
244 | the parent of the calling function (<tt>idx = 0</tt>). It either | ||
245 | enables JIT compilation for a function, disables it and flushes any | ||
246 | already compiled code or only flushes already compiled code. This | ||
247 | applies 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 | LUAJIT_MODE_TRACE|LUAJIT_MODE_FLUSH)</tt></h3> | ||
254 | <p> | ||
255 | Tries to flush the code for the specified trace and all of its | ||
256 | side 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> | ||
261 | This mode defines a wrapper function for calls to C functions. The | ||
262 | first time this is called with <tt>LUAJIT_MODE_ON</tt>, the stack | ||
263 | index at <tt>idx</tt> must be a <tt>lightuserdata</tt> object holding | ||
264 | a pointer to the wrapper function. All <b>subsequently created C | ||
265 | functions</b> are called through the wrapper functions. After the initial | ||
266 | definition <tt>idx</tt> can be left at <tt>0</tt> when turning the mode | ||
267 | on or off. | ||
268 | </p> | ||
269 | <p> | ||
270 | The wrapper function can be used for debugging purposes or to catch | ||
271 | and convert foreign exceptions. Recommended usage can be seen in this | ||
272 | C++ code excerpt: | ||
273 | </p> | ||
274 | <pre class="code"> | ||
275 | #include <exception> | ||
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. | ||
280 | static 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 | |||
294 | static 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> | ||
313 | Note that you can only define <b>a single global wrapper function</b>, | ||
314 | so be careful when using this mechanism from multiple C++ modules. | ||
315 | Also note that this mechanism is not without overhead. It should only | ||
316 | be enabled for definitions of C++ functions that can actually throw | ||
317 | exceptions. If you're embedding LuaJIT into an application, only | ||
318 | enable it <b>after</b> running <tt>luaL_openlibs</tt>. | ||
319 | </p> | ||
320 | <p> | ||
321 | LuaJIT already intercepts exception handling for systems using | ||
322 | ELF/DWARF2 stack unwinding (e.g. Linux). This is a zero-cost mechanism | ||
323 | and always enabled. You don't need to use any wrapper functions, | ||
324 | except when you want to get a more specific error message than | ||
325 | <tt>"C++ 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> |
45 | This is a list of changes between the released versions of LuaJIT.<br> | 45 | This is a list of changes between the released versions of LuaJIT.<br> |
46 | The current <span style="color: #c00000;">development version</span> is <strong>LuaJIT 2.0.0-beta1</strong>.<br> | 46 | The current <span style="color: #c00000;">development version</span> is <strong>LuaJIT 2.0.0-beta2</strong>.<br> |
47 | The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT 1.1.5</strong>. | 47 | The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT 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 — 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 | ||
60 | using 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. | ||
72 | Prevent 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 /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 | ||
82 | negative arguments, too.<br> | ||
83 | This 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 — 2009-10-31</h2> | 86 | <h2 id="LuaJIT-2.0.0-beta1">LuaJIT 2.0.0-beta1 — 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 | |||
72 | Search for: <a href="http://scholar.google.com/scholar?q=Dynamic+Language+Optimizations"><span class="ext">»</span> Dynamic Language Optimizations</a><br> | 72 | Search for: <a href="http://scholar.google.com/scholar?q=Dynamic+Language+Optimizations"><span class="ext">»</span> Dynamic Language Optimizations</a><br> |
73 | Search for: <a href="http://scholar.google.com/scholar?q=SSA+Form"><span class="ext">»</span> SSA Form</a><br> | 73 | Search for: <a href="http://scholar.google.com/scholar?q=SSA+Form"><span class="ext">»</span> SSA Form</a><br> |
74 | Search for: <a href="http://scholar.google.com/scholar?q=Linear+Scan+Register+Allocation"><span class="ext">»</span> Linear Scan Register Allocation</a><br> | 74 | Search for: <a href="http://scholar.google.com/scholar?q=Linear+Scan+Register+Allocation"><span class="ext">»</span> Linear Scan Register Allocation</a><br> |
75 | Here is a list of the <a href="http://article.gmane.org/gmane.comp.lang.lua.general/58908"><span class="ext">»</span> innovative features in LuaJIT</a>.<br> | ||
75 | And, you know, reading the source is of course the only way to enlightenment. :-) | 76 | And, 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 | |||
97 | DirectX/Direct3D (up to version 9) sets the x87 FPU to single-precision | ||
98 | mode by default. This violates the Windows ABI and interferes with the | ||
99 | operation of many programs — LuaJIT is affected, too. Please make | ||
100 | sure you always use the <tt>D3DCREATE_FPU_PRESERVE</tt> flag when | ||
101 | initializing Direct3D.<br> | ||
102 | |||
103 | Direct3D version 10 or higher do not show this behavior anymore. | ||
104 | Consider testing your application with older versions, too.<br> | ||
105 | |||
106 | Similarly, the Borland/Delphi runtime modifies the FPU control word and | ||
107 | enables FP exceptions. Of course this violates the Windows ABI, too. | ||
108 | Please 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 |
92 | currently ignored by compiled code (this will eventually be fixed). If | 115 | currently 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> |
60 | The standard configuration should work fine for most installations. | 60 | The standard configuration should work fine for most installations. |
61 | Usually there is no need to tweak the settings, except when you want to | 61 | Usually there is no need to tweak the settings. The following files |
62 | install to a non-standard path. The following three files hold all | 62 | hold all user-configurable settings: |
63 | user-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> |
67 | particular 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 | ||
69 | only).</li> | 67 | only).</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 |
71 | MinGW and Cygwin.</li> | 69 | under 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 |
73 | MSVC.</li> | 71 | MSVC.</li> |
74 | </ul> | 72 | </ul> |
@@ -97,9 +95,8 @@ terminal window and change to this directory. Now unpack the archive | |||
97 | and change to the newly created directory: | 95 | and change to the newly created directory: |
98 | </p> | 96 | </p> |
99 | <pre class="code"> | 97 | <pre class="code"> |
100 | tar zxf LuaJIT-2.0.0-beta1.tar.gz | 98 | tar zxf LuaJIT-2.0.0-beta2.tar.gz |
101 | cd LuaJIT-2.0.0-beta1 | 99 | cd LuaJIT-2.0.0-beta2</pre> |
102 | </pre> | ||
103 | <h3>Building LuaJIT</h3> | 100 | <h3>Building LuaJIT</h3> |
104 | <p> | 101 | <p> |
105 | The supplied Makefiles try to auto-detect the settings needed for your | 102 | The 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"> |
110 | make | 107 | make |
111 | </pre> | 108 | </pre> |
109 | <p> | ||
110 | By default modules are only searched under the prefix <tt>/usr/local</tt>. | ||
111 | You 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"> | ||
115 | make PREFIX=/home/myself/lj2 | ||
116 | </pre> | ||
117 | <p> | ||
118 | Note for OSX: <tt>MACOSX_DEPLOYMENT_TARGET</tt> is set to <tt>10.4</tt> | ||
119 | in <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> |
114 | The top-level Makefile installs LuaJIT by default under | 123 | The top-level Makefile installs LuaJIT by default under |
@@ -124,20 +133,19 @@ sudo make install | |||
124 | Otherwise specify the directory prefix as an absolute path, e.g.: | 133 | Otherwise specify the directory prefix as an absolute path, e.g.: |
125 | </p> | 134 | </p> |
126 | <pre class="code"> | 135 | <pre class="code"> |
127 | sudo make install PREFIX=/opt/lj2 | 136 | make install PREFIX=/home/myself/lj2 |
128 | </pre> | 137 | </pre> |
129 | <p> | 138 | <p> |
130 | But note that the installation prefix and the prefix for the module paths | 139 | Obviously 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;"> |
134 | Note: to avoid overwriting a previous version, the beta test releases | 142 | Note: to avoid overwriting a previous version, the beta test releases |
135 | only install the LuaJIT executable under the versioned name (i.e. | 143 | only 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 |
137 | for convenience, with a command like this: | 145 | for convenience, with a command like this: |
138 | </p> | 146 | </p> |
139 | <pre class="code" style="color: #c00000;"> | 147 | <pre class="code" style="color: #c00000;"> |
140 | sudo ln -sf luajit-2.0.0-beta1 /usr/local/bin/luajit | 148 | sudo ln -sf luajit-2.0.0-beta2 /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> |
146 | Either install one of the open source SDKs | 154 | Either install one of the open source SDKs |
147 | (<a href="http://mingw.org/"><span class="ext">»</span> MinGW</a> or | 155 | (<a href="http://mingw.org/"><span class="ext">»</span> MinGW</a> or |
148 | <a href="http://www.cygwin.com/"><span class="ext">»</span> Cygwin</a>) which come with modified | 156 | <a href="http://www.cygwin.com/"><span class="ext">»</span> Cygwin</a>), which come with a modified |
149 | versions of GCC plus the required development headers. | 157 | GCC plus the required development headers. |
150 | </p> | 158 | </p> |
151 | <p> | 159 | <p> |
152 | Or install Microsoft's Visual C++ (MSVC) — the freely downloadable | 160 | Or install Microsoft's Visual C++ (MSVC) — 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> |
162 | Open a "Visual Studio .NET Command Prompt" and <tt>cd</tt> to the | 170 | Open a "Visual Studio .NET Command Prompt", <tt>cd</tt> to the |
163 | directory where you've unpacked the sources. Then run this command: | 171 | directory where you've unpacked the sources and run these commands: |
164 | </p> | 172 | </p> |
165 | <pre class="code"> | 173 | <pre class="code"> |
166 | cd src | 174 | cd src |
@@ -176,14 +184,12 @@ are in your path. Then <tt>cd</tt> to the directory where | |||
176 | you've unpacked the sources and run this command for MinGW: | 184 | you've unpacked the sources and run this command for MinGW: |
177 | </p> | 185 | </p> |
178 | <pre class="code"> | 186 | <pre class="code"> |
179 | cd src | ||
180 | mingw32-make | 187 | mingw32-make |
181 | </pre> | 188 | </pre> |
182 | <p> | 189 | <p> |
183 | Or this command for Cygwin: | 190 | Or this command for Cygwin: |
184 | </p> | 191 | </p> |
185 | <pre class="code"> | 192 | <pre class="code"> |
186 | cd src | ||
187 | make | 193 | make |
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> |
194 | Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt> | 200 | Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt> (built in the <tt>src</tt> |
195 | to a newly created directory (any location is ok). Add <tt>lua</tt> | 201 | directory) to a newly created directory (any location is ok). |
196 | and <tt>lua\jit</tt> directories below it and copy all Lua files | 202 | Add <tt>lua</tt> and <tt>lua\jit</tt> directories below it and copy |
197 | from the <tt>lib</tt> directory of the distribution to the latter directory. | 203 | all Lua files from the <tt>lib</tt> directory of the distribution |
204 | to the latter directory. | ||
198 | </p> | 205 | </p> |
199 | <p> | 206 | <p> |
200 | There are no hardcoded | 207 | There 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;"> |
70 | Note: the beta test releases only install under the versioned name on | 70 | Note: the beta test releases only install under the versioned name on |
71 | POSIX systems (to avoid overwriting a previous version). You either need | 71 | POSIX systems (to avoid overwriting a previous version). You either need |
72 | to type <tt>luajit-2.0.0-beta1</tt> to start it or create a symlink | 72 | to type <tt>luajit-2.0.0-beta2</tt> to start it or create a symlink |
73 | with a command like this: | 73 | with a command like this: |
74 | </p> | 74 | </p> |
75 | <pre class="code" style="color: #c00000;"> | 75 | <pre class="code" style="color: #c00000;"> |
76 | sudo ln -sf luajit-2.0.0-beta1 /usr/local/bin/luajit | 76 | sudo ln -sf luajit-2.0.0-beta2 /usr/local/bin/luajit |
77 | </pre> | 77 | </pre> |
78 | <p> | 78 | <p> |
79 | Unlike previous versions <b>optimization is turned on by default</b> in | 79 | Unlike 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 | |||
119 | read the comment block at the start of their source. | 119 | read the comment block at the start of their source. |
120 | They can be found in the <tt>lib</tt> directory of the source | 120 | They can be found in the <tt>lib</tt> directory of the source |
121 | distribution or installed under the <tt>jit</tt> directory. By default | 121 | distribution or installed under the <tt>jit</tt> directory. By default |
122 | this is <tt>/usr/local/share/luajit-2.0.0-beta1/jit</tt> on POSIX | 122 | this is <tt>/usr/local/share/luajit-2.0.0-beta2/jit</tt> on POSIX |
123 | systems. | 123 | systems. |
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> |
92 | The Lua <b>debug API</b> is missing a couple of features (call/return | 92 | The Lua <b>debug API</b> is missing a couple of features (call/return |
93 | hooks) and shows slightly different behavior (no per-coroutine hooks). | 93 | hooks) and shows slightly different behavior (no per-coroutine hooks, |
94 | no tail call counting). | ||
95 | </li> | ||
96 | <li> | ||
97 | <b>Bytecode</b> currently cannot be loaded or dumped. Note that | ||
98 | the bytecode format differs from Lua 5.1 — loading foreign | ||
99 | bytecode is not supported at all. | ||
100 | </li> | ||
101 | <li> | ||
102 | Some of the <b>configuration options</b> of Lua 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> | ||
106 | to enable line editing. It's planned to add support for loading it | ||
107 | on-demand.</li> | ||
108 | </ul> | ||
94 | </li> | 109 | </li> |
95 | <li> | 110 | <li> |
96 | Most other issues you're likely to find (e.g. with the existing test | 111 | Most 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> |
106 | The <b>JIT compiler</b> is not complete (yet) and falls back to the | 121 | The <b>JIT compiler</b> is not complete (yet) and falls back to the |
107 | interpreter in some cases. All of this works transparently, so unless | 122 | interpreter in some cases. All of this works transparently, so unless |
108 | you use -jv, you'll probably never notice (the interpreter is quite | 123 | you use <tt>-jv</tt>, you'll probably never notice (the interpreter is quite |
109 | fast, too). Here are the known issues: | 124 | fast, 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 |
122 | all or some unroll limit will catch it and aborts the trace. | 137 | all or some unroll limit will catch it and abort the trace. |
123 | </li> | 138 | </li> |
124 | <li> | 139 | <li> |
125 | The trace compiler currently does not back off specialization for | 140 | The 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 | ||
3 | luajit \- 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 | ||
12 | This 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. | ||
15 | The virtual machine (VM) is based on a fast interpreter combined with | ||
16 | a 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 | ||
19 | Lua\ 5.1 interpreter. When embedding the VM into an application, | ||
20 | the built library can be used as a drop-in replacement. | ||
21 | .SH OPTIONS | ||
22 | .TP | ||
23 | .BI "\-e " chunk | ||
24 | Run the given chunk of Lua code. | ||
25 | .TP | ||
26 | .BI "\-l " library | ||
27 | Load the named library, just like \fBrequire("\fR\fIlibrary\fR\fB")\fR. | ||
28 | .TP | ||
29 | .BI "\-j " command | ||
30 | Perform LuaJIT control command (optional space after \fB\-j\fR). | ||
31 | .TP | ||
32 | .BI "\-O" [opt] | ||
33 | Control LuaJIT optimizations. | ||
34 | .TP | ||
35 | .B "\-i" | ||
36 | Run in interactive mode. | ||
37 | .TP | ||
38 | .B "\-v" | ||
39 | Show \fBLuaJIT\fR version. | ||
40 | .TP | ||
41 | .B "\-\-" | ||
42 | Stop processing options. | ||
43 | .TP | ||
44 | .B "\-" | ||
45 | Read script from stdin instead. | ||
46 | .PP | ||
47 | After all options are processed, the given \fIscript\fR is run. | ||
48 | The arguments are passed in the global \fIarg\fR table. | ||
49 | .PP | ||
50 | Interactive mode is only entered, if no \fIscript\fR and no \fB\-e\fR | ||
51 | option is given. Interactive mode can be left with EOF (\fICtrl\-Z\fB). | ||
52 | .SH EXAMPLES | ||
53 | .TP | ||
54 | luajit hello.lua world | ||
55 | |||
56 | Prints "Hello world", assuming \fIhello.lua\fR contains: | ||
57 | .br | ||
58 | print("Hello", arg[1]) | ||
59 | .TP | ||
60 | luajit \-e "local x=0; for i=1,1e9 do x=x+i end; print(x)" | ||
61 | |||
62 | Calculates the sum of the numbers from 1 to 1000000000. | ||
63 | .br | ||
64 | And finishes in a reasonable amount of time, too. | ||
65 | .TP | ||
66 | luajit \-jv \-e "for i=1,10 do for j=1,10 do for k=1,100 do end end end" | ||
67 | |||
68 | Runs 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 | ||
76 | More details in the provided HTML docs or at: | ||
77 | .IR http://luajit.org | ||
78 | .br | ||
79 | More about the Lua language can be found at: | ||
80 | .IR http://lua.org/docs.html | ||
81 | .PP | ||
82 | lua(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. | ||
2 | majver=2 | ||
3 | minver=0 | ||
4 | relver=0 | ||
5 | version=${majver}.${minver}.${relver}-beta2 | ||
6 | abiver=5.1 | ||
7 | |||
8 | prefix=/usr/local | ||
9 | exec_prefix=${prefix} | ||
10 | libdir=${exec_prefix}/lib | ||
11 | libname=luajit-${abiver} | ||
12 | includedir=${prefix}/include/luajit-${majver}.${minver} | ||
13 | |||
14 | INSTALL_LMOD=${prefix}/share/lua/${abiver} | ||
15 | INSTALL_CMOD=${prefix}/lib/lua/${abiver} | ||
16 | |||
17 | Name: LuaJIT | ||
18 | Description: Just-in-time compiler for Lua | ||
19 | URL: http://luajit.org | ||
20 | Version: ${version} | ||
21 | Requires: | ||
22 | Libs: -L${libdir} -l${libname} | ||
23 | Libs.private: -Wl,-E -lm -ldl | ||
24 | Cflags: -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 | ||
11 | MAJVER= 2 | ||
12 | MINVER= 0 | ||
13 | RELVER= 0 | ||
14 | ABIVER= 5.1 | ||
15 | NODOTABIVER= 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. | ||
97 | BUILDMODE= 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 | |||
87 | CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(CFLAGS) $(XCFLAGS) | 113 | CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(CFLAGS) $(XCFLAGS) |
88 | LDOPTIONS= $(CCDEBUG) $(LDFLAGS) | 114 | LDOPTIONS= $(CCDEBUG) $(LDFLAGS) |
89 | 115 | ||
90 | HOST_CC= $(CC) | 116 | HOST_CC= $(CC) |
91 | HOST_RM= rm -f | 117 | HOST_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. | ||
122 | HOST_LUA= lua | ||
123 | |||
92 | HOST_XCFLAGS= | 124 | HOST_XCFLAGS= |
93 | HOST_XLDFLAGS= | 125 | HOST_XLDFLAGS= |
94 | HOST_XLIBS= | 126 | HOST_XLIBS= |
127 | HOST_CFLAGS= $(CCOPTIONS) $(HOST_XCFLAGS) $(TARGET_ARCH) | ||
128 | HOST_LDFLAGS= $(LDOPTIONS) $(HOST_XLDFLAGS) | ||
129 | HOST_LIBS= $(HOST_XLIBS) | ||
130 | |||
131 | # Cross-compilation example: make CROSS=i586-mingw32msvc- TARGET_SYS=Windows | ||
132 | CROSS= | ||
133 | STATIC_CC = $(CROSS)$(CC) | ||
134 | DYNAMIC_CC = $(CROSS)$(CC) -fPIC | ||
135 | TARGET_CC= $(STATIC_CC) | ||
136 | TARGET_STCC= $(STATIC_CC) | ||
137 | TARGET_DYNCC= $(DYNAMIC_CC) | ||
138 | TARGET_LD= $(CROSS)$(CC) | ||
139 | TARGET_AR= $(CROSS)ar rcus | ||
140 | TARGET_STRIP= $(CROSS)strip | ||
141 | |||
142 | TARGET_SONAME= libluajit-$(ABIVER).so.$(MAJVER) | ||
143 | TARGET_DYLIBNAME= libluajit-$(NODOTABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib | ||
144 | TARGET_DLLNAME= lua$(NODOTABIVER).dll | ||
145 | TARGET_XSHLDFLAGS= -shared -fPIC -Wl,-soname,$(TARGET_SONAME) | ||
146 | TARGET_DYNXLDOPTS= | ||
95 | 147 | ||
96 | TARGET_CC= $(CC) | ||
97 | TARGET_STRIP= strip | ||
98 | TARGET_XCFLAGS= -D_FILE_OFFSET_BITS=64 | ||
99 | TARGET_XLDFLAGS= | ||
100 | TARGET_XSHLDFLAGS= -shared | ||
101 | TARGET_XLIBS= | ||
102 | TARGET_ARCH= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET)) | 148 | TARGET_ARCH= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET)) |
103 | TARGET_DISABLE= -U_FORTIFY_SOURCE | 149 | TARGET_DISABLE= -U_FORTIFY_SOURCE |
104 | ifneq (,$(findstring stack-protector,$(shell $(CC) -dumpspecs))) | 150 | ifneq (,$(findstring stack-protector,$(shell $(TARGET_CC) -dumpspecs))) |
105 | TARGET_DISABLE+= -fno-stack-protector | 151 | TARGET_DISABLE+= -fno-stack-protector |
106 | endif | 152 | endif |
107 | 153 | ||
154 | TARGET_XCFLAGS= -D_FILE_OFFSET_BITS=64 | ||
155 | TARGET_XLDFLAGS= | ||
156 | TARGET_XLDOPTS= | ||
157 | TARGET_XLIBS= | ||
158 | TARGET_CFLAGS= $(CCOPTIONS) $(TARGET_DISABLE) $(TARGET_XCFLAGS) | ||
159 | TARGET_LDFLAGS= $(LDOPTIONS) $(TARGET_XLDFLAGS) $(TARGET_XLDOPTS) | ||
160 | TARGET_SHLDFLAGS= $(LDOPTIONS) $(TARGET_XSHLDFLAGS) | ||
161 | TARGET_LIBS= -lm $(TARGET_XLIBS) | ||
162 | |||
163 | ifneq (,$(PREFIX)) | ||
164 | ifneq (/usr/local,$(PREFIX)) | ||
165 | TARGET_XCFLAGS+= -DLUA_XROOT=\"$(PREFIX)/\" | ||
166 | ifneq (/usr,$(PREFIX)) | ||
167 | TARGET_DYNXLDOPTS= -Wl,-rpath,$(PREFIX)/lib | ||
168 | endif | ||
169 | endif | ||
170 | endif | ||
171 | |||
172 | ############################################################################## | ||
173 | # System detection. | ||
174 | ############################################################################## | ||
175 | |||
108 | ifneq (,$(findstring Windows,$(OS))) | 176 | ifneq (,$(findstring Windows,$(OS))) |
109 | TARGET_SYS= Windows | 177 | HOST_SYS= Windows |
110 | else | 178 | else |
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 |
115 | endif | 183 | endif |
184 | ifeq (Windows,$(HOST_SYS)) | ||
185 | HOST_RM= del | ||
186 | endif | ||
116 | 187 | ||
117 | ifeq (Linux,$(TARGET_SYS)) | 188 | TARGET_SYS= $(HOST_SYS) |
118 | TARGET_XLIBS= -ldl | ||
119 | TARGET_XLDFLAGS= -Wl,-E | ||
120 | else | ||
121 | ifeq (Windows,$(TARGET_SYS)) | 189 | ifeq (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= | ||
124 | else | 193 | else |
125 | ifeq (Darwin,$(TARGET_SYS)) | 194 | ifeq (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 | ||
129 | else | 203 | else |
130 | TARGET_XLDFLAGS= -Wl,-E | 204 | TARGET_XLDFLAGS= -Wl,-E |
205 | ifeq (Linux,$(TARGET_SYS)) | ||
206 | TARGET_XLIBS= -ldl | ||
207 | endif | ||
131 | endif | 208 | endif |
132 | endif | 209 | endif |
133 | endif | ||
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. | ||
139 | DASM_LUA= lua | ||
140 | |||
141 | Q= @ | ||
142 | E= @echo | ||
143 | #Q= | ||
144 | #E= @: | ||
145 | |||
146 | ############################################################################## | ||
147 | 210 | ||
148 | TARGET_CFLAGS= $(CCOPTIONS) $(TARGET_DISABLE) $(TARGET_XCFLAGS) | ||
149 | TARGET_LDFLAGS= $(LDOPTIONS) $(TARGET_XLDFLAGS) | ||
150 | TARGET_SHLDFLAGS= $(LDOPTIONS) $(TARGET_XSHLDFLAGS) | ||
151 | TARGET_LIBS= -lm $(TARGET_XLIBS) | ||
152 | ifneq (,$(CCDEBUG)) | 211 | ifneq (,$(CCDEBUG)) |
153 | TARGET_STRIP= @: | 212 | TARGET_STRIP= @: |
154 | endif | 213 | endif |
155 | 214 | ||
156 | HOST_CFLAGS= $(CCOPTIONS) $(HOST_XCFLAGS) $(TARGET_ARCH) | 215 | ############################################################################## |
157 | HOST_LDFLAGS= $(LDOPTIONS) $(HOST_XLDFLAGS) | 216 | # Files and pathnames. |
158 | HOST_LIBS= $(HOST_XLIBS) | 217 | ############################################################################## |
159 | 218 | ||
160 | DASM_DIR= ../dynasm | 219 | DASM_DIR= ../dynasm |
161 | DASM= $(DASM_LUA) $(DASM_DIR)/dynasm.lua | 220 | DASM= $(HOST_LUA) $(DASM_DIR)/dynasm.lua |
162 | DASM_FLAGS= | 221 | DASM_FLAGS= |
163 | DASM_DISTFLAGS= -LN | 222 | DASM_DISTFLAGS= -LN |
164 | 223 | ||
165 | BUILDVM_O= buildvm.o buildvm_asm.o buildvm_peobj.o buildvm_lib.o buildvm_fold.o | 224 | BUILDVM_O= buildvm.o buildvm_asm.o buildvm_peobj.o buildvm_lib.o buildvm_fold.o |
166 | BUILDVM_T= buildvm | 225 | BUILDVM_T= buildvm |
226 | BUILDVM_X= ./$(BUILDVM_T) | ||
167 | 227 | ||
168 | HOST_O= $(BUILDVM_O) | 228 | HOST_O= $(BUILDVM_O) |
169 | HOST_T= $(BUILDVM_T) | 229 | HOST_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 | ||
190 | LJVMCORE_O= $(LJVM_O) $(LJCORE_O) | 250 | LJVMCORE_O= $(LJVM_O) $(LJCORE_O) |
251 | LJVMCORE_DYNO= $(LJVMCORE_O:.o=_dyn.o) | ||
252 | |||
253 | LIB_VMDEF= ../lib/vmdef.lua | ||
254 | LIB_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. | ||
194 | LUAJIT_O= luajit.o | 256 | LUAJIT_O= luajit.o |
195 | LUAJIT_SO= luajit.so | 257 | LUAJIT_A= libluajit.a |
258 | LUAJIT_SO= libluajit.so | ||
196 | LUAJIT_T= luajit | 259 | LUAJIT_T= luajit |
197 | 260 | ||
198 | LIB_VMDEF= ../lib/vmdef.lua | 261 | ALL_T= $(LUAJIT_T) $(LUAJIT_A) $(LUAJIT_SO) $(BUILDVM_T) |
262 | ALL_GEN= $(LJVM_S) lj_ffdef.h lj_libdef.h lj_recdef.h $(LIB_VMDEFP) lj_folddef.h | ||
263 | ALL_DYNGEN= buildvm_x86.h | ||
264 | WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest *.pdb *.ilk | ||
265 | ALL_RM= $(ALL_T) $(ALL_GEN) *.o $(WIN_RM) | ||
199 | 266 | ||
200 | TARGET_DEP= $(LIB_VMDEF) | 267 | ############################################################################## |
201 | TARGET_O= $(LJVMCORE_O) $(LUAJIT_O) | 268 | # Build mode handling. |
202 | TARGET_T= $(LUAJIT_T) | 269 | ############################################################################## |
203 | 270 | ||
204 | ALL_GEN= $(LJVM_S) lj_ffdef.h lj_libdef.h lj_recdef.h $(LIB_VMDEF) lj_folddef.h | 271 | # Mixed mode defaults. |
205 | ALL_DYNGEN= buildvm_x86.h | 272 | TARGET_O= $(LUAJIT_A) |
206 | WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest | 273 | TARGET_T= $(LUAJIT_T) $(LUAJIT_SO) |
207 | ALL_RM= $(LUAJIT_T) $(LUAJIT_SO) $(HOST_T) $(ALL_GEN) *.o $(WIN_RM) | 274 | TARGET_DEP= $(LIB_VMDEF) $(LUAJIT_SO) |
208 | 275 | ||
276 | ifeq (Windows,$(HOST_SYS)) | ||
277 | BUILDVM_T= buildvm.exe | ||
278 | LIB_VMDEFP= $(subst /,\\,$(LIB_VMDEF)) | ||
279 | endif | ||
209 | ifeq (Windows,$(TARGET_SYS)) | 280 | ifeq (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 | ||
224 | endif | 295 | endif |
225 | 296 | ||
226 | ############################################################################## | 297 | ifeq (static,$(BUILDMODE)) |
298 | TARGET_DYNCC= @: | ||
299 | TARGET_T= $(LUAJIT_T) | ||
300 | TARGET_DEP= $(LIB_VMDEF) | ||
301 | else | ||
302 | ifeq (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) | ||
308 | else | ||
309 | ifeq (Darwin,$(TARGET_SYS)) | ||
310 | TARGET_DYNCC= @: | ||
311 | LJVMCORE_DYNO= $(LJVMCORE_O) | ||
312 | endif | ||
313 | endif | ||
314 | endif | ||
227 | 315 | ||
228 | default: $(TARGET_T) | 316 | Q= @ |
317 | E= @echo | ||
318 | #Q= | ||
319 | #E= @: | ||
229 | 320 | ||
230 | all: $(TARGET_T) | 321 | ############################################################################## |
322 | # Make targets. | ||
323 | ############################################################################## | ||
324 | |||
325 | default all: $(TARGET_T) | ||
231 | 326 | ||
232 | amalg: | 327 | amalg: |
233 | @grep "^[+|]" ljamalg.c | 328 | @grep "^[+|]" ljamalg.c |
234 | $(MAKE) all "LJCORE_O=ljamalg.o" | 329 | $(MAKE) all "LJCORE_O=ljamalg.o" |
235 | 330 | ||
236 | MAKE_TARGETS= amalg | 331 | clean: |
332 | $(HOST_RM) $(ALL_RM) | ||
333 | |||
334 | cleaner: | ||
335 | $(HOST_RM) $(ALL_RM) $(ALL_DYNGEN) | ||
336 | |||
337 | distclean: clean | ||
338 | $(E) "DYNASM $@" | ||
339 | $(Q)$(DASM) $(DASM_DISTFLAGS) -o buildvm_x86.h buildvm_x86.dasc | ||
340 | |||
341 | depend: | ||
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 | ||
240 | buildvm_x86.h: buildvm_x86.dasc | 360 | buildvm_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 | ||
252 | lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C) | 372 | lj_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 | ||
256 | lj_libdef.h: $(BUILDVM_T) $(LJLIB_C) | 376 | lj_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 | ||
260 | lj_recdef.h: $(BUILDVM_T) $(LJLIB_C) | 380 | lj_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 | ||
268 | lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c | 388 | lj_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 | |||
297 | include Makefile.dep | 414 | include Makefile.dep |
298 | 415 | ||
299 | ############################################################################## | 416 | ############################################################################## |
417 | # Target file rules. | ||
418 | ############################################################################## | ||
300 | 419 | ||
301 | clean: | 420 | $(LUAJIT_A): $(LJVMCORE_O) |
302 | $(HOST_RM) $(ALL_RM) | 421 | $(E) "AR $@" |
303 | 422 | $(Q)$(TARGET_AR) $@ $(LJVMCORE_O) | |
304 | cleaner: clean | ||
305 | $(HOST_RM) $(ALL_DYNGEN) | ||
306 | 423 | ||
307 | distclean: 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) | |
311 | depend: | 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 \ | |||
34 | lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ | 34 | lib_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 |
36 | lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ | 36 | lib_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 |
39 | lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ | 39 | lib_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 | |||
29 | LUALIB_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 | |||
35 | LUALIB_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 | |||
41 | LUALIB_API void luaL_checkany(lua_State *L, int narg) | ||
42 | { | ||
43 | lj_lib_checkany(L, narg); | ||
44 | } | ||
45 | |||
46 | LUALIB_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 | |||
53 | LUALIB_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 | |||
65 | LUALIB_API lua_Number luaL_checknumber(lua_State *L, int narg) | ||
66 | { | ||
67 | return lj_lib_checknum(L, narg); | ||
68 | } | ||
69 | |||
70 | LUALIB_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 | |||
79 | LUALIB_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 | |||
88 | LUALIB_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 | |||
101 | LUALIB_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 | ||
116 | LUALIB_API const char *luaL_findtable(lua_State *L, int idx, | 25 | LUALIB_API const char *luaL_findtable(lua_State *L, int idx, |
@@ -149,6 +58,7 @@ static int libsize(const luaL_Reg *l) | |||
149 | LUALIB_API void luaL_openlib(lua_State *L, const char *libname, | 58 | LUALIB_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 | |||
288 | LUALIB_API int luaL_ref(lua_State *L, int t) | 202 | LUALIB_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 | ||
524 | LUALIB_API int luaopen_io(lua_State *L) | 524 | LUALIB_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) | |||
69 | LJLIB_PUSH(3.14159265358979323846) LJLIB_SET(pi) | 69 | LJLIB_PUSH(3.14159265358979323846) LJLIB_SET(pi) |
70 | LJLIB_PUSH(1e310) LJLIB_SET(huge) | 70 | LJLIB_PUSH(1e310) LJLIB_SET(huge) |
71 | 71 | ||
72 | #ifdef __MACH__ | ||
73 | LJ_FUNCA double lj_wrapper_sinh(double x) { return sinh(x); } | 72 | LJ_FUNCA double lj_wrapper_sinh(double x) { return sinh(x); } |
74 | LJ_FUNCA double lj_wrapper_cosh(double x) { return cosh(x); } | 73 | LJ_FUNCA double lj_wrapper_cosh(double x) { return cosh(x); } |
75 | LJ_FUNCA double lj_wrapper_tanh(double x) { return tanh(x); } | 74 | LJ_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. */ |
102 | static double tw223_step(TW223State *tw) | 100 | static 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) | |||
774 | LUALIB_API int luaopen_string(lua_State *L) | 775 | LUALIB_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 | ||
91 | LJLIB_CF(table_insert) | 91 | LJLIB_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 | ||
120 | LJLIB_CF(table_remove) | 120 | LJLIB_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 | ||
142 | LJLIB_CF(table_concat) | 142 | LJLIB_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 | ||
94 | LUALIB_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 | |||
94 | LUA_API void lua_xmove(lua_State *from, lua_State *to, int n) | 100 | LUA_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 | ||
202 | LUALIB_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 | |||
208 | LUALIB_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 | |||
196 | LUA_API const char *lua_typename(lua_State *L, int t) | 214 | LUA_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) | |||
202 | LUA_API int lua_iscfunction(lua_State *L, int idx) | 220 | LUA_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 | ||
208 | LUA_API int lua_isnumber(lua_State *L, int idx) | 226 | LUA_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 | ||
316 | LUALIB_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 | |||
327 | LUALIB_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 | |||
298 | LUA_API lua_Integer lua_tointeger(lua_State *L, int idx) | 340 | LUA_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 | ||
358 | LUALIB_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 | |||
376 | LUALIB_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 | |||
316 | LUA_API int lua_toboolean(lua_State *L, int idx) | 396 | LUA_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 | ||
420 | LUALIB_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 | |||
437 | LUALIB_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 | |||
458 | LUALIB_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 | |||
340 | LUA_API size_t lua_objlen(lua_State *L, int idx) | 471 | LUA_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) | |||
355 | LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx) | 486 | LUA_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 | ||
361 | LUA_API void *lua_touserdata(lua_State *L, int idx) | 493 | LUA_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__) | ||
769 | typedef 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 | |||
788 | extern void *_Unwind_GetCFA(void *ctx); | ||
789 | extern void _Unwind_DeleteException(void *uex); | ||
790 | |||
791 | /* DWARF2 personality handler referenced from .eh_frame. */ | ||
792 | LJ_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. */ |
9 | ERRDEF(ERRMEM, "not enough memory") | 9 | ERRDEF(ERRMEM, "not enough memory") |
10 | ERRDEF(ERRERR, "error in error handling") | 10 | ERRDEF(ERRERR, "error in error handling") |
11 | ERRDEF(ERRCPP, "C++ exception") | ||
11 | 12 | ||
12 | /* Allocations. */ | 13 | /* Allocations. */ |
13 | ERRDEF(STROV, "string length overflow") | 14 | ERRDEF(STROV, "string length overflow") |
@@ -56,6 +57,9 @@ ERRDEF(NOENV, "no calling environment") | |||
56 | ERRDEF(CYIELD, "attempt to yield across C-call boundary") | 57 | ERRDEF(CYIELD, "attempt to yield across C-call boundary") |
57 | ERRDEF(BADLU, "bad light userdata pointer") | 58 | ERRDEF(BADLU, "bad light userdata pointer") |
58 | ERRDEF(NOGCMM, "bad action while in __gc metamethod") | 59 | ERRDEF(NOGCMM, "bad action while in __gc metamethod") |
60 | #ifdef LUA_USE_WIN | ||
61 | ERRDEF(BADFPU, "bad FPU precision (use D3DCREATE_FPU_PRESERVE with DirectX)") | ||
62 | #endif | ||
59 | 63 | ||
60 | /* Standard library function errors. */ | 64 | /* Standard library function errors. */ |
61 | ERRDEF(ASSERT, "assertion failed!") | 65 | ERRDEF(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 | ||
985 | LJFOLD(LT any any) | 985 | LJFOLD(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 | ||
1019 | LJFOLD(BXOR any any) | 1019 | LJFOLD(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)); |
452 | nocheck: | 452 | nocheck: |
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 | ||
883 | LJ_NORET static void recff_err_ffu(jit_State *J, RecordFFData *rd) | 885 | LJ_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 | ||
1343 | static 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 | |||
1374 | static 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. */ |
195 | void lj_trace_flush(jit_State *J, TraceNo traceno) | 195 | static 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. */ | ||
224 | int 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. */ |
231 | void lj_trace_flushproto(global_State *g, GCproto *pt) | 242 | void 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); | |||
26 | LJ_FUNC void lj_trace_freeproto(global_State *g, GCproto *pt); | 26 | LJ_FUNC void lj_trace_freeproto(global_State *g, GCproto *pt); |
27 | LJ_FUNC void lj_trace_reenableproto(GCproto *pt); | 27 | LJ_FUNC void lj_trace_reenableproto(GCproto *pt); |
28 | LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt); | 28 | LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt); |
29 | LJ_FUNC void lj_trace_flush(jit_State *J, TraceNo traceno); | 29 | LJ_FUNC int lj_trace_flush(jit_State *J, TraceNo traceno); |
30 | LJ_FUNC int lj_trace_flushall(lua_State *L); | 30 | LJ_FUNC int lj_trace_flushall(lua_State *L); |
31 | LJ_FUNC void lj_trace_freestate(global_State *g); | 31 | LJ_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); | |||
46 | LJ_ASMF void lj_gate_lf(void); | 46 | LJ_ASMF void lj_gate_lf(void); |
47 | LJ_ASMF void lj_gate_lv(void); | 47 | LJ_ASMF void lj_gate_lv(void); |
48 | LJ_ASMF void lj_gate_c(void); | 48 | LJ_ASMF void lj_gate_c(void); |
49 | LJ_ASMF void lj_gate_cwrap(void); | ||
49 | 50 | ||
50 | /* Continuations for metamethods. */ | 51 | /* Continuations for metamethods. */ |
51 | LJ_ASMF void lj_cont_cat(void); /* Continue with concatenation. */ | 52 | LJ_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. */ | |||
55 | LJ_ASMF void lj_cont_condf(void); /* Branch if result is false. */ | 56 | LJ_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. */ |
58 | LJ_ASMF void lj_vm_asm_begin(void); | 59 | LJ_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. */ |
61 | LJ_ASMF const uint16_t lj_vm_op_ofs[]; | 62 | LJ_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 | ||
5 | extern "C" { | 3 | extern "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) | |||
55 | static void print_usage(void) | 55 | static 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 | ||
149 | static int getargs(lua_State *L, char **argv, int n) | 149 | static 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. */ |