RELEASE LuaJIT-2.0.0-beta2

This commit is contained in:
Mike Pall 2009-12-08 19:49:20 +01:00
parent 55b1695971
commit 1d1fed48a0
46 changed files with 1289 additions and 441 deletions

56
COPYRIGHT Normal file
View File

@ -0,0 +1,56 @@
===============================================================================
LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
Copyright (C) 2005-2009 Mike Pall. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
===============================================================================
[ LuaJIT includes code from Lua 5.1, which has this license statement: ]
Copyright (C) 1994-2008 Lua.org, PUC-Rio.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================================================
[ LuaJIT includes code from dlmalloc, which has this license statement: ]
This is a version (aka dlmalloc) of malloc/free/realloc written by
Doug Lea and released to the public domain, as explained at
http://creativecommons.org/licenses/publicdomain
===============================================================================

View File

@ -12,46 +12,104 @@
# Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h # Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h
############################################################################## ##############################################################################
BASEVER= 2.0.0 MAJVER= 2
VERSION= 2.0.0-beta1 MINVER= 0
RELVER= 0
PREREL= -beta2
VERSION= $(MAJVER).$(MINVER).$(RELVER)$(PREREL)
ABIVER= 5.1
NODOTABIVER= 51
############################################################################## ##############################################################################
# #
# Change the installation path as needed and modify src/luaconf.h accordingly. # Change the installation path as needed and modify src/luaconf.h accordingly.
# Note: PREFIX must be an absolute path! # Note: PREFIX must be an absolute path!
# #
PREFIX= /usr/local export PREFIX= /usr/local
############################################################################## ##############################################################################
INSTALL_BIN= $(PREFIX)/bin DPREFIX= $(DESTDIR)$(PREFIX)
INSTALL_NAME= luajit-$(VERSION) INSTALL_BIN= $(DPREFIX)/bin
INSTALL_T= $(INSTALL_BIN)/$(INSTALL_NAME) INSTALL_LIB= $(DPREFIX)/lib
INSTALL_TSYM= $(INSTALL_BIN)/luajit INSTALL_SHARE= $(DPREFIX)/share
INSTALL_INC= $(PREFIX)/include/luajit-$(BASEVER) INSTALL_INC= $(DPREFIX)/include/luajit-$(MAJVER).$(MINVER)
INSTALL_JITLIB= $(PREFIX)/share/luajit-$(VERSION)/jit
INSTALL_JITLIB= $(INSTALL_SHARE)/luajit-$(VERSION)/jit
INSTALL_LMOD= $(INSTALL_SHARE)/lua/$(ABIVER)
INSTALL_CMOD= $(INSTALL_LIB)/lua/$(ABIVER)
INSTALL_MAN= $(INSTALL_SHARE)/man/man1
INSTALL_PKGCONFIG= $(INSTALL_LIB)/pkgconfig
INSTALL_TNAME= luajit-$(VERSION)
INSTALL_TSYMNAME= luajit
INSTALL_ANAME= libluajit-$(ABIVER).a
INSTALL_SONAME= libluajit-$(ABIVER).so.$(MAJVER).$(MINVER).$(RELVER)
INSTALL_SOSHORT= libluajit-$(ABIVER).so
INSTALL_DYLIBNAME= libluajit-$(NODOTABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib
INSTALL_DYLIBSHORT1= libluajit-$(NODOTABIVER).dylib
INSTALL_DYLIBSHORT2= libluajit-$(NODOTABIVER).$(MAJVER).dylib
INSTALL_PCNAME= luajit.pc
INSTALL_STATIC= $(INSTALL_LIB)/$(INSTALL_ANAME)
INSTALL_DYN= $(INSTALL_LIB)/$(INSTALL_SONAME)
INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_SOSHORT)
INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_SOSHORT)
INSTALL_T= $(INSTALL_BIN)/$(INSTALL_TNAME)
INSTALL_TSYM= $(INSTALL_BIN)/$(INSTALL_TSYMNAME)
INSTALL_PC= $(INSTALL_PKGCONFIG)/$(INSTALL_PCNAME)
INSTALL_DIRS= $(INSTALL_BIN) $(INSTALL_LIB) $(INSTALL_INC) $(INSTALL_MAN) \
$(INSTALL_PKGCONFIG) $(INSTALL_JITLIB) $(INSTALL_LMOD) $(INSTALL_CMOD)
RM= rm -f
MKDIR= mkdir -p MKDIR= mkdir -p
SYMLINK= ln -f -s SYMLINK= ln -sf
INSTALL_X= install -m 0755 INSTALL_X= install -m 0755
INSTALL_F= install -m 0644 INSTALL_F= install -m 0644
LDCONFIG= ldconfig -n
SED_PC= sed -e "s|^prefix=.*|prefix=$(PREFIX)|"
FILES_T= luajit FILE_T= luajit
FILE_A= libluajit.a
FILE_SO= libluajit.so
FILE_MAN= luajit.1
FILE_PC= luajit.pc
FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h FILES_INC= lua.h lualib.h lauxlib.h luaconf.h lua.hpp luajit.h
FILES_JITLIB= bc.lua v.lua dump.lua dis_x86.lua dis_x64.lua vmdef.lua FILES_JITLIB= bc.lua v.lua dump.lua dis_x86.lua dis_x64.lua vmdef.lua
ifeq (,$(findstring Windows,$(OS)))
ifeq (Darwin,$(shell uname -s))
INSTALL_SONAME= $(INSTALL_DYLIBNAME)
INSTALL_SHORT1= $(INSTALL_LIB)/$(INSTALL_DYLIBSHORT1)
INSTALL_SHORT2= $(INSTALL_LIB)/$(INSTALL_DYLIBSHORT2)
LDCONFIG= :
endif
endif
############################################################################## ##############################################################################
INSTALL_DEP= src/luajit INSTALL_DEP= src/luajit
all $(INSTALL_DEP): default all $(INSTALL_DEP):
@echo "==== Building LuaJIT $(VERSION) ====" @echo "==== Building LuaJIT $(VERSION) ===="
$(MAKE) -C src $(MAKE) -C src
@echo "==== Successfully built LuaJIT $(VERSION) ====" @echo "==== Successfully built LuaJIT $(VERSION) ===="
install: $(INSTALL_DEP) install: $(INSTALL_DEP)
@echo "==== Installing LuaJIT $(VERSION) to $(PREFIX) ====" @echo "==== Installing LuaJIT $(VERSION) to $(PREFIX) ===="
$(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_JITLIB) $(MKDIR) $(INSTALL_DIRS)
cd src && $(INSTALL_X) $(FILES_T) $(INSTALL_T) cd src && $(INSTALL_X) $(FILE_T) $(INSTALL_T)
cd src && test -f $(FILE_A) && $(INSTALL_F) $(FILE_A) $(INSTALL_STATIC) || :
$(RM) $(INSTALL_DYN) $(INSTALL_SHORT1) $(INSTALL_SHORT2)
cd src && test -f $(FILE_SO) && \
$(INSTALL_F) $(FILE_SO) $(INSTALL_DYN) && \
$(LDCONFIG) $(INSTALL_LIB) && \
$(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT1) && \
$(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT2) || :
cd etc && $(INSTALL_F) $(FILE_MAN) $(INSTALL_MAN)
cd etc && $(SED_PC) $(FILE_PC) > $(FILE_PC).tmp && \
$(INSTALL_F) $(FILE_PC).tmp $(INSTALL_PC) && \
$(RM) $(FILE_PC).tmp
cd src && $(INSTALL_F) $(FILES_INC) $(INSTALL_INC) cd src && $(INSTALL_F) $(FILES_INC) $(INSTALL_INC)
cd lib && $(INSTALL_F) $(FILES_JITLIB) $(INSTALL_JITLIB) cd lib && $(INSTALL_F) $(FILES_JITLIB) $(INSTALL_JITLIB)
@echo "==== Successfully installed LuaJIT $(VERSION) to $(PREFIX) ====" @echo "==== Successfully installed LuaJIT $(VERSION) to $(PREFIX) ===="
@ -59,7 +117,7 @@ install: $(INSTALL_DEP)
@echo "Note: the beta releases deliberately do NOT install a symlink for luajit" @echo "Note: the beta releases deliberately do NOT install a symlink for luajit"
@echo "You can do this now by running this command (with sudo):" @echo "You can do this now by running this command (with sudo):"
@echo "" @echo ""
@echo " $(SYMLINK) $(INSTALL_NAME) $(INSTALL_TSYM)" @echo " $(SYMLINK) $(INSTALL_TNAME) $(INSTALL_TSYM)"
@echo "" @echo ""
############################################################################## ##############################################################################
@ -77,8 +135,6 @@ cleaner:
distclean: distclean:
$(MAKE) -C src distclean $(MAKE) -C src distclean
SUB_TARGETS= amalg clean cleaner distclean .PHONY: all install amalg clean cleaner distclean
.PHONY: all install $(SUB_TARGETS)
############################################################################## ##############################################################################

4
README
View File

@ -1,4 +1,4 @@
README for LuaJIT 2.0.0-beta1 README for LuaJIT 2.0.0-beta2
----------------------------- -----------------------------
LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language. LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
@ -7,7 +7,7 @@ Project Homepage: http://luajit.org/
LuaJIT is Copyright (C) 2005-2009 Mike Pall. LuaJIT is Copyright (C) 2005-2009 Mike Pall.
LuaJIT is free software, released under the MIT/X license. LuaJIT is free software, released under the MIT/X license.
See full Copyright Notice in src/luajit.h See full Copyright Notice in the COPYRIGHT file or in luajit.h.
Documentation for LuaJIT is available in HTML format. Documentation for LuaJIT is available in HTML format.
Please point your favorite browser to: Please point your favorite browser to:

View File

