mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 15:14:08 +00:00
RELEASE LuaJIT-2.0.0-beta2
This commit is contained in:
parent
55b1695971
commit
1d1fed48a0
56
COPYRIGHT
Normal file
56
COPYRIGHT
Normal 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
|
||||
|
||||
===============================================================================
|
92
Makefile
92
Makefile
@ -12,46 +12,104 @@
|
||||
# Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h
|
||||
##############################################################################
|
||||
|
||||
BASEVER= 2.0.0
|
||||
VERSION= 2.0.0-beta1
|
||||
MAJVER= 2
|
||||
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.
|
||||
# Note: PREFIX must be an absolute path!
|
||||
#
|
||||
PREFIX= /usr/local
|
||||
export PREFIX= /usr/local
|
||||
##############################################################################
|
||||
|
||||
INSTALL_BIN= $(PREFIX)/bin
|
||||
INSTALL_NAME= luajit-$(VERSION)
|
||||
INSTALL_T= $(INSTALL_BIN)/$(INSTALL_NAME)
|
||||
INSTALL_TSYM= $(INSTALL_BIN)/luajit
|
||||
INSTALL_INC= $(PREFIX)/include/luajit-$(BASEVER)
|
||||
INSTALL_JITLIB= $(PREFIX)/share/luajit-$(VERSION)/jit
|
||||
DPREFIX= $(DESTDIR)$(PREFIX)
|
||||
INSTALL_BIN= $(DPREFIX)/bin
|
||||
INSTALL_LIB= $(DPREFIX)/lib
|
||||
INSTALL_SHARE= $(DPREFIX)/share
|
||||
INSTALL_INC= $(DPREFIX)/include/luajit-$(MAJVER).$(MINVER)
|
||||
|
||||
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
|
||||
SYMLINK= ln -f -s
|
||||
SYMLINK= ln -sf
|
||||
INSTALL_X= install -m 0755
|
||||
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_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
|
||||
|
||||
all $(INSTALL_DEP):
|
||||
default all $(INSTALL_DEP):
|
||||
@echo "==== Building LuaJIT $(VERSION) ===="
|
||||
$(MAKE) -C src
|
||||
@echo "==== Successfully built LuaJIT $(VERSION) ===="
|
||||
|
||||
install: $(INSTALL_DEP)
|
||||
@echo "==== Installing LuaJIT $(VERSION) to $(PREFIX) ===="
|
||||
$(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_JITLIB)
|
||||
cd src && $(INSTALL_X) $(FILES_T) $(INSTALL_T)
|
||||
$(MKDIR) $(INSTALL_DIRS)
|
||||
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 lib && $(INSTALL_F) $(FILES_JITLIB) $(INSTALL_JITLIB)
|
||||
@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 "You can do this now by running this command (with sudo):"
|
||||
@echo ""
|
||||
@echo " $(SYMLINK) $(INSTALL_NAME) $(INSTALL_TSYM)"
|
||||
@echo " $(SYMLINK) $(INSTALL_TNAME) $(INSTALL_TSYM)"
|
||||
@echo ""
|
||||
|
||||
##############################################################################
|
||||
@ -77,8 +135,6 @@ cleaner:
|
||||
distclean:
|
||||
$(MAKE) -C src distclean
|
||||
|
||||
SUB_TARGETS= amalg clean cleaner distclean
|
||||
|
||||
.PHONY: all install $(SUB_TARGETS)
|
||||
.PHONY: all install amalg clean cleaner distclean
|
||||
|
||||
##############################################################################
|
||||
|
4
README
4
README
@ -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.
|
||||
@ -7,7 +7,7 @@ Project Homepage: http://luajit.org/
|
||||
|
||||
LuaJIT is Copyright (C) 2005-2009 Mike Pall.
|
||||
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.
|
||||
Please point your favorite browser to:
|
||||
|
147
doc/api.html
147
doc/api.html
@ -100,12 +100,6 @@ These functions are typically used with the command line options
|
||||
Flushes the whole cache of compiled code.
|
||||
</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>
|
||||
jit.off(func|true [,true|false])<br>
|
||||
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.
|
||||
</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>
|
||||
<p>
|
||||
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,
|
||||
if you want to know more.
|
||||
</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>
|
||||
— 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>
|
||||
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 <exception>
|
||||
#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++ exception"</tt>.
|
||||
</p>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
|
@ -43,7 +43,7 @@ div.major { max-width: 600px; padding: 1em; margin: 1em 0 1em 0; }
|
||||
<div id="main">
|
||||
<p>
|
||||
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 2.0.0-beta1</strong>.<br>
|
||||
The current <span style="color: #c00000;">development version</span> is <strong>LuaJIT 2.0.0-beta2</strong>.<br>
|
||||
The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT 1.1.5</strong>.
|
||||
</p>
|
||||
<p>
|
||||
@ -53,6 +53,36 @@ to see whether newer versions are available.
|
||||
</p>
|
||||
|
||||
<div class="major" style="background: #ffd0d0;">
|
||||
<h2 id="LuaJIT-2.0.0-beta2">LuaJIT 2.0.0-beta2 — 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 /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 — 2009-10-31</h2>
|
||||
<ul>
|
||||
<li>This is the first public release of LuaJIT 2.0.</li>
|
||||
|
23
doc/faq.html
23
doc/faq.html
@ -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">»</span> Dynamic Language Optimizations</a><br>
|
||||
Search for: <a href="http://scholar.google.com/scholar?q=SSA+Form"><span class="ext">»</span> SSA Form</a><br>
|
||||
Search for: <a href="http://scholar.google.com/scholar?q=Linear+Scan+Register+Allocation"><span class="ext">»</span> 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">»</span> innovative features in LuaJIT</a>.<br>
|
||||
And, you know, reading the source is of course the only way to enlightenment. :-)
|
||||
</dd>
|
||||
</dl>
|
||||
@ -86,6 +87,28 @@ functions from Lua 5.0.<br>Please convert your code to the
|
||||
vararg syntax</a>.</dd>
|
||||
</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 — 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>
|
||||
<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
|
||||
|
@ -58,17 +58,15 @@ application under x64-based systems, too.
|
||||
<h2>Configuring LuaJIT</h2>
|
||||
<p>
|
||||
The standard configuration should work fine for most installations.
|
||||
Usually there is no need to tweak the settings, except when you want to
|
||||
install to a non-standard path. The following three files hold all
|
||||
user-configurable settings:
|
||||
Usually there is no need to tweak the settings. The following files
|
||||
hold all user-configurable settings:
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>src/luaconf.h</tt> sets some configuration variables, in
|
||||
particular the default paths for loading modules.</li>
|
||||
<li><tt>Makefile</tt> has settings for installing LuaJIT (POSIX
|
||||
<li><tt>src/luaconf.h</tt> sets some configuration variables.</li>
|
||||
<li><tt>Makefile</tt> has settings for <b>installing</b> LuaJIT (POSIX
|
||||
only).</li>
|
||||
<li><tt>src/Makefile</tt> has settings for compiling LuaJIT under POSIX,
|
||||
MinGW and Cygwin.</li>
|
||||
<li><tt>src/Makefile</tt> has settings for <b>compiling</b> LuaJIT
|
||||
under POSIX, MinGW and Cygwin.</li>
|
||||
<li><tt>src/msvcbuild.bat</tt> has settings for compiling LuaJIT with
|
||||
MSVC.</li>
|
||||
</ul>
|
||||
@ -97,9 +95,8 @@ terminal window and change to this directory. Now unpack the archive
|
||||
and change to the newly created directory:
|
||||
</p>
|
||||
<pre class="code">
|
||||
tar zxf LuaJIT-2.0.0-beta1.tar.gz
|
||||
cd LuaJIT-2.0.0-beta1
|
||||
</pre>
|
||||
tar zxf LuaJIT-2.0.0-beta2.tar.gz
|
||||
cd LuaJIT-2.0.0-beta2</pre>
|
||||
<h3>Building LuaJIT</h3>
|
||||
<p>
|
||||
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">
|
||||
make
|
||||
</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>
|
||||
<p>
|
||||
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.:
|
||||
</p>
|
||||
<pre class="code">
|
||||
sudo make install PREFIX=/opt/lj2
|
||||
make install PREFIX=/home/myself/lj2
|
||||
</pre>
|
||||
<p>
|
||||
But note that the installation prefix and the prefix for the module paths
|
||||
(configured in <tt>src/luaconf.h</tt>) must match.
|
||||
Obviously the prefixes given during build and installation need to be the same.
|
||||
</p>
|
||||
<p style="color: #c00000;">
|
||||
Note: to avoid overwriting a previous version, the beta test releases
|
||||
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:
|
||||
</p>
|
||||
<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 /usr/local/bin/luajit
|
||||
</pre>
|
||||
|
||||
<h2 id="windows">Windows Systems</h2>
|
||||
@ -145,8 +153,8 @@ sudo ln -sf luajit-2.0.0-beta1 /usr/local/bin/luajit
|
||||
<p>
|
||||
Either install one of the open source SDKs
|
||||
(<a href="http://mingw.org/"><span class="ext">»</span> MinGW</a> or
|
||||
<a href="http://www.cygwin.com/"><span class="ext">»</span> Cygwin</a>) which come with modified
|
||||
versions of GCC plus the required development headers.
|
||||
<a href="http://www.cygwin.com/"><span class="ext">»</span> Cygwin</a>), which come with a modified
|
||||
GCC plus the required development headers.
|
||||
</p>
|
||||
<p>
|
||||
Or install Microsoft's Visual C++ (MSVC) — the freely downloadable
|
||||
@ -159,8 +167,8 @@ Next, download the source package and unpack it using an archive manager
|
||||
</p>
|
||||
<h3>Building with MSVC</h3>
|
||||
<p>
|
||||
Open a "Visual Studio .NET Command Prompt" and <tt>cd</tt> to the
|
||||
directory where you've unpacked the sources. Then run this command:
|
||||
Open a "Visual Studio .NET Command Prompt", <tt>cd</tt> to the
|
||||
directory where you've unpacked the sources and run these commands:
|
||||
</p>
|
||||
<pre class="code">
|
||||
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:
|
||||
</p>
|
||||
<pre class="code">
|
||||
cd src
|
||||
mingw32-make
|
||||
</pre>
|
||||
<p>
|
||||
Or this command for Cygwin:
|
||||
</p>
|
||||
<pre class="code">
|
||||
cd src
|
||||
make
|
||||
</pre>
|
||||
<p>
|
||||
@ -191,10 +197,11 @@ Then follow the installation instructions below.
|
||||
</p>
|
||||
<h3>Installing LuaJIT</h3>
|
||||
<p>
|
||||
Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt>
|
||||
to a newly created directory (any location is ok). Add <tt>lua</tt>
|
||||
and <tt>lua\jit</tt> directories below it and copy all Lua files
|
||||
from the <tt>lib</tt> directory of the distribution to the latter directory.
|
||||
Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt> (built in the <tt>src</tt>
|
||||
directory) to a newly created directory (any location is ok).
|
||||
Add <tt>lua</tt> and <tt>lua\jit</tt> directories below it and copy
|
||||
all Lua files from the <tt>lib</tt> directory of the distribution
|
||||
to the latter directory.
|
||||
</p>
|
||||
<p>
|
||||
There are no hardcoded
|
||||
|
@ -69,11 +69,11 @@ interactive mode, too.
|
||||
<p class="indent" style="color: #c00000;">
|
||||
Note: the beta test releases only install under the versioned name on
|
||||
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:
|
||||
</p>
|
||||
<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 /usr/local/bin/luajit
|
||||
</pre>
|
||||
<p>
|
||||
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.
|
||||
They can be found in the <tt>lib</tt> directory of the source
|
||||
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.
|
||||
</p>
|
||||
|
||||
|
@ -90,7 +90,22 @@ known incompatibilities with standard Lua:
|
||||
<ul>
|
||||
<li>
|
||||
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 5.1 — loading foreign
|
||||
bytecode is not supported at all.
|
||||
</li>
|
||||
<li>
|
||||
Some of the <b>configuration options</b> of Lua 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>
|
||||
Most other issues you're likely to find (e.g. with the existing test
|
||||
@ -105,7 +120,7 @@ demonstrable need is shown.
|
||||
<li>
|
||||
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
|
||||
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:
|
||||
<ul>
|
||||
<li>
|
||||
@ -119,7 +134,7 @@ effort.
|
||||
</li>
|
||||
<li>
|
||||
<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>
|
||||
The trace compiler currently does not back off specialization for
|
||||
|
82
etc/luajit.1
Normal file
82
etc/luajit.1
Normal 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
24
etc/luajit.pc
Normal 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}
|
428
src/Makefile
428
src/Makefile
@ -8,10 +8,17 @@
|
||||
# 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
|
||||
# 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.
|
||||
# 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)!
|
||||
# In the meantime, the x86 binary runs fine under a x64 OS.
|
||||
@ -81,89 +88,142 @@ XCFLAGS=
|
||||
#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.
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Flags and options for host and target.
|
||||
##############################################################################
|
||||
|
||||
CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(CFLAGS) $(XCFLAGS)
|
||||
LDOPTIONS= $(CCDEBUG) $(LDFLAGS)
|
||||
|
||||
HOST_CC= $(CC)
|
||||
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.
|
||||
# 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
|
||||
# itself (bootstrapped from the pre-generated file) to run DynASM of course.
|
||||
DASM_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_LUA= lua
|
||||
|
||||
HOST_XCFLAGS=
|
||||
HOST_XLDFLAGS=
|
||||
HOST_XLIBS=
|
||||
HOST_CFLAGS= $(CCOPTIONS) $(HOST_XCFLAGS) $(TARGET_ARCH)
|
||||
HOST_LDFLAGS= $(LDOPTIONS) $(HOST_XLDFLAGS)
|
||||
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= $(DASM_LUA) $(DASM_DIR)/dynasm.lua
|
||||
DASM= $(HOST_LUA) $(DASM_DIR)/dynasm.lua
|
||||
DASM_FLAGS=
|
||||
DASM_DISTFLAGS= -LN
|
||||
|
||||
BUILDVM_O= buildvm.o buildvm_asm.o buildvm_peobj.o buildvm_lib.o buildvm_fold.o
|
||||
BUILDVM_T= buildvm
|
||||
BUILDVM_X= ./$(BUILDVM_T)
|
||||
|
||||
HOST_O= $(BUILDVM_O)
|
||||
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
|
||||
|
||||
LJVMCORE_O= $(LJVM_O) $(LJCORE_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
|
||||
LJVMCORE_DYNO= $(LJVMCORE_O:.o=_dyn.o)
|
||||
|
||||
LIB_VMDEF= ../lib/vmdef.lua
|
||||
LIB_VMDEFP= $(LIB_VMDEF)
|
||||
|
||||
TARGET_DEP= $(LIB_VMDEF)
|
||||
TARGET_O= $(LJVMCORE_O) $(LUAJIT_O)
|
||||
TARGET_T= $(LUAJIT_T)
|
||||
LUAJIT_O= luajit.o
|
||||
LUAJIT_A= libluajit.a
|
||||
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
|
||||
WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest
|
||||
ALL_RM= $(LUAJIT_T) $(LUAJIT_SO) $(HOST_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
|
||||
WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest *.pdb *.ilk
|
||||
ALL_RM= $(ALL_T) $(ALL_GEN) *.o $(WIN_RM)
|
||||
|
||||
##############################################################################
|
||||
# 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:
|
||||
@grep "^[+|]" ljamalg.c
|
||||
$(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:
|
||||
$(HOST_RM) $(ALL_RM)
|
||||
|
||||
cleaner: clean
|
||||
$(HOST_RM) $(ALL_DYNGEN)
|
||||
cleaner:
|
||||
$(HOST_RM) $(ALL_RM) $(ALL_DYNGEN)
|
||||
|
||||
distclean: clean
|
||||
$(E) "DYNASM $@"
|
||||
@ -321,6 +351,86 @@ depend:
|
||||
@test -s lj_folddef.h || $(HOST_RM) lj_folddef.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"
|
||||
|
||||
##############################################################################
|
||||
|
@ -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 \
|
||||
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 \
|
||||
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_state.h \
|
||||
lj_ff.h lj_ffdef.h lj_ctype.h lj_lib.h lj_libdef.h
|
||||
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.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 \
|
||||
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \
|
||||
lj_libdef.h
|
||||
|
@ -71,10 +71,7 @@ err:
|
||||
exit(1);
|
||||
}
|
||||
emit_asm_bytes(ctx, cp, n);
|
||||
if (!strncmp(sym, LABEL_PREFIX, sizeof(LABEL_PREFIX)-1))
|
||||
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. */
|
||||
@ -135,7 +132,7 @@ void emit_asm(BuildCtx *ctx)
|
||||
fprintf(ctx->fp, "\t.text\n");
|
||||
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)
|
||||
fprintf(ctx->fp, ".Lbegin:\n");
|
||||
|
||||
|
@ -188,7 +188,12 @@ void emit_fold(BuildCtx *ctx)
|
||||
} else if ((p[0] == 'F' || p[0] == 'X') && p[1] == '(' && q) {
|
||||
p += 2;
|
||||
*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++;
|
||||
} else {
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
|
@ -264,7 +264,8 @@ void emit_peobj(BuildCtx *ctx)
|
||||
emit_peobj_sym(ctx, name, 0,
|
||||
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++) {
|
||||
int pi = ctx->perm[i];
|
||||
if (pi >= ctx->npc) {
|
||||
|
@ -287,6 +287,35 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
|
||||
| lea RA, [BASE+RA*8]
|
||||
| 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.
|
||||
| // RA = new base, RB = CFUNC, RC = nargs+1, (BASE = old base), PC = return
|
||||
| mov [RA-4], PC
|
||||
@ -312,6 +341,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
|
||||
| mov NRESULTS, RD
|
||||
| test PC, FRAME_TYPE
|
||||
| jz ->BC_RET_Z // Handle regular return to Lua.
|
||||
| // Fallthrough.
|
||||
|
|
||||
|//-- Return handling (non-inline) ---------------------------------------
|
||||
|
|
||||
@ -1455,7 +1485,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
|
||||
| mov ARG5, RA
|
||||
| fstp FPARG1
|
||||
| mov RB, BASE
|
||||
| call extern func
|
||||
| call extern lj_wrapper_ .. func
|
||||
| mov RA, ARG5
|
||||
| mov BASE, RB
|
||||
| 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.align 4\n"
|
||||
".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;
|
||||
default: /* Difficult for other modes. */
|
||||
break;
|
||||
|
@ -20,97 +20,6 @@
|
||||
#include "lj_err.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 ------------------------------------------------- */
|
||||
|
||||
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,
|
||||
const luaL_Reg *l, int nup)
|
||||
{
|
||||
lj_lib_checkfpu(L);
|
||||
if (libname) {
|
||||
int size = libsize(l);
|
||||
/* check whether lib already exists */
|
||||
@ -285,6 +195,10 @@ LUALIB_API void luaL_buffinit(lua_State *L, luaL_Buffer *B)
|
||||
|
||||
#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)
|
||||
{
|
||||
int ref;
|
||||
|
@ -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)
|
||||
{
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
|
||||
if (tvisnil(L->top-1)) {
|
||||
LJ_LIB_REG_(L, NULL, io_method);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
|
||||
}
|
||||
io_fenv_new(L, 0, lj_cf_io_pipe_close); /* top-3 */
|
||||
io_fenv_new(L, 2, lj_cf_io_file_close); /* top-2 */
|
||||
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, stdout, IO_OUTPUT, "stdout");
|
||||
io_std_new(L, stderr, 0, "stderr");
|
||||
lua_pop(L, 1);
|
||||
L->top--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -73,8 +73,9 @@ LJLIB_CF(jit_flush)
|
||||
#if LJ_HASJIT
|
||||
if (L->base < L->top && (tvisnum(L->base) || tvisstr(L->base))) {
|
||||
int traceno = lj_lib_checkint(L, 1);
|
||||
luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE);
|
||||
return 0;
|
||||
setboolV(L->top-1,
|
||||
luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return setjitmode(L, LUAJIT_MODE_FLUSH);
|
||||
|
@ -69,11 +69,9 @@ LJLIB_ASM_(math_max) LJLIB_REC(math_minmax IR_MAX)
|
||||
LJLIB_PUSH(3.14159265358979323846) LJLIB_SET(pi)
|
||||
LJLIB_PUSH(1e310) LJLIB_SET(huge)
|
||||
|
||||
#ifdef __MACH__
|
||||
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_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); \
|
||||
r ^= z; tw->gen[i] = z;
|
||||
|
||||
/* PRNG step function. Returns a double in the range 0.0 <= d < 1.0. */
|
||||
static double tw223_step(TW223State *tw)
|
||||
/* PRNG step function. Returns a double in the range 1.0 <= d < 2.0. */
|
||||
static LJ_NOINLINE double tw223_step(TW223State *tw)
|
||||
{
|
||||
uint64_t z, r = 0;
|
||||
U64double u;
|
||||
@ -108,16 +106,7 @@ static double tw223_step(TW223State *tw)
|
||||
TW223_GEN(2, 55, 24, 7)
|
||||
TW223_GEN(3, 47, 21, 8)
|
||||
u.u64 = (r & (((uint64_t)1 << 52)-1)) | ((uint64_t)0x3ff << 52);
|
||||
#if defined(__GNUC__) && LJ_TARGET_X86 && __pic__
|
||||
/* 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
|
||||
return u.d;
|
||||
}
|
||||
|
||||
/* PRNG initialization function. */
|
||||
@ -146,7 +135,7 @@ LJLIB_CF(math_random)
|
||||
TW223State *tw = (TW223State *)(uddata(udataV(lj_lib_upvalue(L, 1))));
|
||||
double d;
|
||||
if (LJ_UNLIKELY(!tw->valid)) tw223_init(tw, 0.0);
|
||||
d = tw223_step(tw);
|
||||
d = tw223_step(tw) - 1.0;
|
||||
if (n > 0) {
|
||||
double r1 = lj_lib_checknum(L, 1);
|
||||
if (n == 1) {
|
||||
|
@ -354,6 +354,7 @@ static int lj_cf_package_require(lua_State *L)
|
||||
lua_pushvalue(L, -1); /* extra copy to be returned */
|
||||
lua_setfield(L, 2, name); /* _LOADED[name] = true */
|
||||
}
|
||||
lj_lib_checkfpu(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "lualib.h"
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_gc.h"
|
||||
#include "lj_err.h"
|
||||
#include "lj_str.h"
|
||||
#include "lj_tab.h"
|
||||
@ -774,6 +775,7 @@ LJLIB_CF(string_format)
|
||||
LUALIB_API int luaopen_string(lua_State *L)
|
||||
{
|
||||
GCtab *mt;
|
||||
GCstr *mmstr;
|
||||
LJ_LIB_REG(L, string);
|
||||
#if defined(LUA_COMPAT_GFIND)
|
||||
lua_getfield(L, -1, "gmatch");
|
||||
@ -782,8 +784,9 @@ LUALIB_API int luaopen_string(lua_State *L)
|
||||
mt = lj_tab_new(L, 0, 1);
|
||||
/* NOBARRIER: G(L)->mmname[] is a GC root. */
|
||||
setgcref(G(L)->basemt[~LJ_TSTR], obj2gco(mt));
|
||||
settabV(L, lj_tab_setstr(L, mt, strref(G(L)->mmname[MM_index])),
|
||||
tabV(L->top-1));
|
||||
mmstr = strref(G(L)->mmname[MM_index]);
|
||||
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));
|
||||
return 1;
|
||||
}
|
||||
|
@ -74,21 +74,21 @@ LJLIB_CF(table_maxn)
|
||||
TValue *array = tvref(t->array);
|
||||
Node *node;
|
||||
lua_Number m = 0;
|
||||
uint32_t i;
|
||||
for (i = 0; i < t->asize; i++)
|
||||
ptrdiff_t i;
|
||||
for (i = (ptrdiff_t)t->asize - 1; i >= 0; i--)
|
||||
if (!tvisnil(&array[i])) {
|
||||
m = (lua_Number)i;
|
||||
m = (lua_Number)(int32_t)i;
|
||||
break;
|
||||
}
|
||||
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)
|
||||
m = numV(&node[i].key);
|
||||
setnumV(L->top-1, m);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LJLIB_CF(table_insert)
|
||||
LJLIB_CF(table_insert) LJLIB_REC(.)
|
||||
{
|
||||
GCtab *t = lj_lib_checktab(L, 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);
|
||||
copyTV(L, dst, L->top-1);
|
||||
copyTV(L, dst, L->top-1); /* Set new value. */
|
||||
lj_gc_barriert(L, t, dst);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LJLIB_CF(table_remove)
|
||||
LJLIB_CF(table_remove) LJLIB_REC(.)
|
||||
{
|
||||
GCtab *t = lj_lib_checktab(L, 1);
|
||||
int32_t e = (int32_t)lj_tab_len(t);
|
||||
int32_t pos = lj_lib_optint(L, 2, e);
|
||||
if (!(1 <= pos && pos <= e)) /* position is outside bounds? */
|
||||
return 0; /* nothing to remove */
|
||||
lua_rawgeti(L, 1, pos);
|
||||
if (!(1 <= pos && pos <= e)) /* Nothing to remove? */
|
||||
return 0;
|
||||
lua_rawgeti(L, 1, pos); /* Get previous value. */
|
||||
/* NOBARRIER: This just moves existing elements around. */
|
||||
for (; pos < e; pos++) {
|
||||
cTValue *src = lj_tab_getint(t, pos+1);
|
||||
@ -135,8 +135,8 @@ LJLIB_CF(table_remove)
|
||||
setnilV(dst);
|
||||
}
|
||||
}
|
||||
setnilV(lj_tab_setint(L, t, e));
|
||||
return 1;
|
||||
setnilV(lj_tab_setint(L, t, e)); /* Remove (last) value. */
|
||||
return 1; /* Return previous value. */
|
||||
}
|
||||
|
||||
LJLIB_CF(table_concat)
|
||||
|
136
src/lj_api.c
136
src/lj_api.c
@ -91,6 +91,12 @@ LUA_API int lua_checkstack(lua_State *L, int size)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@ -295,6 +313,30 @@ LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
|
||||
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)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
@ -313,6 +355,44 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
|
||||
#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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
11
src/lj_asm.c
11
src/lj_asm.c
@ -738,11 +738,14 @@ static Reg ra_allocref(ASMState *as, IRRef ref, RegSet allow)
|
||||
}
|
||||
RA_DBGX((as, "hintmiss $f $r", ref, r));
|
||||
}
|
||||
/* Invariants should preferably get unused registers. */
|
||||
if (ref < as->loopref && !irt_isphi(ir->t))
|
||||
r = rset_pickbot(pick);
|
||||
else
|
||||
/* Invariants should preferably get unmodified registers. */
|
||||
if (ref < as->loopref && !irt_isphi(ir->t)) {
|
||||
if ((pick & ~as->modset))
|
||||
pick &= ~as->modset;
|
||||
r = rset_pickbot(pick); /* Reduce conflicts with inverse allocation. */
|
||||
} else {
|
||||
r = rset_picktop(pick);
|
||||
}
|
||||
} else {
|
||||
r = ra_evict(as, allow);
|
||||
}
|
||||
|
@ -153,8 +153,7 @@ int luaJIT_setmode(lua_State *L, int idx, int mode)
|
||||
case LUAJIT_MODE_TRACE:
|
||||
if (!(mode & LUAJIT_MODE_FLUSH))
|
||||
return 0; /* Failed. */
|
||||
lj_trace_flush(G2J(g), idx);
|
||||
break;
|
||||
return lj_trace_flush(G2J(g), idx);
|
||||
#else
|
||||
case LUAJIT_MODE_ENGINE:
|
||||
case LUAJIT_MODE_FUNC:
|
||||
@ -165,6 +164,20 @@ int luaJIT_setmode(lua_State *L, int idx, int mode)
|
||||
return 0; /* Failed. */
|
||||
break;
|
||||
#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:
|
||||
return 0; /* Failed. */
|
||||
}
|
||||
|
46
src/lj_err.c
46
src/lj_err.c
@ -676,6 +676,8 @@ LJ_NORET LJ_NOINLINE static void err_argmsg(lua_State *L, int narg,
|
||||
{
|
||||
const char *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". */
|
||||
msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg);
|
||||
else
|
||||
@ -761,3 +763,47 @@ LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...)
|
||||
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
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
/* Basic error handling. */
|
||||
ERRDEF(ERRMEM, "not enough memory")
|
||||
ERRDEF(ERRERR, "error in error handling")
|
||||
ERRDEF(ERRCPP, "C++ exception")
|
||||
|
||||
/* Allocations. */
|
||||
ERRDEF(STROV, "string length overflow")
|
||||
@ -56,6 +57,9 @@ ERRDEF(NOENV, "no calling environment")
|
||||
ERRDEF(CYIELD, "attempt to yield across C-call boundary")
|
||||
ERRDEF(BADLU, "bad light userdata pointer")
|
||||
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. */
|
||||
ERRDEF(ASSERT, "assertion failed!")
|
||||
|
@ -138,7 +138,7 @@ GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env)
|
||||
fn->c.nupvalues = cast_byte(nelems);
|
||||
/* NOBARRIER: The GCfunc is new (marked white). */
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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). */
|
||||
#define gc_mark_curtrace(g) \
|
||||
{ if (G2J(g)->state != LJ_TRACE_IDLE && G2J(g)->curtrace != 0) \
|
||||
gc_traverse_trace(g, &G2J(g)->cur); }
|
||||
{ if (G2J(g)->curtrace != 0) gc_traverse_trace(g, &G2J(g)->cur); }
|
||||
#else
|
||||
#define gc_mark_curtrace(g) UNUSED(g)
|
||||
#endif
|
||||
|
@ -252,6 +252,7 @@ TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t)
|
||||
{
|
||||
IRIns *ir, *cir = J->cur.ir;
|
||||
IRRef ref;
|
||||
lua_assert(!isdead(J2G(J), o));
|
||||
for (ref = J->chain[IR_KGC]; ref; ref = cir[ref].prev)
|
||||
if (ir_kgc(&cir[ref]) == o)
|
||||
goto found;
|
||||
|
@ -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) \
|
||||
(&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. */
|
||||
#define LJLIB_CF(name) static int lj_cf_##name(lua_State *L)
|
||||
#define LJLIB_ASM(name) static int lj_ffh_##name(lua_State *L)
|
||||
|
@ -531,7 +531,7 @@ typedef struct global_State {
|
||||
uint8_t hookmask; /* Hook mask. */
|
||||
uint8_t dispatchmode; /* Dispatch mode. */
|
||||
uint8_t vmevmask; /* VM event mask. */
|
||||
uint8_t unused1;
|
||||
uint8_t wrapmode; /* Wrap mode. */
|
||||
GCRef mainthref; /* Link to main thread. */
|
||||
TValue registrytv; /* Anchor for registry. */
|
||||
TValue tmptv; /* Temporary TValue. */
|
||||
@ -539,6 +539,7 @@ typedef struct global_State {
|
||||
int32_t hookcount; /* Instruction hook countdown. */
|
||||
int32_t hookcstart; /* Start count for instruction hook counter. */
|
||||
lua_Hook hookf; /* Hook function. */
|
||||
lua_CFunction wrapf; /* Wrapper for C function calls. */
|
||||
lua_CFunction panic; /* Called as a last resort for errors. */
|
||||
volatile int32_t vmstate; /* VM state or current JIT code trace number. */
|
||||
GCRef jit_L; /* Current JIT code lua_State or NULL. */
|
||||
|
@ -138,7 +138,7 @@ typedef IRRef (LJ_FASTCALL *FoldFunc)(jit_State *J);
|
||||
/* Macros for the fold specs, so buildvm can recognize them. */
|
||||
#define LJFOLD(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! */
|
||||
|
||||
/* Barrier to prevent using operands across PHIs. */
|
||||
@ -979,7 +979,7 @@ LJFOLDF(comm_equal)
|
||||
/* For non-numbers only: x == x ==> drop; x ~= x ==> fail */
|
||||
if (fins->op1 == fins->op2 && !irt_isnum(fins->t))
|
||||
return CONDFOLD(fins->o == IR_EQ);
|
||||
return comm_swap(J);
|
||||
return fold_comm_swap(J);
|
||||
}
|
||||
|
||||
LJFOLD(LT any any)
|
||||
@ -1013,7 +1013,7 @@ LJFOLDF(comm_dup)
|
||||
{
|
||||
if (fins->op1 == fins->op2) /* x o x ==> x */
|
||||
return LEFTFOLD;
|
||||
return comm_swap(J);
|
||||
return fold_comm_swap(J);
|
||||
}
|
||||
|
||||
LJFOLD(BXOR any any)
|
||||
@ -1021,7 +1021,7 @@ LJFOLDF(comm_bxor)
|
||||
{
|
||||
if (fins->op1 == fins->op2) /* i xor i ==> 0 */
|
||||
return INTFOLD(0);
|
||||
return comm_swap(J);
|
||||
return fold_comm_swap(J);
|
||||
}
|
||||
|
||||
/* -- Simplification of compound expressions ------------------------------ */
|
||||
|
@ -286,7 +286,7 @@ static void loop_unroll(jit_State *J)
|
||||
if (!irt_sametype(t, irr->t)) {
|
||||
if (irt_isnum(t) && irt_isinteger(irr->t)) /* Fix int->num case. */
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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. */
|
||||
IRRef skref = IR(store->op1)->op2;
|
||||
IRRef xkref = IR(xref)->op2;
|
||||
/* Same key type MAY alias. */
|
||||
if (irt_sametype(IR(skref)->t, IR(xkref)->t)) {
|
||||
/* Same key type MAY alias. Need ALOAD check due to multiple int types. */
|
||||
if (loadop == IR_ALOAD || irt_sametype(IR(skref)->t, IR(xkref)->t)) {
|
||||
if (skref == xkref || !irref_isk(skref) || !irref_isk(xkref))
|
||||
return 0; /* A nil store with same const key or var key MAY alias. */
|
||||
/* Different const keys CANNOT alias. */
|
||||
|
@ -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);
|
||||
if (!tref_isk2(a, b)) { /* Shortcut, also handles primitives. */
|
||||
IRType ta = tref_type(a);
|
||||
IRType tb = tref_type(b);
|
||||
IRType ta = tref_isinteger(a) ? IRT_INT : tref_type(a);
|
||||
IRType tb = tref_isinteger(b) ? IRT_INT : tref_type(b);
|
||||
if (ta != tb) {
|
||||
/* Widen mixed number/int comparisons to number/number comparison. */
|
||||
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);
|
||||
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));
|
||||
nocheck:
|
||||
if (mt) {
|
||||
@ -457,6 +457,8 @@ nocheck:
|
||||
copyTV(J->L, &ix->mobjv, mo);
|
||||
ix->mtv = 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);
|
||||
mix.key = lj_ir_kstr(J, mmstr);
|
||||
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_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);
|
||||
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]) {
|
||||
TRef base = lj_ir_toint(J, arg[1]);
|
||||
if (!tref_isk(base) || IR(tref_ref(base))->i != 10)
|
||||
recff_err_ffu(J, rd);
|
||||
recff_err_nyi(J, rd);
|
||||
}
|
||||
if (tref_isstr(tr))
|
||||
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)) {
|
||||
res[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0);
|
||||
} 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);
|
||||
}
|
||||
|
||||
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 -------------------------------------------- */
|
||||
|
||||
#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:
|
||||
/* Emit nothing for two numeric or string consts. */
|
||||
if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) {
|
||||
IRType ta = tref_type(ra);
|
||||
IRType tc = tref_type(rc);
|
||||
IRType ta = tref_isinteger(ra) ? IRT_INT : tref_type(ra);
|
||||
IRType tc = tref_isinteger(rc) ? IRT_INT : tref_type(rc);
|
||||
int irop;
|
||||
if (ta != tc) {
|
||||
/* Widen mixed number/int comparisons to number/number comparison. */
|
||||
|
@ -191,8 +191,8 @@ GCtab *lj_tab_dup(lua_State *L, const GCtab *kt)
|
||||
Node *kn = &knode[i];
|
||||
Node *n = &node[i];
|
||||
Node *next = nextnode(kn);
|
||||
copyTV(L, &n->val, &kn->val);
|
||||
copyTV(L, &n->key, &kn->key);
|
||||
/* Don't use copyTV here, since it asserts on a copy of a DEADKEY. */
|
||||
n->val = kn->val; n->key = kn->key;
|
||||
setmref(n->next, next == NULL? next : (Node *)((char *)next + d));
|
||||
}
|
||||
}
|
||||
|
@ -191,18 +191,12 @@ static void trace_unpatch(jit_State *J, Trace *T)
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush a root trace and any attached side traces. */
|
||||
void lj_trace_flush(jit_State *J, TraceNo traceno)
|
||||
/* Free a root trace and any attached side traces. */
|
||||
static void trace_freeroot(jit_State *J, Trace *T, TraceNo traceno)
|
||||
{
|
||||
Trace *T = NULL;
|
||||
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) {
|
||||
GCproto *pt = &gcref(T->startpt)->pt;
|
||||
TraceNo side;
|
||||
lua_assert(T->root == 0 && pt != NULL);
|
||||
/* First unpatch any modified bytecode. */
|
||||
trace_unpatch(J, T);
|
||||
/* 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. */
|
||||
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. */
|
||||
void lj_trace_flushproto(global_State *g, GCproto *pt)
|
||||
{
|
||||
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. */
|
||||
@ -241,8 +252,11 @@ int lj_trace_flushall(lua_State *L)
|
||||
ptrdiff_t i;
|
||||
if ((J2G(J)->hookmask & HOOK_GC))
|
||||
return 1;
|
||||
for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--)
|
||||
lj_trace_flush(J, (TraceNo)i);
|
||||
for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) {
|
||||
Trace *T = J->trace[i];
|
||||
if (T && T->root == 0)
|
||||
trace_freeroot(J, T, (TraceNo)i);
|
||||
}
|
||||
#ifdef LUA_USE_ASSERT
|
||||
for (i = 0; i < (ptrdiff_t)J->sizetrace; i++)
|
||||
lua_assert(J->trace[i] == NULL);
|
||||
|
@ -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_reenableproto(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 void lj_trace_freestate(global_State *g);
|
||||
|
||||
|
@ -46,6 +46,7 @@ LJ_ASMF void lj_vm_powi(void);
|
||||
LJ_ASMF void lj_gate_lf(void);
|
||||
LJ_ASMF void lj_gate_lv(void);
|
||||
LJ_ASMF void lj_gate_c(void);
|
||||
LJ_ASMF void lj_gate_cwrap(void);
|
||||
|
||||
/* Continuations for metamethods. */
|
||||
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. */
|
||||
|
||||
/* 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. */
|
||||
LJ_ASMF const uint16_t lj_vm_op_ofs[];
|
||||
|
||||
#define makeasmfunc(ofs) \
|
||||
((ASMFunction)((char *)lj_vm_asm_begin + (ofs)))
|
||||
#define makeasmfunc(ofs) ((ASMFunction)(lj_vm_asm_begin + (ofs)))
|
||||
|
||||
#endif
|
||||
|
@ -1,9 +1,9 @@
|
||||
// lua.hpp
|
||||
// Lua header files for C++
|
||||
// <<extern "C">> not supplied automatically because Lua also compiles as C++
|
||||
// C++ wrapper for LuaJIT header files.
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
#include "luajit.h"
|
||||
}
|
||||
|
||||
|
@ -34,13 +34,22 @@
|
||||
".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
|
||||
#else
|
||||
#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_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 \
|
||||
"./?.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 \
|
||||
"./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
|
||||
"./?.so;" LUA_CDIR"?.so;" LUA_XCPATH LUA_CDIR"loadall.so"
|
||||
#endif
|
||||
|
||||
/* Environment variable names for path overrides and initialization code. */
|
||||
|
20
src/luajit.c
20
src/luajit.c
@ -55,16 +55,16 @@ static void laction(int i)
|
||||
static void print_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s [options] [script [args]].\n"
|
||||
"usage: %s [options]... [script [args]...].\n"
|
||||
"Available options are:\n"
|
||||
" -e stat execute string " LUA_QL("stat") "\n"
|
||||
" -l name require library " LUA_QL("name") "\n"
|
||||
" -j cmd perform LuaJIT control command\n"
|
||||
" -O[lvl] set LuaJIT optimization level\n"
|
||||
" -i enter interactive mode after executing " LUA_QL("script") "\n"
|
||||
" -v show version information\n"
|
||||
" -- stop handling options\n"
|
||||
" - execute stdin and stop handling options\n"
|
||||
" -e chunk Execute string " LUA_QL("chunk") ".\n"
|
||||
" -l name Require library " LUA_QL("name") ".\n"
|
||||
" -j cmd Perform LuaJIT control command.\n"
|
||||
" -O[opt] Control LuaJIT optimizations.\n"
|
||||
" -i Enter interactive mode after executing " LUA_QL("script") ".\n"
|
||||
" -v Show version information.\n"
|
||||
" -- Stop handling options.\n"
|
||||
" - Execute stdin and stop handling options.\n"
|
||||
,
|
||||
progname);
|
||||
fflush(stderr);
|
||||
@ -143,7 +143,7 @@ static void print_jit_status(lua_State *L)
|
||||
fputs(lua_toboolean(L, n) ? "JIT: ON" : "JIT: OFF", stderr);
|
||||
for (n++; (s = lua_tostring(L, n)); n++)
|
||||
fprintf(stderr, " %s", s);
|
||||
fputs("\n", stdout);
|
||||
fputs("\n", stderr);
|
||||
}
|
||||
|
||||
static int getargs(lua_State *L, char **argv, int n)
|
||||
|
10
src/luajit.h
10
src/luajit.h
@ -30,9 +30,9 @@
|
||||
|
||||
#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_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_URL "http://luajit.org/"
|
||||
|
||||
@ -49,12 +49,14 @@ enum {
|
||||
|
||||
LUAJIT_MODE_TRACE, /* Flush a compiled trace. */
|
||||
|
||||
LUAJIT_MODE_WRAPCFUNC = 0x10, /* Set wrapper mode for C function calls. */
|
||||
|
||||
LUAJIT_MODE_MAX
|
||||
};
|
||||
|
||||
/* Flags or'ed in to the mode. */
|
||||
#define LUAJIT_MODE_OFF 0x0000 /* Disable JIT compilation. */
|
||||
#define LUAJIT_MODE_ON 0x0100 /* (Re-)enable JIT compilation. */
|
||||
#define LUAJIT_MODE_OFF 0x0000 /* Turn feature off. */
|
||||
#define LUAJIT_MODE_ON 0x0100 /* Turn feature on. */
|
||||
#define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */
|
||||
|
||||
/* LuaJIT public C API. */
|
||||
|
Loading…
Reference in New Issue
Block a user