mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 07:34:07 +00:00
Merge branch 'v2.1' of https://github.com/LuaJIT/LuaJIT into v2.1
This commit is contained in:
commit
04375136ff
@ -1,7 +1,7 @@
|
||||
===============================================================================
|
||||
LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
|
||||
|
||||
Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
Copyright (C) 2005-2017 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
|
||||
|
10
Makefile
10
Makefile
@ -10,13 +10,13 @@
|
||||
# For MSVC, please follow the instructions given in src/msvcbuild.bat.
|
||||
# For MinGW and Cygwin, cd to src and run make with the Makefile there.
|
||||
#
|
||||
# Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
# Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
##############################################################################
|
||||
|
||||
MAJVER= 2
|
||||
MINVER= 1
|
||||
RELVER= 0
|
||||
PREREL= -beta2
|
||||
PREREL= -beta3
|
||||
VERSION= $(MAJVER).$(MINVER).$(RELVER)$(PREREL)
|
||||
ABIVER= 5.1
|
||||
|
||||
@ -86,8 +86,10 @@ 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 bcsave.lua dump.lua p.lua v.lua zone.lua \
|
||||
dis_x86.lua dis_x64.lua dis_arm.lua dis_ppc.lua \
|
||||
dis_mips.lua dis_mipsel.lua dis_s390x.lua vmdef.lua
|
||||
dis_x86.lua dis_x64.lua dis_arm.lua dis_arm64.lua \
|
||||
dis_arm64be.lua dis_ppc.lua dis_mips.lua dis_mipsel.lua \
|
||||
dis_mips64.lua dis_mips64el.lua vmdef.lua dis_s390x.lua
|
||||
>>>>>>> fddef924097f28c46a0a5b45483a6086b33cab81
|
||||
|
||||
ifeq (,$(findstring Windows,$(OS)))
|
||||
HOST_SYS:= $(shell uname -s)
|
||||
|
4
README
4
README
@ -1,11 +1,11 @@
|
||||
README for LuaJIT 2.1.0-beta2
|
||||
README for LuaJIT 2.1.0-beta3
|
||||
-----------------------------
|
||||
|
||||
LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
|
||||
|
||||
Project Homepage: http://luajit.org/
|
||||
|
||||
LuaJIT is Copyright (C) 2005-2016 Mike Pall.
|
||||
LuaJIT is Copyright (C) 2005-2017 Mike Pall.
|
||||
LuaJIT is free software, released under the MIT license.
|
||||
See full Copyright Notice in the COPYRIGHT file or in luajit.h.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2004-2016 Mike Pall.
|
||||
/* Copyright (C) 2004-2017 Mike Pall.
|
||||
*
|
||||
* You are welcome to use the general ideas of this design for your own sites.
|
||||
* But please do not steal the stylesheet, the layout or the color scheme.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2004-2016 Mike Pall.
|
||||
/* Copyright (C) 2004-2017 Mike Pall.
|
||||
*
|
||||
* You are welcome to use the general ideas of this design for your own sites.
|
||||
* But please do not steal the stylesheet, the layout or the color scheme.
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>LuaJIT Change History</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -65,7 +65,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: #0000c0;">stable version</span> is <strong>LuaJIT 2.0.4</strong>.<br>
|
||||
The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT 2.0.5</strong>.<br>
|
||||
</p>
|
||||
<p>
|
||||
Please check the
|
||||
@ -74,6 +74,30 @@ to see whether newer versions are available.
|
||||
</p>
|
||||
|
||||
<div class="major" style="background: #d0d0ff;">
|
||||
<h2 id="LuaJIT-2.1.0-beta3">LuaJIT 2.1.0-beta3 — 2017-05-01</h2>
|
||||
<ul>
|
||||
<li>Rewrite memory block allocator.</li>
|
||||
<li>Add various extension from Lua 5.2/5.3.</li>
|
||||
<li>Remove old Lua 5.0 compatibility defines.</li>
|
||||
<li>Set arg table before evaluating <tt>LUA_INIT</tt> and <tt>-e</tt> chunks.</li>
|
||||
<li>Fix FOLD rules for <tt>math.abs()</tt> and FP negation.</li>
|
||||
<li>Fix soft-float <tt>math.abs()</tt> and negation.</li>
|
||||
<li>Fix formatting of some small denormals at low precision.</li>
|
||||
<li>LJ_GC64: Add JIT compiler support.</li>
|
||||
<li>x64/LJ_GC64: Add JIT compiler backend.</li>
|
||||
<li>x86/x64: Generate BMI2 shifts and rotates, if available.</li>
|
||||
<li>Windows/x86: Add full exception interoperability.</li>
|
||||
<li>ARM64: Add big-endian support.</li>
|
||||
<li>ARM64: Add JIT compiler backend.</li>
|
||||
<li>MIPS: Fix <tt>TSETR</tt> barrier.</li>
|
||||
<li>MIPS: Support MIPS16 interlinking.</li>
|
||||
<li>MIPS soft-float: Fix code generation for <tt>HREF</tt>.</li>
|
||||
<li>MIPS64: Add MIPS64 hard-float JIT compiler backend.</li>
|
||||
<li>MIPS64: Add MIPS64 hard-float/soft-float support to interpreter.</li>
|
||||
<li>FFI: Compile bitfield loads/stores.</li>
|
||||
<li>Various fixes common with the 2.0 branch.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.1.0-beta2">LuaJIT 2.1.0-beta2 — 2016-03-03</h2>
|
||||
<ul>
|
||||
<li>Enable trace stitching.</li>
|
||||
@ -140,6 +164,48 @@ Please take a look at the commit history for more details.
|
||||
</div>
|
||||
|
||||
<div class="major" style="background: #ffffd0;">
|
||||
<h2 id="LuaJIT-2.0.5">LuaJIT 2.0.5 — 2017-05-01</h2>
|
||||
<ul>
|
||||
<li>Add workaround for MSVC 2015 stdio changes.</li>
|
||||
<li>Limit mcode alloc probing, depending on the available pool size.</li>
|
||||
<li>Fix overly restrictive range calculation in mcode allocation.</li>
|
||||
<li>Fix out-of-scope goto handling in parser.</li>
|
||||
<li>Remove internal <tt>__mode = "K"</tt> and replace with safe check.</li>
|
||||
<li>Add "proto" field to <tt>jit.util.funcinfo()</tt>.</li>
|
||||
<li>Fix GC step size calculation.</li>
|
||||
<li>Initialize <tt>uv->immutable</tt> for upvalues of loaded chunks.</li>
|
||||
<li>Fix for cdata vs. non-cdata arithmetics/comparisons.</li>
|
||||
<li>Drop leftover regs in 'for' iterator assignment, too.</li>
|
||||
<li>Fix PHI remarking in SINK pass.</li>
|
||||
<li>Don't try to record outermost <tt>pcall()</tt> return to lower frame.</li>
|
||||
<li>Add guard for obscure aliasing between open upvalues and SSA slots.</li>
|
||||
<li>Remove assumption that <tt>lj_math_random_step()</tt> doesn't clobber FPRs.</li>
|
||||
<li>Fix handling of non-numeric strings in arithmetic coercions.</li>
|
||||
<li>Fix recording of <tt>select(n, ...)</tt> with off-trace varargs</li>
|
||||
<li>Fix install for cross-builds.</li>
|
||||
<li>Don't allocate unused 2nd result register in JIT compiler backend.</li>
|
||||
<li>Drop marks from replayed instructions when sinking.</li>
|
||||
<li>Fix unsinking check.</li>
|
||||
<li>Properly handle OOM in <tt>trace_save()</tt>.</li>
|
||||
<li>Limit number of arguments given to <tt>io.lines()</tt> and <tt>fp:lines()</tt>.</li>
|
||||
<li>Fix narrowing of <tt>TOBIT</tt>.</li>
|
||||
<li>OSX: Fix build with recent XCode.</li>
|
||||
<li>x86/x64: Don't spill an explicit <tt>REF_BASE</tt> in the IR.</li>
|
||||
<li>x86/x64: Fix instruction length decoder.</li>
|
||||
<li>x86/x64: Search for exit jumps with instruction length decoder.</li>
|
||||
<li>ARM: Fix <tt>BLX</tt> encoding for Thumb interworking calls.</li>
|
||||
<li>MIPS: Don't use <tt>RID_GP</tt> as a scratch register.</li>
|
||||
<li>MIPS: Fix emitted code for U32 to float conversion.</li>
|
||||
<li>MIPS: Backport workaround for compact unwind tables.</li>
|
||||
<li>MIPS: Fix cross-endian jit.bcsave.</li>
|
||||
<li>MIPS: Fix <tt>BC_ISNEXT</tt> fallback path.</li>
|
||||
<li>MIPS: Fix use of ffgccheck delay slots in interpreter.</li>
|
||||
<li>FFI: Fix FOLD rules for <tt>int64_t</tt> comparisons.</li>
|
||||
<li>FFI: Fix SPLIT pass for <tt>CONV i64.u64</tt>.</li>
|
||||
<li>FFI: Fix <tt>ipairs()</tt> recording.</li>
|
||||
<li>FFI: Don't propagate qualifiers into subtypes of complex.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.4">LuaJIT 2.0.4 — 2015-05-14</h2>
|
||||
<ul>
|
||||
<li>Fix stack check in narrowing optimization.</li>
|
||||
@ -807,7 +873,7 @@ no point in listing differences over earlier versions.</li>
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>Contact</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -61,8 +61,15 @@
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
If you want to report bugs, propose fixes or suggest enhancements,
|
||||
please use the
|
||||
<a href="https://github.com/LuaJIT/LuaJIT/issues">GitHub issue tracker</a>.
|
||||
</p>
|
||||
<p>
|
||||
Please send general questions to the
|
||||
<a href="http://luajit.org/list.html"><span class="ext">»</span> LuaJIT mailing list</a>.
|
||||
</p>
|
||||
<p>
|
||||
You can also send any questions you have directly to me:
|
||||
</p>
|
||||
|
||||
@ -86,7 +93,7 @@ xD("fyZKB8xv\"FJytmz8.KAB0u52D")
|
||||
<h2>Copyright</h2>
|
||||
<p>
|
||||
All documentation is
|
||||
Copyright © 2005-2016 Mike Pall.
|
||||
Copyright © 2005-2017 Mike Pall.
|
||||
</p>
|
||||
|
||||
|
||||
@ -94,7 +101,7 @@ Copyright © 2005-2016 Mike Pall.
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>Lua/C API Extensions</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -91,8 +91,8 @@ 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
|
||||
The flag can be <tt>LUAJIT_MODE_OFF</tt> to turn a feature off,
|
||||
<tt>LUAJIT_MODE_ON</tt> to turn a feature on, or
|
||||
<tt>LUAJIT_MODE_FLUSH</tt> to flush cached code.
|
||||
</p>
|
||||
<p>
|
||||
@ -179,7 +179,7 @@ Also note that this mechanism is not without overhead.
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>FFI Library</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -322,7 +322,7 @@ without undue conversion penalties.
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>ffi.* API Functions</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -560,7 +560,7 @@ named <tt>i</tt>.
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>FFI Semantics</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -864,7 +864,7 @@ place of a type, you'd need to use <tt>ffi.typeof("int")</tt> instead.
|
||||
<p>
|
||||
The main use for parameterized types are libraries implementing abstract
|
||||
data types
|
||||
(<a href="http://www.freelists.org/post/luajit/ffi-type-of-pointer-to,8"><span class="ext">»</span> example</a>),
|
||||
(<a href="https://www.freelists.org/post/luajit/ffi-type-of-pointer-to,8">example</a>),
|
||||
similar to what can be achieved with C++ template metaprogramming.
|
||||
Another use case are derived types of anonymous structs, which avoids
|
||||
pollution of the global struct namespace.
|
||||
@ -1221,13 +1221,12 @@ The following operations are currently not compiled and may exhibit
|
||||
suboptimal performance, especially when used in inner loops:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Bitfield accesses and initializations.</li>
|
||||
<li>Vector operations.</li>
|
||||
<li>Table initializers.</li>
|
||||
<li>Initialization of nested <tt>struct</tt>/<tt>union</tt> types.</li>
|
||||
<li>Non-default initialization of VLA/VLS or large C types
|
||||
(> 128 bytes or > 16 array elements.</li>
|
||||
<li>Conversions from lightuserdata to <tt>void *</tt>.</li>
|
||||
<li>Bitfield initializations.</li>
|
||||
<li>Pointer differences for element sizes that are not a power of
|
||||
two.</li>
|
||||
<li>Calls to C functions with aggregates passed or returned by
|
||||
@ -1253,7 +1252,7 @@ compiled.</li>
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>FFI Tutorial</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -593,7 +593,7 @@ it to a local variable in the function scope is unnecessary.
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>jit.* Library</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -191,7 +191,7 @@ if you want to know more.
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>Profiler</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -355,7 +355,7 @@ use.
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>Extensions</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -210,7 +210,8 @@ bytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded.
|
||||
<p>
|
||||
Note: <tt>LJ_GC64</tt> mode requires a different frame layout, which implies
|
||||
a different, incompatible bytecode format for ports that use this mode (e.g.
|
||||
ARM64). This may be rectified in the future.
|
||||
ARM64 or MIPS64) or when explicitly enabled for x64. This may be rectified
|
||||
in the future.
|
||||
</p>
|
||||
|
||||
<h3 id="table_new"><tt>table.new(narray, nhash)</tt> allocates a pre-sized table</h3>
|
||||
@ -291,8 +292,8 @@ enabled:
|
||||
<li><tt>load(string|reader [, chunkname [,mode [,env]]])</tt>.</li>
|
||||
<li><tt>loadstring()</tt> is an alias for <tt>load()</tt>.</li>
|
||||
<li><tt>loadfile(filename [,mode [,env]])</tt>.</li>
|
||||
<li><tt>math.log(x [,base])</tt>.
|
||||
<li><tt>string.rep(s, n [,sep])</tt>.
|
||||
<li><tt>math.log(x [,base])</tt>.</li>
|
||||
<li><tt>string.rep(s, n [,sep])</tt>.</li>
|
||||
<li><tt>string.format()</tt>: <tt>%q</tt> reversible.
|
||||
<tt>%s</tt> checks <tt>__tostring</tt>.
|
||||
<tt>%a</tt> and <tt>"%A</tt> added.</li>
|
||||
@ -311,6 +312,26 @@ indexes for varargs.</li>
|
||||
<li><tt>debug.getupvalue()</tt> and <tt>debug.setupvalue()</tt> handle
|
||||
C functions.</li>
|
||||
<li><tt>debug.upvalueid()</tt> and <tt>debug.upvaluejoin()</tt>.</li>
|
||||
<li>Lua/C API extensions:
|
||||
<tt>lua_version()</tt>
|
||||
<tt>lua_upvalueid()</tt>
|
||||
<tt>lua_upvaluejoin()</tt>
|
||||
<tt>lua_loadx()</tt>
|
||||
<tt>lua_copy()</tt>
|
||||
<tt>lua_tonumberx()</tt>
|
||||
<tt>lua_tointegerx()</tt>
|
||||
<tt>luaL_fileresult()</tt>
|
||||
<tt>luaL_execresult()</tt>
|
||||
<tt>luaL_loadfilex()</tt>
|
||||
<tt>luaL_loadbufferx()</tt>
|
||||
<tt>luaL_traceback()</tt>
|
||||
<tt>luaL_setfuncs()</tt>
|
||||
<tt>luaL_pushmodule()</tt>
|
||||
<tt>luaL_newlibtable()</tt>
|
||||
<tt>luaL_newlib()</tt>
|
||||
<tt>luaL_testudata()</tt>
|
||||
<tt>luaL_setmetatable()</tt>
|
||||
</li>
|
||||
<li>Command line option <tt>-E</tt>.</li>
|
||||
<li>Command line checks <tt>__tostring</tt> for errors.</li>
|
||||
</ul>
|
||||
@ -335,7 +356,9 @@ instead of <tt>true</tt>.</li>
|
||||
exit status.</li>
|
||||
<li><tt>debug.setmetatable()</tt> returns object.</li>
|
||||
<li><tt>debug.getuservalue()</tt> and <tt>debug.setuservalue()</tt>.</li>
|
||||
<li>Remove <tt>math.mod()</tt>, <tt>string.gfind()</tt>.
|
||||
<li>Remove <tt>math.mod()</tt>, <tt>string.gfind()</tt>.</li>
|
||||
<li><tt>package.searchers</tt>.</li>
|
||||
<li><tt>module()</tt> returns the module table.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Note: this provides only partial compatibility with Lua 5.2 at the
|
||||
@ -350,6 +373,12 @@ LuaJIT supports some extensions from Lua 5.3:
|
||||
<ul>
|
||||
<li>Unicode escape <tt>'\u{XX...}'</tt> embeds the UTF-8 encoding in string literals.</li>
|
||||
<li>The argument table <tt>arg</tt> can be read (and modified) by <tt>LUA_INIT</tt> and <tt>-e</tt> chunks.</li>
|
||||
<li><tt>io.read()</tt> and <tt>file:read()</tt> accept formats with or without a leading <tt>*</tt>.</li>
|
||||
<li><tt>table.move(a1, f, e, t [,a2])</tt>.</li>
|
||||
<li><tt>coroutine.isyieldable()</tt>.</li>
|
||||
<li>Lua/C API extensions:
|
||||
<tt>lua_isyieldable()</tt>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="exceptions">C++ Exception Interoperability</h2>
|
||||
@ -443,7 +472,7 @@ C++ destructors.</li>
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>Frequently Asked Questions (FAQ)</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -176,7 +176,7 @@ the development of certain features, if they are important to you.
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>Installation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -175,6 +175,14 @@ MSVC or WinSDK.</li>
|
||||
Please read the instructions given in these files, before changing
|
||||
any settings.
|
||||
</p>
|
||||
<p>
|
||||
LuaJIT on x64 currently uses 32 bit GC objects by default.
|
||||
<tt>LJ_GC64</tt> mode may be explicitly enabled:
|
||||
add <tt>XCFLAGS=-DLUAJIT_ENABLE_GC64</tt> to the make command or run
|
||||
<tt>msvcbuild gc64</tt> for MSVC/WinSDK. Please check the note
|
||||
about the <a href="extensions.html#string_dump">bytecode format</a>
|
||||
differences, too.
|
||||
</p>
|
||||
|
||||
<h2 id="posix">POSIX Systems (Linux, OSX, *BSD etc.)</h2>
|
||||
<h3>Prerequisites</h3>
|
||||
@ -190,8 +198,8 @@ open a 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.4.tar.gz
|
||||
cd LuaJIT-2.0.4</pre>
|
||||
tar zxf LuaJIT-2.0.5.tar.gz
|
||||
cd LuaJIT-2.0.5</pre>
|
||||
<h3>Building LuaJIT</h3>
|
||||
<p>
|
||||
The supplied Makefiles try to auto-detect the settings needed for your
|
||||
@ -584,14 +592,11 @@ intend to load Lua/C modules at runtime.
|
||||
</li>
|
||||
<li>
|
||||
If you're building a 64 bit application on OSX which links directly or
|
||||
indirectly against LuaJIT, you need to link your main executable
|
||||
with these flags:
|
||||
indirectly against LuaJIT which is not built for <tt>LJ_GC64</tt> mode,
|
||||
you need to link your main executable with these flags:
|
||||
<pre class="code">
|
||||
-pagezero_size 10000 -image_base 100000000
|
||||
</pre>
|
||||
Also, it's recommended to <tt>rebase</tt> all (self-compiled) shared libraries
|
||||
which are loaded at runtime on OSX/x64 (e.g. C extension modules for Lua).
|
||||
See: <tt>man rebase</tt>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Additional hints for initializing LuaJIT using the C API functions:</p>
|
||||
@ -677,7 +682,7 @@ to me (the upstream) and not you (the package maintainer), anyway.
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>LuaJIT</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -152,7 +152,7 @@ Lua is a powerful, dynamic and light-weight programming language.
|
||||
It may be embedded or used as a general-purpose, stand-alone language.
|
||||
</p>
|
||||
<p>
|
||||
LuaJIT is Copyright © 2005-2016 Mike Pall, released under the
|
||||
LuaJIT is Copyright © 2005-2017 Mike Pall, released under the
|
||||
<a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">»</span> MIT open source license</a>.
|
||||
</p>
|
||||
<p>
|
||||
@ -226,7 +226,7 @@ Please select a sub-topic in the navigation bar to learn more about LuaJIT.
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>Running LuaJIT</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -189,7 +189,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.4/jit</tt> on POSIX
|
||||
this is <tt>/usr/local/share/luajit-2.0.5/jit</tt> on POSIX
|
||||
systems.
|
||||
</p>
|
||||
|
||||
@ -299,7 +299,7 @@ Here are the parameters and their default settings:
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<title>Status</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2016, Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
@ -97,12 +97,23 @@ handled correctly. The error may fall through an on-trace
|
||||
<tt>lua_atpanic</tt> on x64. This issue will be fixed with the new
|
||||
garbage collector.
|
||||
</li>
|
||||
<li>
|
||||
LuaJIT on 64 bit systems provides a <b>limited range</b> of 47 bits for the
|
||||
<b>legacy <tt>lightuserdata</tt></b> data type.
|
||||
This is only relevant on x64 systems which use the negative part of the
|
||||
virtual address space in user mode, e.g. Solaris/x64, and on ARM64 systems
|
||||
configured with a 48 bit or 52 bit VA.
|
||||
Avoid using <tt>lightuserdata</tt> to hold pointers that may point outside
|
||||
of that range, e.g. variables on the stack. In general, avoid this data
|
||||
type for new code and replace it with (much more performant) FFI bindings.
|
||||
FFI cdata pointers can address the full 64 bit range.
|
||||
</li>
|
||||
</ul>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2016 Mike Pall
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** DynASM ARM encoding engine.
|
||||
** Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
@ -254,6 +254,7 @@ void dasm_put(Dst_DECL, int start, ...)
|
||||
case DASM_IMMV8:
|
||||
CK((n & 3) == 0, RANGE_I);
|
||||
n >>= 2;
|
||||
/* fallthrough */
|
||||
case DASM_IMML8:
|
||||
case DASM_IMML12:
|
||||
CK(n >= 0 ? ((n>>((ins>>5)&31)) == 0) :
|
||||
@ -371,6 +372,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
break;
|
||||
case DASM_REL_LG:
|
||||
CK(n >= 0, UNDEF_LG);
|
||||
/* fallthrough */
|
||||
case DASM_REL_PC:
|
||||
CK(n >= 0, UNDEF_PC);
|
||||
n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) - 4;
|
||||
|
@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM ARM module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** DynASM ARM64 encoding engine.
|
||||
** Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM ARM64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** DynASM MIPS encoding engine.
|
||||
** Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
@ -350,6 +350,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
break;
|
||||
case DASM_REL_LG:
|
||||
CK(n >= 0, UNDEF_LG);
|
||||
/* fallthrough */
|
||||
case DASM_REL_PC:
|
||||
CK(n >= 0, UNDEF_PC);
|
||||
n = *DASM_POS2PTR(D, n);
|
||||
|
@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM MIPS32/MIPS64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM MIPS64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
-- This module just sets 64 bit mode for the combined MIPS/MIPS64 module.
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** DynASM PPC/PPC64 encoding engine.
|
||||
** Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
@ -354,6 +354,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
break;
|
||||
case DASM_REL_LG:
|
||||
CK(n >= 0, UNDEF_LG);
|
||||
/* fallthrough */
|
||||
case DASM_REL_PC:
|
||||
CK(n >= 0, UNDEF_PC);
|
||||
n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base);
|
||||
|
@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM PPC/PPC64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
--
|
||||
-- Support for various extensions contributed by Caio Souza Oliveira.
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** DynASM encoding engine prototypes.
|
||||
** Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM x64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
-- This module just sets 64 bit mode for the combined x86/x64 module.
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** DynASM x86 encoding engine.
|
||||
** Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
@ -194,12 +194,13 @@ void dasm_put(Dst_DECL, int start, ...)
|
||||
switch (action) {
|
||||
case DASM_DISP:
|
||||
if (n == 0) { if (mrm < 0) mrm = p[-2]; if ((mrm&7) != 5) break; }
|
||||
case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob;
|
||||
/* fallthrough */
|
||||
case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob; /* fallthrough */
|
||||
case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */
|
||||
case DASM_IMM_D: ofs += 4; break;
|
||||
case DASM_IMM_S: CK(((n+128)&-256) == 0, RANGE_I); goto ob;
|
||||
case DASM_IMM_B: CK((n&-256) == 0, RANGE_I); ob: ofs++; break;
|
||||
case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob;
|
||||
case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob; /* fallthrough */
|
||||
case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break;
|
||||
case DASM_SPACE: p++; ofs += n; break;
|
||||
case DASM_SETLABEL: b[pos-2] = -0x40000000; break; /* Neg. label ofs. */
|
||||
@ -207,8 +208,8 @@ void dasm_put(Dst_DECL, int start, ...)
|
||||
if (*p < 0x40 && p[1] == DASM_DISP) mrm = n;
|
||||
if (*p < 0x20 && (n&7) == 4) ofs++;
|
||||
switch ((*p++ >> 3) & 3) {
|
||||
case 3: n |= b[pos-3];
|
||||
case 2: n |= b[pos-2];
|
||||
case 3: n |= b[pos-3]; /* fallthrough */
|
||||
case 2: n |= b[pos-2]; /* fallthrough */
|
||||
case 1: if (n <= 7) { b[pos-1] |= 0x10; ofs--; }
|
||||
}
|
||||
continue;
|
||||
@ -329,11 +330,14 @@ int dasm_link(Dst_DECL, size_t *szp)
|
||||
pos += 2;
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;
|
||||
/* fallthrough */
|
||||
case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
|
||||
case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
|
||||
case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break;
|
||||
case DASM_LABEL_LG: p++;
|
||||
/* fallthrough */
|
||||
case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */
|
||||
case DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */
|
||||
case DASM_EXTERN: p += 2; break;
|
||||
@ -391,12 +395,15 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
if (mrm != 5) { mm[-1] -= 0x80; break; } }
|
||||
if (((n+128) & -256) != 0) goto wd; else mm[-1] -= 0x40;
|
||||
}
|
||||
/* fallthrough */
|
||||
case DASM_IMM_S: case DASM_IMM_B: wb: dasmb(n); break;
|
||||
case DASM_IMM_DB: if (((n+128)&-256) == 0) {
|
||||
db: if (!mark) mark = cp; mark[-2] += 2; mark = NULL; goto wb;
|
||||
} else mark = NULL;
|
||||
/* fallthrough */
|
||||
case DASM_IMM_D: wd: dasmd(n); break;
|
||||
case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL;
|
||||
/* fallthrough */
|
||||
case DASM_IMM_W: dasmw(n); break;
|
||||
case DASM_VREG: {
|
||||
int t = *p++;
|
||||
@ -421,7 +428,9 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
}
|
||||
case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;
|
||||
b++; n = (int)(ptrdiff_t)D->globals[-n];
|
||||
case DASM_REL_A: rel_a: n -= (int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */
|
||||
/* fallthrough */
|
||||
case DASM_REL_A: rel_a:
|
||||
n -= (unsigned int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */
|
||||
case DASM_REL_PC: rel_pc: {
|
||||
int shrink = *b++;
|
||||
int *pb = DASM_POS2PTR(D, n); if (*pb < 0) { n = pb[1]; goto rel_a; }
|
||||
@ -432,6 +441,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
}
|
||||
case DASM_IMM_LG:
|
||||
p++; if (n < 0) { n = (int)(ptrdiff_t)D->globals[-n]; goto wd; }
|
||||
/* fallthrough */
|
||||
case DASM_IMM_PC: {
|
||||
int *pb = DASM_POS2PTR(D, n);
|
||||
n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);
|
||||
@ -452,6 +462,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
||||
case DASM_EXTERN: n = DASM_EXTERN(Dst, cp, p[1], *p); p += 2; goto wd;
|
||||
case DASM_MARK: mark = cp; break;
|
||||
case DASM_ESC: action = *p++;
|
||||
/* fallthrough */
|
||||
default: *cp++ = action; break;
|
||||
case DASM_SECTION: case DASM_STOP: goto stop;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- DynASM x86/x64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
-- DynASM. A dynamic assembler for code generation engines.
|
||||
-- Originally designed and implemented for LuaJIT.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See below for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@ -17,7 +17,7 @@ local _info = {
|
||||
url = "http://luajit.org/dynasm.html",
|
||||
license = "MIT",
|
||||
copyright = [[
|
||||
Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
Copyright (C) 2005-2017 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
|
||||
|
@ -74,7 +74,7 @@ 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-2016 Mike Pall.
|
||||
\fBLuaJIT\fR is Copyright \(co 2005-2017 Mike Pall.
|
||||
.br
|
||||
\fBLuaJIT\fR is open source software, released under the MIT license.
|
||||
.SH SEE ALSO
|
||||
|
@ -2,7 +2,7 @@
|
||||
majver=2
|
||||
minver=1
|
||||
relver=0
|
||||
version=${majver}.${minver}.${relver}-beta2
|
||||
version=${majver}.${minver}.${relver}-beta3
|
||||
abiver=5.1
|
||||
|
||||
prefix=/usr/local
|
||||
|
11
src/Makefile
11
src/Makefile
@ -7,7 +7,7 @@
|
||||
# Also works with MinGW and Cygwin on Windows.
|
||||
# Please check msvcbuild.bat for building with MSVC on Windows.
|
||||
#
|
||||
# Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
# Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
##############################################################################
|
||||
|
||||
MAJVER= 2
|
||||
@ -110,6 +110,9 @@ XCFLAGS=
|
||||
#XCFLAGS+= -DLUAJIT_NUMMODE=1
|
||||
#XCFLAGS+= -DLUAJIT_NUMMODE=2
|
||||
#
|
||||
# Enable GC64 mode for x64.
|
||||
#XCFLAGS+= -DLUAJIT_ENABLE_GC64
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
@ -242,6 +245,9 @@ ifneq (,$(findstring LJ_TARGET_S390X ,$(TARGET_TESTARCH)))
|
||||
TARGET_LJARCH= s390x
|
||||
else
|
||||
ifneq (,$(findstring LJ_TARGET_ARM64 ,$(TARGET_TESTARCH)))
|
||||
ifneq (,$(findstring __AARCH64EB__ ,$(TARGET_TESTARCH)))
|
||||
TARGET_ARCH= -D__AARCH64EB__=1
|
||||
endif
|
||||
TARGET_LJARCH= arm64
|
||||
else
|
||||
ifneq (,$(findstring LJ_TARGET_PPC ,$(TARGET_TESTARCH)))
|
||||
@ -306,6 +312,7 @@ ifeq (Windows,$(TARGET_SYS))
|
||||
TARGET_XSHLDFLAGS= -shared
|
||||
TARGET_DYNXLDOPTS=
|
||||
else
|
||||
TARGET_AR+= 2>/dev/null
|
||||
ifeq (,$(shell $(TARGET_CC) -o /dev/null -c -x c /dev/null -fno-stack-protector 2>/dev/null || echo 1))
|
||||
TARGET_XCFLAGS+= -fno-stack-protector
|
||||
endif
|
||||
@ -314,7 +321,6 @@ ifeq (Darwin,$(TARGET_SYS))
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.4
|
||||
endif
|
||||
TARGET_STRIP+= -x
|
||||
TARGET_AR+= 2>/dev/null
|
||||
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
|
||||
TARGET_DYNXLDOPTS=
|
||||
TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER)
|
||||
@ -325,7 +331,6 @@ ifeq (Darwin,$(TARGET_SYS))
|
||||
else
|
||||
ifeq (iOS,$(TARGET_SYS))
|
||||
TARGET_STRIP+= -x
|
||||
TARGET_AR+= 2>/dev/null
|
||||
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
|
||||
TARGET_DYNXLDOPTS=
|
||||
TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER)
|
||||
|
@ -3,8 +3,8 @@ lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
|
||||
lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h lj_alloc.h
|
||||
lib_base.o: lib_base.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_debug.h lj_str.h \
|
||||
lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \
|
||||
lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \
|
||||
lj_tab.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cconv.h \
|
||||
lj_ff.h lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \
|
||||
lj_strfmt.h lj_lib.h lj_libdef.h
|
||||
lib_bit.o: lib_bit.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_buf.h lj_gc.h lj_str.h lj_strscan.h \
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** LuaJIT VM builder.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** This is a tool to build the hand-tuned assembler code required for
|
||||
** LuaJIT's bytecode interpreter. It supports a variety of output formats
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** LuaJIT VM builder.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _BUILDVM_H
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** LuaJIT VM builder: Assembler source code emitter.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#include "buildvm.h"
|
||||
@ -141,10 +141,14 @@ static void emit_asm_words(BuildCtx *ctx, uint8_t *p, int n)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i += 4) {
|
||||
uint32_t ins = *(uint32_t *)(p+i);
|
||||
#if LJ_TARGET_ARM64 && LJ_BE
|
||||
ins = lj_bswap(ins); /* ARM64 instructions are always little-endian. */
|
||||
#endif
|
||||
if ((i & 15) == 0)
|
||||
fprintf(ctx->fp, "\t.long 0x%08x", *(uint32_t *)(p+i));
|
||||
fprintf(ctx->fp, "\t.long 0x%08x", ins);
|
||||
else
|
||||
fprintf(ctx->fp, ",0x%08x", *(uint32_t *)(p+i));
|
||||
fprintf(ctx->fp, ",0x%08x", ins);
|
||||
if ((i & 15) == 12) putc('\n', ctx->fp);
|
||||
}
|
||||
if ((n & 15) != 0) putc('\n', ctx->fp);
|
||||
@ -262,7 +266,8 @@ static void emit_asm_label(BuildCtx *ctx, const char *name, int size, int isfunc
|
||||
case BUILD_machasm:
|
||||
fprintf(ctx->fp,
|
||||
"\n\t.private_extern %s\n"
|
||||
"%s:\n", name, name);
|
||||
"\t.no_dead_strip %s\n"
|
||||
"%s:\n", name, name, name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -386,7 +391,7 @@ void emit_asm(BuildCtx *ctx)
|
||||
#if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA)
|
||||
fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n");
|
||||
#endif
|
||||
#if LJ_TARGET_PPC && !LJ_TARGET_PS3
|
||||
#if LJ_TARGET_PPC && !LJ_TARGET_PS3 && !LJ_ABI_SOFTFP
|
||||
/* Hard-float ABI. */
|
||||
fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n");
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** LuaJIT VM builder: IR folding hash table generator.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#include "buildvm.h"
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** LuaJIT VM builder: library definition compiler.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#include "buildvm.h"
|
||||
|
@ -15,7 +15,12 @@ static const uint8_t libbc_code[] = {
|
||||
8,2,0,0,88,3,23,128,59,3,2,0,43,4,0,0,64,4,2,0,76,3,2,0,88,3,18,128,16,1,14,
|
||||
0,41,3,1,0,3,3,1,0,88,3,14,128,3,1,2,0,88,3,12,128,59,3,1,0,22,4,1,1,18,5,2,
|
||||
0,41,6,1,0,77,4,4,128,23,8,1,7,59,9,7,0,64,9,8,0,79,4,252,127,43,4,0,0,64,4,
|
||||
2,0,76,3,2,0,75,0,1,0,0,2,0
|
||||
2,0,76,3,2,0,75,0,1,0,0,2,0,5,12,0,0,0,35,16,0,12,0,16,1,14,0,16,2,14,0,16,
|
||||
3,14,0,11,4,0,0,88,5,1,128,18,4,0,0,16,4,12,0,3,1,2,0,88,5,24,128,33,5,1,3,
|
||||
0,2,3,0,88,6,4,128,2,3,1,0,88,6,2,128,4,4,0,0,88,6,9,128,18,6,1,0,18,7,2,0,
|
||||
41,8,1,0,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79,6,252,127,88,6,8,128,
|
||||
18,6,2,0,18,7,1,0,41,8,255,255,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79,
|
||||
6,252,127,76,4,2,0,0
|
||||
#else
|
||||
0,1,2,0,0,1,2,24,1,0,0,76,1,2,0,241,135,158,166,3,220,203,178,130,4,0,1,2,0,
|
||||
0,1,2,24,1,0,0,76,1,2,0,243,244,148,165,20,198,190,199,252,3,0,1,2,0,0,0,3,
|
||||
@ -28,7 +33,12 @@ static const uint8_t libbc_code[] = {
|
||||
8,2,0,0,88,3,23,128,59,3,2,0,43,4,0,0,64,4,2,0,76,3,2,0,88,3,18,128,16,1,14,
|
||||
0,41,3,1,0,3,3,1,0,88,3,14,128,3,1,2,0,88,3,12,128,59,3,1,0,22,4,1,1,18,5,2,
|
||||
0,41,6,1,0,77,4,4,128,23,8,1,7,59,9,7,0,64,9,8,0,79,4,252,127,43,4,0,0,64,4,
|
||||
2,0,76,3,2,0,75,0,1,0,0,2,0
|
||||
2,0,76,3,2,0,75,0,1,0,0,2,0,5,12,0,0,0,35,16,0,12,0,16,1,14,0,16,2,14,0,16,
|
||||
3,14,0,11,4,0,0,88,5,1,128,18,4,0,0,16,4,12,0,3,1,2,0,88,5,24,128,33,5,1,3,
|
||||
0,2,3,0,88,6,4,128,2,3,1,0,88,6,2,128,4,4,0,0,88,6,9,128,18,6,1,0,18,7,2,0,
|
||||
41,8,1,0,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79,6,252,127,88,6,8,128,
|
||||
18,6,2,0,18,7,1,0,41,8,255,255,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79,
|
||||
6,252,127,76,4,2,0,0
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -40,6 +50,7 @@ static const struct { const char *name; int ofs; } libbc_map[] = {
|
||||
{"table_foreach",136},
|
||||
{"table_getn",207},
|
||||
{"table_remove",226},
|
||||
{NULL,355}
|
||||
{"table_move",355},
|
||||
{NULL,502}
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** LuaJIT VM builder: PE object emitter.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Only used for building on Windows, since we cannot assume the presence
|
||||
** of a suitable assembler. The host and target byte order must match.
|
||||
|
@ -2,7 +2,7 @@
|
||||
-- Lua script to dump the bytecode of the library functions written in Lua.
|
||||
-- The resulting 'buildvm_libbc.h' is used for the build process of LuaJIT.
|
||||
----------------------------------------------------------------------------
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
-- Lua script to generate a customized, minified version of Lua.
|
||||
-- The resulting 'minilua' is used for the build process of LuaJIT.
|
||||
----------------------------------------------------------------------------
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT bytecode listing module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
|
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT module to save/list bytecode.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
@ -63,8 +63,8 @@ local map_type = {
|
||||
}
|
||||
|
||||
local map_arch = {
|
||||
x86 = true, x64 = true, arm = true, arm64 = true, ppc = true,
|
||||
mips = true, mipsel = true,
|
||||
x86 = true, x64 = true, arm = true, arm64 = true, arm64be = true,
|
||||
ppc = true, mips = true, mipsel = true,
|
||||
}
|
||||
|
||||
local map_os = {
|
||||
@ -200,7 +200,7 @@ typedef struct {
|
||||
]]
|
||||
local symname = LJBC_PREFIX..ctx.modname
|
||||
local is64, isbe = false, false
|
||||
if ctx.arch == "x64" or ctx.arch == "arm64" then
|
||||
if ctx.arch == "x64" or ctx.arch == "arm64" or ctx.arch == "arm64be" then
|
||||
is64 = true
|
||||
elseif ctx.arch == "ppc" or ctx.arch == "mips" then
|
||||
isbe = true
|
||||
@ -237,9 +237,9 @@ typedef struct {
|
||||
hdr.eendian = isbe and 2 or 1
|
||||
hdr.eversion = 1
|
||||
hdr.type = f16(1)
|
||||
hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, ppc=20, mips=8, mipsel=8 })[ctx.arch])
|
||||
hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, arm64be=183, ppc=20, mips=8, mipsel=8 })[ctx.arch])
|
||||
if ctx.arch == "mips" or ctx.arch == "mipsel" then
|
||||
hdr.flags = 0x50001006
|
||||
hdr.flags = f32(0x50001006)
|
||||
end
|
||||
hdr.version = f32(1)
|
||||
hdr.shofs = fofs(ffi.offsetof(o, "sect"))
|
||||
@ -275,7 +275,7 @@ typedef struct {
|
||||
o.sect[2].size = fofs(ofs)
|
||||
o.sect[3].type = f32(3) -- .strtab
|
||||
o.sect[3].ofs = fofs(sofs + ofs)
|
||||
o.sect[3].size = fofs(#symname+1)
|
||||
o.sect[3].size = fofs(#symname+2)
|
||||
ffi.copy(o.space+ofs+1, symname)
|
||||
ofs = ofs + #symname + 2
|
||||
o.sect[4].type = f32(1) -- .rodata
|
||||
|
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT ARM disassembler module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This is a helper module used by the LuaJIT machine code dumper module.
|
||||
|
1216
src/jit/dis_arm64.lua
Normal file
1216
src/jit/dis_arm64.lua
Normal file
File diff suppressed because it is too large
Load Diff
12
src/jit/dis_arm64be.lua
Normal file
12
src/jit/dis_arm64be.lua
Normal file
@ -0,0 +1,12 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT ARM64BE disassembler wrapper module.
|
||||
--
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- ARM64 instructions are always little-endian. So just forward to the
|
||||
-- common ARM64 disassembler module. All the interesting stuff is there.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
return require((string.match(..., ".*%.") or "").."dis_arm64")
|
||||
|
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT MIPS disassembler module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT/X license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This is a helper module used by the LuaJIT machine code dumper module.
|
||||
@ -34,15 +34,17 @@ local map_special = {
|
||||
"jrS", "jalrD1S", "movzDST", "movnDST",
|
||||
"syscallY", "breakY", false, "sync",
|
||||
"mfhiD", "mthiS", "mfloD", "mtloS",
|
||||
false, false, false, false,
|
||||
"dsllvDST", false, "dsrlvDST", "dsravDST",
|
||||
"multST", "multuST", "divST", "divuST",
|
||||
false, false, false, false,
|
||||
"dmultST", "dmultuST", "ddivST", "ddivuST",
|
||||
"addDST", "addu|moveDST0", "subDST", "subu|neguDS0T",
|
||||
"andDST", "or|moveDST0", "xorDST", "nor|notDST0",
|
||||
false, false, "sltDST", "sltuDST",
|
||||
false, false, false, false,
|
||||
"daddDST", "dadduDST", "dsubDST", "dsubuDST",
|
||||
"tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ",
|
||||
"teqSTZ", false, "tneSTZ",
|
||||
"teqSTZ", false, "tneSTZ", false,
|
||||
"dsllDTA", false, "dsrlDTA", "dsraDTA",
|
||||
"dsll32DTA", false, "dsrl32DTA", "dsra32DTA",
|
||||
}
|
||||
|
||||
local map_special2 = {
|
||||
@ -60,11 +62,17 @@ local map_bshfl = {
|
||||
[24] = "sehDT",
|
||||
}
|
||||
|
||||
local map_dbshfl = {
|
||||
shift = 6, mask = 31,
|
||||
[2] = "dsbhDT",
|
||||
[5] = "dshdDT",
|
||||
}
|
||||
|
||||
local map_special3 = {
|
||||
shift = 0, mask = 63,
|
||||
[0] = "extTSAK", [4] = "insTSAL",
|
||||
[32] = map_bshfl,
|
||||
[59] = "rdhwrTD",
|
||||
[0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK",
|
||||
[4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL",
|
||||
[32] = map_bshfl, [36] = map_dbshfl, [59] = "rdhwrTD",
|
||||
}
|
||||
|
||||
local map_regimm = {
|
||||
@ -178,8 +186,8 @@ local map_cop1bc = {
|
||||
|
||||
local map_cop1 = {
|
||||
shift = 21, mask = 31,
|
||||
[0] = "mfc1TG", false, "cfc1TG", "mfhc1TG",
|
||||
"mtc1TG", false, "ctc1TG", "mthc1TG",
|
||||
[0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG",
|
||||
"mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG",
|
||||
map_cop1bc, false, false, false,
|
||||
false, false, false, false,
|
||||
map_cop1s, map_cop1d, false, false,
|
||||
@ -213,16 +221,16 @@ local map_pri = {
|
||||
"andiTSU", "ori|liTS0U", "xoriTSU", "luiTU",
|
||||
map_cop0, map_cop1, false, map_cop1x,
|
||||
"beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB",
|
||||
false, false, false, false,
|
||||
"daddiTSI", "daddiuTSI", false, false,
|
||||
map_special2, "jalxJ", false, map_special3,
|
||||
"lbTSO", "lhTSO", "lwlTSO", "lwTSO",
|
||||
"lbuTSO", "lhuTSO", "lwrTSO", false,
|
||||
"sbTSO", "shTSO", "swlTSO", "swTSO",
|
||||
false, false, "swrTSO", "cacheNSO",
|
||||
"llTSO", "lwc1HSO", "lwc2TSO", "prefNSO",
|
||||
false, "ldc1HSO", "ldc2TSO", false,
|
||||
false, "ldc1HSO", "ldc2TSO", "ldTSO",
|
||||
"scTSO", "swc1HSO", "swc2TSO", false,
|
||||
false, "sdc1HSO", "sdc2TSO", false,
|
||||
false, "sdc1HSO", "sdc2TSO", "sdTSO",
|
||||
}
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
@ -306,6 +314,8 @@ local function disass_ins(ctx)
|
||||
x = "f"..band(rshift(op, 21), 31)
|
||||
elseif p == "A" then
|
||||
x = band(rshift(op, 6), 31)
|
||||
elseif p == "E" then
|
||||
x = band(rshift(op, 6), 31) + 32
|
||||
elseif p == "M" then
|
||||
x = band(rshift(op, 11), 31)
|
||||
elseif p == "N" then
|
||||
@ -315,8 +325,12 @@ local function disass_ins(ctx)
|
||||
if x == 0 then x = nil end
|
||||
elseif p == "K" then
|
||||
x = band(rshift(op, 11), 31) + 1
|
||||
elseif p == "P" then
|
||||
x = band(rshift(op, 11), 31) + 33
|
||||
elseif p == "L" then
|
||||
x = band(rshift(op, 11), 31) - last + 1
|
||||
elseif p == "Q" then
|
||||
x = band(rshift(op, 11), 31) - last + 33
|
||||
elseif p == "I" then
|
||||
x = arshift(lshift(op, 16), 16)
|
||||
elseif p == "U" then
|
||||
@ -330,11 +344,12 @@ local function disass_ins(ctx)
|
||||
elseif p == "B" then
|
||||
x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 16)*4 + 4
|
||||
ctx.rel = x
|
||||
x = "0x"..tohex(x)
|
||||
x = format("0x%08x", x)
|
||||
elseif p == "J" then
|
||||
x = band(ctx.addr + ctx.pos, 0xf0000000) + band(op, 0x03ffffff)*4
|
||||
local a = ctx.addr + ctx.pos
|
||||
x = a - band(a, 0x0fffffff) + band(op, 0x03ffffff)*4
|
||||
ctx.rel = x
|
||||
x = "0x"..tohex(x)
|
||||
x = format("0x%08x", x)
|
||||
elseif p == "V" then
|
||||
x = band(rshift(op, 8), 7)
|
||||
if x == 0 then x = nil end
|
||||
|
17
src/jit/dis_mips64.lua
Normal file
17
src/jit/dis_mips64.lua
Normal file
@ -0,0 +1,17 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT MIPS64 disassembler wrapper module.
|
||||
--
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This module just exports the big-endian functions from the
|
||||
-- MIPS disassembler module. All the interesting stuff is there.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
|
||||
return {
|
||||
create = dis_mips.create,
|
||||
disass = dis_mips.disass,
|
||||
regname = dis_mips.regname
|
||||
}
|
||||
|
17
src/jit/dis_mips64el.lua
Normal file
17
src/jit/dis_mips64el.lua
Normal file
@ -0,0 +1,17 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT MIPS64EL disassembler wrapper module.
|
||||
--
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This module just exports the little-endian functions from the
|
||||
-- MIPS disassembler module. All the interesting stuff is there.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
|
||||
return {
|
||||
create = dis_mips.create_el,
|
||||
disass = dis_mips.disass_el,
|
||||
regname = dis_mips.regname
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT MIPSEL disassembler wrapper module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This module just exports the little-endian functions from the
|
||||
|
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT PPC disassembler module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT/X license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This is a helper module used by the LuaJIT machine code dumper module.
|
||||
|
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT x64 disassembler wrapper module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This module just exports the 64 bit functions from the combined
|
||||
|
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT x86/x64 disassembler module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This is a helper module used by the LuaJIT machine code dumper module.
|
||||
|
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT compiler dump module.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
@ -85,7 +85,7 @@ local nexitsym = 0
|
||||
local function fillsymtab_tr(tr, nexit)
|
||||
local t = {}
|
||||
symtabmt.__index = t
|
||||
if jit.arch == "mips" or jit.arch == "mipsel" then
|
||||
if jit.arch:sub(1, 4) == "mips" then
|
||||
t[traceexitstub(tr, 0)] = "exit"
|
||||
return
|
||||
end
|
||||
@ -556,7 +556,7 @@ local function dump_trace(what, tr, func, pc, otr, oex)
|
||||
if what == "start" then
|
||||
if dumpmode.H then out:write('<pre class="ljdump">\n') end
|
||||
out:write("---- TRACE ", tr, " ", what)
|
||||
if otr then out:write(" ", otr, "/", oex) end
|
||||
if otr then out:write(" ", otr, "/", oex == -1 and "stitch" or oex) end
|
||||
out:write(" ", fmtfunc(func, pc), "\n")
|
||||
elseif what == "stop" or what == "abort" then
|
||||
out:write("---- TRACE ", tr, " ", what)
|
||||
|
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT profiler.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
|
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- Verbose mode of the LuaJIT compiler.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
@ -99,7 +99,7 @@ end
|
||||
local function dump_trace(what, tr, func, pc, otr, oex)
|
||||
if what == "start" then
|
||||
startloc = fmtfunc(func, pc)
|
||||
startex = otr and "("..otr.."/"..oex..") " or ""
|
||||
startex = otr and "("..otr.."/"..(oex == -1 and "stitch" or oex)..") " or ""
|
||||
else
|
||||
if what == "abort" then
|
||||
local loc = fmtfunc(func, pc)
|
||||
|
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- LuaJIT profiler zones.
|
||||
--
|
||||
-- Copyright (C) 2005-2016 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
|
@ -15,9 +15,6 @@
|
||||
#include "lua.h"
|
||||
|
||||
|
||||
#define luaL_getn(L,i) ((int)lua_objlen(L, i))
|
||||
#define luaL_setn(L,i,j) ((void)0) /* no op! */
|
||||
|
||||
/* extra error code for `luaL_load' */
|
||||
#define LUA_ERRFILE (LUA_ERRERR+1)
|
||||
|
||||
@ -58,6 +55,10 @@ LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
|
||||
LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
|
||||
const char *const lst[]);
|
||||
|
||||
/* pre-defined references */
|
||||
#define LUA_NOREF (-2)
|
||||
#define LUA_REFNIL (-1)
|
||||
|
||||
LUALIB_API int (luaL_ref) (lua_State *L, int t);
|
||||
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
|
||||
|
||||
@ -84,6 +85,11 @@ LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
|
||||
const char *name, const char *mode);
|
||||
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
|
||||
int level);
|
||||
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
|
||||
LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
|
||||
int sizehint);
|
||||
LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
|
||||
LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
|
||||
|
||||
|
||||
/*
|
||||
@ -113,6 +119,11 @@ LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
|
||||
|
||||
#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
|
||||
|
||||
/* From Lua 5.2. */
|
||||
#define luaL_newlibtable(L, l) \
|
||||
lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
|
||||
#define luaL_newlib(L, l) (luaL_newlibtable(L, l), luaL_setfuncs(L, l, 0))
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Generic Buffer manipulation
|
||||
@ -147,21 +158,4 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
/* compatibility with ref system */
|
||||
|
||||
/* pre-defined references */
|
||||
#define LUA_NOREF (-2)
|
||||
#define LUA_REFNIL (-1)
|
||||
|
||||
#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
|
||||
(lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
|
||||
|
||||
#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
|
||||
|
||||
#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
|
||||
|
||||
|
||||
#define luaL_reg luaL_Reg
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Auxiliary library for the Lua/C API.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major parts taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
@ -107,38 +107,36 @@ LUALIB_API const char *luaL_findtable(lua_State *L, int idx,
|
||||
static int libsize(const luaL_Reg *l)
|
||||
{
|
||||
int size = 0;
|
||||
for (; l->name; l++) size++;
|
||||
for (; l && l->name; l++) size++;
|
||||
return size;
|
||||
}
|
||||
|
||||
LUALIB_API void luaL_pushmodule(lua_State *L, const char *modname, int sizehint)
|
||||
{
|
||||
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
|
||||
lua_getfield(L, -1, modname);
|
||||
if (!lua_istable(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, sizehint) != NULL)
|
||||
lj_err_callerv(L, LJ_ERR_BADMODN, modname);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, modname); /* _LOADED[modname] = new table. */
|
||||
}
|
||||
lua_remove(L, -2); /* Remove _LOADED table. */
|
||||
}
|
||||
|
||||
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 */
|
||||
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
|
||||
lua_getfield(L, -1, libname); /* get _LOADED[libname] */
|
||||
if (!lua_istable(L, -1)) { /* not found? */
|
||||
lua_pop(L, 1); /* remove previous result */
|
||||
/* try global variable (and create one if it does not exist) */
|
||||
if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
|
||||
lj_err_callerv(L, LJ_ERR_BADMODN, libname);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
|
||||
}
|
||||
lua_remove(L, -2); /* remove _LOADED table */
|
||||
lua_insert(L, -(nup+1)); /* move library table to below upvalues */
|
||||
luaL_pushmodule(L, libname, libsize(l));
|
||||
lua_insert(L, -(nup + 1)); /* Move module table below upvalues. */
|
||||
}
|
||||
for (; l->name; l++) {
|
||||
int i;
|
||||
for (i = 0; i < nup; i++) /* copy upvalues to the top */
|
||||
lua_pushvalue(L, -nup);
|
||||
lua_pushcclosure(L, l->func, nup);
|
||||
lua_setfield(L, -(nup+2), l->name);
|
||||
}
|
||||
lua_pop(L, nup); /* remove upvalues */
|
||||
if (l)
|
||||
luaL_setfuncs(L, l, nup);
|
||||
else
|
||||
lua_pop(L, nup); /* Remove upvalues. */
|
||||
}
|
||||
|
||||
LUALIB_API void luaL_register(lua_State *L, const char *libname,
|
||||
@ -147,6 +145,19 @@ LUALIB_API void luaL_register(lua_State *L, const char *libname,
|
||||
luaL_openlib(L, libname, l, 0);
|
||||
}
|
||||
|
||||
LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup)
|
||||
{
|
||||
luaL_checkstack(L, nup, "too many upvalues");
|
||||
for (; l->name; l++) {
|
||||
int i;
|
||||
for (i = 0; i < nup; i++) /* Copy upvalues to the top. */
|
||||
lua_pushvalue(L, -nup);
|
||||
lua_pushcclosure(L, l->func, nup);
|
||||
lua_setfield(L, -(nup + 2), l->name);
|
||||
}
|
||||
lua_pop(L, nup); /* Remove upvalues. */
|
||||
}
|
||||
|
||||
LUALIB_API const char *luaL_gsub(lua_State *L, const char *s,
|
||||
const char *p, const char *r)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Base and coroutine library.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
@ -23,6 +23,7 @@
|
||||
#include "lj_tab.h"
|
||||
#include "lj_meta.h"
|
||||
#include "lj_state.h"
|
||||
#include "lj_frame.h"
|
||||
#if LJ_HASFFI
|
||||
#include "lj_ctype.h"
|
||||
#include "lj_cconv.h"
|
||||
@ -345,7 +346,7 @@ LJLIB_ASM_(xpcall) LJLIB_REC(.)
|
||||
|
||||
static int load_aux(lua_State *L, int status, int envarg)
|
||||
{
|
||||
if (status == 0) {
|
||||
if (status == LUA_OK) {
|
||||
if (tvistab(L->base+envarg-1)) {
|
||||
GCfunc *fn = funcV(L->top-1);
|
||||
GCtab *t = tabV(L->base+envarg-1);
|
||||
@ -418,7 +419,7 @@ LJLIB_CF(dofile)
|
||||
GCstr *fname = lj_lib_optstr(L, 1);
|
||||
setnilV(L->top);
|
||||
L->top = L->base+1;
|
||||
if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != 0)
|
||||
if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != LUA_OK)
|
||||
lua_error(L);
|
||||
lua_call(L, 0, LUA_MULTRET);
|
||||
return (int)(L->top - L->base) - 1;
|
||||
@ -536,7 +537,7 @@ LJLIB_CF(coroutine_status)
|
||||
co = threadV(L->base);
|
||||
if (co == L) s = "running";
|
||||
else if (co->status == LUA_YIELD) s = "suspended";
|
||||
else if (co->status != 0) s = "dead";
|
||||
else if (co->status != LUA_OK) s = "dead";
|
||||
else if (co->base > tvref(co->stack)+1+LJ_FR2) s = "normal";
|
||||
else if (co->top == co->base) s = "dead";
|
||||
else s = "suspended";
|
||||
@ -557,6 +558,12 @@ LJLIB_CF(coroutine_running)
|
||||
#endif
|
||||
}
|
||||
|
||||
LJLIB_CF(coroutine_isyieldable)
|
||||
{
|
||||
setboolV(L->top++, cframe_canyield(L->cframe));
|
||||
return 1;
|
||||
}
|
||||
|
||||
LJLIB_CF(coroutine_create)
|
||||
{
|
||||
lua_State *L1;
|
||||
@ -576,7 +583,7 @@ LJLIB_ASM(coroutine_yield)
|
||||
static int ffh_resume(lua_State *L, lua_State *co, int wrap)
|
||||
{
|
||||
if (co->cframe != NULL || co->status > LUA_YIELD ||
|
||||
(co->status == 0 && co->top == co->base)) {
|
||||
(co->status == LUA_OK && co->top == co->base)) {
|
||||
ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD;
|
||||
if (wrap) lj_err_caller(L, em);
|
||||
setboolV(L->base-1-LJ_FR2, 0);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Bit manipulation library.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#define lib_bit_c
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Debug library.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
@ -283,13 +283,13 @@ LJLIB_CF(debug_setuservalue)
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static const char KEY_HOOK = 'h';
|
||||
#define KEY_HOOK ((void *)0x3004)
|
||||
|
||||
static void hookf(lua_State *L, lua_Debug *ar)
|
||||
{
|
||||
static const char *const hooknames[] =
|
||||
{"call", "return", "line", "count", "tail return"};
|
||||
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
|
||||
lua_pushlightuserdata(L, KEY_HOOK);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
if (lua_isfunction(L, -1)) {
|
||||
lua_pushstring(L, hooknames[(int)ar->event]);
|
||||
@ -334,7 +334,7 @@ LJLIB_CF(debug_sethook)
|
||||
count = luaL_optint(L, arg+3, 0);
|
||||
func = hookf; mask = makemask(smask, count);
|
||||
}
|
||||
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
|
||||
lua_pushlightuserdata(L, KEY_HOOK);
|
||||
lua_pushvalue(L, arg+1);
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
lua_sethook(L, func, mask, count);
|
||||
@ -349,7 +349,7 @@ LJLIB_CF(debug_gethook)
|
||||
if (hook != NULL && hook != hookf) { /* external hook? */
|
||||
lua_pushliteral(L, "external hook");
|
||||
} else {
|
||||
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
|
||||
lua_pushlightuserdata(L, KEY_HOOK);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */
|
||||
}
|
||||
lua_pushstring(L, unmakemask(mask, buff));
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** FFI library.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#define lib_ffi_c
|
||||
@ -194,7 +194,7 @@ LJLIB_CF(ffi_meta___eq) LJLIB_REC(cdata_arith MM_eq)
|
||||
|
||||
LJLIB_CF(ffi_meta___len) LJLIB_REC(cdata_arith MM_len)
|
||||
{
|
||||
return ffi_arith(L);
|
||||
return lj_carith_len(L);
|
||||
}
|
||||
|
||||
LJLIB_CF(ffi_meta___lt) LJLIB_REC(cdata_arith MM_lt)
|
||||
@ -829,7 +829,7 @@ static GCtab *ffi_finalizer(lua_State *L)
|
||||
settabV(L, L->top++, t);
|
||||
setgcref(t->metatable, obj2gco(t));
|
||||
setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "__mode")),
|
||||
lj_str_newlit(L, "K"));
|
||||
lj_str_newlit(L, "k"));
|
||||
t->nomm = (uint8_t)(~(1u<<MM_mode));
|
||||
return t;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Library initialization.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major parts taken verbatim from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
|
13
src/lib_io.c
13
src/lib_io.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** I/O library.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
@ -203,13 +203,12 @@ static int io_file_read(lua_State *L, FILE *fp, int start)
|
||||
for (n = start; nargs-- && ok; n++) {
|
||||
if (tvisstr(L->base+n)) {
|
||||
const char *p = strVdata(L->base+n);
|
||||
if (p[0] != '*')
|
||||
lj_err_arg(L, n+1, LJ_ERR_INVOPT);
|
||||
if (p[1] == 'n')
|
||||
if (p[0] == '*') p++;
|
||||
if (p[0] == 'n')
|
||||
ok = io_file_readnum(L, fp);
|
||||
else if ((p[1] & ~0x20) == 'L')
|
||||
ok = io_file_readline(L, fp, (p[1] == 'l'));
|
||||
else if (p[1] == 'a')
|
||||
else if ((p[0] & ~0x20) == 'L')
|
||||
ok = io_file_readline(L, fp, (p[0] == 'l'));
|
||||
else if (p[0] == 'a')
|
||||
io_file_readall(L, fp);
|
||||
else
|
||||
lj_err_arg(L, n+1, LJ_ERR_INVFMT);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** JIT library.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#define lib_jit_c
|
||||
@ -204,6 +204,7 @@ LJLIB_CF(jit_util_funcinfo)
|
||||
lua_setfield(L, -2, "source");
|
||||
lj_debug_pushloc(L, pt, pc);
|
||||
lua_setfield(L, -2, "loc");
|
||||
setprotoV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "proto")), pt);
|
||||
} else {
|
||||
GCfunc *fn = funcV(L->base);
|
||||
GCtab *t;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Math library.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
@ -221,10 +221,6 @@ LUALIB_API int luaopen_math(lua_State *L)
|
||||
rs = (RandomState *)lua_newuserdata(L, sizeof(RandomState));
|
||||
rs->valid = 0; /* Use lazy initialization to save some time on startup. */
|
||||
LJ_LIB_REG(L, LUA_MATHLIBNAME, math);
|
||||
#if defined(LUA_COMPAT_MOD) && !LJ_52
|
||||
lua_getfield(L, -1, "fmod");
|
||||
lua_setfield(L, -2, "mod");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** OS library.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Package library.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2012 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
@ -193,8 +193,7 @@ static void **ll_register(lua_State *L, const char *path)
|
||||
lua_pop(L, 1);
|
||||
plib = (void **)lua_newuserdata(L, sizeof(void *));
|
||||
*plib = NULL;
|
||||
luaL_getmetatable(L, "_LOADLIB");
|
||||
lua_setmetatable(L, -2);
|
||||
luaL_setmetatable(L, "_LOADLIB");
|
||||
lua_pushfstring(L, "LOADLIB: %s", path);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_settable(L, LUA_REGISTRYINDEX);
|
||||
@ -399,8 +398,7 @@ static int lj_cf_package_loader_preload(lua_State *L)
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static const int sentinel_ = 0;
|
||||
#define sentinel ((void *)&sentinel_)
|
||||
#define sentinel ((void *)0x4004)
|
||||
|
||||
static int lj_cf_package_require(lua_State *L)
|
||||
{
|
||||
@ -490,29 +488,19 @@ static void modinit(lua_State *L, const char *modname)
|
||||
static int lj_cf_package_module(lua_State *L)
|
||||
{
|
||||
const char *modname = luaL_checkstring(L, 1);
|
||||
int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
|
||||
lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
|
||||
if (!lua_istable(L, -1)) { /* not found? */
|
||||
lua_pop(L, 1); /* remove previous result */
|
||||
/* try global variable (and create one if it does not exist) */
|
||||
if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
|
||||
lj_err_callerv(L, LJ_ERR_BADMODN, modname);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
|
||||
}
|
||||
/* check whether table already has a _NAME field */
|
||||
int lastarg = (int)(L->top - L->base);
|
||||
luaL_pushmodule(L, modname, 1);
|
||||
lua_getfield(L, -1, "_NAME");
|
||||
if (!lua_isnil(L, -1)) { /* is table an initialized module? */
|
||||
if (!lua_isnil(L, -1)) { /* Module already initialized? */
|
||||
lua_pop(L, 1);
|
||||
} else { /* no; initialize it */
|
||||
} else {
|
||||
lua_pop(L, 1);
|
||||
modinit(L, modname);
|
||||
}
|
||||
lua_pushvalue(L, -1);
|
||||
setfenv(L);
|
||||
dooptions(L, loaded - 1);
|
||||
return 0;
|
||||
dooptions(L, lastarg);
|
||||
return LJ_52;
|
||||
}
|
||||
|
||||
static int lj_cf_package_seeall(lua_State *L)
|
||||
@ -583,13 +571,16 @@ LUALIB_API int luaopen_package(lua_State *L)
|
||||
lj_lib_pushcf(L, lj_cf_package_unloadlib, 1);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
luaL_register(L, LUA_LOADLIBNAME, package_lib);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_replace(L, LUA_ENVIRONINDEX);
|
||||
lua_copy(L, -1, LUA_ENVIRONINDEX);
|
||||
lua_createtable(L, sizeof(package_loaders)/sizeof(package_loaders[0])-1, 0);
|
||||
for (i = 0; package_loaders[i] != NULL; i++) {
|
||||
lj_lib_pushcf(L, package_loaders[i], 1);
|
||||
lua_rawseti(L, -2, i+1);
|
||||
}
|
||||
#if LJ_52
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, "searchers");
|
||||
#endif
|
||||
lua_setfield(L, -2, "loaders");
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
|
||||
noenv = lua_toboolean(L, -1);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** String library.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
@ -737,10 +737,6 @@ LUALIB_API int luaopen_string(lua_State *L)
|
||||
GCtab *mt;
|
||||
global_State *g;
|
||||
LJ_LIB_REG(L, LUA_STRLIBNAME, string);
|
||||
#if defined(LUA_COMPAT_GFIND) && !LJ_52
|
||||
lua_getfield(L, -1, "gmatch");
|
||||
lua_setfield(L, -2, "gfind");
|
||||
#endif
|
||||
mt = lj_tab_new(L, 0, 1);
|
||||
/* NOBARRIER: basemt is a GC root. */
|
||||
g = G(L);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Table library.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
@ -129,6 +129,26 @@ LJLIB_LUA(table_remove) /*
|
||||
end
|
||||
*/
|
||||
|
||||
LJLIB_LUA(table_move) /*
|
||||
function(a1, f, e, t, a2)
|
||||
CHECK_tab(a1)
|
||||
CHECK_int(f)
|
||||
CHECK_int(e)
|
||||
CHECK_int(t)
|
||||
if a2 == nil then a2 = a1 end
|
||||
CHECK_tab(a2)
|
||||
if e >= f then
|
||||
local d = t - f
|
||||
if t > e or t <= f or a2 ~= a1 then
|
||||
for i=f,e do a2[i+d] = a1[i] end
|
||||
else
|
||||
for i=e,f,-1 do a2[i+d] = a1[i] end
|
||||
end
|
||||
end
|
||||
return a2
|
||||
end
|
||||
*/
|
||||
|
||||
LJLIB_CF(table_concat) LJLIB_REC(.)
|
||||
{
|
||||
GCtab *t = lj_lib_checktab(L, 1);
|
||||
|
@ -343,7 +343,7 @@ static void *CALL_MMAP(size_t size)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4
|
||||
#if LJ_64 && !LJ_GC64 && ((defined(__FreeBSD__) && __FreeBSD__ < 10) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4
|
||||
|
||||
#include <sys/resource.h>
|
||||
|
||||
|
115
src/lj_api.c
115
src/lj_api.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Public Lua/C API.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
@ -112,6 +112,13 @@ LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
|
||||
from->top = f;
|
||||
}
|
||||
|
||||
LUA_API const lua_Number *lua_version(lua_State *L)
|
||||
{
|
||||
static const lua_Number version = LUA_VERSION_NUM;
|
||||
UNUSED(L);
|
||||
return &version;
|
||||
}
|
||||
|
||||
/* -- Stack manipulation -------------------------------------------------- */
|
||||
|
||||
LUA_API int lua_gettop(lua_State *L)
|
||||
@ -152,30 +159,40 @@ LUA_API void lua_insert(lua_State *L, int idx)
|
||||
copyTV(L, p, L->top);
|
||||
}
|
||||
|
||||
LUA_API void lua_replace(lua_State *L, int idx)
|
||||
static void copy_slot(lua_State *L, TValue *f, int idx)
|
||||
{
|
||||
api_checknelems(L, 1);
|
||||
if (idx == LUA_GLOBALSINDEX) {
|
||||
api_check(L, tvistab(L->top-1));
|
||||
api_check(L, tvistab(f));
|
||||
/* NOBARRIER: A thread (i.e. L) is never black. */
|
||||
setgcref(L->env, obj2gco(tabV(L->top-1)));
|
||||
setgcref(L->env, obj2gco(tabV(f)));
|
||||
} else if (idx == LUA_ENVIRONINDEX) {
|
||||
GCfunc *fn = curr_func(L);
|
||||
if (fn->c.gct != ~LJ_TFUNC)
|
||||
lj_err_msg(L, LJ_ERR_NOENV);
|
||||
api_check(L, tvistab(L->top-1));
|
||||
setgcref(fn->c.env, obj2gco(tabV(L->top-1)));
|
||||
lj_gc_barrier(L, fn, L->top-1);
|
||||
api_check(L, tvistab(f));
|
||||
setgcref(fn->c.env, obj2gco(tabV(f)));
|
||||
lj_gc_barrier(L, fn, f);
|
||||
} else {
|
||||
TValue *o = index2adr(L, idx);
|
||||
api_checkvalidindex(L, o);
|
||||
copyTV(L, o, L->top-1);
|
||||
copyTV(L, o, f);
|
||||
if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */
|
||||
lj_gc_barrier(L, curr_func(L), L->top-1);
|
||||
lj_gc_barrier(L, curr_func(L), f);
|
||||
}
|
||||
}
|
||||
|
||||
LUA_API void lua_replace(lua_State *L, int idx)
|
||||
{
|
||||
api_checknelems(L, 1);
|
||||
copy_slot(L, L->top - 1, idx);
|
||||
L->top--;
|
||||
}
|
||||
|
||||
LUA_API void lua_copy(lua_State *L, int fromidx, int toidx)
|
||||
{
|
||||
copy_slot(L, index2adr(L, fromidx), toidx);
|
||||
}
|
||||
|
||||
LUA_API void lua_pushvalue(lua_State *L, int idx)
|
||||
{
|
||||
copyTV(L, L->top, index2adr(L, idx));
|
||||
@ -325,6 +342,22 @@ LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *ok)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
TValue tmp;
|
||||
if (LJ_LIKELY(tvisnumber(o))) {
|
||||
if (ok) *ok = 1;
|
||||
return numberVnum(o);
|
||||
} else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp)) {
|
||||
if (ok) *ok = 1;
|
||||
return numV(&tmp);
|
||||
} else {
|
||||
if (ok) *ok = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
@ -362,7 +395,7 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
|
||||
if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
|
||||
return 0;
|
||||
if (tvisint(&tmp))
|
||||
return (lua_Integer)intV(&tmp);
|
||||
return intV(&tmp);
|
||||
n = numV(&tmp);
|
||||
}
|
||||
#if LJ_64
|
||||
@ -372,6 +405,35 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
|
||||
#endif
|
||||
}
|
||||
|
||||
LUA_API lua_Integer lua_tointegerx(lua_State *L, int idx, int *ok)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
TValue tmp;
|
||||
lua_Number n;
|
||||
if (LJ_LIKELY(tvisint(o))) {
|
||||
if (ok) *ok = 1;
|
||||
return intV(o);
|
||||
} else if (LJ_LIKELY(tvisnum(o))) {
|
||||
n = numV(o);
|
||||
} else {
|
||||
if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) {
|
||||
if (ok) *ok = 0;
|
||||
return 0;
|
||||
}
|
||||
if (tvisint(&tmp)) {
|
||||
if (ok) *ok = 1;
|
||||
return intV(&tmp);
|
||||
}
|
||||
n = numV(&tmp);
|
||||
}
|
||||
if (ok) *ok = 1;
|
||||
#if LJ_64
|
||||
return (lua_Integer)n;
|
||||
#else
|
||||
return lj_num2int(n);
|
||||
#endif
|
||||
}
|
||||
|
||||
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
@ -858,7 +920,7 @@ LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2)
|
||||
lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1]));
|
||||
}
|
||||
|
||||
LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
|
||||
LUALIB_API void *luaL_testudata(lua_State *L, int idx, const char *tname)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
if (tvisudata(o)) {
|
||||
@ -867,8 +929,14 @@ LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
|
||||
if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable))
|
||||
return uddata(ud);
|
||||
}
|
||||
lj_err_argtype(L, idx, tname);
|
||||
return NULL; /* unreachable */
|
||||
return NULL; /* value is not a userdata with a metatable */
|
||||
}
|
||||
|
||||
LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
|
||||
{
|
||||
void *p = luaL_testudata(L, idx, tname);
|
||||
if (!p) lj_err_argtype(L, idx, tname);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* -- Object setters ------------------------------------------------------ */
|
||||
@ -977,6 +1045,12 @@ LUA_API int lua_setmetatable(lua_State *L, int idx)
|
||||
return 1;
|
||||
}
|
||||
|
||||
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
|
||||
{
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, tname);
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
LUA_API int lua_setfenv(lua_State *L, int idx)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
@ -1032,7 +1106,7 @@ static TValue *api_call_base(lua_State *L, int nargs)
|
||||
|
||||
LUA_API void lua_call(lua_State *L, int nargs, int nresults)
|
||||
{
|
||||
api_check(L, L->status == 0 || L->status == LUA_ERRERR);
|
||||
api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
|
||||
api_checknelems(L, nargs+1);
|
||||
lj_vm_call(L, api_call_base(L, nargs), nresults+1);
|
||||
}
|
||||
@ -1043,7 +1117,7 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
|
||||
uint8_t oldh = hook_save(g);
|
||||
ptrdiff_t ef;
|
||||
int status;
|
||||
api_check(L, L->status == 0 || L->status == LUA_ERRERR);
|
||||
api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
|
||||
api_checknelems(L, nargs+1);
|
||||
if (errfunc == 0) {
|
||||
ef = 0;
|
||||
@ -1075,7 +1149,7 @@ LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
|
||||
global_State *g = G(L);
|
||||
uint8_t oldh = hook_save(g);
|
||||
int status;
|
||||
api_check(L, L->status == 0 || L->status == LUA_ERRERR);
|
||||
api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
|
||||
status = lj_vm_cpcall(L, func, ud, cpcall);
|
||||
if (status) hook_restore(g, oldh);
|
||||
return status;
|
||||
@ -1096,6 +1170,11 @@ LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
|
||||
|
||||
/* -- Coroutine yield and resume ------------------------------------------ */
|
||||
|
||||
LUA_API int lua_isyieldable(lua_State *L)
|
||||
{
|
||||
return cframe_canyield(L->cframe);
|
||||
}
|
||||
|
||||
LUA_API int lua_yield(lua_State *L, int nresults)
|
||||
{
|
||||
void *cf = L->cframe;
|
||||
@ -1140,7 +1219,7 @@ LUA_API int lua_resume(lua_State *L, int nargs)
|
||||
{
|
||||
if (L->cframe == NULL && L->status <= LUA_YIELD)
|
||||
return lj_vm_resume(L,
|
||||
L->status == 0 ? api_call_base(L, nargs) : L->top - nargs,
|
||||
L->status == LUA_OK ? api_call_base(L, nargs) : L->top - nargs,
|
||||
0, 0);
|
||||
L->top = L->base;
|
||||
setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP));
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Target architecture selection.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_ARCH_H
|
||||
@ -78,7 +78,7 @@
|
||||
defined(__NetBSD__) || defined(__OpenBSD__) || \
|
||||
defined(__DragonFly__)) && !defined(__ORBIS__)
|
||||
#define LUAJIT_OS LUAJIT_OS_BSD
|
||||
#elif (defined(__sun__) && defined(__svr4__))
|
||||
#elif (defined(__sun__) && defined(__svr4__)) || defined(__HAIKU__)
|
||||
#define LUAJIT_OS LUAJIT_OS_POSIX
|
||||
#elif defined(__CYGWIN__)
|
||||
#define LJ_TARGET_CYGWIN 1
|
||||
@ -205,7 +205,7 @@
|
||||
#define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
|
||||
|
||||
#if __ARM_ARCH____ARM_ARCH_8__ || __ARM_ARCH_8A__
|
||||
#if __ARM_ARCH_8__ || __ARM_ARCH_8A__
|
||||
#define LJ_ARCH_VERSION 80
|
||||
#elif __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH_7S__ || __ARM_ARCH_7VE__
|
||||
#define LJ_ARCH_VERSION 70
|
||||
@ -219,9 +219,14 @@
|
||||
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM64
|
||||
|
||||
#define LJ_ARCH_NAME "arm64"
|
||||
#define LJ_ARCH_BITS 64
|
||||
#if defined(__AARCH64EB__)
|
||||
#define LJ_ARCH_NAME "arm64be"
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_BE
|
||||
#else
|
||||
#define LJ_ARCH_NAME "arm64"
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#endif
|
||||
#define LJ_TARGET_ARM64 1
|
||||
#define LJ_TARGET_EHRETREG 0
|
||||
#define LJ_TARGET_JUMPRANGE 27 /* +-2^27 = +-128MB */
|
||||
@ -230,7 +235,6 @@
|
||||
#define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */
|
||||
#define LJ_TARGET_GC64 1
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
|
||||
#define LJ_ARCH_NOJIT 1 /* NYI */
|
||||
|
||||
#define LJ_ARCH_VERSION 80
|
||||
|
||||
@ -254,6 +258,28 @@
|
||||
#else
|
||||
#define LJ_ARCH_BITS 32
|
||||
#define LJ_ARCH_NAME "ppc"
|
||||
|
||||
#if !defined(LJ_ARCH_HASFPU)
|
||||
#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
|
||||
#define LJ_ARCH_HASFPU 0
|
||||
#else
|
||||
#define LJ_ARCH_HASFPU 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(LJ_ABI_SOFTFP)
|
||||
#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
|
||||
#define LJ_ABI_SOFTFP 1
|
||||
#else
|
||||
#define LJ_ABI_SOFTFP 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LJ_ABI_SOFTFP
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
|
||||
#else
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE
|
||||
#endif
|
||||
|
||||
#define LJ_TARGET_PPC 1
|
||||
@ -262,7 +288,6 @@
|
||||
#define LJ_TARGET_MASKSHIFT 0
|
||||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE
|
||||
|
||||
#if LJ_TARGET_CONSOLE
|
||||
#define LJ_ARCH_PPC32ON64 1
|
||||
@ -340,7 +365,6 @@
|
||||
#define LJ_ARCH_BITS 64
|
||||
#define LJ_TARGET_MIPS64 1
|
||||
#define LJ_TARGET_GC64 1
|
||||
#define LJ_ARCH_NOJIT 1 /* NYI */
|
||||
#endif
|
||||
#define LJ_TARGET_MIPS 1
|
||||
#define LJ_TARGET_EHRETREG 4
|
||||
@ -395,7 +419,7 @@
|
||||
#endif
|
||||
#elif LJ_TARGET_ARM64
|
||||
#if __clang__
|
||||
#if (__clang_major__ < 3) || ((__clang_major__ == 3) && __clang_minor__ < 5)
|
||||
#if ((__clang_major__ < 3) || ((__clang_major__ == 3) && __clang_minor__ < 5)) && !defined(__NX_TOOLCHAIN_MAJOR__)
|
||||
#error "Need at least Clang 3.5 or newer"
|
||||
#endif
|
||||
#else
|
||||
@ -427,23 +451,17 @@
|
||||
#error "Only ARM EABI or iOS 3.0+ ABI is supported"
|
||||
#endif
|
||||
#elif LJ_TARGET_ARM64
|
||||
#if defined(__AARCH64EB__)
|
||||
#error "No support for big-endian ARM64"
|
||||
#endif
|
||||
#if defined(_ILP32)
|
||||
#error "No support for ILP32 model on ARM64"
|
||||
#endif
|
||||
#elif LJ_TARGET_PPC
|
||||
#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
|
||||
#error "No support for PowerPC CPUs without double-precision FPU"
|
||||
#endif
|
||||
#if !LJ_ARCH_PPC64 && LJ_ARCH_ENDIAN == LUAJIT_LE
|
||||
#error "No support for little-endian PPC32"
|
||||
#endif
|
||||
#if LJ_ARCH_PPC64
|
||||
#error "No support for PowerPC 64 bit mode (yet)"
|
||||
#endif
|
||||
#ifdef __NO_FPRS__
|
||||
#if defined(__NO_FPRS__) && !defined(_SOFT_FLOAT)
|
||||
#error "No support for PPC/e500 anymore (use LuaJIT 2.0)"
|
||||
#endif
|
||||
#elif LJ_TARGET_MIPS32
|
||||
@ -528,6 +546,7 @@
|
||||
#define LJ_ABI_SOFTFP 0
|
||||
#endif
|
||||
#define LJ_SOFTFP (!LJ_ARCH_HASFPU)
|
||||
#define LJ_SOFTFP32 (LJ_SOFTFP && LJ_32)
|
||||
|
||||
#if LJ_ARCH_ENDIAN == LUAJIT_BE
|
||||
#define LJ_LE 0
|
||||
|
69
src/lj_asm.c
69
src/lj_asm.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** IR assembler (SSA IR -> machine code).
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#define lj_asm_c
|
||||
@ -91,7 +91,7 @@ typedef struct ASMState {
|
||||
MCode *realign; /* Realign loop if not NULL. */
|
||||
|
||||
#ifdef RID_NUM_KREF
|
||||
int32_t krefk[RID_NUM_KREF];
|
||||
intptr_t krefk[RID_NUM_KREF];
|
||||
#endif
|
||||
IRRef1 phireg[RID_MAX]; /* PHI register references. */
|
||||
uint16_t parentmap[LJ_MAX_JSLOTS]; /* Parent instruction to RegSP map. */
|
||||
@ -144,7 +144,7 @@ static LJ_AINLINE void checkmclim(ASMState *as)
|
||||
#define ra_krefreg(ref) ((Reg)(RID_MIN_KREF + (Reg)(ref)))
|
||||
#define ra_krefk(as, ref) (as->krefk[(ref)])
|
||||
|
||||
static LJ_AINLINE void ra_setkref(ASMState *as, Reg r, int32_t k)
|
||||
static LJ_AINLINE void ra_setkref(ASMState *as, Reg r, intptr_t k)
|
||||
{
|
||||
IRRef ref = (IRRef)(r - RID_MIN_KREF);
|
||||
as->krefk[ref] = k;
|
||||
@ -171,6 +171,8 @@ IRFLDEF(FLOFS)
|
||||
#include "lj_emit_x86.h"
|
||||
#elif LJ_TARGET_ARM
|
||||
#include "lj_emit_arm.h"
|
||||
#elif LJ_TARGET_ARM64
|
||||
#include "lj_emit_arm64.h"
|
||||
#elif LJ_TARGET_PPC
|
||||
#include "lj_emit_ppc.h"
|
||||
#elif LJ_TARGET_MIPS
|
||||
@ -322,7 +324,11 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
|
||||
lua_assert(!rset_test(as->freeset, r));
|
||||
ra_free(as, r);
|
||||
ra_modified(as, r);
|
||||
#if LJ_64
|
||||
emit_loadu64(as, r, ra_krefk(as, ref));
|
||||
#else
|
||||
emit_loadi(as, r, ra_krefk(as, ref));
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
ir = IR(ref);
|
||||
@ -332,7 +338,7 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
|
||||
ra_modified(as, r);
|
||||
ir->r = RID_INIT; /* Do not keep any hint. */
|
||||
RA_DBGX((as, "remat $i $r", ir, r));
|
||||
#if !LJ_SOFTFP
|
||||
#if !LJ_SOFTFP32
|
||||
if (ir->o == IR_KNUM) {
|
||||
emit_loadk64(as, r, ir);
|
||||
} else
|
||||
@ -524,7 +530,7 @@ static void ra_evictk(ASMState *as)
|
||||
|
||||
#ifdef RID_NUM_KREF
|
||||
/* Allocate a register for a constant. */
|
||||
static Reg ra_allock(ASMState *as, int32_t k, RegSet allow)
|
||||
static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow)
|
||||
{
|
||||
/* First try to find a register which already holds the same constant. */
|
||||
RegSet pick, work = ~as->freeset & RSET_GPR;
|
||||
@ -533,9 +539,31 @@ static Reg ra_allock(ASMState *as, int32_t k, RegSet allow)
|
||||
IRRef ref;
|
||||
r = rset_pickbot(work);
|
||||
ref = regcost_ref(as->cost[r]);
|
||||
#if LJ_64
|
||||
if (ref < ASMREF_L) {
|
||||
if (ra_iskref(ref)) {
|
||||
if (k == ra_krefk(as, ref))
|
||||
return r;
|
||||
} else {
|
||||
IRIns *ir = IR(ref);
|
||||
if ((ir->o == IR_KINT64 && k == (int64_t)ir_kint64(ir)->u64) ||
|
||||
#if LJ_GC64
|
||||
(ir->o == IR_KINT && k == ir->i) ||
|
||||
(ir->o == IR_KGC && k == (intptr_t)ir_kgc(ir)) ||
|
||||
((ir->o == IR_KPTR || ir->o == IR_KKPTR) &&
|
||||
k == (intptr_t)ir_kptr(ir))
|
||||
#else
|
||||
(ir->o != IR_KINT64 && k == ir->i)
|
||||
#endif
|
||||
)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (ref < ASMREF_L &&
|
||||
k == (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i))
|
||||
return r;
|
||||
#endif
|
||||
rset_clear(work, r);
|
||||
}
|
||||
pick = as->freeset & allow;
|
||||
@ -555,7 +583,7 @@ static Reg ra_allock(ASMState *as, int32_t k, RegSet allow)
|
||||
}
|
||||
|
||||
/* Allocate a specific register for a constant. */
|
||||
static void ra_allockreg(ASMState *as, int32_t k, Reg r)
|
||||
static void ra_allockreg(ASMState *as, intptr_t k, Reg r)
|
||||
{
|
||||
Reg kr = ra_allock(as, k, RID2RSET(r));
|
||||
if (kr != r) {
|
||||
@ -989,7 +1017,11 @@ static uint32_t ir_khash(IRIns *ir)
|
||||
} else {
|
||||
lua_assert(irt_isgcv(ir->t));
|
||||
lo = u32ptr(ir_kgc(ir));
|
||||
#if LJ_GC64
|
||||
hi = (uint32_t)(u64ptr(ir_kgc(ir)) >> 32) | (irt_toitype(ir->t) << 15);
|
||||
#else
|
||||
hi = lo + HASH_BIAS;
|
||||
#endif
|
||||
}
|
||||
return hashrot(lo, hi);
|
||||
}
|
||||
@ -1087,7 +1119,7 @@ static void asm_bufput(ASMState *as, IRIns *ir)
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_buf_putstr];
|
||||
IRRef args[3];
|
||||
IRIns *irs;
|
||||
int kchar = -1;
|
||||
int kchar = -129;
|
||||
args[0] = ir->op1; /* SBuf * */
|
||||
args[1] = ir->op2; /* GCstr * */
|
||||
irs = IR(ir->op2);
|
||||
@ -1095,7 +1127,7 @@ static void asm_bufput(ASMState *as, IRIns *ir)
|
||||
if (irs->o == IR_KGC) {
|
||||
GCstr *s = ir_kstr(irs);
|
||||
if (s->len == 1) { /* Optimize put of single-char string constant. */
|
||||
kchar = strdata(s)[0];
|
||||
kchar = (int8_t)strdata(s)[0]; /* Signed! */
|
||||
args[1] = ASMREF_TMP1; /* int, truncated to char */
|
||||
ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar];
|
||||
}
|
||||
@ -1122,7 +1154,7 @@ static void asm_bufput(ASMState *as, IRIns *ir)
|
||||
asm_gencall(as, ci, args);
|
||||
if (args[1] == ASMREF_TMP1) {
|
||||
Reg tmp = ra_releasetmp(as, ASMREF_TMP1);
|
||||
if (kchar == -1)
|
||||
if (kchar == -129)
|
||||
asm_tvptr(as, tmp, irs->op1);
|
||||
else
|
||||
ra_allockreg(as, kchar, tmp);
|
||||
@ -1277,7 +1309,7 @@ static void asm_call(ASMState *as, IRIns *ir)
|
||||
asm_gencall(as, ci, args);
|
||||
}
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
#if !LJ_SOFTFP32
|
||||
static void asm_fppow(ASMState *as, IRIns *ir, IRRef lref, IRRef rref)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_pow];
|
||||
@ -1563,6 +1595,8 @@ static void asm_loop(ASMState *as)
|
||||
#include "lj_asm_x86.h"
|
||||
#elif LJ_TARGET_ARM
|
||||
#include "lj_asm_arm.h"
|
||||
#elif LJ_TARGET_ARM64
|
||||
#include "lj_asm_arm64.h"
|
||||
#elif LJ_TARGET_PPC
|
||||
#include "lj_asm_ppc.h"
|
||||
#elif LJ_TARGET_MIPS
|
||||
@ -1624,10 +1658,10 @@ static void asm_ir(ASMState *as, IRIns *ir)
|
||||
case IR_MUL: asm_mul(as, ir); break;
|
||||
case IR_MOD: asm_mod(as, ir); break;
|
||||
case IR_NEG: asm_neg(as, ir); break;
|
||||
#if LJ_SOFTFP
|
||||
#if LJ_SOFTFP32
|
||||
case IR_DIV: case IR_POW: case IR_ABS:
|
||||
case IR_ATAN2: case IR_LDEXP: case IR_FPMATH: case IR_TOBIT:
|
||||
lua_assert(0); /* Unused for LJ_SOFTFP. */
|
||||
lua_assert(0); /* Unused for LJ_SOFTFP32. */
|
||||
break;
|
||||
#else
|
||||
case IR_DIV: asm_div(as, ir); break;
|
||||
@ -1983,6 +2017,7 @@ static void asm_setup_regsp(ASMState *as)
|
||||
ir->prev = REGSP_INIT;
|
||||
if (irt_is64(ir->t) && ir->o != IR_KNULL) {
|
||||
#if LJ_GC64
|
||||
/* The false-positive of irt_is64() for ASMREF_L (REF_NIL) is OK here. */
|
||||
ir->i = 0; /* Will become non-zero only for RIP-relative addresses. */
|
||||
#else
|
||||
/* Make life easier for backends by putting address of constant in i. */
|
||||
@ -2109,9 +2144,12 @@ static void asm_setup_regsp(ASMState *as)
|
||||
if (ir->op2 != REF_NIL && as->evenspill < 4)
|
||||
as->evenspill = 4; /* lj_cdata_newv needs 4 args. */
|
||||
}
|
||||
/* fallthrough */
|
||||
#else
|
||||
/* fallthrough */
|
||||
case IR_CNEW:
|
||||
#endif
|
||||
/* fallthrough */
|
||||
case IR_TNEW: case IR_TDUP: case IR_CNEWI: case IR_TOSTR:
|
||||
case IR_BUFSTR:
|
||||
ir->prev = REGSP_HINT(RID_RET);
|
||||
@ -2132,6 +2170,7 @@ static void asm_setup_regsp(ASMState *as)
|
||||
case IR_LDEXP:
|
||||
#endif
|
||||
#endif
|
||||
/* fallthrough */
|
||||
case IR_POW:
|
||||
if (!LJ_SOFTFP && irt_isnum(ir->t)) {
|
||||
if (inloop)
|
||||
@ -2143,7 +2182,7 @@ static void asm_setup_regsp(ASMState *as)
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
/* fallthrough for integer POW */
|
||||
/* fallthrough */ /* for integer POW */
|
||||
case IR_DIV: case IR_MOD:
|
||||
if (!irt_isnum(ir->t)) {
|
||||
ir->prev = REGSP_HINT(RID_RET);
|
||||
@ -2180,6 +2219,7 @@ static void asm_setup_regsp(ASMState *as)
|
||||
case IR_BSHL: case IR_BSHR: case IR_BSAR:
|
||||
if ((as->flags & JIT_F_BMI2)) /* Except if BMI2 is available. */
|
||||
break;
|
||||
/* fallthrough */
|
||||
case IR_BROL: case IR_BROR:
|
||||
if (!irref_isk(ir->op2) && !ra_hashint(IR(ir->op2)->r)) {
|
||||
IR(ir->op2)->r = REGSP_HINT(RID_ECX);
|
||||
@ -2365,6 +2405,9 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
|
||||
if (!as->loopref)
|
||||
asm_tail_fixup(as, T->link); /* Note: this may change as->mctop! */
|
||||
T->szmcode = (MSize)((char *)as->mctop - (char *)as->mcp);
|
||||
#if LJ_TARGET_MCODE_FIXUP
|
||||
asm_mcode_fixup(T->mcode, T->szmcode);
|
||||
#endif
|
||||
lj_mcode_sync(T->mcode, origtop);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** IR assembler (SSA IR -> machine code).
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_ASM_H
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** ARM IR assembler (SSA IR -> machine code).
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
/* -- Register allocator extensions --------------------------------------- */
|
||||
|
2021
src/lj_asm_arm64.h
Normal file
2021
src/lj_asm_arm64.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
325
src/lj_asm_ppc.h
325
src/lj_asm_ppc.h
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** PPC IR assembler (SSA IR -> machine code).
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
/* -- Register allocator extensions --------------------------------------- */
|
||||
@ -226,6 +226,7 @@ static void asm_fusexrefx(ASMState *as, PPCIns pi, Reg rt, IRRef ref,
|
||||
emit_tab(as, pi, rt, left, right);
|
||||
}
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
/* Fuse to multiply-add/sub instruction. */
|
||||
static int asm_fusemadd(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pir)
|
||||
{
|
||||
@ -245,6 +246,7 @@ static int asm_fusemadd(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pir)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -- Calls --------------------------------------------------------------- */
|
||||
|
||||
@ -253,13 +255,17 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
|
||||
{
|
||||
uint32_t n, nargs = CCI_XNARGS(ci);
|
||||
int32_t ofs = 8;
|
||||
Reg gpr = REGARG_FIRSTGPR, fpr = REGARG_FIRSTFPR;
|
||||
Reg gpr = REGARG_FIRSTGPR;
|
||||
#if !LJ_SOFTFP
|
||||
Reg fpr = REGARG_FIRSTFPR;
|
||||
#endif
|
||||
if ((void *)ci->func)
|
||||
emit_call(as, (void *)ci->func);
|
||||
for (n = 0; n < nargs; n++) { /* Setup args. */
|
||||
IRRef ref = args[n];
|
||||
if (ref) {
|
||||
IRIns *ir = IR(ref);
|
||||
#if !LJ_SOFTFP
|
||||
if (irt_isfp(ir->t)) {
|
||||
if (fpr <= REGARG_LASTFPR) {
|
||||
lua_assert(rset_test(as->freeset, fpr)); /* Already evicted. */
|
||||
@ -271,7 +277,9 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
|
||||
emit_spstore(as, ir, r, ofs);
|
||||
ofs += irt_isnum(ir->t) ? 8 : 4;
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (gpr <= REGARG_LASTGPR) {
|
||||
lua_assert(rset_test(as->freeset, gpr)); /* Already evicted. */
|
||||
ra_leftov(as, gpr, ref);
|
||||
@ -290,8 +298,10 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
|
||||
}
|
||||
checkmclim(as);
|
||||
}
|
||||
#if !LJ_SOFTFP
|
||||
if ((ci->flags & CCI_VARARG)) /* Vararg calls need to know about FPR use. */
|
||||
emit_tab(as, fpr == REGARG_FIRSTFPR ? PPCI_CRXOR : PPCI_CREQV, 6, 6, 6);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Setup result reg/sp for call. Evict scratch regs. */
|
||||
@ -299,8 +309,10 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
|
||||
{
|
||||
RegSet drop = RSET_SCRATCH;
|
||||
int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t));
|
||||
#if !LJ_SOFTFP
|
||||
if ((ci->flags & CCI_NOFPRCLOBBER))
|
||||
drop &= ~RSET_FPR;
|
||||
#endif
|
||||
if (ra_hasreg(ir->r))
|
||||
rset_clear(drop, ir->r); /* Dest reg handled below. */
|
||||
if (hiop && ra_hasreg((ir+1)->r))
|
||||
@ -308,7 +320,7 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
|
||||
ra_evictset(as, drop); /* Evictions must be performed first. */
|
||||
if (ra_used(ir)) {
|
||||
lua_assert(!irt_ispri(ir->t));
|
||||
if (irt_isfp(ir->t)) {
|
||||
if (!LJ_SOFTFP && irt_isfp(ir->t)) {
|
||||
if ((ci->flags & CCI_CASTU64)) {
|
||||
/* Use spill slot or temp slots. */
|
||||
int32_t ofs = ir->s ? sps_scale(ir->s) : SPOFS_TMP;
|
||||
@ -377,6 +389,7 @@ static void asm_retf(ASMState *as, IRIns *ir)
|
||||
|
||||
/* -- Type conversions ---------------------------------------------------- */
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
static void asm_tointg(ASMState *as, IRIns *ir, Reg left)
|
||||
{
|
||||
RegSet allow = RSET_FPR;
|
||||
@ -409,15 +422,23 @@ static void asm_tobit(ASMState *as, IRIns *ir)
|
||||
emit_fai(as, PPCI_STFD, tmp, RID_SP, SPOFS_TMP);
|
||||
emit_fab(as, PPCI_FADD, tmp, left, right);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void asm_conv(ASMState *as, IRIns *ir)
|
||||
{
|
||||
IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
|
||||
#if !LJ_SOFTFP
|
||||
int stfp = (st == IRT_NUM || st == IRT_FLOAT);
|
||||
#endif
|
||||
IRRef lref = ir->op1;
|
||||
lua_assert(irt_type(ir->t) != st);
|
||||
lua_assert(!(irt_isint64(ir->t) ||
|
||||
(st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */
|
||||
#if LJ_SOFTFP
|
||||
/* FP conversions are handled by SPLIT. */
|
||||
lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT));
|
||||
/* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */
|
||||
#else
|
||||
lua_assert(irt_type(ir->t) != st);
|
||||
if (irt_isfp(ir->t)) {
|
||||
Reg dest = ra_dest(as, ir, RSET_FPR);
|
||||
if (stfp) { /* FP to FP conversion. */
|
||||
@ -476,7 +497,9 @@ static void asm_conv(ASMState *as, IRIns *ir)
|
||||
emit_fb(as, PPCI_FCTIWZ, tmp, left);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
if (st >= IRT_I8 && st <= IRT_U16) { /* Extend to 32 bit integer. */
|
||||
Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
|
||||
@ -496,17 +519,41 @@ static void asm_strto(ASMState *as, IRIns *ir)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_strscan_num];
|
||||
IRRef args[2];
|
||||
int32_t ofs;
|
||||
int32_t ofs = SPOFS_TMP;
|
||||
#if LJ_SOFTFP
|
||||
ra_evictset(as, RSET_SCRATCH);
|
||||
if (ra_used(ir)) {
|
||||
if (ra_hasspill(ir->s) && ra_hasspill((ir+1)->s) &&
|
||||
(ir->s & 1) == LJ_BE && (ir->s ^ 1) == (ir+1)->s) {
|
||||
int i;
|
||||
for (i = 0; i < 2; i++) {
|
||||
Reg r = (ir+i)->r;
|
||||
if (ra_hasreg(r)) {
|
||||
ra_free(as, r);
|
||||
ra_modified(as, r);
|
||||
emit_spload(as, ir+i, r, sps_scale((ir+i)->s));
|
||||
}
|
||||
}
|
||||
ofs = sps_scale(ir->s & ~1);
|
||||
} else {
|
||||
Reg rhi = ra_dest(as, ir+1, RSET_GPR);
|
||||
Reg rlo = ra_dest(as, ir, rset_exclude(RSET_GPR, rhi));
|
||||
emit_tai(as, PPCI_LWZ, rhi, RID_SP, ofs);
|
||||
emit_tai(as, PPCI_LWZ, rlo, RID_SP, ofs+4);
|
||||
}
|
||||
}
|
||||
#else
|
||||
RegSet drop = RSET_SCRATCH;
|
||||
if (ra_hasreg(ir->r)) rset_set(drop, ir->r); /* Spill dest reg (if any). */
|
||||
ra_evictset(as, drop);
|
||||
if (ir->s) ofs = sps_scale(ir->s);
|
||||
#endif
|
||||
asm_guardcc(as, CC_EQ);
|
||||
emit_ai(as, PPCI_CMPWI, RID_RET, 0); /* Test return status. */
|
||||
args[0] = ir->op1; /* GCstr *str */
|
||||
args[1] = ASMREF_TMP1; /* TValue *n */
|
||||
asm_gencall(as, ci, args);
|
||||
/* Store the result to the spill slot or temp slots. */
|
||||
ofs = ir->s ? sps_scale(ir->s) : SPOFS_TMP;
|
||||
emit_tai(as, PPCI_ADDI, ra_releasetmp(as, ASMREF_TMP1), RID_SP, ofs);
|
||||
}
|
||||
|
||||
@ -530,7 +577,10 @@ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
|
||||
Reg src = ra_alloc1(as, ref, allow);
|
||||
emit_setgl(as, src, tmptv.gcr);
|
||||
}
|
||||
type = ra_allock(as, irt_toitype(ir->t), allow);
|
||||
if (LJ_SOFTFP && (ir+1)->o == IR_HIOP)
|
||||
type = ra_alloc1(as, ref+1, allow);
|
||||
else
|
||||
type = ra_allock(as, irt_toitype(ir->t), allow);
|
||||
emit_setgl(as, type, tmptv.it);
|
||||
}
|
||||
}
|
||||
@ -574,11 +624,27 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
||||
Reg tisnum = RID_NONE, tmpnum = RID_NONE;
|
||||
IRRef refkey = ir->op2;
|
||||
IRIns *irkey = IR(refkey);
|
||||
int isk = irref_isk(refkey);
|
||||
IRType1 kt = irkey->t;
|
||||
uint32_t khash;
|
||||
MCLabel l_end, l_loop, l_next;
|
||||
|
||||
rset_clear(allow, tab);
|
||||
#if LJ_SOFTFP
|
||||
if (!isk) {
|
||||
key = ra_alloc1(as, refkey, allow);
|
||||
rset_clear(allow, key);
|
||||
if (irkey[1].o == IR_HIOP) {
|
||||
if (ra_hasreg((irkey+1)->r)) {
|
||||
tmpnum = (irkey+1)->r;
|
||||
ra_noweak(as, tmpnum);
|
||||
} else {
|
||||
tmpnum = ra_allocref(as, refkey+1, allow);
|
||||
}
|
||||
rset_clear(allow, tmpnum);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (irt_isnum(kt)) {
|
||||
key = ra_alloc1(as, refkey, RSET_FPR);
|
||||
tmpnum = ra_scratch(as, rset_exclude(RSET_FPR, key));
|
||||
@ -588,6 +654,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
||||
key = ra_alloc1(as, refkey, allow);
|
||||
rset_clear(allow, key);
|
||||
}
|
||||
#endif
|
||||
tmp2 = ra_scratch(as, allow);
|
||||
rset_clear(allow, tmp2);
|
||||
|
||||
@ -610,7 +677,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
||||
asm_guardcc(as, CC_EQ);
|
||||
else
|
||||
emit_condbranch(as, PPCI_BC|PPCF_Y, CC_EQ, l_end);
|
||||
if (irt_isnum(kt)) {
|
||||
if (!LJ_SOFTFP && irt_isnum(kt)) {
|
||||
emit_fab(as, PPCI_FCMPU, 0, tmpnum, key);
|
||||
emit_condbranch(as, PPCI_BC, CC_GE, l_next);
|
||||
emit_ab(as, PPCI_CMPLW, tmp1, tisnum);
|
||||
@ -620,7 +687,10 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
||||
emit_ab(as, PPCI_CMPW, tmp2, key);
|
||||
emit_condbranch(as, PPCI_BC, CC_NE, l_next);
|
||||
}
|
||||
emit_ai(as, PPCI_CMPWI, tmp1, irt_toitype(irkey->t));
|
||||
if (LJ_SOFTFP && ra_hasreg(tmpnum))
|
||||
emit_ab(as, PPCI_CMPW, tmp1, tmpnum);
|
||||
else
|
||||
emit_ai(as, PPCI_CMPWI, tmp1, irt_toitype(irkey->t));
|
||||
if (!irt_ispri(kt))
|
||||
emit_tai(as, PPCI_LWZ, tmp2, dest, (int32_t)offsetof(Node, key.gcr));
|
||||
}
|
||||
@ -629,19 +699,19 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
||||
(((char *)as->mcp-(char *)l_loop) & 0xffffu);
|
||||
|
||||
/* Load main position relative to tab->node into dest. */
|
||||
khash = irref_isk(refkey) ? ir_khash(irkey) : 1;
|
||||
khash = isk ? ir_khash(irkey) : 1;
|
||||
if (khash == 0) {
|
||||
emit_tai(as, PPCI_LWZ, dest, tab, (int32_t)offsetof(GCtab, node));
|
||||
} else {
|
||||
Reg tmphash = tmp1;
|
||||
if (irref_isk(refkey))
|
||||
if (isk)
|
||||
tmphash = ra_allock(as, khash, allow);
|
||||
emit_tab(as, PPCI_ADD, dest, dest, tmp1);
|
||||
emit_tai(as, PPCI_MULLI, tmp1, tmp1, sizeof(Node));
|
||||
emit_asb(as, PPCI_AND, tmp1, tmp2, tmphash);
|
||||
emit_tai(as, PPCI_LWZ, dest, tab, (int32_t)offsetof(GCtab, node));
|
||||
emit_tai(as, PPCI_LWZ, tmp2, tab, (int32_t)offsetof(GCtab, hmask));
|
||||
if (irref_isk(refkey)) {
|
||||
if (isk) {
|
||||
/* Nothing to do. */
|
||||
} else if (irt_isstr(kt)) {
|
||||
emit_tai(as, PPCI_LWZ, tmp1, key, (int32_t)offsetof(GCstr, hash));
|
||||
@ -651,13 +721,19 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
|
||||
emit_asb(as, PPCI_XOR, tmp1, tmp1, tmp2);
|
||||
emit_rotlwi(as, tmp1, tmp1, (HASH_ROT2+HASH_ROT1)&31);
|
||||
emit_tab(as, PPCI_SUBF, tmp2, dest, tmp2);
|
||||
if (irt_isnum(kt)) {
|
||||
if (LJ_SOFTFP ? (irkey[1].o == IR_HIOP) : irt_isnum(kt)) {
|
||||
#if LJ_SOFTFP
|
||||
emit_asb(as, PPCI_XOR, tmp2, key, tmp1);
|
||||
emit_rotlwi(as, dest, tmp1, HASH_ROT1);
|
||||
emit_tab(as, PPCI_ADD, tmp1, tmpnum, tmpnum);
|
||||
#else
|
||||
int32_t ofs = ra_spill(as, irkey);
|
||||
emit_asb(as, PPCI_XOR, tmp2, tmp2, tmp1);
|
||||
emit_rotlwi(as, dest, tmp1, HASH_ROT1);
|
||||
emit_tab(as, PPCI_ADD, tmp1, tmp1, tmp1);
|
||||
emit_tai(as, PPCI_LWZ, tmp2, RID_SP, ofs+4);
|
||||
emit_tai(as, PPCI_LWZ, tmp1, RID_SP, ofs);
|
||||
#endif
|
||||
} else {
|
||||
emit_asb(as, PPCI_XOR, tmp2, key, tmp1);
|
||||
emit_rotlwi(as, dest, tmp1, HASH_ROT1);
|
||||
@ -784,8 +860,8 @@ static PPCIns asm_fxloadins(IRIns *ir)
|
||||
case IRT_U8: return PPCI_LBZ;
|
||||
case IRT_I16: return PPCI_LHA;
|
||||
case IRT_U16: return PPCI_LHZ;
|
||||
case IRT_NUM: return PPCI_LFD;
|
||||
case IRT_FLOAT: return PPCI_LFS;
|
||||
case IRT_NUM: lua_assert(!LJ_SOFTFP); return PPCI_LFD;
|
||||
case IRT_FLOAT: if (!LJ_SOFTFP) return PPCI_LFS;
|
||||
default: return PPCI_LWZ;
|
||||
}
|
||||
}
|
||||
@ -795,8 +871,8 @@ static PPCIns asm_fxstoreins(IRIns *ir)
|
||||
switch (irt_type(ir->t)) {
|
||||
case IRT_I8: case IRT_U8: return PPCI_STB;
|
||||
case IRT_I16: case IRT_U16: return PPCI_STH;
|
||||
case IRT_NUM: return PPCI_STFD;
|
||||
case IRT_FLOAT: return PPCI_STFS;
|
||||
case IRT_NUM: lua_assert(!LJ_SOFTFP); return PPCI_STFD;
|
||||
case IRT_FLOAT: if (!LJ_SOFTFP) return PPCI_STFS;
|
||||
default: return PPCI_STW;
|
||||
}
|
||||
}
|
||||
@ -809,7 +885,7 @@ static void asm_fload(ASMState *as, IRIns *ir)
|
||||
int32_t ofs;
|
||||
if (ir->op1 == REF_NIL) {
|
||||
idx = RID_JGL;
|
||||
ofs = ir->op2 - 32768;
|
||||
ofs = (ir->op2 << 2) - 32768;
|
||||
} else {
|
||||
idx = ra_alloc1(as, ir->op1, RSET_GPR);
|
||||
if (ir->op2 == IRFL_TAB_ARRAY) {
|
||||
@ -839,7 +915,8 @@ static void asm_fstore(ASMState *as, IRIns *ir)
|
||||
|
||||
static void asm_xload(ASMState *as, IRIns *ir)
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);
|
||||
Reg dest = ra_dest(as, ir,
|
||||
(!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
|
||||
lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));
|
||||
if (irt_isi8(ir->t))
|
||||
emit_as(as, PPCI_EXTSB, dest, dest);
|
||||
@ -857,7 +934,8 @@ static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
|
||||
Reg src = ra_alloc1(as, irb->op1, RSET_GPR);
|
||||
asm_fusexrefx(as, PPCI_STWBRX, src, ir->op1, rset_exclude(RSET_GPR, src));
|
||||
} else {
|
||||
Reg src = ra_alloc1(as, ir->op2, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);
|
||||
Reg src = ra_alloc1(as, ir->op2,
|
||||
(!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
|
||||
asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1,
|
||||
rset_exclude(RSET_GPR, src), ofs);
|
||||
}
|
||||
@ -871,10 +949,19 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
|
||||
Reg dest = RID_NONE, type = RID_TMP, tmp = RID_TMP, idx;
|
||||
RegSet allow = RSET_GPR;
|
||||
int32_t ofs = AHUREF_LSX;
|
||||
if (LJ_SOFTFP && (ir+1)->o == IR_HIOP) {
|
||||
t.irt = IRT_NUM;
|
||||
if (ra_used(ir+1)) {
|
||||
type = ra_dest(as, ir+1, allow);
|
||||
rset_clear(allow, type);
|
||||
}
|
||||
ofs = 0;
|
||||
}
|
||||
if (ra_used(ir)) {
|
||||
lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t));
|
||||
if (!irt_isnum(t)) ofs = 0;
|
||||
dest = ra_dest(as, ir, irt_isnum(t) ? RSET_FPR : RSET_GPR);
|
||||
lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||
|
||||
irt_isint(ir->t) || irt_isaddr(ir->t));
|
||||
if (LJ_SOFTFP || !irt_isnum(t)) ofs = 0;
|
||||
dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
|
||||
rset_clear(allow, dest);
|
||||
}
|
||||
idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
|
||||
@ -883,12 +970,13 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
|
||||
asm_guardcc(as, CC_GE);
|
||||
emit_ab(as, PPCI_CMPLW, type, tisnum);
|
||||
if (ra_hasreg(dest)) {
|
||||
if (ofs == AHUREF_LSX) {
|
||||
if (!LJ_SOFTFP && ofs == AHUREF_LSX) {
|
||||
tmp = ra_scratch(as, rset_exclude(rset_exclude(RSET_GPR,
|
||||
(idx&255)), (idx>>8)));
|
||||
emit_fab(as, PPCI_LFDX, dest, (idx&255), tmp);
|
||||
} else {
|
||||
emit_fai(as, PPCI_LFD, dest, idx, ofs);
|
||||
emit_fai(as, LJ_SOFTFP ? PPCI_LWZ : PPCI_LFD, dest, idx,
|
||||
ofs+4*LJ_SOFTFP);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -911,7 +999,7 @@ static void asm_ahustore(ASMState *as, IRIns *ir)
|
||||
int32_t ofs = AHUREF_LSX;
|
||||
if (ir->r == RID_SINK)
|
||||
return;
|
||||
if (irt_isnum(ir->t)) {
|
||||
if (!LJ_SOFTFP && irt_isnum(ir->t)) {
|
||||
src = ra_alloc1(as, ir->op2, RSET_FPR);
|
||||
} else {
|
||||
if (!irt_ispri(ir->t)) {
|
||||
@ -919,11 +1007,14 @@ static void asm_ahustore(ASMState *as, IRIns *ir)
|
||||
rset_clear(allow, src);
|
||||
ofs = 0;
|
||||
}
|
||||
type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
|
||||
if (LJ_SOFTFP && (ir+1)->o == IR_HIOP)
|
||||
type = ra_alloc1(as, (ir+1)->op2, allow);
|
||||
else
|
||||
type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
|
||||
rset_clear(allow, type);
|
||||
}
|
||||
idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
|
||||
if (irt_isnum(ir->t)) {
|
||||
if (!LJ_SOFTFP && irt_isnum(ir->t)) {
|
||||
if (ofs == AHUREF_LSX) {
|
||||
emit_fab(as, PPCI_STFDX, src, (idx&255), RID_TMP);
|
||||
emit_slwi(as, RID_TMP, (idx>>8), 3);
|
||||
@ -948,21 +1039,33 @@ static void asm_sload(ASMState *as, IRIns *ir)
|
||||
IRType1 t = ir->t;
|
||||
Reg dest = RID_NONE, type = RID_NONE, base;
|
||||
RegSet allow = RSET_GPR;
|
||||
int hiop = (LJ_SOFTFP && (ir+1)->o == IR_HIOP);
|
||||
if (hiop)
|
||||
t.irt = IRT_NUM;
|
||||
lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */
|
||||
lua_assert(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK));
|
||||
lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK));
|
||||
lua_assert(LJ_DUALNUM ||
|
||||
!irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)));
|
||||
#if LJ_SOFTFP
|
||||
lua_assert(!(ir->op2 & IRSLOAD_CONVERT)); /* Handled by LJ_SOFTFP SPLIT. */
|
||||
if (hiop && ra_used(ir+1)) {
|
||||
type = ra_dest(as, ir+1, allow);
|
||||
rset_clear(allow, type);
|
||||
}
|
||||
#else
|
||||
if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {
|
||||
dest = ra_scratch(as, RSET_FPR);
|
||||
asm_tointg(as, ir, dest);
|
||||
t.irt = IRT_NUM; /* Continue with a regular number type check. */
|
||||
} else if (ra_used(ir)) {
|
||||
} else
|
||||
#endif
|
||||
if (ra_used(ir)) {
|
||||
lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t));
|
||||
dest = ra_dest(as, ir, irt_isnum(t) ? RSET_FPR : RSET_GPR);
|
||||
dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
|
||||
rset_clear(allow, dest);
|
||||
base = ra_alloc1(as, REF_BASE, allow);
|
||||
rset_clear(allow, base);
|
||||
if ((ir->op2 & IRSLOAD_CONVERT)) {
|
||||
if (!LJ_SOFTFP && (ir->op2 & IRSLOAD_CONVERT)) {
|
||||
if (irt_isint(t)) {
|
||||
emit_tai(as, PPCI_LWZ, dest, RID_SP, SPOFS_TMPLO);
|
||||
dest = ra_scratch(as, RSET_FPR);
|
||||
@ -994,10 +1097,13 @@ dotypecheck:
|
||||
if ((ir->op2 & IRSLOAD_TYPECHECK)) {
|
||||
Reg tisnum = ra_allock(as, (int32_t)LJ_TISNUM, allow);
|
||||
asm_guardcc(as, CC_GE);
|
||||
emit_ab(as, PPCI_CMPLW, RID_TMP, tisnum);
|
||||
#if !LJ_SOFTFP
|
||||
type = RID_TMP;
|
||||
#endif
|
||||
emit_ab(as, PPCI_CMPLW, type, tisnum);
|
||||
}
|
||||
if (ra_hasreg(dest)) emit_fai(as, PPCI_LFD, dest, base, ofs-4);
|
||||
if (ra_hasreg(dest)) emit_fai(as, LJ_SOFTFP ? PPCI_LWZ : PPCI_LFD, dest,
|
||||
base, ofs-(LJ_SOFTFP?0:4));
|
||||
} else {
|
||||
if ((ir->op2 & IRSLOAD_TYPECHECK)) {
|
||||
asm_guardcc(as, CC_NE);
|
||||
@ -1119,6 +1225,7 @@ static void asm_obar(ASMState *as, IRIns *ir)
|
||||
|
||||
/* -- Arithmetic and logic operations ------------------------------------- */
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
static void asm_fparith(ASMState *as, IRIns *ir, PPCIns pi)
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_FPR);
|
||||
@ -1146,13 +1253,17 @@ static void asm_fpmath(ASMState *as, IRIns *ir)
|
||||
else
|
||||
asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void asm_add(ASMState *as, IRIns *ir)
|
||||
{
|
||||
#if !LJ_SOFTFP
|
||||
if (irt_isnum(ir->t)) {
|
||||
if (!asm_fusemadd(as, ir, PPCI_FMADD, PPCI_FMADD))
|
||||
asm_fparith(as, ir, PPCI_FADD);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
|
||||
PPCIns pi;
|
||||
@ -1191,10 +1302,13 @@ static void asm_add(ASMState *as, IRIns *ir)
|
||||
|
||||
static void asm_sub(ASMState *as, IRIns *ir)
|
||||
{
|
||||
#if !LJ_SOFTFP
|
||||
if (irt_isnum(ir->t)) {
|
||||
if (!asm_fusemadd(as, ir, PPCI_FMSUB, PPCI_FNMSUB))
|
||||
asm_fparith(as, ir, PPCI_FSUB);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
PPCIns pi = PPCI_SUBF;
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
Reg left, right;
|
||||
@ -1220,9 +1334,12 @@ static void asm_sub(ASMState *as, IRIns *ir)
|
||||
|
||||
static void asm_mul(ASMState *as, IRIns *ir)
|
||||
{
|
||||
#if !LJ_SOFTFP
|
||||
if (irt_isnum(ir->t)) {
|
||||
asm_fparith(as, ir, PPCI_FMUL);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
PPCIns pi = PPCI_MULLW;
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
|
||||
@ -1250,9 +1367,12 @@ static void asm_mul(ASMState *as, IRIns *ir)
|
||||
|
||||
static void asm_neg(ASMState *as, IRIns *ir)
|
||||
{
|
||||
#if !LJ_SOFTFP
|
||||
if (irt_isnum(ir->t)) {
|
||||
asm_fpunary(as, ir, PPCI_FNEG);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
Reg dest, left;
|
||||
PPCIns pi = PPCI_NEG;
|
||||
if (as->flagmcp == as->mcp) {
|
||||
@ -1563,9 +1683,40 @@ static void asm_bitshift(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pik)
|
||||
PPCI_RLWINM|PPCF_MB(0)|PPCF_ME(31))
|
||||
#define asm_bror(as, ir) lua_assert(0)
|
||||
|
||||
#if LJ_SOFTFP
|
||||
static void asm_sfpmin_max(ASMState *as, IRIns *ir)
|
||||
{
|
||||
CCallInfo ci = lj_ir_callinfo[IRCALL_softfp_cmp];
|
||||
IRRef args[4];
|
||||
MCLabel l_right, l_end;
|
||||
Reg desthi = ra_dest(as, ir, RSET_GPR), destlo = ra_dest(as, ir+1, RSET_GPR);
|
||||
Reg righthi, lefthi = ra_alloc2(as, ir, RSET_GPR);
|
||||
Reg rightlo, leftlo = ra_alloc2(as, ir+1, RSET_GPR);
|
||||
PPCCC cond = (IROp)ir->o == IR_MIN ? CC_EQ : CC_NE;
|
||||
righthi = (lefthi >> 8); lefthi &= 255;
|
||||
rightlo = (leftlo >> 8); leftlo &= 255;
|
||||
args[0^LJ_BE] = ir->op1; args[1^LJ_BE] = (ir+1)->op1;
|
||||
args[2^LJ_BE] = ir->op2; args[3^LJ_BE] = (ir+1)->op2;
|
||||
l_end = emit_label(as);
|
||||
if (desthi != righthi) emit_mr(as, desthi, righthi);
|
||||
if (destlo != rightlo) emit_mr(as, destlo, rightlo);
|
||||
l_right = emit_label(as);
|
||||
if (l_end != l_right) emit_jmp(as, l_end);
|
||||
if (desthi != lefthi) emit_mr(as, desthi, lefthi);
|
||||
if (destlo != leftlo) emit_mr(as, destlo, leftlo);
|
||||
if (l_right == as->mcp+1) {
|
||||
cond ^= 4; l_right = l_end; ++as->mcp;
|
||||
}
|
||||
emit_condbranch(as, PPCI_BC, cond, l_right);
|
||||
ra_evictset(as, RSET_SCRATCH);
|
||||
emit_cmpi(as, RID_RET, 1);
|
||||
asm_gencall(as, &ci, args);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
|
||||
{
|
||||
if (irt_isnum(ir->t)) {
|
||||
if (!LJ_SOFTFP && irt_isnum(ir->t)) {
|
||||
Reg dest = ra_dest(as, ir, RSET_FPR);
|
||||
Reg tmp = dest;
|
||||
Reg right, left = ra_alloc2(as, ir, RSET_FPR);
|
||||
@ -1653,7 +1804,7 @@ static void asm_intcomp_(ASMState *as, IRRef lref, IRRef rref, Reg cr, PPCCC cc)
|
||||
static void asm_comp(ASMState *as, IRIns *ir)
|
||||
{
|
||||
PPCCC cc = asm_compmap[ir->o];
|
||||
if (irt_isnum(ir->t)) {
|
||||
if (!LJ_SOFTFP && irt_isnum(ir->t)) {
|
||||
Reg right, left = ra_alloc2(as, ir, RSET_FPR);
|
||||
right = (left >> 8); left &= 255;
|
||||
asm_guardcc(as, (cc >> 4));
|
||||
@ -1674,6 +1825,44 @@ static void asm_comp(ASMState *as, IRIns *ir)
|
||||
|
||||
#define asm_equal(as, ir) asm_comp(as, ir)
|
||||
|
||||
#if LJ_SOFTFP
|
||||
/* SFP comparisons. */
|
||||
static void asm_sfpcomp(ASMState *as, IRIns *ir)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_softfp_cmp];
|
||||
RegSet drop = RSET_SCRATCH;
|
||||
Reg r;
|
||||
IRRef args[4];
|
||||
args[0^LJ_BE] = ir->op1; args[1^LJ_BE] = (ir+1)->op1;
|
||||
args[2^LJ_BE] = ir->op2; args[3^LJ_BE] = (ir+1)->op2;
|
||||
|
||||
for (r = REGARG_FIRSTGPR; r <= REGARG_FIRSTGPR+3; r++) {
|
||||
if (!rset_test(as->freeset, r) &&
|
||||
regcost_ref(as->cost[r]) == args[r-REGARG_FIRSTGPR])
|
||||
rset_clear(drop, r);
|
||||
}
|
||||
ra_evictset(as, drop);
|
||||
asm_setupresult(as, ir, ci);
|
||||
switch ((IROp)ir->o) {
|
||||
case IR_ULT:
|
||||
asm_guardcc(as, CC_EQ);
|
||||
emit_ai(as, PPCI_CMPWI, RID_RET, 0);
|
||||
case IR_ULE:
|
||||
asm_guardcc(as, CC_EQ);
|
||||
emit_ai(as, PPCI_CMPWI, RID_RET, 1);
|
||||
break;
|
||||
case IR_GE: case IR_GT:
|
||||
asm_guardcc(as, CC_EQ);
|
||||
emit_ai(as, PPCI_CMPWI, RID_RET, 2);
|
||||
default:
|
||||
asm_guardcc(as, (asm_compmap[ir->o] & 0xf));
|
||||
emit_ai(as, PPCI_CMPWI, RID_RET, 0);
|
||||
break;
|
||||
}
|
||||
asm_gencall(as, ci, args);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LJ_HASFFI
|
||||
/* 64 bit integer comparisons. */
|
||||
static void asm_comp64(ASMState *as, IRIns *ir)
|
||||
@ -1703,19 +1892,36 @@ static void asm_comp64(ASMState *as, IRIns *ir)
|
||||
/* Hiword op of a split 64 bit op. Previous op must be the loword op. */
|
||||
static void asm_hiop(ASMState *as, IRIns *ir)
|
||||
{
|
||||
#if LJ_HASFFI
|
||||
#if LJ_HASFFI || LJ_SOFTFP
|
||||
/* HIOP is marked as a store because it needs its own DCE logic. */
|
||||
int uselo = ra_used(ir-1), usehi = ra_used(ir); /* Loword/hiword used? */
|
||||
if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
|
||||
if ((ir-1)->o == IR_CONV) { /* Conversions to/from 64 bit. */
|
||||
as->curins--; /* Always skip the CONV. */
|
||||
#if LJ_HASFFI && !LJ_SOFTFP
|
||||
if (usehi || uselo)
|
||||
asm_conv64(as, ir);
|
||||
return;
|
||||
#endif
|
||||
} else if ((ir-1)->o <= IR_NE) { /* 64 bit integer comparisons. ORDER IR. */
|
||||
as->curins--; /* Always skip the loword comparison. */
|
||||
#if LJ_SOFTFP
|
||||
if (!irt_isint(ir->t)) {
|
||||
asm_sfpcomp(as, ir-1);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if LJ_HASFFI
|
||||
asm_comp64(as, ir);
|
||||
#endif
|
||||
return;
|
||||
#if LJ_SOFTFP
|
||||
} else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) {
|
||||
as->curins--; /* Always skip the loword min/max. */
|
||||
if (uselo || usehi)
|
||||
asm_sfpmin_max(as, ir-1);
|
||||
return;
|
||||
#endif
|
||||
} else if ((ir-1)->o == IR_XSTORE) {
|
||||
as->curins--; /* Handle both stores here. */
|
||||
if ((ir-1)->r != RID_SINK) {
|
||||
@ -1726,14 +1932,27 @@ static void asm_hiop(ASMState *as, IRIns *ir)
|
||||
}
|
||||
if (!usehi) return; /* Skip unused hiword op for all remaining ops. */
|
||||
switch ((ir-1)->o) {
|
||||
#if LJ_HASFFI
|
||||
case IR_ADD: as->curins--; asm_add64(as, ir); break;
|
||||
case IR_SUB: as->curins--; asm_sub64(as, ir); break;
|
||||
case IR_NEG: as->curins--; asm_neg64(as, ir); break;
|
||||
#endif
|
||||
#if LJ_SOFTFP
|
||||
case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
|
||||
case IR_STRTO:
|
||||
if (!uselo)
|
||||
ra_allocref(as, ir->op1, RSET_GPR); /* Mark lo op as used. */
|
||||
break;
|
||||
#endif
|
||||
case IR_CALLN:
|
||||
case IR_CALLS:
|
||||
case IR_CALLXS:
|
||||
if (!uselo)
|
||||
ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */
|
||||
break;
|
||||
#if LJ_SOFTFP
|
||||
case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR:
|
||||
#endif
|
||||
case IR_CNEWI:
|
||||
/* Nothing to do here. Handled by lo op itself. */
|
||||
break;
|
||||
@ -1797,8 +2016,19 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
|
||||
if ((sn & SNAP_NORESTORE))
|
||||
continue;
|
||||
if (irt_isnum(ir->t)) {
|
||||
#if LJ_SOFTFP
|
||||
Reg tmp;
|
||||
RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
|
||||
lua_assert(irref_isk(ref)); /* LJ_SOFTFP: must be a number constant. */
|
||||
tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, allow);
|
||||
emit_tai(as, PPCI_STW, tmp, RID_BASE, ofs+(LJ_BE?4:0));
|
||||
if (rset_test(as->freeset, tmp+1)) allow = RID2RSET(tmp+1);
|
||||
tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, allow);
|
||||
emit_tai(as, PPCI_STW, tmp, RID_BASE, ofs+(LJ_BE?0:4));
|
||||
#else
|
||||
Reg src = ra_alloc1(as, ref, RSET_FPR);
|
||||
emit_fai(as, PPCI_STFD, src, RID_BASE, ofs);
|
||||
#endif
|
||||
} else {
|
||||
Reg type;
|
||||
RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
|
||||
@ -1811,6 +2041,10 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
|
||||
if ((sn & (SNAP_CONT|SNAP_FRAME))) {
|
||||
if (s == 0) continue; /* Do not overwrite link to previous frame. */
|
||||
type = ra_allock(as, (int32_t)(*flinks--), allow);
|
||||
#if LJ_SOFTFP
|
||||
} else if ((sn & SNAP_SOFTFPNUM)) {
|
||||
type = ra_alloc1(as, ref+1, rset_exclude(RSET_GPR, RID_BASE));
|
||||
#endif
|
||||
} else {
|
||||
type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
|
||||
}
|
||||
@ -1947,14 +2181,15 @@ static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci)
|
||||
int nslots = 2, ngpr = REGARG_NUMGPR, nfpr = REGARG_NUMFPR;
|
||||
asm_collectargs(as, ir, ci, args);
|
||||
for (i = 0; i < nargs; i++)
|
||||
if (args[i] && irt_isfp(IR(args[i])->t)) {
|
||||
if (!LJ_SOFTFP && args[i] && irt_isfp(IR(args[i])->t)) {
|
||||
if (nfpr > 0) nfpr--; else nslots = (nslots+3) & ~1;
|
||||
} else {
|
||||
if (ngpr > 0) ngpr--; else nslots++;
|
||||
}
|
||||
if (nslots > as->evenspill) /* Leave room for args in stack slots. */
|
||||
as->evenspill = nslots;
|
||||
return irt_isfp(ir->t) ? REGSP_HINT(RID_FPRET) : REGSP_HINT(RID_RET);
|
||||
return (!LJ_SOFTFP && irt_isfp(ir->t)) ? REGSP_HINT(RID_FPRET) :
|
||||
REGSP_HINT(RID_RET);
|
||||
}
|
||||
|
||||
static void asm_setup_target(ASMState *as)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** x86/x64 IR assembler (SSA IR -> machine code).
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
/* -- Guard handling ------------------------------------------------------ */
|
||||
@ -234,10 +234,10 @@ static void asm_fusefref(ASMState *as, IRIns *ir, RegSet allow)
|
||||
as->mrm.idx = RID_NONE;
|
||||
if (ir->op1 == REF_NIL) {
|
||||
#if LJ_GC64
|
||||
as->mrm.ofs = (int32_t)ir->op2 - GG_OFS(dispatch);
|
||||
as->mrm.ofs = (int32_t)(ir->op2 << 2) - GG_OFS(dispatch);
|
||||
as->mrm.base = RID_DISPATCH;
|
||||
#else
|
||||
as->mrm.ofs = (int32_t)ir->op2 + ptr2addr(J2GG(as->J));
|
||||
as->mrm.ofs = (int32_t)(ir->op2 << 2) + ptr2addr(J2GG(as->J));
|
||||
as->mrm.base = RID_NONE;
|
||||
#endif
|
||||
return;
|
||||
@ -387,6 +387,7 @@ static Reg asm_fuseloadk64(ASMState *as, IRIns *ir)
|
||||
ir->i = (int32_t)(as->mctop - as->mcbot);
|
||||
as->mcbot += 8;
|
||||
as->mclim = as->mcbot + MCLIM_REDZONE;
|
||||
lj_mcode_commitbot(as->J, as->mcbot);
|
||||
}
|
||||
as->mrm.ofs = (int32_t)mcpofs(as, as->mctop - ir->i);
|
||||
as->mrm.base = RID_RIP;
|
||||
@ -1065,7 +1066,8 @@ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
|
||||
emit_u32(as, irt_toitype(ir->t) << 15);
|
||||
emit_rmro(as, XO_ARITHi, XOg_OR, dest, 4);
|
||||
} else {
|
||||
emit_movmroi(as, dest, 4, (irt_toitype(ir->t) << 15) | 0x7fff);
|
||||
/* Currently, no caller passes integers that might end up here. */
|
||||
emit_movmroi(as, dest, 4, (irt_toitype(ir->t) << 15));
|
||||
}
|
||||
emit_movtomro(as, REX_64IR(ir, src), dest, 0);
|
||||
}
|
||||
@ -1757,7 +1759,7 @@ static void asm_sload(ASMState *as, IRIns *ir)
|
||||
emit_i8(as, irt_toitype(t));
|
||||
emit_rr(as, XO_ARITHi8, XOg_CMP, tmp);
|
||||
emit_shifti(as, XOg_SAR|REX_64, tmp, 47);
|
||||
emit_rmro(as, XO_MOV, tmp|REX_64, base, ofs+4);
|
||||
emit_rmro(as, XO_MOV, tmp|REX_64, base, ofs);
|
||||
#else
|
||||
} else {
|
||||
emit_i8(as, irt_toitype(t));
|
||||
@ -1790,8 +1792,9 @@ static void asm_cnew(ASMState *as, IRIns *ir)
|
||||
Reg r64 = sz == 8 ? REX_64 : 0;
|
||||
if (irref_isk(ir->op2)) {
|
||||
IRIns *irk = IR(ir->op2);
|
||||
uint64_t k = irk->o == IR_KINT64 ? ir_k64(irk)->u64 :
|
||||
(uint64_t)(uint32_t)irk->i;
|
||||
uint64_t k = (irk->o == IR_KINT64 ||
|
||||
(LJ_GC64 && (irk->o == IR_KPTR || irk->o == IR_KKPTR))) ?
|
||||
ir_k64(irk)->u64 : (uint64_t)(uint32_t)irk->i;
|
||||
if (sz == 4 || checki32((int64_t)k)) {
|
||||
emit_i32(as, (int32_t)k);
|
||||
emit_rmro(as, XO_MOVmi, r64, RID_RET, sizeof(GCcdata));
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Bytecode instruction modes.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#define lj_bc_c
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Bytecode instruction format.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_BC_H
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Bytecode dump definitions.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_BCDUMP_H
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Bytecode reader.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#define lj_bcread_c
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Bytecode writer.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#define lj_bcwrite_c
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Buffer handling.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#define lj_buf_c
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Buffer handling.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_BUF_H
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** C data arithmetic.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#include "lj_obj.h"
|
||||
@ -274,6 +274,15 @@ int lj_carith_op(lua_State *L, MMS mm)
|
||||
return lj_carith_meta(L, cts, &ca, mm);
|
||||
}
|
||||
|
||||
/* No built-in functionality for length of cdata. */
|
||||
int lj_carith_len(lua_State *L)
|
||||
{
|
||||
CTState *cts = ctype_cts(L);
|
||||
CDArith ca;
|
||||
carith_checkarg(L, cts, &ca);
|
||||
return lj_carith_meta(L, cts, &ca, MM_len);
|
||||
}
|
||||
|
||||
/* -- 64 bit bit operations helpers --------------------------------------- */
|
||||
|
||||
#if LJ_64
|
||||
@ -347,7 +356,6 @@ uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -- 64 bit integer arithmetic helpers ----------------------------------- */
|
||||
|
||||
#if LJ_32 && LJ_HASJIT
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** C data arithmetic.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CARITH_H
|
||||
@ -11,6 +11,7 @@
|
||||
#if LJ_HASFFI
|
||||
|
||||
LJ_FUNC int lj_carith_op(lua_State *L, MMS mm);
|
||||
LJ_FUNC int lj_carith_len(lua_State *L);
|
||||
|
||||
#if LJ_32
|
||||
LJ_FUNC uint64_t lj_carith_shl64(uint64_t x, int32_t sh);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** FFI C call handling.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#include "lj_obj.h"
|
||||
@ -301,7 +301,7 @@
|
||||
unsigned int cl = ccall_classify_struct(cts, ctr); \
|
||||
if ((cl & 4)) { /* Combine float HFA from separate registers. */ \
|
||||
CTSize i = (cl >> 8) - 1; \
|
||||
do { ((uint32_t *)dp)[i] = cc->fpr[i].u32; } while (i--); \
|
||||
do { ((uint32_t *)dp)[i] = cc->fpr[i].lo; } while (i--); \
|
||||
} else { \
|
||||
if (cl > 1) sp = (uint8_t *)&cc->fpr[0]; \
|
||||
memcpy(dp, sp, ctr->size); \
|
||||
@ -331,7 +331,7 @@
|
||||
|
||||
#define CCALL_HANDLE_COMPLEXARG \
|
||||
/* Pass complex by value in separate (!) FPRs or on stack. */ \
|
||||
isfp = ctr->size == 2*sizeof(float) ? 2 : 1;
|
||||
isfp = sz == 2*sizeof(float) ? 2 : 1;
|
||||
|
||||
#define CCALL_HANDLE_REGARG \
|
||||
if (LJ_TARGET_IOS && isva) { \
|
||||
@ -359,6 +359,13 @@
|
||||
} \
|
||||
}
|
||||
|
||||
#if LJ_BE
|
||||
#define CCALL_HANDLE_RET \
|
||||
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
|
||||
sp = (uint8_t *)&cc->fpr[0].f;
|
||||
#endif
|
||||
|
||||
|
||||
#elif LJ_TARGET_PPC
|
||||
/* -- PPC calling conventions --------------------------------------------- */
|
||||
|
||||
@ -380,6 +387,24 @@
|
||||
#define CCALL_HANDLE_COMPLEXARG \
|
||||
/* Pass complex by value in 2 or 4 GPRs. */
|
||||
|
||||
#define CCALL_HANDLE_GPR \
|
||||
/* Try to pass argument in GPRs. */ \
|
||||
if (n > 1) { \
|
||||
lua_assert(n == 2 || n == 4); /* int64_t or complex (float). */ \
|
||||
if (ctype_isinteger(d->info) || ctype_isfp(d->info)) \
|
||||
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
|
||||
else if (ngpr + n > maxgpr) \
|
||||
ngpr = maxgpr; /* Prevent reordering. */ \
|
||||
} \
|
||||
if (ngpr + n <= maxgpr) { \
|
||||
dp = &cc->gpr[ngpr]; \
|
||||
ngpr += n; \
|
||||
goto done; \
|
||||
} \
|
||||
|
||||
#if LJ_ABI_SOFTFP
|
||||
#define CCALL_HANDLE_REGARG CCALL_HANDLE_GPR
|
||||
#else
|
||||
#define CCALL_HANDLE_REGARG \
|
||||
if (isfp) { /* Try to pass argument in FPRs. */ \
|
||||
if (nfpr + 1 <= CCALL_NARG_FPR) { \
|
||||
@ -388,24 +413,16 @@
|
||||
d = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ \
|
||||
goto done; \
|
||||
} \
|
||||
} else { /* Try to pass argument in GPRs. */ \
|
||||
if (n > 1) { \
|
||||
lua_assert(n == 2 || n == 4); /* int64_t or complex (float). */ \
|
||||
if (ctype_isinteger(d->info)) \
|
||||
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
|
||||
else if (ngpr + n > maxgpr) \
|
||||
ngpr = maxgpr; /* Prevent reordering. */ \
|
||||
} \
|
||||
if (ngpr + n <= maxgpr) { \
|
||||
dp = &cc->gpr[ngpr]; \
|
||||
ngpr += n; \
|
||||
goto done; \
|
||||
} \
|
||||
} else { \
|
||||
CCALL_HANDLE_GPR \
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !LJ_ABI_SOFTFP
|
||||
#define CCALL_HANDLE_RET \
|
||||
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
|
||||
ctr = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */
|
||||
#endif
|
||||
|
||||
#elif LJ_TARGET_MIPS32
|
||||
/* -- MIPS o32 calling conventions ---------------------------------------- */
|
||||
@ -865,7 +882,8 @@ noth: /* Not a homogeneous float/double aggregate. */
|
||||
return 0; /* Struct is in GPRs. */
|
||||
}
|
||||
|
||||
void ccall_copy_struct(CCallState *cc, CType *ctr, void *dp, void *sp, int ft)
|
||||
static void ccall_copy_struct(CCallState *cc, CType *ctr, void *dp, void *sp,
|
||||
int ft)
|
||||
{
|
||||
if (LJ_ABI_SOFTFP ? ft :
|
||||
((ft & 3) == FTYPE_FLOAT || (ft >> 2) == FTYPE_FLOAT)) {
|
||||
@ -1068,9 +1086,16 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
||||
*(int32_t *)dp = d->size == 1 ? (int32_t)*(int8_t *)dp :
|
||||
(int32_t)*(int16_t *)dp;
|
||||
}
|
||||
#if LJ_TARGET_ARM64 && LJ_BE
|
||||
if (isfp && d->size == sizeof(float))
|
||||
((float *)dp)[1] = ((float *)dp)[0]; /* Floats occupy high slot. */
|
||||
#endif
|
||||
#if LJ_TARGET_MIPS64 || (LJ_TARGET_ARM64 && LJ_BE)
|
||||
if ((ctype_isinteger_or_bool(d->info) || ctype_isenum(d->info)
|
||||
#if LJ_TARGET_MIPS64
|
||||
if ((ctype_isinteger_or_bool(d->info) || ctype_isenum(d->info) ||
|
||||
(isfp && nsp == 0)) && d->size <= 4) {
|
||||
|| (isfp && nsp == 0)
|
||||
#endif
|
||||
) && d->size <= 4) {
|
||||
*(int64_t *)dp = (int64_t)*(int32_t *)dp; /* Sign-extend to 64 bit. */
|
||||
}
|
||||
#endif
|
||||
@ -1111,7 +1136,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
||||
}
|
||||
if (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */
|
||||
|
||||
#if LJ_TARGET_X64 || LJ_TARGET_PPC
|
||||
#if LJ_TARGET_X64 || (LJ_TARGET_PPC && !LJ_ABI_SOFTFP)
|
||||
cc->nfpr = nfpr; /* Required for vararg functions. */
|
||||
#endif
|
||||
cc->nsp = nsp;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** FFI C call handling.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CCALL_H
|
||||
@ -79,16 +79,16 @@ typedef union FPRArg {
|
||||
typedef intptr_t GPRArg;
|
||||
typedef union FPRArg {
|
||||
double d;
|
||||
float f;
|
||||
uint32_t u32;
|
||||
struct { LJ_ENDIAN_LOHI(float f; , float g;) };
|
||||
struct { LJ_ENDIAN_LOHI(uint32_t lo; , uint32_t hi;) };
|
||||
} FPRArg;
|
||||
|
||||
#elif LJ_TARGET_PPC
|
||||
|
||||
#define CCALL_NARG_GPR 8
|
||||
#define CCALL_NARG_FPR 8
|
||||
#define CCALL_NARG_FPR (LJ_ABI_SOFTFP ? 0 : 8)
|
||||
#define CCALL_NRET_GPR 4 /* For complex double. */
|
||||
#define CCALL_NRET_FPR 1
|
||||
#define CCALL_NRET_FPR (LJ_ABI_SOFTFP ? 0 : 1)
|
||||
#define CCALL_SPS_EXTRA 4
|
||||
#define CCALL_SPS_FREE 0
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** FFI C callback handling.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#include "lj_obj.h"
|
||||
@ -173,16 +173,16 @@ static void callback_mcode_init(global_State *g, uint32_t *page)
|
||||
uint32_t *p = page;
|
||||
void *target = (void *)lj_vm_ffi_callback;
|
||||
MSize slot;
|
||||
*p++ = A64I_LDRLx | A64F_D(RID_X11) | A64F_S19(4);
|
||||
*p++ = A64I_LDRLx | A64F_D(RID_X10) | A64F_S19(5);
|
||||
*p++ = A64I_BR | A64F_N(RID_X11);
|
||||
*p++ = A64I_NOP;
|
||||
*p++ = A64I_LE(A64I_LDRLx | A64F_D(RID_X11) | A64F_S19(4));
|
||||
*p++ = A64I_LE(A64I_LDRLx | A64F_D(RID_X10) | A64F_S19(5));
|
||||
*p++ = A64I_LE(A64I_BR | A64F_N(RID_X11));
|
||||
*p++ = A64I_LE(A64I_NOP);
|
||||
((void **)p)[0] = target;
|
||||
((void **)p)[1] = g;
|
||||
p += 4;
|
||||
for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {
|
||||
*p++ = A64I_MOVZw | A64F_D(RID_X9) | A64F_U16(slot);
|
||||
*p = A64I_B | A64F_S26((page-p) & 0x03ffffffu);
|
||||
*p++ = A64I_LE(A64I_MOVZw | A64F_D(RID_X9) | A64F_U16(slot));
|
||||
*p = A64I_LE(A64I_B | A64F_S26((page-p) & 0x03ffffffu));
|
||||
p++;
|
||||
}
|
||||
lua_assert(p - page <= CALLBACK_MCODE_SIZE);
|
||||
@ -419,6 +419,23 @@ void lj_ccallback_mcode_free(CTState *cts)
|
||||
|
||||
#elif LJ_TARGET_PPC
|
||||
|
||||
#define CALLBACK_HANDLE_GPR \
|
||||
if (n > 1) { \
|
||||
lua_assert(((LJ_ABI_SOFTFP && ctype_isnum(cta->info)) || /* double. */ \
|
||||
ctype_isinteger(cta->info)) && n == 2); /* int64_t. */ \
|
||||
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
|
||||
} \
|
||||
if (ngpr + n <= maxgpr) { \
|
||||
sp = &cts->cb.gpr[ngpr]; \
|
||||
ngpr += n; \
|
||||
goto done; \
|
||||
}
|
||||
|
||||
#if LJ_ABI_SOFTFP
|
||||
#define CALLBACK_HANDLE_REGARG \
|
||||
CALLBACK_HANDLE_GPR \
|
||||
UNUSED(isfp);
|
||||
#else
|
||||
#define CALLBACK_HANDLE_REGARG \
|
||||
if (isfp) { \
|
||||
if (nfpr + 1 <= CCALL_NARG_FPR) { \
|
||||
@ -427,20 +444,15 @@ void lj_ccallback_mcode_free(CTState *cts)
|
||||
goto done; \
|
||||
} \
|
||||
} else { /* Try to pass argument in GPRs. */ \
|
||||
if (n > 1) { \
|
||||
lua_assert(ctype_isinteger(cta->info) && n == 2); /* int64_t. */ \
|
||||
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
|
||||
} \
|
||||
if (ngpr + n <= maxgpr) { \
|
||||
sp = &cts->cb.gpr[ngpr]; \
|
||||
ngpr += n; \
|
||||
goto done; \
|
||||
} \
|
||||
CALLBACK_HANDLE_GPR \
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !LJ_ABI_SOFTFP
|
||||
#define CALLBACK_HANDLE_RET \
|
||||
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
|
||||
*(double *)dp = *(float *)dp; /* FPRs always hold doubles. */
|
||||
#endif
|
||||
|
||||
#elif LJ_TARGET_MIPS32
|
||||
|
||||
@ -632,6 +644,10 @@ static void callback_conv_result(CTState *cts, lua_State *L, TValue *o)
|
||||
#if CCALL_NUM_FPR
|
||||
if (ctype_isfp(ctr->info))
|
||||
dp = (uint8_t *)&cts->cb.fpr[0];
|
||||
#endif
|
||||
#if LJ_TARGET_ARM64 && LJ_BE
|
||||
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float))
|
||||
dp = (uint8_t *)&cts->cb.fpr[0].f[1];
|
||||
#endif
|
||||
lj_cconv_ct_tv(cts, ctr, dp, o, 0);
|
||||
#ifdef CALLBACK_HANDLE_RET
|
||||
@ -646,7 +662,7 @@ static void callback_conv_result(CTState *cts, lua_State *L, TValue *o)
|
||||
*(int32_t *)dp = ctr->size == 1 ? (int32_t)*(int8_t *)dp :
|
||||
(int32_t)*(int16_t *)dp;
|
||||
}
|
||||
#if LJ_TARGET_MIPS64
|
||||
#if LJ_TARGET_MIPS64 || (LJ_TARGET_ARM64 && LJ_BE)
|
||||
/* Always sign-extend results to 64 bits. Even a soft-fp 'float'. */
|
||||
if (ctr->size <= 4 &&
|
||||
(LJ_ABI_SOFTFP || ctype_isinteger_or_bool(ctr->info)))
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** FFI C callback handling.
|
||||
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_CCALLBACK_H
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user