@ -100,12 +100,6 @@ These functions are typically used with the command line options
Flushes the whole cache of compiled code. Flushes the whole cache of compiled code.
</p> </p>
<h3 id="jit_flush_tr"><tt>jit.flush(tr)</tt></h3>
<p>
Flushes the code for the specified root trace and all of its
side traces from the cache.
</p>
<h3 id="jit_onoff_func"><tt>jit.on(func|true [,true|false])<br> <h3 id="jit_onoff_func"><tt>jit.on(func|true [,true|false])<br>
jit.off(func|true [,true|false])<br> jit.off(func|true [,true|false])<br>
jit.flush(func|true [,true|false])</tt></h3> 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
debugging purposes. debugging purposes.
</p> </p>
<h3 id="jit_flush_tr"><tt>status = jit.flush(tr)</tt></h3>
<p>
Tries to flush the code for the specified trace and all of its
side traces from the cache. Returns <tt>true</tt> on success.
Returns <tt>false</tt> if there are still links to this trace.
</p>
<h3 id="jit_version"><tt>jit.version</tt></h3> <h3 id="jit_version"><tt>jit.version</tt></h3>
<p> <p>
Contains the LuaJIT version string. Contains the LuaJIT version string.
@ -189,6 +190,140 @@ The debug modules <tt>-jbc</tt>, <tt>-jv</tt> and <tt>-jdump</tt> make
extensive use of these functions. Please check out their source code, extensive use of these functions. Please check out their source code,
if you want to know more. if you want to know more.
</p> </p>
<h2 id="c_api">C API extensions</h2>
<p>
LuaJIT adds some extensions to the Lua/C API. The LuaJIT include
directory must be in the compiler search path (<tt>-I<i>path</i></tt>)
to be able to include the required header for C code:
</p>
<pre class="code">
#include "luajit.h"
</pre>
<p>
Or for C++ code:
</p>
<pre class="code">
#include "lua.hpp"
</pre>
<h2 id="luaJIT_setmode"><tt>luaJIT_setmode(L, idx, mode)</tt>
&mdash; Control VM</h2>
<p>
This is a C API extension to allow control of the VM from C code. The
full prototype of <tt>LuaJIT_setmode</tt> is:
</p>
<pre class="code">
LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
</pre>
<p>
The returned status is either success (<tt>1</tt>) or failure (<tt>0</tt>).
The second argument is either <tt>0</tt> or a stack index (similar to the
other Lua/C API functions).
</p>
<p>
The third argument specifies the mode, which is 'or'ed with a flag.
The flag can be <tt>LUAJIT_MODE_OFF</tt> to turn a feature on,
<tt>LUAJIT_MODE_ON</tt> to turn a feature off, or
<tt>LUAJIT_MODE_FLUSH</tt> to flush cached code.
</p>
<p>
The following modes are defined:
</p>
<h3 id="mode_engine"><tt>luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|flag)</tt></h3>
<p>
Turn the whole JIT compiler on or off or flush the whole cache of compiled code.
</p>
<h3 id="mode_func"><tt>luaJIT_setmode(L, idx, LUAJIT_MODE_FUNC|flag)</tt><br>
<tt>luaJIT_setmode(L, idx, LUAJIT_MODE_ALLFUNC|flag)</tt><br>
<tt>luaJIT_setmode(L, idx, LUAJIT_MODE_ALLSUBFUNC|flag)</tt></h3>
<p>
This sets the mode for the function at the stack index <tt>idx</tt> or
the parent of the calling function (<tt>idx = 0</tt>). It either
enables JIT compilation for a function, disables it and flushes any
already compiled code or only flushes already compiled code. This
applies recursively to all subfunctions of the function with
<tt>LUAJIT_MODE_ALLFUNC</tt> or only to the subfunctions with
<tt>LUAJIT_MODE_ALLSUBFUNC</tt>.
</p>
<h3 id="mode_engine"><tt>luaJIT_setmode(L, trace,<br>
&nbsp;&nbsp;LUAJIT_MODE_TRACE|LUAJIT_MODE_FLUSH)</tt></h3>
<p>
Tries to flush the code for the specified trace and all of its
side traces from the cache.
</p>
<h3 id="mode_engine"><tt>luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|flag)</tt></h3>
<p>
This mode defines a wrapper function for calls to C functions. The
first time this is called with <tt>LUAJIT_MODE_ON</tt>, the stack
index at <tt>idx</tt> must be a <tt>lightuserdata</tt> object holding
a pointer to the wrapper function. All <b>subsequently created C
functions</b> are called through the wrapper functions. After the initial
definition <tt>idx</tt> can be left at <tt>0</tt> when turning the mode
on or off.
</p>
<p>
The wrapper function can be used for debugging purposes or to catch
and convert foreign exceptions. Recommended usage can be seen in this
C++ code excerpt:
</p>
<pre class="code">
#include &lt;exception&gt;
#include "lua.hpp"
// Catch C++ exceptions and convert them to Lua error messages.
// Customize as needed for your own exception classes.
static int wrap_exceptions(lua_State *L, lua_CFunction f)
{
try {
return f(L); // Call wrapped function and return result.
} catch (const char *s) { // Catch and convert exceptions.
lua_pushstring(L, s);
} catch (std::exception& e) {
lua_pushstring(L, e.what());
} catch (...) {
lua_pushliteral(L, "caught (...)");
}
return lua_error(L); // Rethrow as a Lua error.
}
static int myregister(lua_State *L)
{
...
// Define wrapper function and enable it.
lua_pushlightuserdata(L, (void *)wrap_exceptions);
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
lua_pop(L, 1);
luaL_register(L, "mymodule", myfuncs); // Pass luaL_Reg list.
luaJIT_setmode(L, 0, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_OFF);
...
// Wrap some more C++ functions which might throw an exception.
luaJIT_setmode(L, 0, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
lua_pushcfunction(L, mythrowingfunc1);
lua_pushcclosure(L, mythrowingfunc2, 1);
luaJIT_setmode(L, 0, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_OFF);
...
}
</pre>
<p>
Note that you can only define <b>a single global wrapper function</b>,
so be careful when using this mechanism from multiple C++ modules.
Also note that this mechanism is not without overhead. It should only
be enabled for definitions of C++ functions that can actually throw
exceptions. If you're embedding LuaJIT into an application, only
enable it <b>after</b> running <tt>luaL_openlibs</tt>.
</p>
<p>
LuaJIT already intercepts exception handling for systems using
ELF/DWARF2 stack unwinding (e.g. Linux). This is a zero-cost mechanism
and always enabled. You don't need to use any wrapper functions,
except when you want to get a more specific error message than
<tt>"C++&nbsp;exception"</tt>.
</p>
<br class="flush"> <br class="flush">
</div> </div>
<div id="foot"> <div id="foot">

View File

@ -43,7 +43,7 @@ div.major { max-width: 600px; padding: 1em; margin: 1em 0 1em 0; }
<div id="main"> <div id="main">
<p> <p>
This is a list of changes between the released versions of LuaJIT.<br> This is a list of changes between the released versions of LuaJIT.<br>
The current <span style="color: #c00000;">development version</span> is <strong>LuaJIT&nbsp;2.0.0-beta1</strong>.<br> The current <span style="color: #c00000;">development version</span> is <strong>LuaJIT&nbsp;2.0.0-beta2</strong>.<br>
The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT&nbsp;1.1.5</strong>. The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT&nbsp;1.1.5</strong>.
</p> </p>
<p> <p>
@ -53,6 +53,36 @@ to see whether newer versions are available.
</p> </p>
<div class="major" style="background: #ffd0d0;"> <div class="major" style="background: #ffd0d0;">
<h2 id="LuaJIT-2.0.0-beta2">LuaJIT 2.0.0-beta2 &mdash; 2009-11-09</h2>
<ul>
<li>Reorganize build system. Build static+shared library on POSIX.</li>
<li>Allow C++ exception conversion on all platforms
using a wrapper function.</li>
<li>Automatically catch C++ exceptions and rethrow Lua error
(ELF/DWARF2 only).</li>
<li>Check for the correct x87 FPU precision at strategic points.</li>
<li>Always use wrappers for libm functions.</li>
<li>Resurrect metamethod name strings before copying them.</li>
<li>Mark current trace, even if compiler is idle.</li>
<li>Ensure FILE metatable is created only once.</li>
<li>Fix type comparisons when different integer types are involved.</li>
<li>Fix getmetatable() recording.</li>
<li>Fix TDUP with dead keys in template table.</li>
<li><tt>jit.flush(tr)</tt> returns status.
Prevent manual flush of a trace that's still linked.</li>
<li>Improve register allocation heuristics for invariant references.</li>
<li>Compile the push/pop variants of <tt>table.insert()</tt> and
<tt>table.remove()</tt>.</li>
<li>Compatibility with MSVC <tt>link&nbsp/debug</tt>.</li>
<li>Fix <tt>lua_iscfunction()</tt>.</li>
<li>Fix <tt>math.random()</tt> when compiled with <tt>-fpic</tt> (OSX).</li>
<li>Fix <tt>table.maxn()</tt>.</li>
<li>Bump <tt>MACOSX_DEPLOYMENT_TARGET</tt> to <tt>10.4</tt></li>
<li><tt>luaL_check*()</tt> and <tt>luaL_opt*()</tt> now support
negative arguments, too.<br>
This matches the behavior of Lua 5.1, but not the specification.</li>
</ul>
<h2 id="LuaJIT-2.0.0-beta1">LuaJIT 2.0.0-beta1 &mdash; 2009-10-31</h2> <h2 id="LuaJIT-2.0.0-beta1">LuaJIT 2.0.0-beta1 &mdash; 2009-10-31</h2>
<ul> <ul>
<li>This is the first public release of LuaJIT 2.0.</li> <li>This is the first public release of LuaJIT 2.0.</li>

View File

@ -72,6 +72,7 @@ Search for: <a href="http://scholar.google.com/scholar?q=JIT+Compiler"><span cla
Search for: <a href="http://scholar.google.com/scholar?q=Dynamic+Language+Optimizations"><span class="ext">&raquo;</span>&nbsp;Dynamic Language Optimizations</a><br> Search for: <a href="http://scholar.google.com/scholar?q=Dynamic+Language+Optimizations"><span class="ext">&raquo;</span>&nbsp;Dynamic Language Optimizations</a><br>
Search for: <a href="http://scholar.google.com/scholar?q=SSA+Form"><span class="ext">&raquo;</span>&nbsp;SSA Form</a><br> Search for: <a href="http://scholar.google.com/scholar?q=SSA+Form"><span class="ext">&raquo;</span>&nbsp;SSA Form</a><br>
Search for: <a href="http://scholar.google.com/scholar?q=Linear+Scan+Register+Allocation"><span class="ext">&raquo;</span>&nbsp;Linear Scan Register Allocation</a><br> Search for: <a href="http://scholar.google.com/scholar?q=Linear+Scan+Register+Allocation"><span class="ext">&raquo;</span>&nbsp;Linear Scan Register Allocation</a><br>
Here is a list of the <a href="http://article.gmane.org/gmane.comp.lang.lua.general/58908"><span class="ext">&raquo;</span>&nbsp;innovative features in LuaJIT</a>.<br>
And, you know, reading the source is of course the only way to enlightenment. :-) And, you know, reading the source is of course the only way to enlightenment. :-)
</dd> </dd>
</dl> </dl>
@ -86,6 +87,28 @@ functions from Lua 5.0.<br>Please convert your code to the
vararg syntax</a>.</dd> vararg syntax</a>.</dd>
</dl> </dl>
<dl>
<dt>Q: Why do I get this error: "bad FPU precision"?<br>
<dt>Q: I get weird behavior after initializing Direct3D.<br>
<dt>Q: Some FPU operations crash after I load a Delphi DLL.<br>
</dt>
<dd>
DirectX/Direct3D (up to version 9) sets the x87 FPU to single-precision
mode by default. This violates the Windows ABI and interferes with the
operation of many programs &mdash; LuaJIT is affected, too. Please make
sure you always use the <tt>D3DCREATE_FPU_PRESERVE</tt> flag when
initializing Direct3D.<br>
Direct3D version 10 or higher do not show this behavior anymore.
Consider testing your application with older versions, too.<br>
Similarly, the Borland/Delphi runtime modifies the FPU control word and
enables FP exceptions. Of course this violates the Windows ABI, too.
Please check the Delphi docs for the Set8087CW method.
</dl>
<dl> <dl>
<dt>Q: Sometimes Ctrl-C fails to stop my Lua program. Why?</dt> <dt>Q: Sometimes Ctrl-C fails to stop my Lua program. Why?</dt>
<dd>The interrupt signal handler sets a Lua debug hook. But this is <dd>The interrupt signal handler sets a Lua debug hook. But this is

View File

@ -58,17 +58,15 @@ application under x64-based systems, too.
<h2>Configuring LuaJIT</h2> <h2>Configuring LuaJIT</h2>
<p> <p>
The standard configuration should work fine for most installations. The standard configuration should work fine for most installations.
Usually there is no need to tweak the settings, except when you want to Usually there is no need to tweak the settings. The following files
install to a non-standard path. The following three files hold all hold all user-configurable settings:
user-configurable settings:
</p> </p>
<ul> <ul>
<li><tt>src/luaconf.h</tt> sets some configuration variables, in <li><tt>src/luaconf.h</tt> sets some configuration variables.</li>
particular the default paths for loading modules.</li> <li><tt>Makefile</tt> has settings for <b>installing</b> LuaJIT (POSIX
<li><tt>Makefile</tt> has settings for installing LuaJIT (POSIX
only).</li> only).</li>
<li><tt>src/Makefile</tt> has settings for compiling LuaJIT under POSIX, <li><tt>src/Makefile</tt> has settings for <b>compiling</b> LuaJIT
MinGW and Cygwin.</li> under POSIX, MinGW and Cygwin.</li>
<li><tt>src/msvcbuild.bat</tt> has settings for compiling LuaJIT with <li><tt>src/msvcbuild.bat</tt> has settings for compiling LuaJIT with
MSVC.</li> MSVC.</li>
</ul> </ul>
@ -97,9 +95,8 @@ terminal window and change to this directory. Now unpack the archive
and change to the newly created directory: and change to the newly created directory:
</p> </p>
<pre class="code"> <pre class="code">
tar zxf LuaJIT-2.0.0-beta1.tar.gz tar zxf LuaJIT-2.0.0-beta2.tar.gz
cd LuaJIT-2.0.0-beta1 cd LuaJIT-2.0.0-beta2</pre>
</pre>
<h3>Building LuaJIT</h3> <h3>Building LuaJIT</h3>
<p> <p>
The supplied Makefiles try to auto-detect the settings needed for your 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:
<pre class="code"> <pre class="code">
make make
</pre> </pre>
<p>
By default modules are only searched under the prefix <tt>/usr/local</tt>.
You can add an extra prefix to the search paths by appending the
<tt>PREFIX</tt> option, e.g.:
</p>
<pre class="code">
make PREFIX=/home/myself/lj2
</pre>
<p>
Note for OSX: <tt>MACOSX_DEPLOYMENT_TARGET</tt> is set to <tt>10.4</tt>
in <tt>src/Makefile</tt>. Change it, if you want to build on an older version.
</p>
<h3>Installing LuaJIT</h3> <h3>Installing LuaJIT</h3>
<p> <p>
The top-level Makefile installs LuaJIT by default under The top-level Makefile installs LuaJIT by default under
@ -124,20 +133,19 @@ sudo make install
Otherwise specify the directory prefix as an absolute path, e.g.: Otherwise specify the directory prefix as an absolute path, e.g.:
</p> </p>
<pre class="code"> <pre class="code">
sudo make install PREFIX=/opt/lj2 make install PREFIX=/home/myself/lj2
</pre> </pre>
<p> <p>
But note that the installation prefix and the prefix for the module paths Obviously the prefixes given during build and installation need to be the same.
(configured in <tt>src/luaconf.h</tt>) must match.
</p> </p>
<p style="color: #c00000;"> <p style="color: #c00000;">
Note: to avoid overwriting a previous version, the beta test releases Note: to avoid overwriting a previous version, the beta test releases
only install the LuaJIT executable under the versioned name (i.e. only install the LuaJIT executable under the versioned name (i.e.
<tt>luajit-2.0.0-beta1</tt>). You probably want to create a symlink <tt>luajit-2.0.0-beta2</tt>). You probably want to create a symlink
for convenience, with a command like this: for convenience, with a command like this:
</p> </p>
<pre class="code" style="color: #c00000;"> <pre class="code" style="color: #c00000;">
sudo ln -sf luajit-2.0.0-beta1 /usr/local/bin/luajit sudo ln -sf luajit-2.0.0-beta2&nbsp;/usr/local/bin/luajit
</pre> </pre>
<h2 id="windows">Windows Systems</h2> <h2 id="windows">Windows Systems</h2>
@ -145,8 +153,8 @@ sudo ln -sf luajit-2.0.0-beta1 /usr/local/bin/luajit
<p> <p>
Either install one of the open source SDKs Either install one of the open source SDKs
(<a href="http://mingw.org/"><span class="ext">&raquo;</span>&nbsp;MinGW</a> or (<a href="http://mingw.org/"><span class="ext">&raquo;</span>&nbsp;MinGW</a> or
<a href="http://www.cygwin.com/"><span class="ext">&raquo;</span>&nbsp;Cygwin</a>) which come with modified <a href="http://www.cygwin.com/"><span class="ext">&raquo;</span>&nbsp;Cygwin</a>), which come with a modified
versions of GCC plus the required development headers. GCC plus the required development headers.
</p> </p>
<p> <p>
Or install Microsoft's Visual C++ (MSVC) &mdash; the freely downloadable Or install Microsoft's Visual C++ (MSVC) &mdash; the freely downloadable
@ -159,8 +167,8 @@ Next, download the source package and unpack it using an archive manager
</p> </p>
<h3>Building with MSVC</h3> <h3>Building with MSVC</h3>
<p> <p>
Open a "Visual Studio .NET Command Prompt" and <tt>cd</tt> to the Open a "Visual Studio .NET Command Prompt", <tt>cd</tt> to the
directory where you've unpacked the sources. Then run this command: directory where you've unpacked the sources and run these commands:
</p> </p>
<pre class="code"> <pre class="code">
cd src cd src
@ -176,14 +184,12 @@ are in your path. Then <tt>cd</tt> to the directory where
you've unpacked the sources and run this command for MinGW: you've unpacked the sources and run this command for MinGW:
</p> </p>
<pre class="code"> <pre class="code">
cd src
mingw32-make mingw32-make
</pre> </pre>
<p> <p>
Or this command for Cygwin: Or this command for Cygwin:
</p> </p>
<pre class="code"> <pre class="code">
cd src
make make
</pre> </pre>
<p> <p>
@ -191,10 +197,11 @@ Then follow the installation instructions below.
</p> </p>
<h3>Installing LuaJIT</h3> <h3>Installing LuaJIT</h3>
<p> <p>
Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt> Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt> (built in the <tt>src</tt>
to a newly created directory (any location is ok). Add <tt>lua</tt> directory) to a newly created directory (any location is ok).
and <tt>lua\jit</tt> directories below it and copy all Lua files Add <tt>lua</tt> and <tt>lua\jit</tt> directories below it and copy
from the <tt>lib</tt> directory of the distribution to the latter directory. all Lua files from the <tt>lib</tt> directory of the distribution
to the latter directory.
</p> </p>
<p> <p>
There are no hardcoded There are no hardcoded

View File

@ -69,11 +69,11 @@ interactive mode, too.
<p class="indent" style="color: #c00000;"> <p class="indent" style="color: #c00000;">
Note: the beta test releases only install under the versioned name on Note: the beta test releases only install under the versioned name on
POSIX systems (to avoid overwriting a previous version). You either need POSIX systems (to avoid overwriting a previous version). You either need
to type <tt>luajit-2.0.0-beta1</tt> to start it or create a symlink to type <tt>luajit-2.0.0-beta2</tt> to start it or create a symlink
with a command like this: with a command like this:
</p> </p>
<pre class="code" style="color: #c00000;"> <pre class="code" style="color: #c00000;">
sudo ln -sf luajit-2.0.0-beta1 /usr/local/bin/luajit sudo ln -sf luajit-2.0.0-beta2&nbsp;/usr/local/bin/luajit
</pre> </pre>
<p> <p>
Unlike previous versions <b>optimization is turned on by default</b> in 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
read the comment block at the start of their source. read the comment block at the start of their source.
They can be found in the <tt>lib</tt> directory of the source They can be found in the <tt>lib</tt> directory of the source
distribution or installed under the <tt>jit</tt> directory. By default distribution or installed under the <tt>jit</tt> directory. By default
this is <tt>/usr/local/share/luajit-2.0.0-beta1/jit</tt> on POSIX this is <tt>/usr/local/share/luajit-2.0.0-beta2/jit</tt> on POSIX
systems. systems.
</p> </p>

View File

@ -90,7 +90,22 @@ known incompatibilities with standard Lua:
<ul> <ul>
<li> <li>
The Lua <b>debug API</b> is missing a couple of features (call/return The Lua <b>debug API</b> is missing a couple of features (call/return
hooks) and shows slightly different behavior (no per-coroutine hooks). hooks) and shows slightly different behavior (no per-coroutine hooks,
no tail call counting).
</li>
<li>
<b>Bytecode</b> currently cannot be loaded or dumped. Note that
the bytecode format differs from Lua&nbsp;5.1 &mdash; loading foreign
bytecode is not supported at all.
</li>
<li>
Some of the <b>configuration options</b> of Lua&nbsp;5.1 are not supported:
<ul>
<li>The <b>number type</b> cannot be changed (it's always a <tt>double</tt>).</li>
<li>The stand-alone executable cannot be linked with <b>readline</b>
to enable line editing. It's planned to add support for loading it
on-demand.</li>
</ul>
</li> </li>
<li> <li>
Most other issues you're likely to find (e.g. with the existing test Most other issues you're likely to find (e.g. with the existing test
@ -105,7 +120,7 @@ demonstrable need is shown.
<li> <li>
The <b>JIT compiler</b> is not complete (yet) and falls back to the The <b>JIT compiler</b> is not complete (yet) and falls back to the
interpreter in some cases. All of this works transparently, so unless interpreter in some cases. All of this works transparently, so unless
you use -jv, you'll probably never notice (the interpreter is quite you use <tt>-jv</tt>, you'll probably never notice (the interpreter is quite
fast, too). Here are the known issues: fast, too). Here are the known issues:
<ul> <ul>
<li> <li>
@ -119,7 +134,7 @@ effort.
</li> </li>
<li> <li>
<b>Recursion</b> is not traced yet. Often no trace will be generated at <b>Recursion</b> is not traced yet. Often no trace will be generated at
all or some unroll limit will catch it and aborts the trace. all or some unroll limit will catch it and abort the trace.
</li> </li>
<li> <li>
The trace compiler currently does not back off specialization for The trace compiler currently does not back off specialization for

82
etc/luajit.1 Normal file
View File

@ -0,0 +1,82 @@
.TH luajit 1 "" "" "LuaJIT documentation"
.SH NAME
luajit \- Just-In-Time Compiler for the Lua Language
\fB
.SH SYNOPSIS
.B luajit
[\fIoptions\fR]... [\fIscript\fR [\fIargs\fR]...]
.SH "WEB SITE"
.IR http://luajit.org
.SH DESCRIPTION
.PP
This is the command-line program to run Lua programs with \fBLuaJIT\fR.
.PP
\fBLuaJIT\fR is a just-in-time (JIT) compiler for the Lua language.
The virtual machine (VM) is based on a fast interpreter combined with
a trace compiler. It can significantly improve the performance of Lua programs.
.PP
\fBLuaJIT\fR is API\- and ABI-compatible with the VM of the standard
Lua\ 5.1 interpreter. When embedding the VM into an application,
the built library can be used as a drop-in replacement.
.SH OPTIONS
.TP
.BI "\-e " chunk
Run the given chunk of Lua code.
.TP
.BI "\-l " library
Load the named library, just like \fBrequire("\fR\fIlibrary\fR\fB")\fR.
.TP
.BI "\-j " command
Perform LuaJIT control command (optional space after \fB\-j\fR).
.TP
.BI "\-O" [opt]
Control LuaJIT optimizations.
.TP
.B "\-i"
Run in interactive mode.
.TP
.B "\-v"
Show \fBLuaJIT\fR version.
.TP
.B "\-\-"
Stop processing options.
.TP
.B "\-"
Read script from stdin instead.
.PP
After all options are processed, the given \fIscript\fR is run.
The arguments are passed in the global \fIarg\fR table.
.PP
Interactive mode is only entered, if no \fIscript\fR and no \fB\-e\fR
option is given. Interactive mode can be left with EOF (\fICtrl\-Z\fB).
.SH EXAMPLES
.TP
luajit hello.lua world
Prints "Hello world", assuming \fIhello.lua\fR contains:
.br
print("Hello", arg[1])
.TP
luajit \-e "local x=0; for i=1,1e9 do x=x+i end; print(x)"
Calculates the sum of the numbers from 1 to 1000000000.
.br
And finishes in a reasonable amount of time, too.
.TP
luajit \-jv \-e "for i=1,10 do for j=1,10 do for k=1,100 do end end end"
Runs some nested loops and shows the resulting traces.
.SH COPYRIGHT
.PP
\fBLuaJIT\fR is Copyright \(co 2005-2009 Mike Pall.
.br
\fBLuaJIT\fR is open source software, released under the MIT/X license.
.SH SEE ALSO
.PP
More details in the provided HTML docs or at:
.IR http://luajit.org
.br
More about the Lua language can be found at:
.IR http://lua.org/docs.html
.PP
lua(1)

24
etc/luajit.pc Normal file
View File

@ -0,0 +1,24 @@
# Package information for LuaJIT to be used by pkg-config.
majver=2
minver=0
relver=0
version=${majver}.${minver}.${relver}-beta2
abiver=5.1
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
libname=luajit-${abiver}
includedir=${prefix}/include/luajit-${majver}.${minver}
INSTALL_LMOD=${prefix}/share/lua/${abiver}
INSTALL_CMOD=${prefix}/lib/lua/${abiver}
Name: LuaJIT
Description: Just-in-time compiler for Lua
URL: http://luajit.org
Version: ${version}
Requires:
Libs: -L${libdir} -l${libname}
Libs.private: -Wl,-E -lm -ldl
Cflags: -I${includedir}

View File

@ -8,10 +8,17 @@
# Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h # Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h
############################################################################## ##############################################################################
MAJVER= 2
MINVER= 0
RELVER= 0
ABIVER= 5.1
NODOTABIVER= 51
############################################################################## ##############################################################################
# Compiler options: change them as needed. This mainly affects the speed of # Compiler options: change them as needed. This mainly affects the speed of
# the JIT compiler itself, not the speed of the JIT compiled code. # the JIT compiler itself, not the speed of the JIT compiled code.
# Turn any of the optional settings on by removing the '#' in front of them. # Turn any of the optional settings on by removing the '#' in front of them.
# You need to 'make clean' and 'make' again, if you change any options.
# #
# Note: LuaJIT can only be compiled for x86, and not for x64 (yet)! # Note: LuaJIT can only be compiled for x86, and not for x64 (yet)!
# In the meantime, the x86 binary runs fine under a x64 OS. # In the meantime, the x86 binary runs fine under a x64 OS.
@ -81,89 +88,142 @@ XCFLAGS=
#XCFLAGS+= -DLUA_USE_ASSERT #XCFLAGS+= -DLUA_USE_ASSERT
# #
############################################################################## ##############################################################################
##############################################################################
# Build mode: override the mode as needed. Default is mixed mode on POSIX.
# On Windows this is the same as dynamic mode.
#
# Mixed mode creates a static + dynamic library and a statically linked luajit.
BUILDMODE= mixed
#
# Static mode creates a static library and a statically linked luajit.
#BUILDMODE= static
#
# Dynamic mode creates a dynamic library and a dynamically linked luajit.
# Note: this executable will only run when the library is installed!
#BUILDMODE= dynamic
##############################################################################
# You probably don't need to change anything below this line. # You probably don't need to change anything below this line.
############################################################################## ##############################################################################
##############################################################################
# Flags and options for host and target.
##############################################################################
CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(CFLAGS) $(XCFLAGS) CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(CFLAGS) $(XCFLAGS)
LDOPTIONS= $(CCDEBUG) $(LDFLAGS) LDOPTIONS= $(CCDEBUG) $(LDFLAGS)
HOST_CC= $(CC) HOST_CC= $(CC)
HOST_RM= rm -f HOST_RM= rm -f
HOST_XCFLAGS=
HOST_XLDFLAGS=
HOST_XLIBS=
TARGET_CC= $(CC)
TARGET_STRIP= strip
TARGET_XCFLAGS= -D_FILE_OFFSET_BITS=64
TARGET_XLDFLAGS=
TARGET_XSHLDFLAGS= -shared
TARGET_XLIBS=
TARGET_ARCH= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET))
TARGET_DISABLE= -U_FORTIFY_SOURCE
ifneq (,$(findstring stack-protector,$(shell $(CC) -dumpspecs)))
TARGET_DISABLE+= -fno-stack-protector
endif
ifneq (,$(findstring Windows,$(OS)))
TARGET_SYS= Windows
else
TARGET_SYS:= $(shell uname -s)
ifneq (,$(findstring CYGWIN,$(TARGET_SYS)))
TARGET_SYS= Windows
endif
endif
ifeq (Linux,$(TARGET_SYS))
TARGET_XLIBS= -ldl
TARGET_XLDFLAGS= -Wl,-E
else
ifeq (Windows,$(TARGET_SYS))
HOST_RM= del
TARGET_STRIP= strip --strip-unneeded
else
ifeq (Darwin,$(TARGET_SYS))
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup
TARGET_STRIP= strip -x
export MACOSX_DEPLOYMENT_TARGET=10.3
else
TARGET_XLDFLAGS= -Wl,-E
endif
endif
endif
# NOTE: The LuaJIT distribution comes with a pre-generated buildvm_*.h. # NOTE: The LuaJIT distribution comes with a pre-generated buildvm_*.h.
# You DO NOT NEED an installed copy of (plain) Lua 5.1 to run DynASM unless # You DO NOT NEED an installed copy of (plain) Lua 5.1 to run DynASM unless
# you want to MODIFY the corresponding *.dasc file. You can also use LuaJIT # you want to MODIFY the corresponding *.dasc file. You can also use LuaJIT
# itself (bootstrapped from the pre-generated file) to run DynASM of course. # itself (bootstrapped from the pre-generated file) to run DynASM of course.
DASM_LUA= lua HOST_LUA= lua
Q= @
E= @echo
#Q=
#E= @:
##############################################################################
TARGET_CFLAGS= $(CCOPTIONS) $(TARGET_DISABLE) $(TARGET_XCFLAGS)
TARGET_LDFLAGS= $(LDOPTIONS) $(TARGET_XLDFLAGS)
TARGET_SHLDFLAGS= $(LDOPTIONS) $(TARGET_XSHLDFLAGS)
TARGET_LIBS= -lm $(TARGET_XLIBS)
ifneq (,$(CCDEBUG))
TARGET_STRIP= @:
endif
HOST_XCFLAGS=
HOST_XLDFLAGS=
HOST_XLIBS=
HOST_CFLAGS= $(CCOPTIONS) $(HOST_XCFLAGS) $(TARGET_ARCH) HOST_CFLAGS= $(CCOPTIONS) $(HOST_XCFLAGS) $(TARGET_ARCH)
HOST_LDFLAGS= $(LDOPTIONS) $(HOST_XLDFLAGS) HOST_LDFLAGS= $(LDOPTIONS) $(HOST_XLDFLAGS)
HOST_LIBS= $(HOST_XLIBS) HOST_LIBS= $(HOST_XLIBS)
# Cross-compilation example: make CROSS=i586-mingw32msvc- TARGET_SYS=Windows
CROSS=
STATIC_CC = $(CROSS)$(CC)
DYNAMIC_CC = $(CROSS)$(CC) -fPIC
TARGET_CC= $(STATIC_CC)
TARGET_STCC= $(STATIC_CC)
TARGET_DYNCC= $(DYNAMIC_CC)
TARGET_LD= $(CROSS)$(CC)
TARGET_AR= $(CROSS)ar rcus
TARGET_STRIP= $(CROSS)strip
TARGET_SONAME= libluajit-$(ABIVER).so.$(MAJVER)
TARGET_DYLIBNAME= libluajit-$(NODOTABIVER).$(MAJVER).$(MINVER).$(RELVER).dylib
TARGET_DLLNAME= lua$(NODOTABIVER).dll
TARGET_XSHLDFLAGS= -shared -fPIC -Wl,-soname,$(TARGET_SONAME)
TARGET_DYNXLDOPTS=
TARGET_ARCH= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET))
TARGET_DISABLE= -U_FORTIFY_SOURCE
ifneq (,$(findstring stack-protector,$(shell $(TARGET_CC) -dumpspecs)))
TARGET_DISABLE+= -fno-stack-protector
endif
TARGET_XCFLAGS= -D_FILE_OFFSET_BITS=64
TARGET_XLDFLAGS=
TARGET_XLDOPTS=
TARGET_XLIBS=
TARGET_CFLAGS= $(CCOPTIONS) $(TARGET_DISABLE) $(TARGET_XCFLAGS)
TARGET_LDFLAGS= $(LDOPTIONS) $(TARGET_XLDFLAGS) $(TARGET_XLDOPTS)
TARGET_SHLDFLAGS= $(LDOPTIONS) $(TARGET_XSHLDFLAGS)
TARGET_LIBS= -lm $(TARGET_XLIBS)
ifneq (,$(PREFIX))
ifneq (/usr/local,$(PREFIX))
TARGET_XCFLAGS+= -DLUA_XROOT=\"$(PREFIX)/\"
ifneq (/usr,$(PREFIX))
TARGET_DYNXLDOPTS= -Wl,-rpath,$(PREFIX)/lib
endif
endif
endif
##############################################################################
# System detection.
##############################################################################
ifneq (,$(findstring Windows,$(OS)))
HOST_SYS= Windows
else
HOST_SYS:= $(shell uname -s)
ifneq (,$(findstring CYGWIN,$(TARGET_SYS)))
HOST_SYS= Windows
endif
endif
ifeq (Windows,$(HOST_SYS))
HOST_RM= del
endif
TARGET_SYS= $(HOST_SYS)
ifeq (Windows,$(TARGET_SYS))
TARGET_STRIP+= --strip-unneeded
TARGET_XSHLDFLAGS= -shared
TARGET_DYNXLDOPTS=
else
ifeq (Darwin,$(TARGET_SYS))
export MACOSX_DEPLOYMENT_TARGET=10.4
TARGET_STRIP+= -x
TARGET_AR+= 2>/dev/null
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
ifneq (,$(TARGET_DYNXLDOPTS))
TARGET_DYNXLDOPTS=
TARGET_XSHLDFLAGS+= -install_name $(PREFIX)/lib/$(TARGET_DYLIBNAME)
endif
else
TARGET_XLDFLAGS= -Wl,-E
ifeq (Linux,$(TARGET_SYS))
TARGET_XLIBS= -ldl
endif
endif
endif
ifneq (,$(CCDEBUG))
TARGET_STRIP= @:
endif
##############################################################################
# Files and pathnames.
##############################################################################
DASM_DIR= ../dynasm DASM_DIR= ../dynasm
DASM= $(DASM_LUA) $(DASM_DIR)/dynasm.lua DASM= $(HOST_LUA) $(DASM_DIR)/dynasm.lua
DASM_FLAGS= DASM_FLAGS=
DASM_DISTFLAGS= -LN DASM_DISTFLAGS= -LN
BUILDVM_O= buildvm.o buildvm_asm.o buildvm_peobj.o buildvm_lib.o buildvm_fold.o BUILDVM_O= buildvm.o buildvm_asm.o buildvm_peobj.o buildvm_lib.o buildvm_fold.o
BUILDVM_T= buildvm BUILDVM_T= buildvm
BUILDVM_X= ./$(BUILDVM_T)
HOST_O= $(BUILDVM_O) HOST_O= $(BUILDVM_O)
HOST_T= $(BUILDVM_T) HOST_T= $(BUILDVM_T)
@ -188,121 +248,91 @@ LJCORE_O= lj_gc.o lj_err.o lj_ctype.o lj_bc.o lj_obj.o \
$(LJLIB_O) lib_init.o $(LJLIB_O) lib_init.o
LJVMCORE_O= $(LJVM_O) $(LJCORE_O) LJVMCORE_O= $(LJVM_O) $(LJCORE_O)
LJVMCORE_DYNO= $(LJVMCORE_O:.o=_dyn.o)
# NYI: Need complete support for building as a shared library on POSIX.
# This is currently *only* suitable for MinGW and Cygwin, see below.
LUAJIT_O= luajit.o
LUAJIT_SO= luajit.so
LUAJIT_T= luajit
LIB_VMDEF= ../lib/vmdef.lua LIB_VMDEF= ../lib/vmdef.lua
LIB_VMDEFP= $(LIB_VMDEF)
TARGET_DEP= $(LIB_VMDEF) LUAJIT_O= luajit.o
TARGET_O= $(LJVMCORE_O) $(LUAJIT_O) LUAJIT_A= libluajit.a
TARGET_T= $(LUAJIT_T) LUAJIT_SO= libluajit.so
LUAJIT_T= luajit
ALL_GEN= $(LJVM_S) lj_ffdef.h lj_libdef.h lj_recdef.h $(LIB_VMDEF) lj_folddef.h ALL_T= $(LUAJIT_T) $(LUAJIT_A) $(LUAJIT_SO) $(BUILDVM_T)
ALL_GEN= $(LJVM_S) lj_ffdef.h lj_libdef.h lj_recdef.h $(LIB_VMDEFP) lj_folddef.h
ALL_DYNGEN= buildvm_x86.h ALL_DYNGEN= buildvm_x86.h
WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest *.pdb *.ilk
ALL_RM= $(LUAJIT_T) $(LUAJIT_SO) $(HOST_T) $(ALL_GEN) *.o $(WIN_RM) ALL_RM= $(ALL_T) $(ALL_GEN) *.o $(WIN_RM)
ifeq (Windows,$(TARGET_SYS))
LJVM_BOUT= $(LJVM_O)
LJVM_MODE= peobj
LIB_VMDEF= ..\lib\vmdef.lua
# Imported symbols are bound to a specific DLL name under Windows.
LUAJIT_SO= lua51.dll
LUAJIT_T= luajit.exe
BUILDVM_T= buildvm.exe
#
# You can comment out the following two lines to build a static executable.
# But then you won't be able to dynamically load any C modules, because
# they bind to lua51.dll.
#
TARGET_XCFLAGS+= -DLUA_BUILD_AS_DLL
TARGET_O= $(LUAJIT_SO) $(LUAJIT_O)
endif
##############################################################################
# Build mode handling.
############################################################################## ##############################################################################
default: $(TARGET_T) # Mixed mode defaults.
TARGET_O= $(LUAJIT_A)
TARGET_T= $(LUAJIT_T) $(LUAJIT_SO)
TARGET_DEP= $(LIB_VMDEF) $(LUAJIT_SO)
all: $(TARGET_T) ifeq (Windows,$(HOST_SYS))
BUILDVM_T= buildvm.exe
LIB_VMDEFP= $(subst /,\\,$(LIB_VMDEF))
endif
ifeq (Windows,$(TARGET_SYS))
DYNAMIC_CC= $(STATIC_CC)
LJVM_BOUT= $(LJVM_O)
LJVM_MODE= peobj
LUAJIT_SO= $(TARGET_DLLNAME)
LUAJIT_T= luajit.exe
ifneq ($(HOST_SYS),$(TARGET_SYS))
HOST_XCFLAGS+= -malign-double
endif
# Mixed mode is not supported on Windows. And static mode doesn't work well.
# C modules cannot be loaded, because they bind to lua51.dll.
ifneq (static,$(BUILDMODE))
BUILDMODE= dynamic
TARGET_XCFLAGS+= -DLUA_BUILD_AS_DLL
endif
endif
ifeq (static,$(BUILDMODE))
TARGET_DYNCC= @:
TARGET_T= $(LUAJIT_T)
TARGET_DEP= $(LIB_VMDEF)
else
ifeq (dynamic,$(BUILDMODE))
TARGET_CC= $(DYNAMIC_CC)
TARGET_DYNCC= @:
LJVMCORE_DYNO= $(LJVMCORE_O)
TARGET_O= $(LUAJIT_SO)
TARGET_XLDOPTS= $(TARGET_DYNXLDOPTS)
else
ifeq (Darwin,$(TARGET_SYS))
TARGET_DYNCC= @:
LJVMCORE_DYNO= $(LJVMCORE_O)
endif
endif
endif
Q= @
E= @echo
#Q=
#E= @:
##############################################################################
# Make targets.
##############################################################################
default all: $(TARGET_T)
amalg: amalg:
@grep "^[+|]" ljamalg.c @grep "^[+|]" ljamalg.c
$(MAKE) all "LJCORE_O=ljamalg.o" $(MAKE) all "LJCORE_O=ljamalg.o"
MAKE_TARGETS= amalg
##############################################################################
buildvm_x86.h: buildvm_x86.dasc
$(E) "DYNASM $@"
$(Q)$(DASM) $(DASM_FLAGS) -o $@ buildvm_x86.dasc
$(BUILDVM_T): $(BUILDVM_O)
$(E) "HOSTLINK $@"
$(Q)$(HOST_CC) $(HOST_LDFLAGS) -o $@ $(BUILDVM_O) $(HOST_LIBS)
$(LJVM_BOUT): $(BUILDVM_T)
$(E) "BUILDVM $@"
$(Q)./$(BUILDVM_T) -m $(LJVM_MODE) -o $@
lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)./$(BUILDVM_T) -m ffdef -o $@ $(LJLIB_C)
lj_libdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)./$(BUILDVM_T) -m libdef -o $@ $(LJLIB_C)
lj_recdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)./$(BUILDVM_T) -m recdef -o $@ $(LJLIB_C)
$(LIB_VMDEF): $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)./$(BUILDVM_T) -m vmdef -o $@ $(LJLIB_C)
lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c
$(E) "BUILDVM $@"
$(Q)./$(BUILDVM_T) -m folddef -o $@ lj_opt_fold.c
$(LUAJIT_SO): $(LJVMCORE_O)
$(E) "LINK $@"
$(Q)$(TARGET_CC) $(TARGET_SHLDFLAGS) -o $@ $(LJVMCORE_O) $(TARGET_LIBS)
$(Q)$(TARGET_STRIP) $@
$(LUAJIT_T): $(TARGET_O) $(TARGET_DEP)
$(E) "LINK $@"
$(Q)$(TARGET_CC) $(TARGET_LDFLAGS) -o $@ $(TARGET_O) $(TARGET_LIBS)
$(Q)$(TARGET_STRIP) $@
$(E) "OK Successfully built LuaJIT"
##############################################################################
%.o: %.c
$(E) "CC $@"
$(Q)$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
%.o: %.s
$(E) "ASM $@"
$(Q)$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
$(HOST_O): %.o: %.c
$(E) "HOSTCC $@"
$(Q)$(HOST_CC) $(HOST_CFLAGS) -c -o $@ $<
include Makefile.dep
##############################################################################
clean: clean:
$(HOST_RM) $(ALL_RM) $(HOST_RM) $(ALL_RM)
cleaner: clean cleaner:
$(HOST_RM) $(ALL_DYNGEN) $(HOST_RM) $(ALL_RM) $(ALL_DYNGEN)
distclean: clean distclean: clean
$(E) "DYNASM $@" $(E) "DYNASM $@"
@ -321,6 +351,86 @@ depend:
@test -s lj_folddef.h || $(HOST_RM) lj_folddef.h @test -s lj_folddef.h || $(HOST_RM) lj_folddef.h
@test -s buildvm_x86.h || $(HOST_RM) buildvm_x86.h @test -s buildvm_x86.h || $(HOST_RM) buildvm_x86.h
.PHONY: default all $(MAKE_TARGETS) clean cleaner distclean depend .PHONY: default all amalg clean cleaner distclean depend
##############################################################################
# Rules for generated files.
##############################################################################
buildvm_x86.h: buildvm_x86.dasc
$(E) "DYNASM $@"
$(Q)$(DASM) $(DASM_FLAGS) -o $@ buildvm_x86.dasc
$(BUILDVM_T): $(BUILDVM_O)
$(E) "HOSTLINK $@"
$(Q)$(HOST_CC) $(HOST_LDFLAGS) -o $@ $(BUILDVM_O) $(HOST_LIBS)
$(LJVM_BOUT): $(BUILDVM_T)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m $(LJVM_MODE) -o $@
lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m ffdef -o $@ $(LJLIB_C)
lj_libdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m libdef -o $@ $(LJLIB_C)
lj_recdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m recdef -o $@ $(LJLIB_C)
$(LIB_VMDEF): $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m vmdef -o $(LIB_VMDEFP) $(LJLIB_C)
lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m folddef -o $@ lj_opt_fold.c
##############################################################################
# Object file rules.
##############################################################################
%.o: %.c
$(E) "CC $@"
$(Q)$(TARGET_DYNCC) $(TARGET_CFLAGS) -c -o $(@:.o=_dyn.o) $<
$(Q)$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
%.o: %.s
$(E) "ASM $@"
$(Q)$(TARGET_DYNCC) $(TARGET_CFLAGS) -c -o $(@:.o=_dyn.o) $<
$(Q)$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
$(LUAJIT_O):
$(E) "CC $@"
$(Q)$(TARGET_STCC) $(TARGET_CFLAGS) -c -o $@ $<
$(HOST_O): %.o: %.c
$(E) "HOSTCC $@"
$(Q)$(HOST_CC) $(HOST_CFLAGS) -c -o $@ $<
include Makefile.dep
##############################################################################
# Target file rules.
##############################################################################
$(LUAJIT_A): $(LJVMCORE_O)
$(E) "AR $@"
$(Q)$(TARGET_AR) $@ $(LJVMCORE_O)
# The dependency on _O, but linking with _DYNO is intentional.
$(LUAJIT_SO): $(LJVMCORE_O)
$(E) "DYNLINK $@"
$(Q)$(TARGET_LD) $(TARGET_SHLDFLAGS) -o $@ $(LJVMCORE_DYNO) $(TARGET_LIBS)
$(Q)$(TARGET_STRIP) $@
$(LUAJIT_T): $(TARGET_O) $(LUAJIT_O) $(TARGET_DEP)
$(E) "LINK $@"
$(Q)$(TARGET_LD) $(TARGET_LDFLAGS) -o $@ $(LUAJIT_O) $(TARGET_O) $(TARGET_LIBS)
$(Q)$(TARGET_STRIP) $@
$(E) "OK Successfully built LuaJIT"
############################################################################## ##############################################################################

View File

@ -34,8 +34,8 @@ lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h
lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_state.h \ lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h \
lj_ff.h lj_ffdef.h lj_ctype.h lj_lib.h lj_libdef.h lj_state.h lj_ff.h lj_ffdef.h lj_ctype.h lj_lib.h lj_libdef.h
lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \ lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \
lj_libdef.h lj_libdef.h

View File

@ -71,10 +71,7 @@ err:
exit(1); exit(1);
} }
emit_asm_bytes(ctx, cp, n); emit_asm_bytes(ctx, cp, n);
if (!strncmp(sym, LABEL_PREFIX, sizeof(LABEL_PREFIX)-1))
fprintf(ctx->fp, "\t%s _%s\n", opname, sym); fprintf(ctx->fp, "\t%s _%s\n", opname, sym);
else
fprintf(ctx->fp, "\t%s _" LABEL_PREFIX "wrapper_%s\n", opname, sym);
} }
/* Emit an assembler label. */ /* Emit an assembler label. */
@ -135,7 +132,7 @@ void emit_asm(BuildCtx *ctx)
fprintf(ctx->fp, "\t.text\n"); fprintf(ctx->fp, "\t.text\n");
emit_asm_align(ctx, 4); emit_asm_align(ctx, 4);
emit_asm_label(ctx, LABEL_ASM_BEGIN, 0, 1); emit_asm_label(ctx, LABEL_ASM_BEGIN, 0, 0);
if (ctx->mode == BUILD_elfasm) if (ctx->mode == BUILD_elfasm)
fprintf(ctx->fp, ".Lbegin:\n"); fprintf(ctx->fp, ".Lbegin:\n");

View File

@ -188,7 +188,12 @@ void emit_fold(BuildCtx *ctx)
} else if ((p[0] == 'F' || p[0] == 'X') && p[1] == '(' && q) { } else if ((p[0] == 'F' || p[0] == 'X') && p[1] == '(' && q) {
p += 2; p += 2;
*q = '\0'; *q = '\0';
fprintf(ctx->fp, funcidx ? ",\n %s" : " %s", p); if (funcidx)
fprintf(ctx->fp, ",\n");
if (p[-2] == 'X')
fprintf(ctx->fp, " %s", p);
else
fprintf(ctx->fp, " fold_%s", p);
funcidx++; funcidx++;
} else { } else {
buf[strlen(buf)-1] = '\0'; buf[strlen(buf)-1] = '\0';

View File

@ -264,7 +264,8 @@ void emit_peobj(BuildCtx *ctx)
emit_peobj_sym(ctx, name, 0, emit_peobj_sym(ctx, name, 0,
PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN); PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
} }
emit_peobj_sym_func(ctx, PEOBJ_SYM_PREFIX LABEL_ASM_BEGIN, 0); emit_peobj_sym(ctx, PEOBJ_SYM_PREFIX LABEL_ASM_BEGIN, 0,
PEOBJ_SECT_TEXT, PEOBJ_TYPE_NULL, PEOBJ_SCL_EXTERN);
for (i = nzsym; i < ctx->nsym; i++) { for (i = nzsym; i < ctx->nsym; i++) {
int pi = ctx->perm[i]; int pi = ctx->perm[i];
if (pi >= ctx->npc) { if (pi >= ctx->npc) {

View File

@ -287,6 +287,35 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
| lea RA, [BASE+RA*8] | lea RA, [BASE+RA*8]
| jmp <9 | jmp <9
| |
|->gate_cwrap: // Call gate for wrapped C functions.
| // RA = new base, RB = CFUNC, RC = nargs+1, (BASE = old base), PC = return
| mov [RA-4], PC
| mov KBASE, CFUNC:RB->f
| mov L:RB, SAVE_L
| lea RC, [RA+NARGS:RC*8-8]
| mov L:RB->base, RA
| lea RA, [RC+8*LUA_MINSTACK]
| mov ARG2, KBASE
| mov ARG1, L:RB
| mov L:RB->top, RC
| cmp RA, L:RB->maxstack
| ja ->gate_c_growstack // Need to grow stack.
| set_vmstate C
| // (lua_State *L, lua_CFunction f)
| call aword [DISPATCH+DISPATCH_GL(wrapf)]
| set_vmstate INTERP
| // nresults returned in eax (RD).
| mov BASE, L:RB->base
| lea RA, [BASE+RD*8]
| neg RA
| add RA, L:RB->top // RA = (L->top-(L->base+nresults))*8
|->vm_returnc:
| add RD, 1 // RD = nresults+1
| mov NRESULTS, RD
| test PC, FRAME_TYPE
| jz ->BC_RET_Z // Handle regular return to Lua.
| jmp ->vm_return
|
|->gate_c: // Call gate for C functions. |->gate_c: // Call gate for C functions.
| // RA = new base, RB = CFUNC, RC = nargs+1, (BASE = old base), PC = return | // RA = new base, RB = CFUNC, RC = nargs+1, (BASE = old base), PC = return
| mov [RA-4], PC | mov [RA-4], PC
@ -312,6 +341,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
| mov NRESULTS, RD | mov NRESULTS, RD
| test PC, FRAME_TYPE | test PC, FRAME_TYPE
| jz ->BC_RET_Z // Handle regular return to Lua. | jz ->BC_RET_Z // Handle regular return to Lua.
| // Fallthrough.
| |
|//-- Return handling (non-inline) --------------------------------------- |//-- Return handling (non-inline) ---------------------------------------
| |
@ -1455,7 +1485,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
| mov ARG5, RA | mov ARG5, RA
| fstp FPARG1 | fstp FPARG1
| mov RB, BASE | mov RB, BASE
| call extern func | call extern lj_wrapper_ .. func
| mov RA, ARG5 | mov RA, ARG5
| mov BASE, RB | mov BASE, RB
| jmp ->fff_resn | jmp ->fff_resn
@ -3584,6 +3614,85 @@ static void emit_asm_debug(BuildCtx *ctx)
"\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */ "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
"\t.align 4\n" "\t.align 4\n"
".LEFDE0:\n\n", (int)ctx->codesz); ".LEFDE0:\n\n", (int)ctx->codesz);
fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
fprintf(ctx->fp,
".Lframe1:\n"
"\t.long .LECIE1-.LSCIE1\n"
".LSCIE1:\n"
"\t.long 0\n"
"\t.byte 0x1\n"
"\t.string \"zPR\"\n"
"\t.uleb128 0x1\n"
"\t.sleb128 -4\n"
"\t.byte 0x8\n"
"\t.uleb128 6\n" /* augmentation length */
"\t.byte 0x1b\n" /* pcrel|sdata4 */
"\t.long lj_err_unwind_dwarf-.\n"
"\t.byte 0x1b\n" /* pcrel|sdata4 */
"\t.byte 0xc\n\t.uleb128 0x4\n\t.uleb128 0x4\n"
"\t.byte 0x88\n\t.uleb128 0x1\n"
"\t.align 4\n"
".LECIE1:\n\n");
fprintf(ctx->fp,
".LSFDE1:\n"
"\t.long .LEFDE1-.LASFDE1\n"
".LASFDE1:\n"
"\t.long .LASFDE1-.Lframe1\n"
"\t.long .Lbegin-.\n"
"\t.long %d\n"
"\t.uleb128 0\n" /* augmentation length */
"\t.byte 0xe\n\t.uleb128 0x30\n" /* def_cfa_offset */
"\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
"\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
"\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
"\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
"\t.align 4\n"
".LEFDE1:\n\n", (int)ctx->codesz);
break;
case BUILD_machasm:
/* NYI: OSX ignores it. Something must be missing. */
fprintf(ctx->fp, "\t.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n");
fprintf(ctx->fp,
"EH_frame1:\n"
"\t.set L$set$0,LECIE1-LSCIE1\n"
"\t.long L$set$0\n"
"LSCIE1:\n"
"\t.long 0\n"
"\t.byte 0x1\n"
"\t.ascii \"zPR\"\n"
"\t.byte 0x1\n"
"\t.byte 128-4\n"
"\t.byte 0x8\n"
"\t.byte 6\n" /* augmentation length */
"\t.byte 0x9b\n" /* indirect|pcrel|sdata4 */
"\t.long L_lj_err_unwind_dwarf$non_lazy_ptr-.\n"
"\t.byte 0x1b\n" /* pcrel|sdata4 */
"\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH-O. */
"\t.byte 0x88\n\t.byte 0x1\n"
"\t.align 2\n"
"LECIE1:\n\n");
fprintf(ctx->fp,
"_lj_vm_asm_begin.eh:\n"
"LSFDE1:\n"
"\t.set L$set$1,LEFDE1-LASFDE1\n"
"\t.long L$set$1\n"
"LASFDE1:\n"
"\t.long LASFDE1-EH_frame1\n"
"\t.long _lj_vm_asm_begin-.\n"
"\t.long %d\n"
"\t.byte 0\n" /* augmentation length */
"\t.byte 0xe\n\t.byte 0x30\n" /* def_cfa_offset */
"\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
"\t.byte 0x87\n\t.byte 0x3\n" /* offset edi */
"\t.byte 0x86\n\t.byte 0x4\n" /* offset esi */
"\t.byte 0x83\n\t.byte 0x5\n" /* offset ebx */
"\t.align 2\n"
"LEFDE1:\n\n", (int)ctx->codesz);
fprintf(ctx->fp,
"\t.non_lazy_symbol_pointer\n"
"L_lj_err_unwind_dwarf$non_lazy_ptr:\n"
".indirect_symbol _lj_err_unwind_dwarf\n"
".long 0\n");
break; break;
default: /* Difficult for other modes. */ default: /* Difficult for other modes. */
break; break;

View File

@ -20,97 +20,6 @@
#include "lj_err.h" #include "lj_err.h"
#include "lj_lib.h" #include "lj_lib.h"
/* convert a stack index to positive */
#define abs_index(L, i) \
((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1)
/* -- Type checks --------------------------------------------------------- */
LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
{
if (!lua_checkstack(L, size))
lj_err_callerv(L, LJ_ERR_STKOVM, msg);
}
LUALIB_API void luaL_checktype(lua_State *L, int narg, int tt)
{
if (lua_type(L, narg) != tt)
lj_err_argt(L, narg, tt);
}
LUALIB_API void luaL_checkany(lua_State *L, int narg)
{
lj_lib_checkany(L, narg);
}
LUALIB_API const char *luaL_checklstring(lua_State *L, int narg, size_t *len)
{
GCstr *s = lj_lib_checkstr(L, narg);
if (len != NULL) *len = s->len;
return strdata(s);
}
LUALIB_API const char *luaL_optlstring(lua_State *L, int narg,
const char *def, size_t *len)
{
GCstr *s = lj_lib_optstr(L, narg);
if (s) {
if (len != NULL) *len = s->len;
return strdata(s);
}
if (len != NULL) *len = def ? strlen(def) : 0;
return def;
}
LUALIB_API lua_Number luaL_checknumber(lua_State *L, int narg)
{
return lj_lib_checknum(L, narg);
}
LUALIB_API lua_Number luaL_optnumber(lua_State *L, int narg, lua_Number def)
{
lj_lib_opt(L, narg,
return lj_lib_checknum(L, narg);
,
return def;
)
}
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int narg)
{
#if LJ_64
return (lua_Integer)lj_lib_checknum(L, narg);
#else
return lj_lib_checkint(L, narg);
#endif
}
LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int narg, lua_Integer def)
{
#if LJ_64
lj_lib_opt(L, narg,
return (lua_Integer)lj_lib_checknum(L, narg);
,
return def;
)
#else
return lj_lib_optint(L, narg, def);
#endif
}
LUALIB_API int luaL_checkoption(lua_State *L, int narg, const char *def,
const char *const lst[])
{
GCstr *s = lj_lib_optstr(L, narg);
const char *opt = s ? strdata(s) : def;
uint32_t i;
if (!opt) lj_err_argt(L, narg, LUA_TSTRING);
for (i = 0; lst[i]; i++)
if (strcmp(lst[i], opt) == 0)
return (int)i;
lj_err_argv(L, narg, LJ_ERR_INVOPTM, opt);
}
/* -- Module registration ------------------------------------------------- */ /* -- Module registration ------------------------------------------------- */
LUALIB_API const char *luaL_findtable(lua_State *L, int idx, LUALIB_API const char *luaL_findtable(lua_State *L, int idx,
@ -149,6 +58,7 @@ static int libsize(const luaL_Reg *l)
LUALIB_API void luaL_openlib(lua_State *L, const char *libname, LUALIB_API void luaL_openlib(lua_State *L, const char *libname,
const luaL_Reg *l, int nup) const luaL_Reg *l, int nup)
{ {
lj_lib_checkfpu(L);
if (libname) { if (libname) {
int size = libsize(l); int size = libsize(l);
/* check whether lib already exists */ /* check whether lib already exists */
@ -285,6 +195,10 @@ LUALIB_API void luaL_buffinit(lua_State *L, luaL_Buffer *B)
#define FREELIST_REF 0 #define FREELIST_REF 0
/* Convert a stack index to an absolute index. */
#define abs_index(L, i) \
((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1)
LUALIB_API int luaL_ref(lua_State *L, int t) LUALIB_API int luaL_ref(lua_State *L, int t)
{ {
int ref; int ref;

View File

@ -523,8 +523,11 @@ static void io_fenv_new(lua_State *L, int narr, lua_CFunction cls)
LUALIB_API int luaopen_io(lua_State *L) LUALIB_API int luaopen_io(lua_State *L)
{ {
lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
if (tvisnil(L->top-1)) {
LJ_LIB_REG_(L, NULL, io_method); LJ_LIB_REG_(L, NULL, io_method);
lua_setfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); lua_setfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
}
io_fenv_new(L, 0, lj_cf_io_pipe_close); /* top-3 */ io_fenv_new(L, 0, lj_cf_io_pipe_close); /* top-3 */
io_fenv_new(L, 2, lj_cf_io_file_close); /* top-2 */ io_fenv_new(L, 2, lj_cf_io_file_close); /* top-2 */
LJ_LIB_REG(L, io); LJ_LIB_REG(L, io);
@ -532,7 +535,7 @@ LUALIB_API int luaopen_io(lua_State *L)
io_std_new(L, stdin, IO_INPUT, "stdin"); io_std_new(L, stdin, IO_INPUT, "stdin");
io_std_new(L, stdout, IO_OUTPUT, "stdout"); io_std_new(L, stdout, IO_OUTPUT, "stdout");
io_std_new(L, stderr, 0, "stderr"); io_std_new(L, stderr, 0, "stderr");
lua_pop(L, 1); L->top--;
return 1; return 1;
} }

View File

@ -73,8 +73,9 @@ LJLIB_CF(jit_flush)
#if LJ_HASJIT #if LJ_HASJIT
if (L->base < L->top && (tvisnum(L->base) || tvisstr(L->base))) { if (L->base < L->top && (tvisnum(L->base) || tvisstr(L->base))) {
int traceno = lj_lib_checkint(L, 1); int traceno = lj_lib_checkint(L, 1);
luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE); setboolV(L->top-1,
return 0; luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE));
return 1;
} }
#endif #endif
return setjitmode(L, LUAJIT_MODE_FLUSH); return setjitmode(L, LUAJIT_MODE_FLUSH);

View File

@ -69,11 +69,9 @@ LJLIB_ASM_(math_max) LJLIB_REC(math_minmax IR_MAX)
LJLIB_PUSH(3.14159265358979323846) LJLIB_SET(pi) LJLIB_PUSH(3.14159265358979323846) LJLIB_SET(pi)
LJLIB_PUSH(1e310) LJLIB_SET(huge) LJLIB_PUSH(1e310) LJLIB_SET(huge)
#ifdef __MACH__
LJ_FUNCA double lj_wrapper_sinh(double x) { return sinh(x); } LJ_FUNCA double lj_wrapper_sinh(double x) { return sinh(x); }
LJ_FUNCA double lj_wrapper_cosh(double x) { return cosh(x); } LJ_FUNCA double lj_wrapper_cosh(double x) { return cosh(x); }
LJ_FUNCA double lj_wrapper_tanh(double x) { return tanh(x); } LJ_FUNCA double lj_wrapper_tanh(double x) { return tanh(x); }
#endif
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
@ -98,8 +96,8 @@ typedef union { uint64_t u64; double d; } U64double;
z = (((z<<q)^z) >> (k-s)) ^ ((z&((uint64_t)(int64_t)-1 << (64-k)))<<s); \ z = (((z<<q)^z) >> (k-s)) ^ ((z&((uint64_t)(int64_t)-1 << (64-k)))<<s); \
r ^= z; tw->gen[i] = z; r ^= z; tw->gen[i] = z;
/* PRNG step function. Returns a double in the range 0.0 <= d < 1.0. */ /* PRNG step function. Returns a double in the range 1.0 <= d < 2.0. */
static double tw223_step(TW223State *tw) static LJ_NOINLINE double tw223_step(TW223State *tw)
{ {
uint64_t z, r = 0; uint64_t z, r = 0;
U64double u; U64double u;
@ -108,16 +106,7 @@ static double tw223_step(TW223State *tw)
TW223_GEN(2, 55, 24, 7) TW223_GEN(2, 55, 24, 7)
TW223_GEN(3, 47, 21, 8) TW223_GEN(3, 47, 21, 8)
u.u64 = (r & (((uint64_t)1 << 52)-1)) | ((uint64_t)0x3ff << 52); u.u64 = (r & (((uint64_t)1 << 52)-1)) | ((uint64_t)0x3ff << 52);
#if defined(__GNUC__) && LJ_TARGET_X86 && __pic__ return u.d;
/* Compensate for unbelievable GCC pessimization. */
{
volatile U64double u1;
u1.u64 = (uint64_t)0x3f8 << 52;
return u.d - u1.d;
}
#else
return u.d - 1.0;
#endif
} }
/* PRNG initialization function. */ /* PRNG initialization function. */
@ -146,7 +135,7 @@ LJLIB_CF(math_random)
TW223State *tw = (TW223State *)(uddata(udataV(lj_lib_upvalue(L, 1)))); TW223State *tw = (TW223State *)(uddata(udataV(lj_lib_upvalue(L, 1))));
double d; double d;
if (LJ_UNLIKELY(!tw->valid)) tw223_init(tw, 0.0); if (LJ_UNLIKELY(!tw->valid)) tw223_init(tw, 0.0);
d = tw223_step(tw); d = tw223_step(tw) - 1.0;
if (n > 0) { if (n > 0) {
double r1 = lj_lib_checknum(L, 1); double r1 = lj_lib_checknum(L, 1);
if (n == 1) { if (n == 1) {

View File

@ -354,6 +354,7 @@ static int lj_cf_package_require(lua_State *L)
lua_pushvalue(L, -1); /* extra copy to be returned */ lua_pushvalue(L, -1); /* extra copy to be returned */
lua_setfield(L, 2, name); /* _LOADED[name] = true */ lua_setfield(L, 2, name); /* _LOADED[name] = true */
} }
lj_lib_checkfpu(L);
return 1; return 1;
} }

View File

@ -16,6 +16,7 @@
#include "lualib.h" #include "lualib.h"
#include "lj_obj.h" #include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h" #include "lj_err.h"
#include "lj_str.h" #include "lj_str.h"
#include "lj_tab.h" #include "lj_tab.h"
@ -774,6 +775,7 @@ LJLIB_CF(string_format)
LUALIB_API int luaopen_string(lua_State *L) LUALIB_API int luaopen_string(lua_State *L)
{ {
GCtab *mt; GCtab *mt;
GCstr *mmstr;
LJ_LIB_REG(L, string); LJ_LIB_REG(L, string);
#if defined(LUA_COMPAT_GFIND) #if defined(LUA_COMPAT_GFIND)
lua_getfield(L, -1, "gmatch"); lua_getfield(L, -1, "gmatch");
@ -782,8 +784,9 @@ LUALIB_API int luaopen_string(lua_State *L)
mt = lj_tab_new(L, 0, 1); mt = lj_tab_new(L, 0, 1);
/* NOBARRIER: G(L)->mmname[] is a GC root. */ /* NOBARRIER: G(L)->mmname[] is a GC root. */
setgcref(G(L)->basemt[~LJ_TSTR], obj2gco(mt)); setgcref(G(L)->basemt[~LJ_TSTR], obj2gco(mt));
settabV(L, lj_tab_setstr(L, mt, strref(G(L)->mmname[MM_index])), mmstr = strref(G(L)->mmname[MM_index]);
tabV(L->top-1)); if (isdead(G(L), obj2gco(mmstr))) flipwhite(obj2gco(mmstr));
settabV(L, lj_tab_setstr(L, mt, mmstr), tabV(L->top-1));
mt->nomm = cast_byte(~(1u<<MM_index)); mt->nomm = cast_byte(~(1u<<MM_index));
return 1; return 1;
} }

View File

@ -74,21 +74,21 @@ LJLIB_CF(table_maxn)
TValue *array = tvref(t->array); TValue *array = tvref(t->array);
Node *node; Node *node;
lua_Number m = 0; lua_Number m = 0;
uint32_t i; ptrdiff_t i;
for (i = 0; i < t->asize; i++) for (i = (ptrdiff_t)t->asize - 1; i >= 0; i--)
if (!tvisnil(&array[i])) { if (!tvisnil(&array[i])) {
m = (lua_Number)i; m = (lua_Number)(int32_t)i;
break; break;
} }
node = noderef(t->node); node = noderef(t->node);
for (i = 0; i <= t->hmask; i++) for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
if (tvisnum(&node[i].key) && numV(&node[i].key) > m) if (tvisnum(&node[i].key) && numV(&node[i].key) > m)
m = numV(&node[i].key); m = numV(&node[i].key);
setnumV(L->top-1, m); setnumV(L->top-1, m);
return 1; return 1;
} }
LJLIB_CF(table_insert) LJLIB_CF(table_insert) LJLIB_REC(.)
{ {
GCtab *t = lj_lib_checktab(L, 1); GCtab *t = lj_lib_checktab(L, 1);
int32_t n, i = (int32_t)lj_tab_len(t) + 1; int32_t n, i = (int32_t)lj_tab_len(t) + 1;
@ -111,20 +111,20 @@ LJLIB_CF(table_insert)
} }
{ {
TValue *dst = lj_tab_setint(L, t, i); TValue *dst = lj_tab_setint(L, t, i);
copyTV(L, dst, L->top-1); copyTV(L, dst, L->top-1); /* Set new value. */
lj_gc_barriert(L, t, dst); lj_gc_barriert(L, t, dst);
} }
return 0; return 0;
} }
LJLIB_CF(table_remove) LJLIB_CF(table_remove) LJLIB_REC(.)
{ {
GCtab *t = lj_lib_checktab(L, 1); GCtab *t = lj_lib_checktab(L, 1);
int32_t e = (int32_t)lj_tab_len(t); int32_t e = (int32_t)lj_tab_len(t);
int32_t pos = lj_lib_optint(L, 2, e); int32_t pos = lj_lib_optint(L, 2, e);
if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ if (!(1 <= pos && pos <= e)) /* Nothing to remove? */
return 0; /* nothing to remove */ return 0;
lua_rawgeti(L, 1, pos); lua_rawgeti(L, 1, pos); /* Get previous value. */
/* NOBARRIER: This just moves existing elements around. */ /* NOBARRIER: This just moves existing elements around. */
for (; pos < e; pos++) { for (; pos < e; pos++) {
cTValue *src = lj_tab_getint(t, pos+1); cTValue *src = lj_tab_getint(t, pos+1);
@ -135,8 +135,8 @@ LJLIB_CF(table_remove)
setnilV(dst); setnilV(dst);
} }
} }
setnilV(lj_tab_setint(L, t, e)); setnilV(lj_tab_setint(L, t, e)); /* Remove (last) value. */
return 1; return 1; /* Return previous value. */
} }
LJLIB_CF(table_concat) LJLIB_CF(table_concat)

View File

@ -91,6 +91,12 @@ LUA_API int lua_checkstack(lua_State *L, int size)
return 1; return 1;
} }
LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
{
if (!lua_checkstack(L, size))
lj_err_callerv(L, LJ_ERR_STKOVM, msg);
}
LUA_API void lua_xmove(lua_State *from, lua_State *to, int n) LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
{ {
TValue *f, *t; TValue *f, *t;
@ -193,6 +199,18 @@ LUA_API int lua_type(lua_State *L, int idx)
} }
} }
LUALIB_API void luaL_checktype(lua_State *L, int idx, int tt)
{
if (lua_type(L, idx) != tt)
lj_err_argt(L, idx, tt);
}
LUALIB_API void luaL_checkany(lua_State *L, int idx)
{
if (index2adr(L, idx) == niltv(L))
lj_err_arg(L, idx, LJ_ERR_NOVAL);
}
LUA_API const char *lua_typename(lua_State *L, int t) LUA_API const char *lua_typename(lua_State *L, int t)
{ {
UNUSED(L); UNUSED(L);
@ -202,7 +220,7 @@ LUA_API const char *lua_typename(lua_State *L, int t)
LUA_API int lua_iscfunction(lua_State *L, int idx) LUA_API int lua_iscfunction(lua_State *L, int idx)
{ {
cTValue *o = index2adr(L, idx); cTValue *o = index2adr(L, idx);
return !isluafunc(funcV(o)); return tvisfunc(o) && !isluafunc(funcV(o));
} }
LUA_API int lua_isnumber(lua_State *L, int idx) 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)
return 0; return 0;
} }
LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
{
cTValue *o = index2adr(L, idx);
TValue tmp;
if (tvisnum(o))
return numV(o);
else if (!(tvisstr(o) && lj_str_numconv(strVdata(o), &tmp)))
lj_err_argt(L, idx, LUA_TNUMBER);
return numV(&tmp);
}
LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def)
{
cTValue *o = index2adr(L, idx);
TValue tmp;
if (tvisnum(o))
return numV(o);
else if (tvisnil(o))
return def;
else if (!(tvisstr(o) && lj_str_numconv(strVdata(o), &tmp)))
lj_err_argt(L, idx, LUA_TNUMBER);
return numV(&tmp);
}
LUA_API lua_Integer lua_tointeger(lua_State *L, int idx) LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
{ {
cTValue *o = index2adr(L, idx); cTValue *o = index2adr(L, idx);
@ -313,6 +355,44 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
#endif #endif
} }
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
{
cTValue *o = index2adr(L, idx);
TValue tmp;
lua_Number n;
if (LJ_LIKELY(tvisnum(o)))
n = numV(o);
else if (tvisstr(o) && lj_str_numconv(strVdata(o), &tmp))
n = numV(&tmp);
else
lj_err_argt(L, idx, LUA_TNUMBER);
#if LJ_64
return (lua_Integer)n;
#else
return lj_num2int(n);
#endif
}
LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
{
cTValue *o = index2adr(L, idx);
TValue tmp;
lua_Number n;
if (LJ_LIKELY(tvisnum(o)))
n = numV(o);
else if (tvisnil(o))
return def;
else if (tvisstr(o) && lj_str_numconv(strVdata(o), &tmp))
n = numV(&tmp);
else
lj_err_argt(L, idx, LUA_TNUMBER);
#if LJ_64
return (lua_Integer)n;
#else
return lj_num2int(n);
#endif
}
LUA_API int lua_toboolean(lua_State *L, int idx) LUA_API int lua_toboolean(lua_State *L, int idx)
{ {
cTValue *o = index2adr(L, idx); cTValue *o = index2adr(L, idx);
@ -337,6 +417,57 @@ LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
return strdata(s); return strdata(s);
} }
LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
{
TValue *o = index2adr(L, idx);
GCstr *s;
if (LJ_LIKELY(tvisstr(o))) {
s = strV(o);
} else if (tvisnum(o)) {
lj_gc_check(L);
o = index2adr(L, idx); /* GC may move the stack. */
s = lj_str_fromnum(L, &o->n);
} else {
lj_err_argt(L, idx, LUA_TSTRING);
}
if (len != NULL) *len = s->len;
return strdata(s);
}
LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
const char *def, size_t *len)
{
TValue *o = index2adr(L, idx);
GCstr *s;
if (LJ_LIKELY(tvisstr(o))) {
s = strV(o);
} else if (tvisnil(o)) {
if (len != NULL) *len = def ? strlen(def) : 0;
return def;
} else if (tvisnum(o)) {
lj_gc_check(L);
o = index2adr(L, idx); /* GC may move the stack. */
s = lj_str_fromnum(L, &o->n);
} else {
lj_err_argt(L, idx, LUA_TSTRING);
}
if (len != NULL) *len = s->len;
return strdata(s);
}
LUALIB_API int luaL_checkoption(lua_State *L, int idx, const char *def,
const char *const lst[])
{
ptrdiff_t i;
const char *s = lua_tolstring(L, idx, NULL);
if (s == NULL && (s = def) == NULL)
lj_err_argt(L, idx, LUA_TSTRING);
for (i = 0; lst[i]; i++)
if (strcmp(lst[i], s) == 0)
return (int)i;
lj_err_argv(L, idx, LJ_ERR_INVOPTM, s);
}
LUA_API size_t lua_objlen(lua_State *L, int idx) LUA_API size_t lua_objlen(lua_State *L, int idx)
{ {
TValue *o = index2adr(L, idx); TValue *o = index2adr(L, idx);
@ -355,7 +486,8 @@ LUA_API size_t lua_objlen(lua_State *L, int idx)
LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx) LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx)
{ {
cTValue *o = index2adr(L, idx); cTValue *o = index2adr(L, idx);
return funcV(o)->c.gate == lj_gate_c ? funcV(o)->c.f : NULL; ASMFunction gate = funcV(o)->c.gate;
return (gate == lj_gate_c || gate == lj_gate_cwrap) ? funcV(o)->c.f : NULL;
} }
LUA_API void *lua_touserdata(lua_State *L, int idx) LUA_API void *lua_touserdata(lua_State *L, int idx)

View File

@ -738,11 +738,14 @@ static Reg ra_allocref(ASMState *as, IRRef ref, RegSet allow)
} }
RA_DBGX((as, "hintmiss $f $r", ref, r)); RA_DBGX((as, "hintmiss $f $r", ref, r));
} }
/* Invariants should preferably get unused registers. */ /* Invariants should preferably get unmodified registers. */
if (ref < as->loopref && !irt_isphi(ir->t)) if (ref < as->loopref && !irt_isphi(ir->t)) {
r = rset_pickbot(pick); if ((pick & ~as->modset))
else pick &= ~as->modset;
r = rset_pickbot(pick); /* Reduce conflicts with inverse allocation. */
} else {
r = rset_picktop(pick); r = rset_picktop(pick);
}
} else { } else {
r = ra_evict(as, allow); r = ra_evict(as, allow);
} }

View File

@ -153,8 +153,7 @@ int luaJIT_setmode(lua_State *L, int idx, int mode)
case LUAJIT_MODE_TRACE: case LUAJIT_MODE_TRACE:
if (!(mode & LUAJIT_MODE_FLUSH)) if (!(mode & LUAJIT_MODE_FLUSH))
return 0; /* Failed. */ return 0; /* Failed. */
lj_trace_flush(G2J(g), idx); return lj_trace_flush(G2J(g), idx);
break;
#else #else
case LUAJIT_MODE_ENGINE: case LUAJIT_MODE_ENGINE:
case LUAJIT_MODE_FUNC: case LUAJIT_MODE_FUNC:
@ -165,6 +164,20 @@ int luaJIT_setmode(lua_State *L, int idx, int mode)
return 0; /* Failed. */ return 0; /* Failed. */
break; break;
#endif #endif
case LUAJIT_MODE_WRAPCFUNC:
if ((mode & LUAJIT_MODE_ON)) {
if (idx != 0) {
cTValue *tv = idx > 0 ? L->base + (idx-1) : L->top + idx;
if (tvislightud(tv) && lightudV(tv) != NULL)
g->wrapf = (lua_CFunction)lightudV(tv);
else
return 0; /* Failed. */
}
g->wrapmode = 1;
} else {
g->wrapmode = 0;
}
break;
default: default:
return 0; /* Failed. */ return 0; /* Failed. */
} }

View File

@ -676,6 +676,8 @@ LJ_NORET LJ_NOINLINE static void err_argmsg(lua_State *L, int narg,
{ {
const char *fname = "?"; const char *fname = "?";
const char *ftype = getfuncname(L, L->base - 1, &fname); const char *ftype = getfuncname(L, L->base - 1, &fname);
if (narg < 0 && narg > LUA_REGISTRYINDEX)
narg = (L->top - L->base) + narg + 1;
if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */ if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */
msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg); msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg);
else else
@ -761,3 +763,47 @@ LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...)
return 0; /* unreachable */ return 0; /* unreachable */
} }
/* -- C++ exception support ----------------------------------------------- */
#if defined(__ELF__) || defined(__MACH__)
typedef enum
{
_URC_NO_REASON,
_URC_FOREIGN_EXCEPTION_CAUGHT,
_URC_FATAL_PHASE2_ERROR,
_URC_FATAL_PHASE1_ERROR,
_URC_NORMAL_STOP,
_URC_END_OF_STACK,
_URC_HANDLER_FOUND,
_URC_INSTALL_CONTEXT,
_URC_CONTINUE_UNWIND
} _Unwind_Reason_Code;
#define _UA_SEARCH_PHASE 1
#define _UA_CLEANUP_PHASE 2
#define _UA_HANDLER_FRAME 4
#define _UA_FORCE_UNWIND 8
#define _UA_END_OF_STACK 16
extern void *_Unwind_GetCFA(void *ctx);
extern void _Unwind_DeleteException(void *uex);
/* DWARF2 personality handler referenced from .eh_frame. */
LJ_FUNCA int lj_err_unwind_dwarf(int version, int actions, uint64_t uexclass,
void *uex, void *ctx)
{
if (version != 1)
return _URC_FATAL_PHASE1_ERROR;
UNUSED(uexclass);
if ((actions & _UA_SEARCH_PHASE))
return _URC_HANDLER_FOUND;
if ((actions & _UA_HANDLER_FRAME)) {
void *cf = _Unwind_GetCFA(ctx);
lua_State *L = cframe_L(cf);
_Unwind_DeleteException(uex);
lj_err_msg(L, LJ_ERR_ERRCPP);
}
return _URC_CONTINUE_UNWIND;
}
#endif

View File

@ -8,6 +8,7 @@
/* Basic error handling. */ /* Basic error handling. */
ERRDEF(ERRMEM, "not enough memory") ERRDEF(ERRMEM, "not enough memory")
ERRDEF(ERRERR, "error in error handling") ERRDEF(ERRERR, "error in error handling")
ERRDEF(ERRCPP, "C++ exception")
/* Allocations. */ /* Allocations. */
ERRDEF(STROV, "string length overflow") ERRDEF(STROV, "string length overflow")
@ -56,6 +57,9 @@ ERRDEF(NOENV, "no calling environment")
ERRDEF(CYIELD, "attempt to yield across C-call boundary") ERRDEF(CYIELD, "attempt to yield across C-call boundary")
ERRDEF(BADLU, "bad light userdata pointer") ERRDEF(BADLU, "bad light userdata pointer")
ERRDEF(NOGCMM, "bad action while in __gc metamethod") ERRDEF(NOGCMM, "bad action while in __gc metamethod")
#ifdef LUA_USE_WIN
ERRDEF(BADFPU, "bad FPU precision (use D3DCREATE_FPU_PRESERVE with DirectX)")
#endif
/* Standard library function errors. */ /* Standard library function errors. */
ERRDEF(ASSERT, "assertion failed!") ERRDEF(ASSERT, "assertion failed!")

View File

@ -138,7 +138,7 @@ GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env)
fn->c.nupvalues = cast_byte(nelems); fn->c.nupvalues = cast_byte(nelems);
/* NOBARRIER: The GCfunc is new (marked white). */ /* NOBARRIER: The GCfunc is new (marked white). */
setgcref(fn->c.env, obj2gco(env)); setgcref(fn->c.env, obj2gco(env));
fn->c.gate = lj_gate_c; fn->c.gate = G(L)->wrapmode ? lj_gate_cwrap : lj_gate_c;
return fn; return fn;
} }

View File

@ -230,8 +230,7 @@ static void gc_traverse_trace(global_State *g, Trace *T)
/* The current trace is a GC root while not anchored in the prototype (yet). */ /* The current trace is a GC root while not anchored in the prototype (yet). */
#define gc_mark_curtrace(g) \ #define gc_mark_curtrace(g) \
{ if (G2J(g)->state != LJ_TRACE_IDLE && G2J(g)->curtrace != 0) \ { if (G2J(g)->curtrace != 0) gc_traverse_trace(g, &G2J(g)->cur); }
gc_traverse_trace(g, &G2J(g)->cur); }
#else #else
#define gc_mark_curtrace(g) UNUSED(g) #define gc_mark_curtrace(g) UNUSED(g)
#endif #endif

View File

@ -252,6 +252,7 @@ TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t)
{ {
IRIns *ir, *cir = J->cur.ir; IRIns *ir, *cir = J->cur.ir;
IRRef ref; IRRef ref;
lua_assert(!isdead(J2G(J), o));
for (ref = J->chain[IR_KGC]; ref; ref = cir[ref].prev) for (ref = J->chain[IR_KGC]; ref; ref = cir[ref].prev)
if (ir_kgc(&cir[ref]) == o) if (ir_kgc(&cir[ref]) == o)
goto found; goto found;

View File

@ -48,6 +48,15 @@ LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst);
#define lj_lib_upvalue(L, n) \ #define lj_lib_upvalue(L, n) \
(&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1]) (&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1])
#ifdef LUA_USE_WIN
#define lj_lib_checkfpu(L) \
do { setnumV(L->top++, (lua_Number)1437217655); \
if (lua_tointeger(L, -1) != 1437217655) lj_err_caller(L, LJ_ERR_BADFPU); \
L->top--; } while (0)
#else
#define lj_lib_checkfpu(L) UNUSED(L)
#endif
/* Library function declarations. Scanned by buildvm. */ /* Library function declarations. Scanned by buildvm. */
#define LJLIB_CF(name) static int lj_cf_##name(lua_State *L) #define LJLIB_CF(name) static int lj_cf_##name(lua_State *L)
#define LJLIB_ASM(name) static int lj_ffh_##name(lua_State *L) #define LJLIB_ASM(name) static int lj_ffh_##name(lua_State *L)

View File

@ -531,7 +531,7 @@ typedef struct global_State {
uint8_t hookmask; /* Hook mask. */ uint8_t hookmask; /* Hook mask. */
uint8_t dispatchmode; /* Dispatch mode. */ uint8_t dispatchmode; /* Dispatch mode. */
uint8_t vmevmask; /* VM event mask. */ uint8_t vmevmask; /* VM event mask. */
uint8_t unused1; uint8_t wrapmode; /* Wrap mode. */
GCRef mainthref; /* Link to main thread. */ GCRef mainthref; /* Link to main thread. */
TValue registrytv; /* Anchor for registry. */ TValue registrytv; /* Anchor for registry. */
TValue tmptv; /* Temporary TValue. */ TValue tmptv; /* Temporary TValue. */
@ -539,6 +539,7 @@ typedef struct global_State {
int32_t hookcount; /* Instruction hook countdown. */ int32_t hookcount; /* Instruction hook countdown. */
int32_t hookcstart; /* Start count for instruction hook counter. */ int32_t hookcstart; /* Start count for instruction hook counter. */
lua_Hook hookf; /* Hook function. */ lua_Hook hookf; /* Hook function. */
lua_CFunction wrapf; /* Wrapper for C function calls. */
lua_CFunction panic; /* Called as a last resort for errors. */ lua_CFunction panic; /* Called as a last resort for errors. */
volatile int32_t vmstate; /* VM state or current JIT code trace number. */ volatile int32_t vmstate; /* VM state or current JIT code trace number. */
GCRef jit_L; /* Current JIT code lua_State or NULL. */ GCRef jit_L; /* Current JIT code lua_State or NULL. */

View File

@ -138,7 +138,7 @@ typedef IRRef (LJ_FASTCALL *FoldFunc)(jit_State *J);
/* Macros for the fold specs, so buildvm can recognize them. */ /* Macros for the fold specs, so buildvm can recognize them. */
#define LJFOLD(x) #define LJFOLD(x)
#define LJFOLDX(x) #define LJFOLDX(x)
#define LJFOLDF(name) static TRef LJ_FASTCALL name(jit_State *J) #define LJFOLDF(name) static TRef LJ_FASTCALL fold_##name(jit_State *J)
/* Note: They must be at the start of a line or buildvm ignores them! */ /* Note: They must be at the start of a line or buildvm ignores them! */
/* Barrier to prevent using operands across PHIs. */ /* Barrier to prevent using operands across PHIs. */
@ -979,7 +979,7 @@ LJFOLDF(comm_equal)
/* For non-numbers only: x == x ==> drop; x ~= x ==> fail */ /* For non-numbers only: x == x ==> drop; x ~= x ==> fail */
if (fins->op1 == fins->op2 && !irt_isnum(fins->t)) if (fins->op1 == fins->op2 && !irt_isnum(fins->t))
return CONDFOLD(fins->o == IR_EQ); return CONDFOLD(fins->o == IR_EQ);
return comm_swap(J); return fold_comm_swap(J);
} }
LJFOLD(LT any any) LJFOLD(LT any any)
@ -1013,7 +1013,7 @@ LJFOLDF(comm_dup)
{ {
if (fins->op1 == fins->op2) /* x o x ==> x */ if (fins->op1 == fins->op2) /* x o x ==> x */
return LEFTFOLD; return LEFTFOLD;
return comm_swap(J); return fold_comm_swap(J);
} }
LJFOLD(BXOR any any) LJFOLD(BXOR any any)
@ -1021,7 +1021,7 @@ LJFOLDF(comm_bxor)
{ {
if (fins->op1 == fins->op2) /* i xor i ==> 0 */ if (fins->op1 == fins->op2) /* i xor i ==> 0 */
return INTFOLD(0); return INTFOLD(0);
return comm_swap(J); return fold_comm_swap(J);
} }
/* -- Simplification of compound expressions ------------------------------ */ /* -- Simplification of compound expressions ------------------------------ */

View File

@ -286,7 +286,7 @@ static void loop_unroll(jit_State *J)
if (!irt_sametype(t, irr->t)) { if (!irt_sametype(t, irr->t)) {
if (irt_isnum(t) && irt_isinteger(irr->t)) /* Fix int->num case. */ if (irt_isnum(t) && irt_isinteger(irr->t)) /* Fix int->num case. */
subst[ins] = tref_ref(emitir(IRTN(IR_TONUM), ref, 0)); subst[ins] = tref_ref(emitir(IRTN(IR_TONUM), ref, 0));
else else if (!(irt_isinteger(t) && irt_isinteger(irr->t)))
lj_trace_err(J, LJ_TRERR_TYPEINS); lj_trace_err(J, LJ_TRERR_TYPEINS);
} }
} }

View File

@ -519,8 +519,8 @@ int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref)
} else if (irt_isnil(store->t)) { /* Must check any nil store. */ } else if (irt_isnil(store->t)) { /* Must check any nil store. */
IRRef skref = IR(store->op1)->op2; IRRef skref = IR(store->op1)->op2;
IRRef xkref = IR(xref)->op2; IRRef xkref = IR(xref)->op2;
/* Same key type MAY alias. */ /* Same key type MAY alias. Need ALOAD check due to multiple int types. */
if (irt_sametype(IR(skref)->t, IR(xkref)->t)) { if (loadop == IR_ALOAD || irt_sametype(IR(skref)->t, IR(xkref)->t)) {
if (skref == xkref || !irref_isk(skref) || !irref_isk(xkref)) if (skref == xkref || !irref_isk(skref) || !irref_isk(xkref))
return 0; /* A nil store with same const key or var key MAY alias. */ return 0; /* A nil store with same const key or var key MAY alias. */
/* Different const keys CANNOT alias. */ /* Different const keys CANNOT alias. */

View File

@ -168,8 +168,8 @@ static int rec_objcmp(jit_State *J, TRef a, TRef b, cTValue *av, cTValue *bv)
{ {
int diff = !lj_obj_equal(av, bv); int diff = !lj_obj_equal(av, bv);
if (!tref_isk2(a, b)) { /* Shortcut, also handles primitives. */ if (!tref_isk2(a, b)) { /* Shortcut, also handles primitives. */
IRType ta = tref_type(a); IRType ta = tref_isinteger(a) ? IRT_INT : tref_type(a);
IRType tb = tref_type(b); IRType tb = tref_isinteger(b) ? IRT_INT : tref_type(b);
if (ta != tb) { if (ta != tb) {
/* Widen mixed number/int comparisons to number/number comparison. */ /* Widen mixed number/int comparisons to number/number comparison. */
if (ta == IRT_INT && tb == IRT_NUM) { if (ta == IRT_INT && tb == IRT_NUM) {
@ -447,7 +447,7 @@ static int rec_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
mix.tab = lj_ir_ktab(J, mt); mix.tab = lj_ir_ktab(J, mt);
goto nocheck; goto nocheck;
} }
ix->mt = mix.tab; ix->mt = mt ? mix.tab : TREF_NIL;
emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB)); emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB));
nocheck: nocheck:
if (mt) { if (mt) {
@ -457,6 +457,8 @@ nocheck:
copyTV(J->L, &ix->mobjv, mo); copyTV(J->L, &ix->mobjv, mo);
ix->mtv = mt; ix->mtv = mt;
settabV(J->L, &mix.tabv, mt); settabV(J->L, &mix.tabv, mt);
if (isdead(J2G(J), obj2gco(mmstr)))
flipwhite(obj2gco(mmstr)); /* Need same logic as lj_str_new(). */
setstrV(J->L, &mix.keyv, mmstr); setstrV(J->L, &mix.keyv, mmstr);
mix.key = lj_ir_kstr(J, mmstr); mix.key = lj_ir_kstr(J, mmstr);
mix.val = 0; mix.val = 0;
@ -880,7 +882,7 @@ static void recff_nyi(jit_State *J, TRef *res, RecordFFData *rd)
lj_trace_err_info(J, LJ_TRERR_NYIFF); lj_trace_err_info(J, LJ_TRERR_NYIFF);
} }
LJ_NORET static void recff_err_ffu(jit_State *J, RecordFFData *rd) LJ_NORET static void recff_err_nyi(jit_State *J, RecordFFData *rd)
{ {
setfuncV(J->L, &J->errinfo, rd->fn); setfuncV(J->L, &J->errinfo, rd->fn);
lj_trace_err_info(J, LJ_TRERR_NYIFFU); lj_trace_err_info(J, LJ_TRERR_NYIFFU);
@ -986,7 +988,7 @@ static void recff_tonumber(jit_State *J, TRef *res, RecordFFData *rd)
if (arg[1]) { if (arg[1]) {
TRef base = lj_ir_toint(J, arg[1]); TRef base = lj_ir_toint(J, arg[1]);
if (!tref_isk(base) || IR(tref_ref(base))->i != 10) if (!tref_isk(base) || IR(tref_ref(base))->i != 10)
recff_err_ffu(J, rd); recff_err_nyi(J, rd);
} }
if (tref_isstr(tr)) if (tref_isstr(tr))
tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0); tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
@ -1016,7 +1018,7 @@ static void recff_tostring(jit_State *J, TRef *res, RecordFFData *rd)
} else if (tref_isnumber(tr)) { } else if (tref_isnumber(tr)) {
res[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0); res[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0);
} else { } else {
recff_err_ffu(J, rd); recff_err_nyi(J, rd);
} }
} }
} }
@ -1338,6 +1340,58 @@ static void recff_table_getn(jit_State *J, TRef *res, RecordFFData *rd)
UNUSED(rd); UNUSED(rd);
} }
static void recff_table_remove(jit_State *J, TRef *res, RecordFFData *rd)
{
if (tref_istab(arg[0])) {
if (!arg[1] || tref_isnil(arg[1])) { /* Simple pop: t[#t] = nil */
TRef trlen = emitir(IRTI(IR_TLEN), arg[0], 0);
GCtab *t = tabV(&rd->argv[0]);
MSize len = lj_tab_len(t);
emitir(IRTGI(len ? IR_NE : IR_EQ), trlen, lj_ir_kint(J, 0));
if (len) {
RecordIndex ix;
ix.tab = arg[0];
ix.key = trlen;
settabV(J->L, &ix.tabv, t);
setintV(&ix.keyv, len);
ix.idxchain = 0;
if (rd->cres != 0) { /* Specialize load only if result needed. */
ix.val = 0;
res[0] = rec_idx(J, &ix); /* Load previous value. */
/* Assumes ix.key/ix.tab is not modified for raw rec_idx(). */
}
ix.val = TREF_NIL;
rec_idx(J, &ix); /* Remove value. */
} else {
rd->nres = 0;
}
} else { /* Complex case: remove in the middle. */
recff_err_nyi(J, rd);
}
} /* else: Interpreter will throw. */
}
static void recff_table_insert(jit_State *J, TRef *res, RecordFFData *rd)
{
rd->nres = 0;
if (tref_istab(arg[0]) && arg[1]) {
if (!arg[2]) { /* Simple push: t[#t+1] = v */
TRef trlen = emitir(IRTI(IR_TLEN), arg[0], 0);
GCtab *t = tabV(&rd->argv[0]);
RecordIndex ix;
ix.tab = arg[0];
ix.val = arg[1];
ix.key = emitir(IRTI(IR_ADD), trlen, lj_ir_kint(J, 1));
settabV(J->L, &ix.tabv, t);
setintV(&ix.keyv, lj_tab_len(t) + 1);
ix.idxchain = 0;
rec_idx(J, &ix); /* Set new value. */
} else { /* Complex case: insert in the middle. */
recff_err_nyi(J, rd);
}
} /* else: Interpreter will throw. */
}
/* -- Record calls and returns -------------------------------------------- */ /* -- Record calls and returns -------------------------------------------- */
#undef arg #undef arg
@ -1618,8 +1672,8 @@ void lj_record_ins(jit_State *J)
case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
/* Emit nothing for two numeric or string consts. */ /* Emit nothing for two numeric or string consts. */
if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) { if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) {
IRType ta = tref_type(ra); IRType ta = tref_isinteger(ra) ? IRT_INT : tref_type(ra);
IRType tc = tref_type(rc); IRType tc = tref_isinteger(rc) ? IRT_INT : tref_type(rc);
int irop; int irop;
if (ta != tc) { if (ta != tc) {
/* Widen mixed number/int comparisons to number/number comparison. */ /* Widen mixed number/int comparisons to number/number comparison. */

View File

@ -191,8 +191,8 @@ GCtab *lj_tab_dup(lua_State *L, const GCtab *kt)
Node *kn = &knode[i]; Node *kn = &knode[i];
Node *n = &node[i]; Node *n = &node[i];
Node *next = nextnode(kn); Node *next = nextnode(kn);
copyTV(L, &n->val, &kn->val); /* Don't use copyTV here, since it asserts on a copy of a DEADKEY. */
copyTV(L, &n->key, &kn->key); n->val = kn->val; n->key = kn->key;
setmref(n->next, next == NULL? next : (Node *)((char *)next + d)); setmref(n->next, next == NULL? next : (Node *)((char *)next + d));
} }
} }

View File

@ -191,18 +191,12 @@ static void trace_unpatch(jit_State *J, Trace *T)
} }
} }
/* Flush a root trace and any attached side traces. */ /* Free a root trace and any attached side traces. */
void lj_trace_flush(jit_State *J, TraceNo traceno) static void trace_freeroot(jit_State *J, Trace *T, TraceNo traceno)
{ {
Trace *T = NULL; GCproto *pt = &gcref(T->startpt)->pt;
GCproto *pt;
if (traceno > 0 && traceno <= J->sizetrace)
T = J->trace[traceno];
if (T == NULL)
return;
pt = &gcref(T->startpt)->pt;
if (T->root == 0 && pt != NULL) {
TraceNo side; TraceNo side;
lua_assert(T->root == 0 && pt != NULL);
/* First unpatch any modified bytecode. */ /* First unpatch any modified bytecode. */
trace_unpatch(J, T); trace_unpatch(J, T);
/* Unlink root trace from chain anchored in prototype. */ /* Unlink root trace from chain anchored in prototype. */
@ -224,14 +218,31 @@ void lj_trace_flush(jit_State *J, TraceNo traceno)
} }
/* Now free the trace itself. */ /* Now free the trace itself. */
trace_free(J, traceno); trace_free(J, traceno);
} /* Flush for non-root traces is currently ignored. */ }
/* Flush a root trace + side traces, if there are no links to it. */
int lj_trace_flush(jit_State *J, TraceNo traceno)
{
if (traceno > 0 && traceno < J->sizetrace) {
Trace *T = J->trace[traceno];
if (T && T->root == 0) {
ptrdiff_t i;
for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--)
if (i != (ptrdiff_t)traceno && J->trace[i] &&
J->trace[i]->root != traceno && J->trace[i]->link == traceno)
return 0; /* Failed: existing link to trace. */
trace_freeroot(J, T, traceno);
return 1; /* Ok. */
}
}
return 0; /* Failed. */
} }
/* Flush all traces associated with a prototype. */ /* Flush all traces associated with a prototype. */
void lj_trace_flushproto(global_State *g, GCproto *pt) void lj_trace_flushproto(global_State *g, GCproto *pt)
{ {
while (pt->trace != 0) while (pt->trace != 0)
lj_trace_flush(G2J(g), pt->trace); trace_freeroot(G2J(g), G2J(g)->trace[pt->trace], pt->trace);
} }
/* Flush all traces. */ /* Flush all traces. */
@ -241,8 +252,11 @@ int lj_trace_flushall(lua_State *L)
ptrdiff_t i; ptrdiff_t i;
if ((J2G(J)->hookmask & HOOK_GC)) if ((J2G(J)->hookmask & HOOK_GC))
return 1; return 1;
for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) {
lj_trace_flush(J, (TraceNo)i); Trace *T = J->trace[i];
if (T && T->root == 0)
trace_freeroot(J, T, (TraceNo)i);
}
#ifdef LUA_USE_ASSERT #ifdef LUA_USE_ASSERT
for (i = 0; i < (ptrdiff_t)J->sizetrace; i++) for (i = 0; i < (ptrdiff_t)J->sizetrace; i++)
lua_assert(J->trace[i] == NULL); lua_assert(J->trace[i] == NULL);

View File

@ -26,7 +26,7 @@ LJ_FUNC_NORET void lj_trace_err_info(jit_State *J, TraceError e);
LJ_FUNC void lj_trace_freeproto(global_State *g, GCproto *pt); LJ_FUNC void lj_trace_freeproto(global_State *g, GCproto *pt);
LJ_FUNC void lj_trace_reenableproto(GCproto *pt); LJ_FUNC void lj_trace_reenableproto(GCproto *pt);
LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt); LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt);
LJ_FUNC void lj_trace_flush(jit_State *J, TraceNo traceno); LJ_FUNC int lj_trace_flush(jit_State *J, TraceNo traceno);
LJ_FUNC int lj_trace_flushall(lua_State *L); LJ_FUNC int lj_trace_flushall(lua_State *L);
LJ_FUNC void lj_trace_freestate(global_State *g); LJ_FUNC void lj_trace_freestate(global_State *g);

View File

@ -46,6 +46,7 @@ LJ_ASMF void lj_vm_powi(void);
LJ_ASMF void lj_gate_lf(void); LJ_ASMF void lj_gate_lf(void);
LJ_ASMF void lj_gate_lv(void); LJ_ASMF void lj_gate_lv(void);
LJ_ASMF void lj_gate_c(void); LJ_ASMF void lj_gate_c(void);
LJ_ASMF void lj_gate_cwrap(void);
/* Continuations for metamethods. */ /* Continuations for metamethods. */
LJ_ASMF void lj_cont_cat(void); /* Continue with concatenation. */ 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. */
LJ_ASMF void lj_cont_condf(void); /* Branch if result is false. */ LJ_ASMF void lj_cont_condf(void); /* Branch if result is false. */
/* Start of the ASM code. */ /* Start of the ASM code. */
LJ_ASMF void lj_vm_asm_begin(void); LJ_ASMF char lj_vm_asm_begin[];
/* Opcode handler offsets, relative to lj_vm_asm_begin. */ /* Opcode handler offsets, relative to lj_vm_asm_begin. */
LJ_ASMF const uint16_t lj_vm_op_ofs[]; LJ_ASMF const uint16_t lj_vm_op_ofs[];
#define makeasmfunc(ofs) \ #define makeasmfunc(ofs) ((ASMFunction)(lj_vm_asm_begin + (ofs)))
((ASMFunction)((char *)lj_vm_asm_begin + (ofs)))
#endif #endif

View File

@ -1,9 +1,9 @@
// lua.hpp // C++ wrapper for LuaJIT header files.
// Lua header files for C++
// <<extern "C">> not supplied automatically because Lua also compiles as C++
extern "C" { extern "C" {
#include "lua.h" #include "lua.h"
#include "lualib.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h"
#include "luajit.h"
} }

View File

@ -34,13 +34,22 @@
".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
#else #else
#define LUA_ROOT "/usr/local/" #define LUA_ROOT "/usr/local/"
#define LUA_JDIR LUA_ROOT "share/luajit-2.0.0-beta1/"
#define LUA_LDIR LUA_ROOT "share/lua/5.1/" #define LUA_LDIR LUA_ROOT "share/lua/5.1/"
#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" #define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
#ifdef LUA_XROOT
#define LUA_JDIR LUA_XROOT "share/luajit-2.0.0-beta2/"
#define LUA_XPATH \
";" LUA_XROOT "share/lua/5.1/?.lua;" LUA_XROOT "share/lua/5.1/?/init.lua"
#define LUA_XCPATH LUA_XROOT "lib/lua/5.1/?.lua;"
#else
#define LUA_JDIR LUA_ROOT "share/luajit-2.0.0-beta2/"
#define LUA_XPATH
#define LUA_XCPATH
#endif
#define LUA_PATH_DEFAULT \ #define LUA_PATH_DEFAULT \
"./?.lua;" LUA_JDIR"?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" "./?.lua;" LUA_JDIR"?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua" LUA_XPATH
#define LUA_CPATH_DEFAULT \ #define LUA_CPATH_DEFAULT \
"./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" "./?.so;" LUA_CDIR"?.so;" LUA_XCPATH LUA_CDIR"loadall.so"
#endif #endif
/* Environment variable names for path overrides and initialization code. */ /* Environment variable names for path overrides and initialization code. */

View File

@ -55,16 +55,16 @@ static void laction(int i)
static void print_usage(void) static void print_usage(void)
{ {
fprintf(stderr, fprintf(stderr,
"usage: %s [options] [script [args]].\n" "usage: %s [options]... [script [args]...].\n"
"Available options are:\n" "Available options are:\n"
" -e stat execute string " LUA_QL("stat") "\n" " -e chunk Execute string " LUA_QL("chunk") ".\n"
" -l name require library " LUA_QL("name") "\n" " -l name Require library " LUA_QL("name") ".\n"
" -j cmd perform LuaJIT control command\n" " -j cmd Perform LuaJIT control command.\n"
" -O[lvl] set LuaJIT optimization level\n" " -O[opt] Control LuaJIT optimizations.\n"
" -i enter interactive mode after executing " LUA_QL("script") "\n" " -i Enter interactive mode after executing " LUA_QL("script") ".\n"
" -v show version information\n" " -v Show version information.\n"
" -- stop handling options\n" " -- Stop handling options.\n"
" - execute stdin and stop handling options\n" " - Execute stdin and stop handling options.\n"
, ,
progname); progname);
fflush(stderr); fflush(stderr);
@ -143,7 +143,7 @@ static void print_jit_status(lua_State *L)
fputs(lua_toboolean(L, n) ? "JIT: ON" : "JIT: OFF", stderr); fputs(lua_toboolean(L, n) ? "JIT: ON" : "JIT: OFF", stderr);
for (n++; (s = lua_tostring(L, n)); n++) for (n++; (s = lua_tostring(L, n)); n++)
fprintf(stderr, " %s", s); fprintf(stderr, " %s", s);
fputs("\n", stdout); fputs("\n", stderr);
} }
static int getargs(lua_State *L, char **argv, int n) static int getargs(lua_State *L, char **argv, int n)

View File

@ -30,9 +30,9 @@
#include "lua.h" #include "lua.h"
#define LUAJIT_VERSION "LuaJIT 2.0.0-beta1" #define LUAJIT_VERSION "LuaJIT 2.0.0-beta2"
#define LUAJIT_VERSION_NUM 20000 /* Version 2.0.0 = 02.00.00. */ #define LUAJIT_VERSION_NUM 20000 /* Version 2.0.0 = 02.00.00. */
#define LUAJIT_VERSION_SYM luaJIT_version_2_0_0_beta1 #define LUAJIT_VERSION_SYM luaJIT_version_2_0_0_beta2
#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2009 Mike Pall" #define LUAJIT_COPYRIGHT "Copyright (C) 2005-2009 Mike Pall"
#define LUAJIT_URL "http://luajit.org/" #define LUAJIT_URL "http://luajit.org/"
@ -49,12 +49,14 @@ enum {
LUAJIT_MODE_TRACE, /* Flush a compiled trace. */ LUAJIT_MODE_TRACE, /* Flush a compiled trace. */
LUAJIT_MODE_WRAPCFUNC = 0x10, /* Set wrapper mode for C function calls. */
LUAJIT_MODE_MAX LUAJIT_MODE_MAX
}; };
/* Flags or'ed in to the mode. */ /* Flags or'ed in to the mode. */
#define LUAJIT_MODE_OFF 0x0000 /* Disable JIT compilation. */ #define LUAJIT_MODE_OFF 0x0000 /* Turn feature off. */
#define LUAJIT_MODE_ON 0x0100 /* (Re-)enable JIT compilation. */ #define LUAJIT_MODE_ON 0x0100 /* Turn feature on. */
#define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */ #define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */
/* LuaJIT public C API. */ /* LuaJIT public C API. */