This is a list of changes between the released versions of LuaJIT.
-The current stable version is LuaJIT 2.0.3.
+The current stable version is LuaJIT 2.0.5.
Please check the @@ -72,6 +71,98 @@
LuaJIT Change History
LuaJIT 2.0.5 — 2017-05-01
+-
+
- Add workaround for MSVC 2015 stdio changes. +
- Limit mcode alloc probing, depending on the available pool size. +
- Fix overly restrictive range calculation in mcode allocation. +
- Fix out-of-scope goto handling in parser. +
- Remove internal __mode = "K" and replace with safe check. +
- Add "proto" field to jit.util.funcinfo(). +
- Fix GC step size calculation. +
- Initialize uv->immutable for upvalues of loaded chunks. +
- Fix for cdata vs. non-cdata arithmetics/comparisons. +
- Drop leftover regs in 'for' iterator assignment, too. +
- Fix PHI remarking in SINK pass. +
- Don't try to record outermost pcall() return to lower frame. +
- Add guard for obscure aliasing between open upvalues and SSA slots. +
- Remove assumption that lj_math_random_step() doesn't clobber FPRs. +
- Fix handling of non-numeric strings in arithmetic coercions. +
- Fix recording of select(n, ...) with off-trace varargs +
- Fix install for cross-builds. +
- Don't allocate unused 2nd result register in JIT compiler backend. +
- Drop marks from replayed instructions when sinking. +
- Fix unsinking check. +
- Properly handle OOM in trace_save(). +
- Limit number of arguments given to io.lines() and fp:lines(). +
- Fix narrowing of TOBIT. +
- OSX: Fix build with recent XCode. +
- x86/x64: Don't spill an explicit REF_BASE in the IR. +
- x86/x64: Fix instruction length decoder. +
- x86/x64: Search for exit jumps with instruction length decoder. +
- ARM: Fix BLX encoding for Thumb interworking calls. +
- MIPS: Don't use RID_GP as a scratch register. +
- MIPS: Fix emitted code for U32 to float conversion. +
- MIPS: Backport workaround for compact unwind tables. +
- MIPS: Fix cross-endian jit.bcsave. +
- MIPS: Fix BC_ISNEXT fallback path. +
- MIPS: Fix use of ffgccheck delay slots in interpreter. +
- FFI: Fix FOLD rules for int64_t comparisons. +
- FFI: Fix SPLIT pass for CONV i64.u64. +
- FFI: Fix ipairs() recording. +
- FFI: Don't propagate qualifiers into subtypes of complex. +
LuaJIT 2.0.4 — 2015-05-14
+-
+
- Fix stack check in narrowing optimization. +
- Fix Lua/C API typecheck error for special indexes. +
- Fix string to number conversion. +
- Fix lexer error for chunks without tokens. +
- Don't compile IR_RETF after CALLT to ff with-side effects. +
- Fix BC_UCLO/BC_JMP join optimization in Lua parser. +
- Fix corner case in string to number conversion. +
- Gracefully handle lua_error() for a suspended coroutine. +
- Avoid error messages when building with Clang. +
- Fix snapshot #0 handling for traces with a stack check on entry. +
- Fix fused constant loads under high register pressure. +
- Invalidate backpropagation cache after DCE. +
- Fix ABC elimination. +
- Fix debug info for main chunk of stripped bytecode. +
- Fix FOLD rule for string.sub(s, ...) == k. +
- Fix FOLD rule for STRREF of SNEW. +
- Fix frame traversal while searching for error function. +
- Prevent GC estimate miscalculation due to buffer growth. +
- Prevent adding side traces for stack checks. +
- Fix top slot calculation for snapshots with continuations. +
- Fix check for reuse of SCEV results in FORL. +
- Add PS Vita port. +
- Fix compatibility issues with Illumos. +
- Fix DragonFly build (unsupported). +
- OpenBSD/x86: Better executable memory allocation for W^X mode. +
- x86: Fix argument checks for ipairs() iterator. +
- x86: lj_math_random_step() clobbers XMM regs on OSX Clang. +
- x86: Fix code generation for unused result of math.random(). +
- x64: Allow building with LUAJIT_USE_SYSMALLOC and LUAJIT_USE_VALGRIND. +
- x86/x64: Fix argument check for bit shifts. +
- x86/x64: Fix code generation for fused test/arith ops. +
- ARM: Fix write barrier check in BC_USETS. +
- PPC: Fix red zone overflow in machine code generation. +
- PPC: Don't use mcrxr on PPE. +
- Various archs: Fix excess stack growth in interpreter. +
- FFI: Fix FOLD rule for TOBIT + CONV num.u32. +
- FFI: Prevent DSE across ffi.string(). +
- FFI: No meta fallback when indexing pointer to incomplete struct. +
- FFI: Fix initialization of unions of subtypes. +
- FFI: Fix cdata vs. non-cdata arithmetic and comparisons. +
- FFI: Fix __index/__newindex metamethod resolution for ctypes. +
- FFI: Fix compilation of reference field access. +
- FFI: Fix frame traversal for backtraces with FFI callbacks. +
- FFI: Fix recording of indexing a struct pointer ctype object itself. +
- FFI: Allow non-scalar cdata to be compared for equality by address. +
- FFI: Fix pseudo type conversions for type punning. +
LuaJIT 2.0.3 — 2014-03-12
- Add PS4 port. @@ -918,7 +1009,7 @@
LuaJIT 1.0.0 — 2005-08-29
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/contact.html b/doc/contact.html index 0483a829..54ddf742 100644 --- a/doc/contact.html +++ b/doc/contact.html @@ -3,8 +3,7 @@
Contact
+If you want to report bugs, propose fixes or suggest enhancements, +please use the +GitHub issue tracker. +
+Please send general questions to the » LuaJIT mailing list. +
+You can also send any questions you have directly to me:
@@ -84,7 +90,7 @@Contact
Copyright
All documentation is -Copyright © 2005-2014 Mike Pall. +Copyright © 2005-2018 Mike Pall.
@@ -92,7 +98,7 @@Copyright
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/ext_c_api.html b/doc/ext_c_api.html index 48503361..38259566 100644 --- a/doc/ext_c_api.html +++ b/doc/ext_c_api.html @@ -3,8 +3,7 @@
luaJIT_setmode(L, idx, mode)
The third argument specifies the mode, which is 'or'ed with a flag. -The flag can be LUAJIT_MODE_OFF to turn a feature on, -LUAJIT_MODE_ON to turn a feature off, or +The flag can be LUAJIT_MODE_OFF to turn a feature off, +LUAJIT_MODE_ON to turn a feature on, or LUAJIT_MODE_FLUSH to flush cached code.
@@ -177,7 +176,7 @@
luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|flag)
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/ext_ffi.html b/doc/ext_ffi.html index fa9ca971..74ca2944 100644 --- a/doc/ext_ffi.html +++ b/doc/ext_ffi.html @@ -3,8 +3,7 @@
Motivating Example: Using C Data Structures
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/ext_ffi_api.html b/doc/ext_ffi_api.html index dcffcfa3..10f2d022 100644 --- a/doc/ext_ffi_api.html +++ b/doc/ext_ffi_api.html @@ -3,8 +3,7 @@
Extensions to the Lua Parser
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html index 7e5f7035..218049d4 100644 --- a/doc/ext_ffi_semantics.html +++ b/doc/ext_ffi_semantics.html @@ -3,8 +3,7 @@
Parameterized Types
The main use for parameterized types are libraries implementing abstract data types -(» example), +(example), 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. @@ -1235,7 +1234,7 @@
Current Status
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/ext_ffi_tutorial.html b/doc/ext_ffi_tutorial.html index 01fb8992..cd455cf1 100644 --- a/doc/ext_ffi_tutorial.html +++ b/doc/ext_ffi_tutorial.html @@ -3,8 +3,7 @@
To Cache or Not to Cache
individual C functions like this:-local funca, funcb = ffi.C.funcb, ffi.C.funcb -- Not helpful! +local funca, funcb = ffi.C.funca, ffi.C.funcb -- Not helpful! local function foo(x, n) for i=1,n do funcb(funca(x, i), 1) end end @@ -591,7 +590,7 @@To Cache or Not to Cache
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/ext_jit.html b/doc/ext_jit.html index 098be5e0..ce6dcd61 100644 --- a/doc/ext_jit.html +++ b/doc/ext_jit.html @@ -3,8 +3,7 @@
jit.os
jit.arch
Contains the target architecture name: -"x86", "x64" or "ppcspe". +"x86", "x64", "arm", "ppc", "ppcspe", or "mips".
jit.opt.* — JIT compiler optimization control
@@ -189,7 +188,7 @@jit.util.* — JIT compiler introspection
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/extensions.html b/doc/extensions.html index 20b597f1..fa412e0e 100644 --- a/doc/extensions.html +++ b/doc/extensions.html @@ -3,8 +3,7 @@
Extensions from Lua 5.2
Extensions from Lua 5.2
exit status.Note: this provides only partial compatibility with Lua 5.2 at the @@ -398,7 +397,7 @@
C++ Exception Interoperability
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/faq.html b/doc/faq.html index ffc2ae89..9338be48 100644 --- a/doc/faq.html +++ b/doc/faq.html @@ -3,8 +3,7 @@
Frequently Asked Questions (FAQ)
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/install.html b/doc/install.html index 2388ff33..befffa73 100644 --- a/doc/install.html +++ b/doc/install.html @@ -3,8 +3,7 @@
Installation
GCC 3.4
GCC 3.4
GCC 3.4
GCC 3.4
GCC 3.4
Clang
WinSDK
MinGW, Cygwin
Clang
WinSDK v7.0
ARM9E+
PSP2 (PS VITA)
Clang
Prerequisites
and change to the newly created directory:-tar zxf LuaJIT-2.0.3.tar.gz -cd LuaJIT-2.0.3+tar zxf LuaJIT-2.0.5.tar.gz +cd LuaJIT-2.0.5
Building LuaJIT
The supplied Makefiles try to auto-detect the settings needed for your @@ -344,9 +343,12 @@
Cross-compiling LuaJIT
you're compiling on a Windows or OSX host for embedded Linux or Android, you need to add TARGET_SYS=Linux to the examples below. For a minimal target OS, you may need to disable the built-in allocator in -src/Makefile and use TARGET_SYS=Other. The examples -below only show some popular targets — please check the comments -in src/Makefile for more details. +src/Makefile and use TARGET_SYS=Other. Don't forget to +specify the same TARGET_SYS for the install step, too. + ++The examples below only show some popular targets — please check +the comments in src/Makefile for more details.
# Cross-compile to a 32 bit binary on a multilib x64 OS @@ -439,8 +441,7 @@Cross-compiling LuaJIT
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
-You can cross-compile for iOS 3.0+ (iPhone/iPad) using the » iOS SDK. -The environment variables need to match the iOS SDK version: +You can cross-compile for iOS 3.0+ (iPhone/iPad) using the » iOS SDK:
Note: the JIT compiler is disabled for iOS, because regular iOS Apps @@ -450,49 +451,62 @@
Cross-compiling LuaJIT
Or use Android. :-p-IXCODE=`xcode-select -print-path` -ISDK=$IXCODE/Platforms/iPhoneOS.platform/Developer -ISDKVER=iPhoneOS6.0.sdk -ISDKP=$ISDK/usr/bin/ -ISDKF="-arch armv7 -isysroot $ISDK/SDKs/$ISDKVER" -make HOST_CC="gcc -m32 -arch i386" CROSS=$ISDKP TARGET_FLAGS="$ISDKF" \ - TARGET_SYS=iOS +ISDKP=$(xcrun --sdk iphoneos --show-sdk-path) +ICC=$(xcrun --sdk iphoneos --find clang) +ISDKF="-arch armv7 -isysroot $ISDKP" +make DEFAULT_CC=clang HOST_CC="clang -m32 -arch i386" \ + CROSS="$(dirname $ICC)/" TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS+ +
Cross-compiling for consoles
-You can cross-compile for PS3 using the PS3 SDK from -a Linux host or a Windows host (requires 32 bit MinGW (GCC) on the host, -too). Due to restrictions on consoles, the JIT compiler is disabled and -only the fast interpreter is built: +Building LuaJIT for consoles requires both a supported host compiler +(x86 or x64) and a cross-compiler (to PPC or ARM) from the official +console SDK.
--make HOST_CC="gcc -m32" CROSS=ppu-lv2- -
-You can cross-compile for PS4 from a Windows host using -the PS4 SDK (ORBIS) plus 64 bit MSVC. Due to restrictions on -consoles, the JIT compiler is disabled and only the fast interpreter -is built. +Due to restrictions on consoles, the JIT compiler is disabled and only +the fast interpreter is built. This is still faster than plain Lua, +but much slower than the JIT compiler. The FFI is disabled, too, since +it's not very useful in such an environment.
-Open a "Visual Studio .NET Command Prompt" (64 bit host compiler), -cd to the directory where you've unpacked the sources and run -the following commands. This builds a static library libluajit.a, +The following commands build a static library libluajit.a, which can be linked against your game, just like the Lua library.
++To cross-compile for PS3 from a Linux host (requires +32 bit GCC, i.e. multilib Linux/x64) or a Windows host (requires +32 bit MinGW), run this command: +
++make HOST_CC="gcc -m32" CROSS=ppu-lv2- ++
+To cross-compile for PS4 from a Windows host, +open a "Visual Studio .NET Command Prompt" (64 bit host compiler), +cd to the directory where you've unpacked the sources and +run the following commands: +
cd src ps4build
-You can cross-compile for Xbox 360 using the -Xbox 360 SDK (MSVC + XEDK). Due to restrictions on consoles, the -JIT compiler is disabled and only the fast interpreter is built. +To cross-compile for PS Vita from a Windows host, +open a "Visual Studio .NET Command Prompt" (32 bit host compiler), +cd to the directory where you've unpacked the sources and +run the following commands:
++cd src +psvitabuild +
-Open a "Visual Studio .NET Command Prompt" (32 bit host compiler), +To cross-compile for Xbox 360 from a Windows host, +open a "Visual Studio .NET Command Prompt" (32 bit host compiler), cd to the directory where you've unpacked the sources and run -the following commands. This builds a static library luajit20.lib, -which can be linked against your game, just like the Lua library. +the following commands:
cd src @@ -621,7 +635,7 @@Hints for Distribution Maintainers
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/luajit.html b/doc/luajit.html index 43af69c9..d8f531d5 100644 --- a/doc/luajit.html +++ b/doc/luajit.html @@ -3,8 +3,7 @@LuaJIT - - + @@ -38,6 +37,9 @@ table.os2 td { color: #ffa040; } +table.os3 td { + color: #40ffff; +} table.compiler td { color: #2080ff; background: #62bf41; @@ -147,7 +149,7 @@LuaJIT
It may be embedded or used as a general-purpose, stand-alone language.-LuaJIT is Copyright © 2005-2014 Mike Pall, released under the +LuaJIT is Copyright © 2005-2018 Mike Pall, released under the » MIT open source license.
@@ -158,7 +160,10 @@
Compatibility
Windows Linux BSD OSX POSIX -
++ Embedded Android iOS PS3 PS4 Xbox 360 + Embedded Android iOS +
PS3 PS4 PS Vita Xbox 360
@@ -218,7 +223,7 @@ GCC CLANG
LLVMMSVC More ...
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/running.html b/doc/running.html index c01c52d5..08d7f710 100644 --- a/doc/running.html +++ b/doc/running.html @@ -3,8 +3,7 @@Running LuaJIT - - + @@ -186,7 +185,7 @@-j cmd[=arg[,arg...]]
read the comment block at the start of their source. They can be found in the lib directory of the source distribution or installed under the jit directory. By default -this is /usr/local/share/luajit-2.0.3/jit on POSIX +this is /usr/local/share/luajit-2.0.5/jit on POSIX systems. @@ -296,7 +295,7 @@-O[level]
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/doc/status.html b/doc/status.html index ddcaed33..ea61db19 100644 --- a/doc/status.html +++ b/doc/status.html @@ -1,10 +1,9 @@ -Status & Roadmap +Status - - + @@ -17,7 +16,7 @@ LuaJIT-Status & Roadmap
+Status
- -
- @@ -89,12 +88,6 @@
Current Status
in LuaJIT (no per-coroutine hooks, no tail call counting).- -Some checks are missing in the JIT-compiled code for obscure situations -with open upvalues aliasing one of the SSA slots later on (or -vice versa). Bonus points, if you can find a real world test case for -this. -
-- Currently some out-of-memory errors from on-trace code are not handled correctly. The error may fall through an on-trace pcall or it may be passed on to the function set with @@ -102,20 +95,11 @@
Current Status
garbage collector.Roadmap
--Please refer to the -» LuaJIT Roadmap 2012/2013 and an -» update on release planning for details. -
--
-Copyright © 2005-2014 Mike Pall +Copyright © 2005-2018 · Contact diff --git a/dynasm/dasm_arm.h b/dynasm/dasm_arm.h index 435bbf5e..1d404ccd 100644 --- a/dynasm/dasm_arm.h +++ b/dynasm/dasm_arm.h @@ -1,6 +1,6 @@ /* ** DynASM ARM encoding engine. -** Copyright (C) 2005-2014 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; diff --git a/dynasm/dasm_arm.lua b/dynasm/dasm_arm.lua index b3a8827e..9ece1d7f 100644 --- a/dynasm/dasm_arm.lua +++ b/dynasm/dasm_arm.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM ARM module. -- --- Copyright (C) 2005-2014 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. ------------------------------------------------------------------------------ @@ -923,19 +923,22 @@ local function parse_template(params, template, nparams, pos) end map_op[".template__"] = function(params, template, nparams) - if not params then return sub(template, 9) end + if not params then return template:gsub("%x%x%x%x%x%x%x%x", "") end -- Limit number of section buffer positions used by a single dasm_put(). -- A single opcode needs a maximum of 3 positions. if secpos+3 > maxsecpos then wflush() end local pos = wpos() - local apos, spos = #actargs, secpos + local lpos, apos, spos = #actlist, #actargs, secpos local ok, err for t in gmatch(template, "[^|]+") do ok, err = pcall(parse_template, params, t, nparams, pos) if ok then return end secpos = spos + actlist[lpos+1] = nil + actlist[lpos+2] = nil + actlist[lpos+3] = nil actargs[apos+1] = nil actargs[apos+2] = nil actargs[apos+3] = nil diff --git a/dynasm/dasm_mips.h b/dynasm/dasm_mips.h index 43595889..46af0349 100644 --- a/dynasm/dasm_mips.h +++ b/dynasm/dasm_mips.h @@ -1,6 +1,6 @@ /* ** DynASM MIPS encoding engine. -** Copyright (C) 2005-2014 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); diff --git a/dynasm/dasm_mips.lua b/dynasm/dasm_mips.lua index 82942cbb..af530427 100644 --- a/dynasm/dasm_mips.lua +++ b/dynasm/dasm_mips.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM MIPS module. -- --- Copyright (C) 2005-2014 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. ------------------------------------------------------------------------------ @@ -757,9 +757,9 @@ map_op[".template__"] = function(params, template, nparams) elseif p == "X" then op = op + parse_index(params[n]); n = n + 1 elseif p == "B" or p == "J" then - local mode, n, s = parse_label(params[n], false) - if p == "B" then n = n + 2048 end - waction("REL_"..mode, n, s, 1) + local mode, m, s = parse_label(params[n], false) + if p == "B" then m = m + 2048 end + waction("REL_"..mode, m, s, 1) n = n + 1 elseif p == "A" then op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1 diff --git a/dynasm/dasm_ppc.h b/dynasm/dasm_ppc.h index 5ccff250..81b9a76b 100644 --- a/dynasm/dasm_ppc.h +++ b/dynasm/dasm_ppc.h @@ -1,6 +1,6 @@ /* ** DynASM PPC encoding engine. -** Copyright (C) 2005-2014 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) - (int)((char *)cp - base); diff --git a/dynasm/dasm_ppc.lua b/dynasm/dasm_ppc.lua index 61da50ef..77031fb2 100644 --- a/dynasm/dasm_ppc.lua +++ b/dynasm/dasm_ppc.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM PPC module. -- --- Copyright (C) 2005-2014 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. ------------------------------------------------------------------------------ @@ -1056,9 +1056,9 @@ map_op[".template__"] = function(params, template, nparams) elseif p == "M" then op = op + parse_shiftmask(params[n], false); n = n + 1 elseif p == "J" or p == "K" then - local mode, n, s = parse_label(params[n], false) - if p == "K" then n = n + 2048 end - waction("REL_"..mode, n, s, 1) + local mode, m, s = parse_label(params[n], false) + if p == "K" then m = m + 2048 end + waction("REL_"..mode, m, s, 1) n = n + 1 elseif p == "0" then if band(shr(op, rs), 31) == 0 then werror("cannot use r0") end diff --git a/dynasm/dasm_proto.h b/dynasm/dasm_proto.h index e77bb844..f5e79c7a 100644 --- a/dynasm/dasm_proto.h +++ b/dynasm/dasm_proto.h @@ -1,6 +1,6 @@ /* ** DynASM encoding engine prototypes. -** Copyright (C) 2005-2014 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. */ diff --git a/dynasm/dasm_x64.lua b/dynasm/dasm_x64.lua index 91d676d1..e8bdeb37 100644 --- a/dynasm/dasm_x64.lua +++ b/dynasm/dasm_x64.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM x64 module. -- --- Copyright (C) 2005-2014 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. diff --git a/dynasm/dasm_x86.h b/dynasm/dasm_x86.h index 97cbbea8..8ae911df 100644 --- a/dynasm/dasm_x86.h +++ b/dynasm/dasm_x86.h @@ -1,6 +1,6 @@ /* ** DynASM x86 encoding engine. -** Copyright (C) 2005-2014 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,17 +194,19 @@ void dasm_put(Dst_DECL, int start, ...) switch (action) { case DASM_DISP: if (n == 0) { if ((mrm&7) == 4) 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. */ case DASM_VREG: CK((n&-8) == 0 && (n != 4 || (*p&1) == 0), RANGE_VREG); - if (*p++ == 1 && *p == DASM_DISP) mrm = n; continue; + if (*p++ == 1 && *p == DASM_DISP) mrm = n; + continue; } mrm = 4; } else { @@ -322,11 +324,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; @@ -384,17 +389,22 @@ 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++; if (t >= 2) n<<=3; cp[-1] |= n; break; } 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; } @@ -405,6 +415,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); @@ -425,6 +436,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; } diff --git a/dynasm/dasm_x86.lua b/dynasm/dasm_x86.lua index f3859e3e..21c20865 100644 --- a/dynasm/dasm_x86.lua +++ b/dynasm/dasm_x86.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM x86/x64 module. -- --- Copyright (C) 2005-2014 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2017 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. ------------------------------------------------------------------------------ @@ -1081,7 +1081,11 @@ local map_op = { btr_2 = "mrqdw:0FB3Rm|miqdw:0FBA6mU", bts_2 = "mrqdw:0FABRm|miqdw:0FBA5mU", + shld_3 = "mriqdw:0FA4RmU|mrC/qq:0FA5Rm|mrC/dd:|mrC/ww:", + shrd_3 = "mriqdw:0FACRmU|mrC/qq:0FADRm|mrC/dd:|mrC/ww:", + rdtsc_0 = "0F31", -- P1+ + rdpmc_0 = "0F33", -- P6+ cpuid_0 = "0FA2", -- P1+ -- floating point ops @@ -1114,6 +1118,9 @@ local map_op = { fucompp_0 = "DAE9", fcompp_0 = "DED9", + fldenv_1 = "x.:D94m", + fnstenv_1 = "x.:D96m", + fstenv_1 = "x.:9BD96m", fldcw_1 = "xw:nD95m", fstcw_1 = "xw:n9BD97m", fnstcw_1 = "xw:nD97m", @@ -1184,11 +1191,13 @@ local map_op = { cvtsi2sd_2 = "rm/od:F20F2ArM|rm/oq:F20F2ArXM", cvtsi2ss_2 = "rm/od:F30F2ArM|rm/oq:F30F2ArXM", cvtss2sd_2 = "rro:F30F5ArM|rx/od:", - cvtss2si_2 = "rr/do:F20F2CrM|rr/qo:|rxd:|rx/qd:", + cvtss2si_2 = "rr/do:F30F2DrM|rr/qo:|rxd:|rx/qd:", cvttpd2dq_2 = "rmo:660FE6rM", cvttps2dq_2 = "rmo:F30F5BrM", cvttsd2si_2 = "rr/do:F20F2CrM|rr/qo:|rx/dq:|rxq:", cvttss2si_2 = "rr/do:F30F2CrM|rr/qo:|rxd:|rx/qd:", + fxsave_1 = "x.:0FAE0m", + fxrstor_1 = "x.:0FAE1m", ldmxcsr_1 = "xd:0FAE2m", lfence_0 = "0FAEE8", maskmovdqu_2 = "rro:660FF7rM", @@ -1239,7 +1248,7 @@ local map_op = { pcmpgtb_2 = "rmo:660F64rM", pcmpgtd_2 = "rmo:660F66rM", pcmpgtw_2 = "rmo:660F65rM", - pextrw_3 = "rri/do:660FC5rMU|xri/wo:660F3A15nrMU", -- Mem op: SSE4.1 only. + pextrw_3 = "rri/do:660FC5rMU|xri/wo:660F3A15nRmU", -- Mem op: SSE4.1 only. pinsrw_3 = "rri/od:660FC4rMU|rxi/ow:", pmaddwd_2 = "rmo:660FF5rM", pmaxsw_2 = "rmo:660FEErM", @@ -1344,7 +1353,7 @@ local map_op = { dpps_3 = "rmio:660F3A40rMU", extractps_3 = "mri/do:660F3A17RmU|rri/qo:660F3A17RXmU", insertps_3 = "rrio:660F3A41rMU|rxi/od:", - movntdqa_2 = "rmo:660F382ArM", + movntdqa_2 = "rxo:660F382ArM", mpsadbw_3 = "rmio:660F3A42rMU", packusdw_2 = "rmo:660F382BrM", pblendvb_3 = "rmRo:660F3810rM", diff --git a/dynasm/dynasm.lua b/dynasm/dynasm.lua index 0ea8697c..c46e956e 100644 --- a/dynasm/dynasm.lua +++ b/dynasm/dynasm.lua @@ -2,7 +2,7 @@ -- DynASM. A dynamic assembler for code generation engines. -- Originally designed and implemented for LuaJIT. -- --- Copyright (C) 2005-2014 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-2014 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 diff --git a/etc/luajit.1 b/etc/luajit.1 index 723a708c..0d263db7 100644 --- a/etc/luajit.1 +++ b/etc/luajit.1 @@ -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-2014 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 diff --git a/etc/luajit.pc b/etc/luajit.pc index d3f0cf30..36840ab8 100644 --- a/etc/luajit.pc +++ b/etc/luajit.pc @@ -1,7 +1,7 @@ # Package information for LuaJIT to be used by pkg-config. majver=2 minver=0 -relver=3 +relver=5 version=${majver}.${minver}.${relver} abiver=5.1 diff --git a/src/Makefile b/src/Makefile index 9551781a..2c780de0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -7,12 +7,12 @@ # Also works with MinGW and Cygwin on Windows. # Please check msvcbuild.bat for building with MSVC on Windows. # -# Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +# Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ############################################################################## MAJVER= 2 MINVER= 0 -RELVER= 3 +RELVER= 5 ABIVER= 5.1 NODOTABIVER= 51 @@ -24,11 +24,13 @@ NODOTABIVER= 51 # removing the '#' in front of them. Make sure you force a full recompile # with "make clean", followed by "make" if you change any options. # +DEFAULT_CC = gcc +# # LuaJIT builds as a native 32 or 64 bit binary by default. -CC= gcc +CC= $(DEFAULT_CC) # # Use this if you want to force a 32 bit build on a 64 bit multilib OS. -#CC= gcc -m32 +#CC= $(DEFAULT_CC) -m32 # # Since the assembler part does NOT maintain a frame pointer, it's pointless # to slow down the C part by not omitting it. Debugging, tracebacks and @@ -122,8 +124,10 @@ XCFLAGS= # # Use the system provided memory allocator (realloc) instead of the # bundled memory allocator. This is slower, but sometimes helpful for -# debugging. It's helpful for Valgrind's memcheck tool, too. This option -# cannot be enabled on x64, since the built-in allocator is mandatory. +# debugging. This option cannot be enabled on x64, since realloc usually +# doesn't return addresses in the right address range. +# OTOH this option is mandatory for Valgrind's memcheck tool on x64 and +# the only way to get useful results from it for all other architectures. #XCFLAGS+= -DLUAJIT_USE_SYSMALLOC # # This define is required to run LuaJIT under Valgrind. The Valgrind @@ -148,6 +152,29 @@ XCFLAGS= # You probably don't need to change anything below this line! ############################################################################## +############################################################################## +# Host system detection. +############################################################################## + +ifeq (Windows,$(findstring Windows,$(OS))$(MSYSTEM)$(TERM)) + HOST_SYS= Windows + HOST_RM= del +else + HOST_SYS:= $(shell uname -s) + ifneq (,$(findstring MINGW,$(HOST_SYS))) + HOST_SYS= Windows + HOST_MSYS= mingw + endif + ifneq (,$(findstring MSYS,$(HOST_SYS))) + HOST_SYS= Windows + HOST_MSYS= mingw + endif + ifneq (,$(findstring CYGWIN,$(HOST_SYS))) + HOST_SYS= Windows + HOST_MSYS= cygwin + endif +endif + ############################################################################## # Flags and options for host and target. ############################################################################## @@ -167,7 +194,7 @@ CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(XCFLAGS) $(CFLAGS) LDOPTIONS= $(CCDEBUG) $(LDFLAGS) HOST_CC= $(CC) -HOST_RM= rm -f +HOST_RM?= rm -f # If left blank, minilua is built and used. You can supply an installed # copy of (plain) Lua 5.1 or 5.2, plus Lua BitOp. E.g. with: HOST_LUA=lua HOST_LUA= @@ -241,9 +268,6 @@ ifneq (,$(findstring LJ_TARGET_PS3 1,$(TARGET_TESTARCH))) TARGET_ARCH+= -D__CELLOS_LV2__ TARGET_XCFLAGS+= -DLUAJIT_USE_SYSMALLOC endif -ifneq (,$(findstring LJ_NO_UNWIND 1,$(TARGET_TESTARCH))) - TARGET_ARCH+= -DLUAJIT_NO_UNWIND -endif TARGET_XCFLAGS+= $(CCOPT_$(TARGET_LJARCH)) TARGET_ARCH+= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET_LJARCH)) @@ -264,39 +288,24 @@ ifneq (,$(LMULTILIB)) endif ############################################################################## -# System detection. +# Target system detection. ############################################################################## -ifeq (Windows,$(findstring Windows,$(OS))$(MSYSTEM)$(TERM)) - HOST_SYS= Windows - HOST_RM= del -else - HOST_SYS:= $(shell uname -s) - ifneq (,$(findstring MINGW,$(HOST_SYS))) - HOST_SYS= Windows - HOST_MSYS= mingw - endif - ifneq (,$(findstring CYGWIN,$(HOST_SYS))) - HOST_SYS= Windows - HOST_MSYS= cygwin - endif -endif - TARGET_SYS?= $(HOST_SYS) ifeq (Windows,$(TARGET_SYS)) TARGET_STRIP+= --strip-unneeded 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 ifeq (Darwin,$(TARGET_SYS)) ifeq (,$(MACOSX_DEPLOYMENT_TARGET)) export MACOSX_DEPLOYMENT_TARGET=10.4 endif TARGET_STRIP+= -x - 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 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) @@ -307,15 +316,10 @@ ifeq (Darwin,$(TARGET_SYS)) else ifeq (iOS,$(TARGET_SYS)) TARGET_STRIP+= -x - TARGET_AR+= 2>/dev/null - TARGET_XCFLAGS+= -fno-stack-protector 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) else - ifneq (,$(findstring stack-protector,$(shell $(TARGET_CC) -dumpspecs))) - TARGET_XCFLAGS+= -fno-stack-protector - endif ifneq (SunOS,$(TARGET_SYS)) ifneq (PS3,$(TARGET_SYS)) TARGET_XLDFLAGS+= -Wl,-E @@ -399,6 +403,10 @@ ifeq (,$(findstring LJ_ABI_SOFTFP 1,$(TARGET_TESTARCH))) else TARGET_ARCH+= -DLJ_ABI_SOFTFP=1 endif +ifneq (,$(findstring LJ_NO_UNWIND 1,$(TARGET_TESTARCH))) + DASM_AFLAGS+= -D NO_UNWIND + TARGET_ARCH+= -DLUAJIT_NO_UNWIND +endif DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH)))) ifeq (Windows,$(TARGET_SYS)) DASM_AFLAGS+= -D WIN diff --git a/src/Makefile.dep b/src/Makefile.dep index 8ca33151..9e14d617 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -90,7 +90,7 @@ lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_ccallback.h lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_state.h lj_frame.h \ - lj_bc.h lj_jit.h lj_ir.h + lj_bc.h lj_vm.h lj_jit.h lj_ir.h lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_err.h lj_errmsg.h lj_func.h lj_str.h lj_tab.h lj_meta.h lj_debug.h \ lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h lj_jit.h lj_ir.h \ diff --git a/src/host/buildvm.c b/src/host/buildvm.c index 7687ad7a..b9560f31 100644 --- a/src/host/buildvm.c +++ b/src/host/buildvm.c @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder. -** Copyright (C) 2005-2014 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 diff --git a/src/host/buildvm.h b/src/host/buildvm.h index f9dc8c4f..e6dd3dcb 100644 --- a/src/host/buildvm.h +++ b/src/host/buildvm.h @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _BUILDVM_H diff --git a/src/host/buildvm_asm.c b/src/host/buildvm_asm.c index 9b28b3b3..81a3969a 100644 --- a/src/host/buildvm_asm.c +++ b/src/host/buildvm_asm.c @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder: Assembler source code emitter. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "buildvm.h" @@ -183,7 +183,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; @@ -286,7 +287,7 @@ void emit_asm(BuildCtx *ctx) fprintf(ctx->fp, "\n"); switch (ctx->mode) { case BUILD_elfasm: -#if !LJ_TARGET_PS3 +#if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA) fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n"); #endif #if LJ_TARGET_PPCSPE diff --git a/src/host/buildvm_fold.c b/src/host/buildvm_fold.c index 7f5d9f2f..d579f4d4 100644 --- a/src/host/buildvm_fold.c +++ b/src/host/buildvm_fold.c @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder: IR folding hash table generator. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "buildvm.h" @@ -9,7 +9,7 @@ /* Context for the folding hash table generator. */ static int lineno; -static int funcidx; +static uint32_t funcidx; static uint32_t foldkeys[BUILD_MAX_FOLD]; static uint32_t nkeys; diff --git a/src/host/buildvm_lib.c b/src/host/buildvm_lib.c index eafdab98..569e2caf 100644 --- a/src/host/buildvm_lib.c +++ b/src/host/buildvm_lib.c @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder: library definition compiler. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "buildvm.h" diff --git a/src/host/buildvm_peobj.c b/src/host/buildvm_peobj.c index 138b0423..aab00d68 100644 --- a/src/host/buildvm_peobj.c +++ b/src/host/buildvm_peobj.c @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder: PE object emitter. -** Copyright (C) 2005-2014 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. diff --git a/src/host/genminilua.lua b/src/host/genminilua.lua index 04c55188..50feff01 100644 --- a/src/host/genminilua.lua +++ b/src/host/genminilua.lua @@ -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-2014 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 ---------------------------------------------------------------------------- @@ -157,11 +157,11 @@ local function merge_includes(src) if includes[name] then return "" end includes[name] = true local fp = assert(io.open(LUA_SOURCE..name, "r")) - local src = fp:read("*a") + local inc = fp:read("*a") assert(fp:close()) - src = gsub(src, "#ifndef%s+%w+_h\n#define%s+%w+_h\n", "") - src = gsub(src, "#endif%s*$", "") - return merge_includes(src) + inc = gsub(inc, "#ifndef%s+%w+_h\n#define%s+%w+_h\n", "") + inc = gsub(inc, "#endif%s*$", "") + return merge_includes(inc) end) end @@ -300,6 +300,7 @@ local function strip_unused3(src) src = gsub(src, "if%([^\n]*hookmask[^\n]*&&\n[^\n]*%b{}\n", "") src = gsub(src, "(twoto%b()%()", "%1(size_t)") src = gsub(src, "isizearray)) +if(cast(unsigned int,key)-1 sizearray)) return&t->array[key-1]; else{ lua_Number nk=cast_num(key); diff --git a/src/jit/bc.lua b/src/jit/bc.lua index 9df19c7b..a2f84aaf 100644 --- a/src/jit/bc.lua +++ b/src/jit/bc.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT bytecode listing module. -- --- Copyright (C) 2005-2014 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 ---------------------------------------------------------------------------- -- @@ -41,7 +41,7 @@ -- Cache some library functions and objects. local jit = require("jit") -assert(jit.version_num == 20003, "LuaJIT core/library version mismatch") +assert(jit.version_num == 20005, "LuaJIT core/library version mismatch") local jutil = require("jit.util") local vmdef = require("jit.vmdef") local bit = require("bit") diff --git a/src/jit/bcsave.lua b/src/jit/bcsave.lua index f55bda97..c94064e4 100644 --- a/src/jit/bcsave.lua +++ b/src/jit/bcsave.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT module to save/list bytecode. -- --- Copyright (C) 2005-2014 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 ---------------------------------------------------------------------------- -- @@ -11,7 +11,7 @@ ------------------------------------------------------------------------------ local jit = require("jit") -assert(jit.version_num == 20003, "LuaJIT core/library version mismatch") +assert(jit.version_num == 20005, "LuaJIT core/library version mismatch") local bit = require("bit") -- Symbol name prefix for LuaJIT bytecode. @@ -69,7 +69,7 @@ local map_arch = { local map_os = { linux = true, windows = true, osx = true, freebsd = true, netbsd = true, - openbsd = true, solaris = true, + openbsd = true, dragonfly = true, solaris = true, } local function checkarg(str, map, err) @@ -239,7 +239,7 @@ typedef struct { hdr.type = f16(1) hdr.machine = f16(({ x86=3, x64=62, arm=40, ppc=20, ppcspe=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 diff --git a/src/jit/dis_arm.lua b/src/jit/dis_arm.lua index b3d0ebc2..91ebb7d5 100644 --- a/src/jit/dis_arm.lua +++ b/src/jit/dis_arm.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT ARM disassembler module. -- --- Copyright (C) 2005-2014 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. @@ -12,7 +12,7 @@ local type = type local sub, byte, format = string.sub, string.byte, string.format -local match, gmatch, gsub = string.match, string.gmatch, string.gsub +local match, gmatch = string.match, string.gmatch local concat = table.concat local bit = require("bit") local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex diff --git a/src/jit/dis_mips.lua b/src/jit/dis_mips.lua index 47a7a83b..02dfc172 100644 --- a/src/jit/dis_mips.lua +++ b/src/jit/dis_mips.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT MIPS disassembler module. -- --- Copyright (C) 2005-2014 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. @@ -11,8 +11,8 @@ ------------------------------------------------------------------------------ local type = type -local sub, byte, format = string.sub, string.byte, string.format -local match, gmatch, gsub = string.match, string.gmatch, string.gsub +local byte, format = string.byte, string.format +local match, gmatch = string.match, string.gmatch local concat = table.concat local bit = require("bit") local band, bor, tohex = bit.band, bit.bor, bit.tohex diff --git a/src/jit/dis_mipsel.lua b/src/jit/dis_mipsel.lua index d19de319..c9c2e245 100644 --- a/src/jit/dis_mipsel.lua +++ b/src/jit/dis_mipsel.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT MIPSEL disassembler wrapper module. -- --- Copyright (C) 2005-2014 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 diff --git a/src/jit/dis_ppc.lua b/src/jit/dis_ppc.lua index cfaf982f..4043aeb8 100644 --- a/src/jit/dis_ppc.lua +++ b/src/jit/dis_ppc.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT PPC disassembler module. -- --- Copyright (C) 2005-2014 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. @@ -13,7 +13,7 @@ ------------------------------------------------------------------------------ local type = type -local sub, byte, format = string.sub, string.byte, string.format +local byte, format = string.byte, string.format local match, gmatch, gsub = string.match, string.gmatch, string.gsub local concat = table.concat local bit = require("bit") diff --git a/src/jit/dis_x64.lua b/src/jit/dis_x64.lua index 4f491695..08918035 100644 --- a/src/jit/dis_x64.lua +++ b/src/jit/dis_x64.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT x64 disassembler wrapper module. -- --- Copyright (C) 2005-2014 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 diff --git a/src/jit/dis_x86.lua b/src/jit/dis_x86.lua index 0b865ab6..74d0f529 100644 --- a/src/jit/dis_x86.lua +++ b/src/jit/dis_x86.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT x86/x64 disassembler module. -- --- Copyright (C) 2005-2014 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. diff --git a/src/jit/dump.lua b/src/jit/dump.lua index 556ce883..666ba438 100644 --- a/src/jit/dump.lua +++ b/src/jit/dump.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT compiler dump module. -- --- Copyright (C) 2005-2014 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 ---------------------------------------------------------------------------- -- @@ -55,7 +55,7 @@ -- Cache some library functions and objects. local jit = require("jit") -assert(jit.version_num == 20003, "LuaJIT core/library version mismatch") +assert(jit.version_num == 20005, "LuaJIT core/library version mismatch") local jutil = require("jit.util") local vmdef = require("jit.vmdef") local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc @@ -63,9 +63,9 @@ local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr local bit = require("bit") -local band, shl, shr = bit.band, bit.lshift, bit.rshift +local band, shr = bit.band, bit.rshift local sub, gsub, format = string.sub, string.gsub, string.format -local byte, char, rep = string.byte, string.char, string.rep +local byte, rep = string.byte, string.rep local type, tostring = type, tostring local stdout, stderr = io.stdout, io.stderr @@ -207,7 +207,7 @@ local colortype_ansi = { "\027[35m%s\027[m", } -local function colorize_text(s, t) +local function colorize_text(s) return s end @@ -324,7 +324,7 @@ local function formatk(tr, idx) s = format("userdata:%p", k) else s = format("[%p]", k) - if s == "[0x00000000]" then s = "NULL" end + if s == "[NULL]" then s = "NULL" end end elseif t == 21 then -- int64_t s = sub(tostring(k), 1, -3) @@ -564,6 +564,7 @@ local function dump_trace(what, tr, func, pc, otr, oex) end if dumpmode.H then out:write("\n\n") else out:write("\n") end else + if what == "flush" then symtab, nexitsym = {}, 0 end out:write("---- TRACE ", what, "\n\n") end out:flush() @@ -643,7 +644,8 @@ end local function dumpon(opt, outfile) if active then dumpoff() end - local colormode = os.getenv("COLORTERM") and "A" or "T" + local term = os.getenv("TERM") + local colormode = (term and term:match("color") or os.getenv("COLORTERM")) and "A" or "T" if opt then opt = gsub(opt, "[TAH]", function(mode) colormode = mode; return ""; end) end diff --git a/src/jit/v.lua b/src/jit/v.lua index 197e67c6..47ee3941 100644 --- a/src/jit/v.lua +++ b/src/jit/v.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- Verbose mode of the LuaJIT compiler. -- --- Copyright (C) 2005-2014 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 ---------------------------------------------------------------------------- -- @@ -59,7 +59,7 @@ -- Cache some library functions and objects. local jit = require("jit") -assert(jit.version_num == 20003, "LuaJIT core/library version mismatch") +assert(jit.version_num == 20005, "LuaJIT core/library version mismatch") local jutil = require("jit.util") local vmdef = require("jit.vmdef") local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo diff --git a/src/lib_aux.c b/src/lib_aux.c index 1b01fe07..7af1cd43 100644 --- a/src/lib_aux.c +++ b/src/lib_aux.c @@ -1,6 +1,6 @@ /* ** Auxiliary library for the Lua/C API. -** Copyright (C) 2005-2014 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 @@ -302,7 +302,7 @@ static int panic(lua_State *L) #ifdef LUAJIT_USE_SYSMALLOC -#if LJ_64 +#if LJ_64 && !defined(LUAJIT_USE_VALGRIND) #error "Must use builtin allocator for 64 bit target" #endif diff --git a/src/lib_base.c b/src/lib_base.c index 30e88f19..162bbbb2 100644 --- a/src/lib_base.c +++ b/src/lib_base.c @@ -1,6 +1,6 @@ /* ** Base and coroutine library. -** Copyright (C) 2005-2014 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 diff --git a/src/lib_bit.c b/src/lib_bit.c index 739924b0..6dffdfac 100644 --- a/src/lib_bit.c +++ b/src/lib_bit.c @@ -1,6 +1,6 @@ /* ** Bit manipulation library. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lib_bit_c diff --git a/src/lib_debug.c b/src/lib_debug.c index 97f032f1..54c3b7e2 100644 --- a/src/lib_debug.c +++ b/src/lib_debug.c @@ -1,6 +1,6 @@ /* ** Debug library. -** Copyright (C) 2005-2014 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 diff --git a/src/lib_ffi.c b/src/lib_ffi.c index e789ad6c..83483d95 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c @@ -1,6 +1,6 @@ /* ** FFI library. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lib_ffi_c @@ -136,6 +136,7 @@ static int ffi_index_meta(lua_State *L, CTState *cts, CType *ct, MMS mm) return 0; } } + copyTV(L, base, L->top); tv = L->top-1; } return lj_meta_tailcall(L, tv); @@ -192,7 +193,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) @@ -810,7 +811,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< top - L->base); + if (n > LJ_MAX_UPVAL) + lj_err_caller(L, LJ_ERR_UNPACK); + lua_pushcclosure(L, io_file_iter, n); + return 1; +} + /* -- I/O file methods ---------------------------------------------------- */ #define LJLIB_MODULE_io_method @@ -361,8 +370,7 @@ LJLIB_CF(io_method_setvbuf) LJLIB_CF(io_method_lines) { io_tofile(L); - lua_pushcclosure(L, io_file_iter, (int)(L->top - L->base)); - return 1; + return io_file_lines(L); } LJLIB_CF(io_method___gc) @@ -426,7 +434,7 @@ LJLIB_CF(io_popen) LJLIB_CF(io_tmpfile) { IOFileUD *iof = io_file_new(L); -#if LJ_TARGET_PS3 || LJ_TARGET_PS4 +#if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PSVITA iof->fp = NULL; errno = ENOSYS; #else iof->fp = tmpfile(); @@ -492,8 +500,7 @@ LJLIB_CF(io_lines) } else { /* io.lines() iterates over stdin. */ setudataV(L, L->base, IOSTDF_UD(L, GCROOT_IO_INPUT)); } - lua_pushcclosure(L, io_file_iter, (int)(L->top - L->base)); - return 1; + return io_file_lines(L); } LJLIB_CF(io_type) diff --git a/src/lib_jit.c b/src/lib_jit.c index 0fadf8b9..d2fcf21b 100644 --- a/src/lib_jit.c +++ b/src/lib_jit.c @@ -1,6 +1,6 @@ /* ** JIT library. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lib_jit_c @@ -199,6 +199,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; diff --git a/src/lib_math.c b/src/lib_math.c index 3aa5c6b0..4c708a47 100644 --- a/src/lib_math.c +++ b/src/lib_math.c @@ -1,6 +1,6 @@ /* ** Math library. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include diff --git a/src/lib_os.c b/src/lib_os.c index f62e8c8b..8c96b86c 100644 --- a/src/lib_os.c +++ b/src/lib_os.c @@ -1,13 +1,12 @@ /* ** OS library. -** Copyright (C) 2005-2014 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 */ #include -#include #include #define lib_os_c @@ -27,13 +26,17 @@ #include #endif +#if !LJ_TARGET_PSVITA +#include +#endif + /* ------------------------------------------------------------------------ */ #define LJLIB_MODULE_os LJLIB_CF(os_execute) { -#if LJ_TARGET_CONSOLE +#if LJ_NO_SYSTEM #if LJ_52 errno = ENOSYS; return luaL_fileresult(L, 0, NULL); @@ -70,7 +73,7 @@ LJLIB_CF(os_rename) LJLIB_CF(os_tmpname) { -#if LJ_TARGET_PS3 || LJ_TARGET_PS4 +#if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PSVITA lj_err_caller(L, LJ_ERR_OSUNIQF); return 0; #else @@ -254,6 +257,9 @@ LJLIB_CF(os_difftime) LJLIB_CF(os_setlocale) { +#if LJ_TARGET_PSVITA + lua_pushliteral(L, "C"); +#else GCstr *s = lj_lib_optstr(L, 1); const char *str = s ? strdata(s) : NULL; int opt = lj_lib_checkopt(L, 2, 6, @@ -265,6 +271,7 @@ LJLIB_CF(os_setlocale) else if (opt == 4) opt = LC_MONETARY; else if (opt == 6) opt = LC_ALL; lua_pushstring(L, setlocale(opt, str)); +#endif return 1; } diff --git a/src/lib_package.c b/src/lib_package.c index e3410390..01b63d63 100644 --- a/src/lib_package.c +++ b/src/lib_package.c @@ -1,6 +1,6 @@ /* ** Package library. -** Copyright (C) 2005-2014 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 diff --git a/src/lib_string.c b/src/lib_string.c index 9ec6d0c3..c1e595c9 100644 --- a/src/lib_string.c +++ b/src/lib_string.c @@ -1,6 +1,6 @@ /* ** String library. -** Copyright (C) 2005-2014 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 @@ -850,20 +850,21 @@ LJLIB_CF(string_format) } else { /* format item */ char form[MAX_FMTSPEC]; /* to store the format (`%...') */ char buff[MAX_FMTITEM]; /* to store the formatted item */ + int n = 0; if (++arg > top) luaL_argerror(L, arg, lj_obj_typename[0]); strfrmt = scanformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': - sprintf(buff, form, lj_lib_checkint(L, arg)); + n = sprintf(buff, form, lj_lib_checkint(L, arg)); break; case 'd': case 'i': addintlen(form); - sprintf(buff, form, num2intfrm(L, arg)); + n = sprintf(buff, form, num2intfrm(L, arg)); break; case 'o': case 'u': case 'x': case 'X': addintlen(form); - sprintf(buff, form, num2uintfrm(L, arg)); + n = sprintf(buff, form, num2uintfrm(L, arg)); break; case 'e': case 'E': case 'f': case 'g': case 'G': case 'a': case 'A': { TValue tv; @@ -880,10 +881,10 @@ LJLIB_CF(string_format) nbuf[len] = '\0'; for (p = form; *p < 'A' && *p != '.'; p++) ; *p++ = 's'; *p = '\0'; - sprintf(buff, form, nbuf); + n = sprintf(buff, form, nbuf); break; } - sprintf(buff, form, (double)tv.n); + n = sprintf(buff, form, (double)tv.n); break; } case 'q': @@ -902,14 +903,14 @@ LJLIB_CF(string_format) luaL_addvalue(&b); continue; } - sprintf(buff, form, strdata(str)); + n = sprintf(buff, form, strdata(str)); break; } default: lj_err_callerv(L, LJ_ERR_STRFMTO, *(strfrmt -1)); break; } - luaL_addlstring(&b, buff, strlen(buff)); + luaL_addlstring(&b, buff, n); } } luaL_pushresult(&b); diff --git a/src/lib_table.c b/src/lib_table.c index e0e8302f..b2856ee2 100644 --- a/src/lib_table.c +++ b/src/lib_table.c @@ -1,6 +1,6 @@ /* ** Table library. -** Copyright (C) 2005-2014 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 diff --git a/src/lj.supp b/src/lj.supp index 411f2617..217f7c89 100644 --- a/src/lj.supp +++ b/src/lj.supp @@ -24,3 +24,18 @@ Memcheck:Cond fun:lj_str_new } +{ + Optimized string compare + Memcheck:Addr4 + fun:str_fastcmp +} +{ + Optimized string compare + Memcheck:Addr1 + fun:str_fastcmp +} +{ + Optimized string compare + Memcheck:Cond + fun:str_fastcmp +} diff --git a/src/lj_alloc.c b/src/lj_alloc.c index f856a7a0..dc64dca9 100644 --- a/src/lj_alloc.c +++ b/src/lj_alloc.c @@ -179,23 +179,29 @@ static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) #if defined(MAP_32BIT) +#if defined(__sun__) +#define MMAP_REGION_START ((uintptr_t)0x1000) +#else /* Actually this only gives us max. 1GB in current Linux kernels. */ +#define MMAP_REGION_START ((uintptr_t)0) +#endif + static LJ_AINLINE void *CALL_MMAP(size_t size) { int olderr = errno; - void *ptr = mmap(NULL, size, MMAP_PROT, MAP_32BIT|MMAP_FLAGS, -1, 0); + void *ptr = mmap((void *)MMAP_REGION_START, size, MMAP_PROT, MAP_32BIT|MMAP_FLAGS, -1, 0); errno = olderr; return ptr; } -#elif LJ_TARGET_OSX || LJ_TARGET_PS4 || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__sun__) +#elif LJ_TARGET_OSX || LJ_TARGET_PS4 || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__sun__) || LJ_TARGET_CYGWIN /* OSX and FreeBSD mmap() use a naive first-fit linear search. ** That's perfect for us. Except that -pagezero_size must be set for OSX, ** otherwise the lower 4GB are blocked. And the 32GB RLIMIT_DATA needs ** to be reduced to 250MB on FreeBSD. */ -#if LJ_TARGET_OSX +#if LJ_TARGET_OSX || defined(__DragonFly__) #define MMAP_REGION_START ((uintptr_t)0x10000) #elif LJ_TARGET_PS4 #define MMAP_REGION_START ((uintptr_t)0x4000) @@ -232,7 +238,7 @@ static LJ_AINLINE void *CALL_MMAP(size_t size) return p; } if (p != CMFAIL) munmap(p, size); -#ifdef __sun__ +#if defined(__sun__) || defined(__DragonFly__) alloc_hint += 0x1000000; /* Need near-exhaustive linear scan. */ if (alloc_hint + size < MMAP_REGION_END) continue; #endif diff --git a/src/lj_api.c b/src/lj_api.c index bc5290b2..7b0b3f9d 100644 --- a/src/lj_api.c +++ b/src/lj_api.c @@ -1,6 +1,6 @@ /* ** Public Lua/C API. -** Copyright (C) 2005-2014 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 diff --git a/src/lj_arch.h b/src/lj_arch.h index 0196eedc..5f7e4456 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h @@ -1,6 +1,6 @@ /* ** Target architecture selection. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_ARCH_H @@ -67,9 +67,13 @@ #elif defined(__MACH__) && defined(__APPLE__) #define LUAJIT_OS LUAJIT_OS_OSX #elif (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \ - defined(__NetBSD__) || defined(__OpenBSD__)) && !defined(__ORBIS__) + defined(__NetBSD__) || defined(__OpenBSD__) || \ + defined(__DragonFly__)) && !defined(__ORBIS__) #define LUAJIT_OS LUAJIT_OS_BSD -#elif (defined(__sun__) && defined(__svr4__)) || defined(__CYGWIN__) +#elif (defined(__sun__) && defined(__svr4__)) +#define LUAJIT_OS LUAJIT_OS_POSIX +#elif defined(__CYGWIN__) +#define LJ_TARGET_CYGWIN 1 #define LUAJIT_OS LUAJIT_OS_POSIX #else #define LUAJIT_OS LUAJIT_OS_OTHER @@ -111,6 +115,11 @@ #define NULL ((void*)0) #endif +#ifdef __psp2__ +#define LJ_TARGET_PSVITA 1 +#define LJ_TARGET_CONSOLE 1 +#endif + #if _XBOX_VER >= 200 #define LJ_TARGET_XBOX360 1 #define LJ_TARGET_CONSOLE 1 @@ -127,7 +136,7 @@ #define LJ_ARCH_NAME "x86" #define LJ_ARCH_BITS 32 #define LJ_ARCH_ENDIAN LUAJIT_LE -#if LJ_TARGET_WINDOWS || __CYGWIN__ +#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN #define LJ_ABI_WIN 1 #else #define LJ_ABI_WIN 0 @@ -145,7 +154,11 @@ #define LJ_ARCH_NAME "x64" #define LJ_ARCH_BITS 64 #define LJ_ARCH_ENDIAN LUAJIT_LE -#define LJ_ABI_WIN LJ_TARGET_WINDOWS +#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN +#define LJ_ABI_WIN 1 +#else +#define LJ_ABI_WIN 0 +#endif #define LJ_TARGET_X64 1 #define LJ_TARGET_X86ORX64 1 #define LJ_TARGET_EHRETREG 0 @@ -175,7 +188,9 @@ #define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */ #define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL -#if __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH_7S__ +#if __ARM_ARCH____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 #elif __ARM_ARCH_6T2__ #define LJ_ARCH_VERSION 61 @@ -324,7 +339,7 @@ #if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE) #error "No support for PowerPC CPUs without double-precision FPU" #endif -#if defined(_LITTLE_ENDIAN) +#if defined(_LITTLE_ENDIAN) && (!defined(_BYTE_ORDER) || (_BYTE_ORDER == _LITTLE_ENDIAN)) #error "No support for little-endian PowerPC" #endif #if defined(_LP64) @@ -334,6 +349,9 @@ #if defined(__mips_soft_float) #error "No support for MIPS CPUs without FPU" #endif +#if defined(_LP64) +#error "No support for MIPS64" +#endif #endif #endif @@ -411,8 +429,16 @@ #if defined(__symbian__) #define LUAJIT_NO_EXP2 #endif +#if LJ_TARGET_CONSOLE || (LJ_TARGET_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0) +#define LJ_NO_SYSTEM 1 +#endif + +#if !defined(LUAJIT_NO_UNWIND) && __GNU_COMPACT_EH__ +/* NYI: no support for compact unwind specification, yet. */ +#define LUAJIT_NO_UNWIND 1 +#endif -#if defined(LUAJIT_NO_UNWIND) || defined(__symbian__) || LJ_TARGET_IOS || LJ_TARGET_PS3 +#if defined(LUAJIT_NO_UNWIND) || defined(__symbian__) || LJ_TARGET_IOS || LJ_TARGET_PS3 || LJ_TARGET_PS4 #define LJ_NO_UNWIND 1 #endif diff --git a/src/lj_asm.c b/src/lj_asm.c index 264649ae..dd7186f6 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -1,6 +1,6 @@ /* ** IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_asm_c @@ -353,6 +353,7 @@ static Reg ra_rematk(ASMState *as, IRRef ref) static int32_t ra_spill(ASMState *as, IRIns *ir) { int32_t slot = ir->s; + lua_assert(ir >= as->ir + REF_TRUE); if (!ra_hasspill(slot)) { if (irt_is64(ir->t)) { slot = as->evenspill; @@ -1372,6 +1373,11 @@ static void asm_head_side(ASMState *as) int pass3 = 0; IRRef i; + if (as->snapno && as->topslot > as->parent->topslot) { + /* Force snap #0 alloc to prevent register overwrite in stack check. */ + as->snapno = 0; + asm_snap_alloc(as); + } allow = asm_head_side_base(as, irp, allow); /* Scan all parent SLOADs and collect register dependencies. */ @@ -1719,6 +1725,7 @@ static void asm_setup_regsp(ASMState *as) case IR_SNEW: case IR_XSNEW: case IR_NEWREF: if (REGARG_NUMGPR < 3 && as->evenspill < 3) as->evenspill = 3; /* lj_str_new and lj_tab_newkey need 3 args. */ + /* fallthrough */ case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWI: case IR_TOSTR: ir->prev = REGSP_HINT(RID_RET); if (inloop) @@ -1744,7 +1751,7 @@ static void asm_setup_regsp(ASMState *as) #endif continue; } - /* 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); diff --git a/src/lj_asm.h b/src/lj_asm.h index f5d0159b..2819481b 100644 --- a/src/lj_asm.h +++ b/src/lj_asm.h @@ -1,6 +1,6 @@ /* ** IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_ASM_H diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h index 72f205d9..961f7e39 100644 --- a/src/lj_asm_arm.h +++ b/src/lj_asm_arm.h @@ -1,6 +1,6 @@ /* ** ARM IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Register allocator extensions --------------------------------------- */ @@ -426,7 +426,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci) { RegSet drop = RSET_SCRATCH; - int hiop = ((ir+1)->o == IR_HIOP); + int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)); if (ra_hasreg(ir->r)) rset_clear(drop, ir->r); /* Dest reg handled below. */ if (hiop && ra_hasreg((ir+1)->r)) @@ -976,7 +976,6 @@ static void asm_newref(ASMState *as, IRIns *ir) static void asm_uref(ASMState *as, IRIns *ir) { - /* NYI: Check that UREFO is still open and not aliasing a slot. */ Reg dest = ra_dest(as, ir, RSET_GPR); if (irref_isk(ir->op1)) { GCfunc *fn = ir_kfunc(IR(ir->op1)); diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index e5c67b53..76311903 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h @@ -1,6 +1,6 @@ /* ** MIPS IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Register allocator extensions --------------------------------------- */ @@ -65,10 +65,9 @@ static Reg ra_alloc2(ASMState *as, IRIns *ir, RegSet allow) static void asm_sparejump_setup(ASMState *as) { MCode *mxp = as->mcbot; - /* Assumes sizeof(MCLink) == 8. */ - if (((uintptr_t)mxp & (LJ_PAGESIZE-1)) == 8) { + if (((uintptr_t)mxp & (LJ_PAGESIZE-1)) == sizeof(MCLink)) { lua_assert(MIPSI_NOP == 0); - memset(mxp+2, 0, MIPS_SPAREJUMP*8); + memset(mxp, 0, MIPS_SPAREJUMP*2*sizeof(MCode)); mxp += MIPS_SPAREJUMP*2; lua_assert(mxp < as->mctop); lj_mcode_sync(as->mcbot, mxp); @@ -291,7 +290,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci) { RegSet drop = RSET_SCRATCH; - int hiop = ((ir+1)->o == IR_HIOP); + int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)); if ((ci->flags & CCI_NOFPRCLOBBER)) drop &= ~RSET_FPR; if (ra_hasreg(ir->r)) @@ -443,18 +442,14 @@ static void asm_conv(ASMState *as, IRIns *ir) /* y = (x ^ 0x8000000) + 2147483648.0 */ Reg left = ra_alloc1(as, lref, RSET_GPR); Reg tmp = ra_scratch(as, rset_exclude(RSET_FPR, dest)); - emit_fgh(as, irt_isfloat(ir->t) ? MIPSI_ADD_S : MIPSI_ADD_D, - dest, dest, tmp); - emit_fg(as, irt_isfloat(ir->t) ? MIPSI_CVT_S_W : MIPSI_CVT_D_W, - dest, dest); if (irt_isfloat(ir->t)) - emit_lsptr(as, MIPSI_LWC1, (tmp & 31), - (void *)lj_ir_k64_find(as->J, U64x(4f000000,4f000000)), - RSET_GPR); - else - emit_lsptr(as, MIPSI_LDC1, (tmp & 31), - (void *)lj_ir_k64_find(as->J, U64x(41e00000,00000000)), - RSET_GPR); + emit_fg(as, MIPSI_CVT_S_D, dest, dest); + /* Must perform arithmetic with doubles to keep the precision. */ + emit_fgh(as, MIPSI_ADD_D, dest, dest, tmp); + emit_fg(as, MIPSI_CVT_D_W, dest, dest); + emit_lsptr(as, MIPSI_LDC1, (tmp & 31), + (void *)lj_ir_k64_find(as->J, U64x(41e00000,00000000)), + RSET_GPR); emit_tg(as, MIPSI_MTC1, RID_TMP, dest); emit_dst(as, MIPSI_XOR, RID_TMP, RID_TMP, left); emit_ti(as, MIPSI_LUI, RID_TMP, 0x8000); @@ -793,7 +788,6 @@ static void asm_newref(ASMState *as, IRIns *ir) static void asm_uref(ASMState *as, IRIns *ir) { - /* NYI: Check that UREFO is still open and not aliasing a slot. */ Reg dest = ra_dest(as, ir, RSET_GPR); if (irref_isk(ir->op1)) { GCfunc *fn = ir_kfunc(IR(ir->op1)); @@ -1938,7 +1932,11 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) MCode tjump = MIPSI_J|(((uintptr_t)target>>2)&0x03ffffffu); for (p++; p < pe; p++) { if (*p == exitload) { /* Look for load of exit number. */ - if (((p[-1] ^ (px-p)) & 0xffffu) == 0) { /* Look for exitstub branch. */ + /* Look for exitstub branch. Yes, this covers all used branch variants. */ + if (((p[-1] ^ (px-p)) & 0xffffu) == 0 && + ((p[-1] & 0xf0000000u) == MIPSI_BEQ || + (p[-1] & 0xfc1e0000u) == MIPSI_BLTZ || + (p[-1] & 0xffe00000u) == MIPSI_BC1F)) { ptrdiff_t delta = target - p; if (((delta + 0x8000) >> 16) == 0) { /* Patch in-range branch. */ patchbranch: @@ -1948,7 +1946,9 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) if (!cstart) cstart = p-1; } else { /* Branch out of range. Use spare jump slot in mcarea. */ int i; - for (i = 2; i < 2+MIPS_SPAREJUMP*2; i += 2) { + for (i = (int)(sizeof(MCLink)/sizeof(MCode)); + i < (int)(sizeof(MCLink)/sizeof(MCode)+MIPS_SPAREJUMP*2); + i += 2) { if (mcarea[i] == tjump) { delta = mcarea+i - p; goto patchbranch; diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h index e1a496a7..d8a14c83 100644 --- a/src/lj_asm_ppc.h +++ b/src/lj_asm_ppc.h @@ -1,6 +1,6 @@ /* ** PPC IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Register allocator extensions --------------------------------------- */ @@ -49,6 +49,8 @@ static void asm_exitstub_setup(ASMState *as, ExitNo nexits) { ExitNo i; MCode *mxp = as->mctop; + if (mxp - (nexits + 3 + MCLIM_REDZONE) < as->mclim) + asm_mclimit(as); /* 1: mflr r0; bl ->vm_exit_handler; li r0, traceno; bl <1; bl <1; ... */ for (i = nexits-1; (int32_t)i >= 0; i--) *--mxp = PPCI_BL|(((-3-i)&0x00ffffffu)<<2); @@ -296,7 +298,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci) { RegSet drop = RSET_SCRATCH; - int hiop = ((ir+1)->o == IR_HIOP); + int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)); if ((ci->flags & CCI_NOFPRCLOBBER)) drop &= ~RSET_FPR; if (ra_hasreg(ir->r)) @@ -787,7 +789,6 @@ static void asm_newref(ASMState *as, IRIns *ir) static void asm_uref(ASMState *as, IRIns *ir) { - /* NYI: Check that UREFO is still open and not aliasing a slot. */ Reg dest = ra_dest(as, ir, RSET_GPR); if (irref_isk(ir->op1)) { GCfunc *fn = ir_kfunc(IR(ir->op1)); diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index fda911e5..10468bb7 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h @@ -1,6 +1,6 @@ /* ** x86/x64 IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Guard handling ------------------------------------------------------ */ @@ -325,6 +325,14 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow) as->mrm.base = as->mrm.idx = RID_NONE; return RID_MRM; } + } else if (ref == REF_BASE || ir->o == IR_KINT64) { + RegSet avail = as->freeset & ~as->modset & RSET_GPR; + lua_assert(allow != RSET_EMPTY); + if (!(avail & (avail-1))) { /* Fuse if less than two regs available. */ + as->mrm.ofs = ptr2addr(ref == REF_BASE ? (void *)&J2G(as->J)->jit_base : (void *)ir_kint64(ir)); + as->mrm.base = as->mrm.idx = RID_NONE; + return RID_MRM; + } } else if (mayfuse(as, ref)) { RegSet xallow = (allow & RSET_GPR) ? allow : RSET_GPR; if (ir->o == IR_SLOAD) { @@ -361,7 +369,7 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow) return RID_MRM; } } - if (!(as->freeset & allow) && + if (!(as->freeset & allow) && !emit_canremat(ref) && (allow == RSET_EMPTY || ra_hasspill(ir->s) || iscrossref(as, ref))) goto fusespill; return ra_allocref(as, ref, allow); @@ -523,7 +531,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci) { RegSet drop = RSET_SCRATCH; - int hiop = (LJ_32 && (ir+1)->o == IR_HIOP); + int hiop = (LJ_32 && (ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)); if ((ci->flags & CCI_NOFPRCLOBBER)) drop &= ~RSET_FPR; if (ra_hasreg(ir->r)) @@ -571,7 +579,7 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci) lua_assert(!irt_ispri(ir->t)); ra_destreg(as, ir, RID_RET); } - } else if (LJ_32 && irt_isfp(ir->t)) { + } else if (LJ_32 && irt_isfp(ir->t) && !(ci->flags & CCI_CASTU64)) { emit_x87op(as, XI_FPOP); /* Pop unused result from x87 st0. */ } } @@ -1207,7 +1215,6 @@ static void asm_newref(ASMState *as, IRIns *ir) static void asm_uref(ASMState *as, IRIns *ir) { - /* NYI: Check that UREFO is still open and not aliasing a slot. */ Reg dest = ra_dest(as, ir, RSET_GPR); if (irref_isk(ir->op1)) { GCfunc *fn = ir_kfunc(IR(ir->op1)); @@ -1828,8 +1835,12 @@ static void asm_intarith(ASMState *as, IRIns *ir, x86Arith xa) Reg dest, right; int32_t k = 0; if (as->flagmcp == as->mcp) { /* Drop test r,r instruction. */ - as->flagmcp = NULL; - as->mcp += (LJ_64 && *as->mcp < XI_TESTb) ? 3 : 2; + MCode *p = as->mcp + ((LJ_64 && *as->mcp < XI_TESTb) ? 3 : 2); + if ((p[1] & 15) < 14) { + if ((p[1] & 15) >= 12) p[1] -= 4; /* L <->S, NL <-> NS */ + as->flagmcp = NULL; + as->mcp = p; + } /* else: cannot transform LE/NLE to cc without use of OF. */ } right = IR(rref)->r; if (ra_hasreg(right)) { @@ -2764,6 +2775,106 @@ static void asm_setup_target(ASMState *as) /* -- Trace patching ------------------------------------------------------ */ +static const uint8_t map_op1[256] = { +0x92,0x92,0x92,0x92,0x52,0x45,0x51,0x51,0x92,0x92,0x92,0x92,0x52,0x45,0x51,0x20, +0x92,0x92,0x92,0x92,0x52,0x45,0x51,0x51,0x92,0x92,0x92,0x92,0x52,0x45,0x51,0x51, +0x92,0x92,0x92,0x92,0x52,0x45,0x10,0x51,0x92,0x92,0x92,0x92,0x52,0x45,0x10,0x51, +0x92,0x92,0x92,0x92,0x52,0x45,0x10,0x51,0x92,0x92,0x92,0x92,0x52,0x45,0x10,0x51, +#if LJ_64 +0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14, +#else +0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51, +#endif +0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51, +0x51,0x51,0x92,0x92,0x10,0x10,0x12,0x11,0x45,0x86,0x52,0x93,0x51,0x51,0x51,0x51, +0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, +0x93,0x86,0x93,0x93,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92, +0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x47,0x51,0x51,0x51,0x51,0x51, +#if LJ_64 +0x59,0x59,0x59,0x59,0x51,0x51,0x51,0x51,0x52,0x45,0x51,0x51,0x51,0x51,0x51,0x51, +#else +0x55,0x55,0x55,0x55,0x51,0x51,0x51,0x51,0x52,0x45,0x51,0x51,0x51,0x51,0x51,0x51, +#endif +0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05, +0x93,0x93,0x53,0x51,0x70,0x71,0x93,0x86,0x54,0x51,0x53,0x51,0x51,0x52,0x51,0x51, +0x92,0x92,0x92,0x92,0x52,0x52,0x51,0x51,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92, +0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x45,0x45,0x47,0x52,0x51,0x51,0x51,0x51, +0x10,0x51,0x10,0x10,0x51,0x51,0x63,0x66,0x51,0x51,0x51,0x51,0x51,0x51,0x92,0x92 +}; + +static const uint8_t map_op2[256] = { +0x93,0x93,0x93,0x93,0x52,0x52,0x52,0x52,0x52,0x52,0x51,0x52,0x51,0x93,0x52,0x94, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x53,0x53,0x53,0x53,0x53,0x53,0x53,0x53,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x34,0x51,0x35,0x51,0x51,0x51,0x51,0x51, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x53,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x94,0x54,0x54,0x54,0x93,0x93,0x93,0x52,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x52,0x52,0x52,0x93,0x94,0x93,0x51,0x51,0x52,0x52,0x52,0x93,0x94,0x93,0x93,0x93, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x94,0x93,0x93,0x93,0x93,0x93, +0x93,0x93,0x94,0x93,0x94,0x94,0x94,0x93,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, +0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x52 +}; + +static uint32_t asm_x86_inslen(const uint8_t* p) +{ + uint32_t result = 0; + uint32_t prefixes = 0; + uint32_t x = map_op1[*p]; + for (;;) { + switch (x >> 4) { + case 0: return result + x + (prefixes & 4); + case 1: prefixes |= x; x = map_op1[*++p]; result++; break; + case 2: x = map_op2[*++p]; break; + case 3: p++; goto mrm; + case 4: result -= (prefixes & 2); /* fallthrough */ + case 5: return result + (x & 15); + case 6: /* Group 3. */ + if (p[1] & 0x38) x = 2; + else if ((prefixes & 2) && (x == 0x66)) x = 4; + goto mrm; + case 7: /* VEX c4/c5. */ + if (LJ_32 && p[1] < 0xc0) { + x = 2; + goto mrm; + } + if (x == 0x70) { + x = *++p & 0x1f; + result++; + if (x >= 2) { + p += 2; + result += 2; + goto mrm; + } + } + p++; + result++; + x = map_op2[*++p]; + break; + case 8: result -= (prefixes & 2); /* fallthrough */ + case 9: mrm: /* ModR/M and possibly SIB. */ + result += (x & 15); + x = *++p; + switch (x >> 6) { + case 0: if ((x & 7) == 5) return result + 4; break; + case 1: result++; break; + case 2: result += 4; break; + case 3: return result; + } + if ((x & 7) == 4) { + result++; + if (x < 0x40 && (p[1] & 7) == 5) result += 4; + } + return result; + } + } +} + /* Patch exit jumps of existing machine code to a new target. */ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) { @@ -2776,18 +2887,13 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) if (len > 5 && p[len-5] == XI_JMP && p+len-6 + *(int32_t *)(p+len-4) == px) *(int32_t *)(p+len-4) = jmprel(p+len, target); /* Do not patch parent exit for a stack check. Skip beyond vmstate update. */ - for (; p < pe; p++) - if (*(uint32_t *)(p+(LJ_64 ? 3 : 2)) == stateaddr && p[0] == XI_MOVmi) { - p += LJ_64 ? 11 : 10; + for (; p < pe; p += asm_x86_inslen(p)) + if (*(uint32_t *)(p+(LJ_64 ? 3 : 2)) == stateaddr && p[0] == XI_MOVmi) break; - } lua_assert(p < pe); - for (; p < pe; p++) { - if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px) { + for (; p < pe; p += asm_x86_inslen(p)) + if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px) *(int32_t *)(p+2) = jmprel(p+6, target); - p += 5; - } - } lj_mcode_sync(T->mcode, T->mcode + T->szmcode); lj_mcode_patch(J, mcarea, 1); } diff --git a/src/lj_bc.c b/src/lj_bc.c index d5d3d78d..a597692c 100644 --- a/src/lj_bc.c +++ b/src/lj_bc.c @@ -1,6 +1,6 @@ /* ** Bytecode instruction modes. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_bc_c diff --git a/src/lj_bc.h b/src/lj_bc.h index 1a4ade31..108c10f2 100644 --- a/src/lj_bc.h +++ b/src/lj_bc.h @@ -1,6 +1,6 @@ /* ** Bytecode instruction format. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_BC_H diff --git a/src/lj_bcdump.h b/src/lj_bcdump.h index 77a789e9..ba53c0a1 100644 --- a/src/lj_bcdump.h +++ b/src/lj_bcdump.h @@ -1,6 +1,6 @@ /* ** Bytecode dump definitions. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_BCDUMP_H diff --git a/src/lj_bcread.c b/src/lj_bcread.c index c0baece4..6a462bd6 100644 --- a/src/lj_bcread.c +++ b/src/lj_bcread.c @@ -1,6 +1,6 @@ /* ** Bytecode reader. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_bcread_c diff --git a/src/lj_bcwrite.c b/src/lj_bcwrite.c index dcdaa10a..fae1ebb3 100644 --- a/src/lj_bcwrite.c +++ b/src/lj_bcwrite.c @@ -1,6 +1,6 @@ /* ** Bytecode writer. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_bcwrite_c diff --git a/src/lj_carith.c b/src/lj_carith.c index 9f94091d..c34596ca 100644 --- a/src/lj_carith.c +++ b/src/lj_carith.c @@ -1,6 +1,6 @@ /* ** C data arithmetic. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -62,7 +62,7 @@ static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca) TValue *o2 = i == 0 ? o+1 : o-1; CType *ct = ctype_raw(cts, cdataV(o2)->ctypeid); ca->ct[i] = NULL; - ca->p[i] = NULL; + ca->p[i] = (uint8_t *)strVdata(o); ok = 0; if (ctype_isenum(ct->info)) { CTSize ofs; @@ -79,7 +79,7 @@ static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca) } } else { ca->ct[i] = NULL; - ca->p[i] = NULL; + ca->p[i] = (void *)(intptr_t)1; /* To make it unequal. */ ok = 0; } } @@ -234,7 +234,9 @@ static int lj_carith_meta(lua_State *L, CTState *cts, CDArith *ca, MMS mm) const char *repr[2]; int i, isenum = -1, isstr = -1; if (mm == MM_eq) { /* Equality checks never raise an error. */ - setboolV(L->top-1, 0); + int eq = ca->p[0] == ca->p[1]; + setboolV(L->top-1, eq); + setboolV(&G(L)->tmptv2, eq); /* Remember for trace recorder. */ return 1; } for (i = 0; i < 2; i++) { @@ -270,6 +272,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 integer arithmetic helpers ----------------------------------- */ #if LJ_32 && LJ_HASJIT diff --git a/src/lj_carith.h b/src/lj_carith.h index 8b28556d..82fc8245 100644 --- a/src/lj_carith.h +++ b/src/lj_carith.h @@ -1,6 +1,6 @@ /* ** C data arithmetic. -** Copyright (C) 2005-2014 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_HASJIT LJ_FUNC int64_t lj_carith_mul64(int64_t x, int64_t k); diff --git a/src/lj_ccall.c b/src/lj_ccall.c index 70c9ba5e..65076e77 100644 --- a/src/lj_ccall.c +++ b/src/lj_ccall.c @@ -1,6 +1,6 @@ /* ** FFI C call handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" diff --git a/src/lj_ccall.h b/src/lj_ccall.h index c3ea9e6f..9089e6c7 100644 --- a/src/lj_ccall.h +++ b/src/lj_ccall.h @@ -1,6 +1,6 @@ /* ** FFI C call handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CCALL_H diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c index d872d671..06a74019 100644 --- a/src/lj_ccallback.c +++ b/src/lj_ccallback.c @@ -1,6 +1,6 @@ /* ** FFI C callback handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" diff --git a/src/lj_ccallback.h b/src/lj_ccallback.h index 45b5ff02..a8cdad38 100644 --- a/src/lj_ccallback.h +++ b/src/lj_ccallback.h @@ -1,6 +1,6 @@ /* ** FFI C callback handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CCALLBACK_H diff --git a/src/lj_cconv.c b/src/lj_cconv.c index de4938e4..ab398adc 100644 --- a/src/lj_cconv.c +++ b/src/lj_cconv.c @@ -1,6 +1,6 @@ /* ** C type conversions. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -702,6 +702,7 @@ static void cconv_substruct_init(CTState *cts, CType *d, uint8_t *dp, } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) { cconv_substruct_init(cts, ctype_rawchild(cts, df), dp+df->size, o, len, ip); + if ((d->info & CTF_UNION)) break; } /* Ignore all other entries in the chain. */ } } diff --git a/src/lj_cconv.h b/src/lj_cconv.h index 17e0f050..0a0b66c9 100644 --- a/src/lj_cconv.h +++ b/src/lj_cconv.h @@ -1,6 +1,6 @@ /* ** C type conversions. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CCONV_H diff --git a/src/lj_cdata.c b/src/lj_cdata.c index 590ddf10..49b1aa50 100644 --- a/src/lj_cdata.c +++ b/src/lj_cdata.c @@ -1,6 +1,6 @@ /* ** C data management. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -127,16 +127,16 @@ CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, uint8_t **pp, integer_key: if (ctype_ispointer(ct->info)) { CTSize sz = lj_ctype_size(cts, ctype_cid(ct->info)); /* Element size. */ - if (sz != CTSIZE_INVALID) { - if (ctype_isptr(ct->info)) { - p = (uint8_t *)cdata_getptr(p, ct->size); - } else if ((ct->info & (CTF_VECTOR|CTF_COMPLEX))) { - if ((ct->info & CTF_COMPLEX)) idx &= 1; - *qual |= CTF_CONST; /* Valarray elements are constant. */ - } - *pp = p + idx*(int32_t)sz; - return ct; + if (sz == CTSIZE_INVALID) + lj_err_caller(cts->L, LJ_ERR_FFI_INVSIZE); + if (ctype_isptr(ct->info)) { + p = (uint8_t *)cdata_getptr(p, ct->size); + } else if ((ct->info & (CTF_VECTOR|CTF_COMPLEX))) { + if ((ct->info & CTF_COMPLEX)) idx &= 1; + *qual |= CTF_CONST; /* Valarray elements are constant. */ } + *pp = p + idx*(int32_t)sz; + return ct; } } else if (tviscdata(key)) { /* Integer cdata key. */ GCcdata *cdk = cdataV(key); diff --git a/src/lj_cdata.h b/src/lj_cdata.h index 6c8e7a1a..4bb65db2 100644 --- a/src/lj_cdata.h +++ b/src/lj_cdata.h @@ -1,6 +1,6 @@ /* ** C data management. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CDATA_H diff --git a/src/lj_clib.c b/src/lj_clib.c index ccb99e55..8dc3c10e 100644 --- a/src/lj_clib.c +++ b/src/lj_clib.c @@ -1,6 +1,6 @@ /* ** FFI C library loader. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -39,7 +39,7 @@ LJ_NORET LJ_NOINLINE static void clib_error_(lua_State *L) #define clib_error(L, fmt, name) clib_error_(L) -#if defined(__CYGWIN__) +#if LJ_TARGET_CYGWIN #define CLIB_SOPREFIX "cyg" #else #define CLIB_SOPREFIX "lib" @@ -47,7 +47,7 @@ LJ_NORET LJ_NOINLINE static void clib_error_(lua_State *L) #if LJ_TARGET_OSX #define CLIB_SOEXT "%s.dylib" -#elif defined(__CYGWIN__) +#elif LJ_TARGET_CYGWIN #define CLIB_SOEXT "%s.dll" #else #define CLIB_SOEXT "%s.so" @@ -56,14 +56,14 @@ LJ_NORET LJ_NOINLINE static void clib_error_(lua_State *L) static const char *clib_extname(lua_State *L, const char *name) { if (!strchr(name, '/') -#ifdef __CYGWIN__ +#if LJ_TARGET_CYGWIN && !strchr(name, '\\') #endif ) { if (!strchr(name, '.')) { name = lj_str_pushf(L, CLIB_SOEXT, name); L->top--; -#ifdef __CYGWIN__ +#if LJ_TARGET_CYGWIN } else { return name; #endif diff --git a/src/lj_clib.h b/src/lj_clib.h index 47373288..fcc9dac5 100644 --- a/src/lj_clib.h +++ b/src/lj_clib.h @@ -1,6 +1,6 @@ /* ** FFI C library loader. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CLIB_H diff --git a/src/lj_cparse.c b/src/lj_cparse.c index 6ffe16a2..f111537d 100644 --- a/src/lj_cparse.c +++ b/src/lj_cparse.c @@ -1,6 +1,6 @@ /* ** C declaration parser. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -310,13 +310,17 @@ static CPToken cp_next_(CPState *cp) else return '/'; break; case '|': - if (cp_get(cp) != '|') return '|'; cp_get(cp); return CTOK_OROR; + if (cp_get(cp) != '|') return '|'; + cp_get(cp); return CTOK_OROR; case '&': - if (cp_get(cp) != '&') return '&'; cp_get(cp); return CTOK_ANDAND; + if (cp_get(cp) != '&') return '&'; + cp_get(cp); return CTOK_ANDAND; case '=': - if (cp_get(cp) != '=') return '='; cp_get(cp); return CTOK_EQ; + if (cp_get(cp) != '=') return '='; + cp_get(cp); return CTOK_EQ; case '!': - if (cp_get(cp) != '=') return '!'; cp_get(cp); return CTOK_NE; + if (cp_get(cp) != '=') return '!'; + cp_get(cp); return CTOK_NE; case '<': if (cp_get(cp) == '=') { cp_get(cp); return CTOK_LE; } else if (cp->c == '<') { cp_get(cp); return CTOK_SHL; } @@ -326,7 +330,8 @@ static CPToken cp_next_(CPState *cp) else if (cp->c == '>') { cp_get(cp); return CTOK_SHR; } return '>'; case '-': - if (cp_get(cp) != '>') return '-'; cp_get(cp); return CTOK_DEREF; + if (cp_get(cp) != '>') return '-'; + cp_get(cp); return CTOK_DEREF; case '$': return cp_param(cp); case '\0': return CTOK_EOF; @@ -585,28 +590,34 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri) k->id = k2.id > k3.id ? k2.id : k3.id; continue; } + /* fallthrough */ case 1: if (cp_opt(cp, CTOK_OROR)) { cp_expr_sub(cp, &k2, 2); k->i32 = k->u32 || k2.u32; k->id = CTID_INT32; continue; } + /* fallthrough */ case 2: if (cp_opt(cp, CTOK_ANDAND)) { cp_expr_sub(cp, &k2, 3); k->i32 = k->u32 && k2.u32; k->id = CTID_INT32; continue; } + /* fallthrough */ case 3: if (cp_opt(cp, '|')) { cp_expr_sub(cp, &k2, 4); k->u32 = k->u32 | k2.u32; goto arith_result; } + /* fallthrough */ case 4: if (cp_opt(cp, '^')) { cp_expr_sub(cp, &k2, 5); k->u32 = k->u32 ^ k2.u32; goto arith_result; } + /* fallthrough */ case 5: if (cp_opt(cp, '&')) { cp_expr_sub(cp, &k2, 6); k->u32 = k->u32 & k2.u32; goto arith_result; } + /* fallthrough */ case 6: if (cp_opt(cp, CTOK_EQ)) { cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 == k2.u32; k->id = CTID_INT32; @@ -615,6 +626,7 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri) cp_expr_sub(cp, &k2, 7); k->i32 = k->u32 != k2.u32; k->id = CTID_INT32; continue; } + /* fallthrough */ case 7: if (cp_opt(cp, '<')) { cp_expr_sub(cp, &k2, 8); @@ -649,6 +661,7 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri) k->id = CTID_INT32; continue; } + /* fallthrough */ case 8: if (cp_opt(cp, CTOK_SHL)) { cp_expr_sub(cp, &k2, 9); k->u32 = k->u32 << k2.u32; @@ -661,6 +674,7 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri) k->u32 = k->u32 >> k2.u32; continue; } + /* fallthrough */ case 9: if (cp_opt(cp, '+')) { cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 + k2.u32; @@ -670,6 +684,7 @@ static void cp_expr_infix(CPState *cp, CPValue *k, int pri) } else if (cp_opt(cp, '-')) { cp_expr_sub(cp, &k2, 10); k->u32 = k->u32 - k2.u32; goto arith_result; } + /* fallthrough */ case 10: if (cp_opt(cp, '*')) { cp_expr_unary(cp, &k2); k->u32 = k->u32 * k2.u32; goto arith_result; @@ -798,6 +813,10 @@ static void cp_push_type(CPDecl *decl, CTypeID id) cp_push(decl, info & ~CTMASK_CID, size); /* Copy type. */ break; case CT_ARRAY: + if ((ct->info & (CTF_VECTOR|CTF_COMPLEX))) { + info |= (decl->attr & CTF_QUAL); + decl->attr &= ~CTF_QUAL; + } cp_push_type(decl, ctype_cid(info)); /* Unroll. */ cp_push(decl, info & ~CTMASK_CID, size); /* Copy type. */ decl->stack[decl->pos].sib = 1; /* Mark as already checked and sized. */ diff --git a/src/lj_cparse.h b/src/lj_cparse.h index 586f4945..bad1060b 100644 --- a/src/lj_cparse.h +++ b/src/lj_cparse.h @@ -1,6 +1,6 @@ /* ** C declaration parser. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CPARSE_H diff --git a/src/lj_crecord.c b/src/lj_crecord.c index da9013f0..bc88d635 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -1,6 +1,6 @@ /* ** Trace recorder for C data operations. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_ffrecord_c @@ -794,7 +794,7 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) } } else if (tref_isstr(idx)) { GCstr *name = strV(&rd->argv[1]); - if (cd->ctypeid == CTID_CTYPEID) + if (cd && cd->ctypeid == CTID_CTYPEID) ct = ctype_raw(cts, crec_constructor(J, cd, ptr)); if (ctype_isstruct(ct->info)) { CTSize fofs; @@ -835,6 +835,7 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) CType *cct = ctype_rawchild(cts, ct); if (ctype_isstruct(cct->info)) { ct = cct; + cd = NULL; if (tref_isstr(idx)) goto again; } } @@ -847,8 +848,11 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) /* Resolve reference for field. */ ct = ctype_get(cts, sid); - if (ctype_isref(ct->info)) + if (ctype_isref(ct->info)) { ptr = emitir(IRT(IR_XLOAD, IRT_PTR), ptr, 0); + sid = ctype_cid(ct->info); + ct = ctype_get(cts, sid); + } while (ctype_isattrib(ct->info)) ct = ctype_child(cts, ct); /* Skip attributes. */ @@ -1201,7 +1205,7 @@ void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd) static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm) { - if (ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) { + if (sp[0] && sp[1] && ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) { IRType dt; CTypeID id; TRef tr; @@ -1259,6 +1263,7 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm) { CTState *cts = ctype_ctsG(J2G(J)); CType *ctp = s[0]; + if (!(sp[0] && sp[1])) return 0; if (ctype_isptr(ctp->info) || ctype_isrefarray(ctp->info)) { if ((mm == MM_sub || mm == MM_eq || mm == MM_lt || mm == MM_le) && (ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) { @@ -1317,7 +1322,8 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm) } /* Record ctype arithmetic metamethods. */ -static void crec_arith_meta(jit_State *J, CTState *cts, RecordFFData *rd) +static TRef crec_arith_meta(jit_State *J, TRef *sp, CType **s, CTState *cts, + RecordFFData *rd) { cTValue *tv = NULL; if (J->base[0]) { @@ -1338,13 +1344,20 @@ static void crec_arith_meta(jit_State *J, CTState *cts, RecordFFData *rd) if (tvisfunc(tv)) { J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; rd->nres = -1; /* Pending tailcall. */ - return; + return 0; } /* NYI: non-function metamethods. */ - } else if ((MMS)rd->data == MM_eq) { - J->base[0] = TREF_FALSE; - return; + } else if ((MMS)rd->data == MM_eq) { /* Fallback cdata pointer comparison. */ + if (sp[0] && sp[1] && ctype_isnum(s[0]->info) == ctype_isnum(s[1]->info)) { + /* Assume true comparison. Fixup and emit pending guard later. */ + lj_ir_set(J, IRTG(IR_EQ, IRT_PTR), sp[0], sp[1]); + J->postproc = LJ_POST_FIXGUARD; + return TREF_TRUE; + } else { + return TREF_FALSE; + } } lj_trace_err(J, LJ_TRERR_BADTYPE); + return 0; } void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) @@ -1357,7 +1370,7 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) TRef tr = J->base[i]; CType *ct = ctype_get(cts, CTID_DOUBLE); if (!tr) { - goto trymeta; + lj_trace_err(J, LJ_TRERR_BADTYPE); } else if (tref_iscdata(tr)) { CTypeID id = argv2cdata(J, tr, &rd->argv[i])->ctypeid; IRType t; @@ -1387,11 +1400,12 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) } if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct); if (ctype_isnum(ct->info)) { - if (t == IRT_CDATA) goto trymeta; - if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); - tr = emitir(IRT(IR_XLOAD, t), tr, 0); - } else if (!(ctype_isptr(ct->info) || ctype_isrefarray(ct->info))) { - goto trymeta; + if (t == IRT_CDATA) { + tr = 0; + } else { + if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); + tr = emitir(IRT(IR_XLOAD, t), tr, 0); + } } } else if (tref_isnil(tr)) { tr = lj_ir_kptr(J, NULL); @@ -1411,10 +1425,17 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, str)); ct = ctype_child(cts, cct); tr = lj_ir_kint(J, (int32_t)ofs); - } /* else: interpreter will throw. */ - } /* else: interpreter will throw. */ + } else { /* Interpreter will throw or return false. */ + ct = ctype_get(cts, CTID_P_VOID); + } + } else if (ctype_isptr(ct->info)) { + tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCstr))); + } else { + ct = ctype_get(cts, CTID_P_VOID); + } } else if (!tref_isnum(tr)) { - goto trymeta; + tr = 0; + ct = ctype_get(cts, CTID_P_VOID); } ok: s[i] = ct; @@ -1422,22 +1443,20 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) } { TRef tr; - if ((tr = crec_arith_int64(J, sp, s, (MMS)rd->data)) || - (tr = crec_arith_ptr(J, sp, s, (MMS)rd->data))) { - J->base[0] = tr; - /* Fixup cdata comparisons, too. Avoids some cdata escapes. */ - if (J->postproc == LJ_POST_FIXGUARD && frame_iscont(J->L->base-1) && - !irt_isguard(J->guardemit)) { - const BCIns *pc = frame_contpc(J->L->base-1) - 1; - if (bc_op(*pc) <= BC_ISNEP) { - setframe_pc(&J2G(J)->tmptv, pc); - J2G(J)->tmptv.u32.lo = ((tref_istrue(tr) ^ bc_op(*pc)) & 1); - J->postproc = LJ_POST_FIXCOMP; - } + if (!(tr = crec_arith_int64(J, sp, s, (MMS)rd->data)) && + !(tr = crec_arith_ptr(J, sp, s, (MMS)rd->data)) && + !(tr = crec_arith_meta(J, sp, s, cts, rd))) + return; + J->base[0] = tr; + /* Fixup cdata comparisons, too. Avoids some cdata escapes. */ + if (J->postproc == LJ_POST_FIXGUARD && frame_iscont(J->L->base-1) && + !irt_isguard(J->guardemit)) { + const BCIns *pc = frame_contpc(J->L->base-1) - 1; + if (bc_op(*pc) <= BC_ISNEP) { + setframe_pc(&J2G(J)->tmptv, pc); + J2G(J)->tmptv.u32.lo = ((tref_istrue(tr) ^ bc_op(*pc)) & 1); + J->postproc = LJ_POST_FIXCOMP; } - } else { - trymeta: - crec_arith_meta(J, cts, rd); } } } @@ -1642,6 +1661,8 @@ void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) d = ctype_get(cts, CTID_DOUBLE); J->base[0] = crec_ct_tv(J, d, 0, J->base[0], &rd->argv[0]); } else { + /* Specialize to the ctype that couldn't be converted. */ + argv2cdata(J, J->base[0], &rd->argv[0]); J->base[0] = TREF_NIL; } } diff --git a/src/lj_crecord.h b/src/lj_crecord.h index fb77ca60..8e0afd18 100644 --- a/src/lj_crecord.h +++ b/src/lj_crecord.h @@ -1,6 +1,6 @@ /* ** Trace recorder for C data operations. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CRECORD_H diff --git a/src/lj_ctype.c b/src/lj_ctype.c index e9fe0943..9417500c 100644 --- a/src/lj_ctype.c +++ b/src/lj_ctype.c @@ -1,6 +1,6 @@ /* ** C type management. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" diff --git a/src/lj_ctype.h b/src/lj_ctype.h index ff8ee069..2aefd3b6 100644 --- a/src/lj_ctype.h +++ b/src/lj_ctype.h @@ -1,6 +1,6 @@ /* ** C type management. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CTYPE_H @@ -42,18 +42,18 @@ LJ_STATIC_ASSERT(((int)CT_STRUCT & (int)CT_ARRAY) == CT_STRUCT); ** ---------- info ------------ ** |type flags... A cid | size | sib | next | name | ** +----------------------------+--------+-------+-------+-------+-- -** |NUM BFvcUL.. A | size | | type | | -** |STRUCT ..vcU..V A | size | field | name? | name? | -** |PTR ..vcR... A cid | size | | type | | -** |ARRAY VCvc...V A cid | size | | type | | -** |VOID ..vc.... A | size | | type | | +** |NUM BFcvUL.. A | size | | type | | +** |STRUCT ..cvU..V A | size | field | name? | name? | +** |PTR ..cvR... A cid | size | | type | | +** |ARRAY VCcv...V A cid | size | | type | | +** |VOID ..cv.... A | size | | type | | ** |ENUM A cid | size | const | name? | name? | ** |FUNC ....VS.. cc cid | nargs | field | name? | name? | ** |TYPEDEF cid | | | name | name | ** |ATTRIB attrnum cid | attr | sib? | type? | | ** |FIELD cid | offset | field | | name? | -** |BITFIELD B.vcU csz bsz pos | offset | field | | name? | -** |CONSTVAL c cid | value | const | name | name | +** |BITFIELD B.cvU csz bsz pos | offset | field | | name? | +** |CONSTVAL c cid | value | const | name | name | ** |EXTERN cid | | sib? | name | name | ** |KW tok | size | | name | name | ** +----------------------------+--------+-------+-------+-------+-- diff --git a/src/lj_debug.c b/src/lj_debug.c index 4653a4ec..a684302c 100644 --- a/src/lj_debug.c +++ b/src/lj_debug.c @@ -1,6 +1,6 @@ /* ** Debugging and introspection. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_debug_c @@ -14,6 +14,7 @@ #include "lj_state.h" #include "lj_frame.h" #include "lj_bc.h" +#include "lj_vm.h" #if LJ_HASJIT #include "lj_jit.h" #endif @@ -86,7 +87,8 @@ static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe) if (frame_islua(f)) { f = frame_prevl(f); } else { - if (frame_isc(f)) + if (frame_isc(f) || (LJ_HASFFI && frame_iscont(f) && + (f-1)->u32.lo == LJ_CONT_FFI_CALLBACK)) cf = cframe_raw(cframe_prev(cf)); f = frame_prevd(f); } @@ -463,7 +465,7 @@ int lj_debug_getinfo(lua_State *L, const char *what, lj_Debug *ar, int ext) lj_debug_shortname(ar->short_src, name); ar->linedefined = (int)firstline; ar->lastlinedefined = (int)(firstline + pt->numline); - ar->what = firstline ? "Lua" : "main"; + ar->what = (firstline || !pt->numline) ? "Lua" : "main"; } else { ar->source = "=[C]"; ar->short_src[0] = '['; diff --git a/src/lj_debug.h b/src/lj_debug.h index bec6b4f3..d10d0da2 100644 --- a/src/lj_debug.h +++ b/src/lj_debug.h @@ -1,6 +1,6 @@ /* ** Debugging and introspection. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_DEBUG_H diff --git a/src/lj_def.h b/src/lj_def.h index 3c43be78..21cc59a4 100644 --- a/src/lj_def.h +++ b/src/lj_def.h @@ -1,6 +1,6 @@ /* ** LuaJIT common internal definitions. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_DEF_H @@ -111,7 +111,7 @@ typedef uintptr_t BloomFilter; #define bloomset(b, x) ((b) |= bloombit((x))) #define bloomtest(b, x) ((b) & bloombit((x))) -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__psp2__) #define LJ_NORET __attribute__((noreturn)) #define LJ_ALIGN(n) __attribute__((aligned(n))) @@ -119,7 +119,7 @@ typedef uintptr_t BloomFilter; #define LJ_AINLINE inline __attribute__((always_inline)) #define LJ_NOINLINE __attribute__((noinline)) -#if defined(__ELF__) || defined(__MACH__) +#if defined(__ELF__) || defined(__MACH__) || defined(__psp2__) #if !((defined(__sun__) && defined(__svr4__)) || defined(__CELLOS_LV2__)) #define LJ_NOAPI extern __attribute__((visibility("hidden"))) #endif @@ -150,6 +150,9 @@ static LJ_AINLINE uint32_t lj_fls(uint32_t x) #if defined(__arm__) static LJ_AINLINE uint32_t lj_bswap(uint32_t x) { +#if defined(__psp2__) + return __builtin_rev(x); +#else uint32_t r; #if __ARM_ARCH_6__ || __ARM_ARCH_6J__ || __ARM_ARCH_6T2__ || __ARM_ARCH_6Z__ ||\ __ARM_ARCH_6ZK__ || __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ @@ -163,6 +166,7 @@ static LJ_AINLINE uint32_t lj_bswap(uint32_t x) #endif return ((r & 0xff00ffffu) >> 8) ^ lj_ror(x, 8); #endif +#endif } static LJ_AINLINE uint64_t lj_bswap64(uint64_t x) diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c index 58d6c3e2..627379a2 100644 --- a/src/lj_dispatch.c +++ b/src/lj_dispatch.c @@ -1,6 +1,6 @@ /* ** Instruction dispatch handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_dispatch_c diff --git a/src/lj_dispatch.h b/src/lj_dispatch.h index 5960e64a..e46a0eee 100644 --- a/src/lj_dispatch.h +++ b/src/lj_dispatch.h @@ -1,6 +1,6 @@ /* ** Instruction dispatch handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_DISPATCH_H diff --git a/src/lj_emit_arm.h b/src/lj_emit_arm.h index 3bac3679..285c98de 100644 --- a/src/lj_emit_arm.h +++ b/src/lj_emit_arm.h @@ -1,6 +1,6 @@ /* ** ARM instruction emitter. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Constant encoding --------------------------------------------------- */ @@ -273,7 +273,7 @@ static void emit_call(ASMState *as, void *target) ptrdiff_t delta = ((char *)target - (char *)p) - 8; if ((((delta>>2) + 0x00800000) >> 24) == 0) { if ((delta & 1)) - *p = ARMI_BLX | ((uint32_t)(delta>>2) & 0x00ffffffu) | ((delta&2) << 27); + *p = ARMI_BLX | ((uint32_t)(delta>>2) & 0x00ffffffu) | ((delta&2) << 23); else *p = ARMI_BL | ((uint32_t)(delta>>2) & 0x00ffffffu); } else { /* Target out of range: need indirect call. But don't use R0-R3. */ diff --git a/src/lj_emit_mips.h b/src/lj_emit_mips.h index dc9197ad..ed62608a 100644 --- a/src/lj_emit_mips.h +++ b/src/lj_emit_mips.h @@ -1,6 +1,6 @@ /* ** MIPS instruction emitter. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Emit basic instructions --------------------------------------------- */ diff --git a/src/lj_emit_ppc.h b/src/lj_emit_ppc.h index 3a2ae389..14099302 100644 --- a/src/lj_emit_ppc.h +++ b/src/lj_emit_ppc.h @@ -1,6 +1,6 @@ /* ** PPC instruction emitter. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Emit basic instructions --------------------------------------------- */ diff --git a/src/lj_emit_x86.h b/src/lj_emit_x86.h index 8cfb654f..9c371a95 100644 --- a/src/lj_emit_x86.h +++ b/src/lj_emit_x86.h @@ -1,6 +1,6 @@ /* ** x86/x64 instruction emitter. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* -- Emit basic instructions --------------------------------------------- */ @@ -268,10 +268,12 @@ static void emit_movmroi(ASMState *as, Reg base, int32_t ofs, int32_t i) /* mov r, i / xor r, r */ static void emit_loadi(ASMState *as, Reg r, int32_t i) { - /* XOR r,r is shorter, but modifies the flags. This is bad for HIOP. */ + /* XOR r,r is shorter, but modifies the flags. This is bad for HIOP/jcc. */ if (i == 0 && !(LJ_32 && (IR(as->curins)->o == IR_HIOP || (as->curins+1 < as->T->nins && - IR(as->curins+1)->o == IR_HIOP)))) { + IR(as->curins+1)->o == IR_HIOP))) && + !((*as->mcp == 0x0f && (as->mcp[1] & 0xf0) == XI_JCCn) || + (*as->mcp & 0xf0) == XI_JCCs)) { emit_rr(as, XO_ARITH(XOg_XOR), r, r); } else { MCode *p = as->mcp; diff --git a/src/lj_err.c b/src/lj_err.c index db182673..13a1ded7 100644 --- a/src/lj_err.c +++ b/src/lj_err.c @@ -1,6 +1,6 @@ /* ** Error handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_err_c @@ -57,10 +57,10 @@ ** EXT cannot be enabled on WIN32 since system exceptions use code-driven SEH. ** EXT is mandatory on WIN64 since the calling convention has an abundance ** of callee-saved registers (rbx, rbp, rsi, rdi, r12-r15, xmm6-xmm15). -** EXT is mandatory on POSIX/x64 since the interpreter doesn't save r12/r13. +** The POSIX/x64 interpreter only saves r12/r13 for INT (e.g. PS4). */ -#if defined(__GNUC__) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) +#if defined(__GNUC__) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) && !LJ_NO_UNWIND #define LJ_UNWIND_EXT 1 #elif LJ_TARGET_X64 && LJ_TARGET_WINDOWS #define LJ_UNWIND_EXT 1 @@ -153,6 +153,7 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK) goto unwind_c; #endif + /* fallthrough */ case FRAME_VARG: /* Vararg frame. */ frame = frame_prevd(frame); break; @@ -186,7 +187,7 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) /* -- External frame unwinding -------------------------------------------- */ -#if defined(__GNUC__) && !LJ_NO_UNWIND && !LJ_TARGET_WINDOWS +#if defined(__GNUC__) && !LJ_NO_UNWIND && !LJ_ABI_WIN /* ** We have to use our own definitions instead of the mandatory (!) unwind.h, @@ -352,7 +353,7 @@ LJ_FUNCA int lj_err_unwind_arm(int state, void *ucb, _Unwind_Context *ctx) #endif -#elif LJ_TARGET_X64 && LJ_TARGET_WINDOWS +#elif LJ_TARGET_X64 && LJ_ABI_WIN /* ** Someone in Redmond owes me several days of my life. A lot of this is @@ -378,7 +379,7 @@ typedef struct UndocumentedDispatcherContext { ULONG64 EstablisherFrame; ULONG64 TargetIp; PCONTEXT ContextRecord; - PEXCEPTION_ROUTINE LanguageHandler; + void (*LanguageHandler)(void); PVOID HandlerData; PUNWIND_HISTORY_TABLE HistoryTable; ULONG ScopeIndex; @@ -417,7 +418,9 @@ LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec, if (cf2) { /* We catch it, so start unwinding the upper frames. */ if (rec->ExceptionCode == LJ_MSVC_EXCODE || rec->ExceptionCode == LJ_GCC_EXCODE) { +#if LJ_TARGET_WINDOWS __DestructExceptionObject(rec, 1); +#endif setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); } else if (!LJ_EXCODE_CHECK(rec->ExceptionCode)) { /* Don't catch access violations etc. */ @@ -499,8 +502,7 @@ static ptrdiff_t finderrfunc(lua_State *L) { cTValue *frame = L->base-1, *bot = tvref(L->stack); void *cf = L->cframe; - while (frame > bot) { - lua_assert(cf != NULL); + while (frame > bot && cf) { while (cframe_nres(cframe_raw(cf)) < 0) { /* cframe without frame? */ if (frame >= restorestack(L, -cframe_nres(cf))) break; @@ -518,12 +520,14 @@ static ptrdiff_t finderrfunc(lua_State *L) case FRAME_C: cf = cframe_prev(cf); /* fallthrough */ + case FRAME_VARG: + frame = frame_prevd(frame); + break; case FRAME_CONT: #if LJ_HASFFI if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK) cf = cframe_prev(cf); #endif - case FRAME_VARG: frame = frame_prevd(frame); break; case FRAME_CP: @@ -725,9 +729,23 @@ LJ_NOINLINE void lj_err_arg(lua_State *L, int narg, ErrMsg em) /* Typecheck error for arguments. */ LJ_NOINLINE void lj_err_argtype(lua_State *L, int narg, const char *xname) { - TValue *o = narg < 0 ? L->top + narg : L->base + narg-1; - const char *tname = o < L->top ? lj_typename(o) : lj_obj_typename[0]; - const char *msg = lj_str_pushf(L, err2msg(LJ_ERR_BADTYPE), xname, tname); + const char *tname, *msg; + if (narg <= LUA_REGISTRYINDEX) { + if (narg >= LUA_GLOBALSINDEX) { + tname = lj_obj_itypename[~LJ_TTAB]; + } else { + GCfunc *fn = curr_func(L); + int idx = LUA_GLOBALSINDEX - narg; + if (idx <= fn->c.nupvalues) + tname = lj_typename(&fn->c.upvalue[idx-1]); + else + tname = lj_obj_typename[0]; + } + } else { + TValue *o = narg < 0 ? L->top + narg : L->base + narg-1; + tname = o < L->top ? lj_typename(o) : lj_obj_typename[0]; + } + msg = lj_str_pushf(L, err2msg(LJ_ERR_BADTYPE), xname, tname); err_argmsg(L, narg, msg); } diff --git a/src/lj_err.h b/src/lj_err.h index 7ea512a3..cba5fb71 100644 --- a/src/lj_err.h +++ b/src/lj_err.h @@ -1,6 +1,6 @@ /* ** Error handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_ERR_H diff --git a/src/lj_errmsg.h b/src/lj_errmsg.h index 137831eb..ac552f40 100644 --- a/src/lj_errmsg.h +++ b/src/lj_errmsg.h @@ -1,6 +1,6 @@ /* ** VM error messages. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* This file may be included multiple times with different ERRDEF macros. */ diff --git a/src/lj_ff.h b/src/lj_ff.h index d91a7395..31d65a00 100644 --- a/src/lj_ff.h +++ b/src/lj_ff.h @@ -1,6 +1,6 @@ /* ** Fast function IDs. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_FF_H diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index 794bbd43..da09dca5 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c @@ -1,6 +1,6 @@ /* ** Fast function call recorder. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_ffrecord_c @@ -366,11 +366,12 @@ static void LJ_FASTCALL recff_ipairs_aux(jit_State *J, RecordFFData *rd) static void LJ_FASTCALL recff_ipairs(jit_State *J, RecordFFData *rd) { - if (!(LJ_52 && recff_metacall(J, rd, MM_ipairs))) { - TRef tab = J->base[0]; - if (tref_istab(tab)) { + TRef tr = J->base[0]; + if (!((LJ_52 || (LJ_HASFFI && tref_iscdata(tr))) && + recff_metacall(J, rd, MM_ipairs))) { + if (tref_istab(tr)) { J->base[0] = lj_ir_kfunc(J, funcV(&J->fn->c.upvalue[0])); - J->base[1] = tab; + J->base[1] = tr; J->base[2] = lj_ir_kint(J, 0); rd->nres = 3; } /* else: Interpreter will throw. */ @@ -538,10 +539,8 @@ static void LJ_FASTCALL recff_math_degrad(jit_State *J, RecordFFData *rd) static void LJ_FASTCALL recff_math_pow(jit_State *J, RecordFFData *rd) { - TRef tr = lj_ir_tonum(J, J->base[0]); - if (!tref_isnumber_str(J->base[1])) - lj_trace_err(J, LJ_TRERR_BADTYPE); - J->base[0] = lj_opt_narrow_pow(J, tr, J->base[1], &rd->argv[1]); + J->base[0] = lj_opt_narrow_pow(J, J->base[0], J->base[1], + &rd->argv[0], &rd->argv[1]); UNUSED(rd); } diff --git a/src/lj_ffrecord.h b/src/lj_ffrecord.h index b3bc6627..3b407450 100644 --- a/src/lj_ffrecord.h +++ b/src/lj_ffrecord.h @@ -1,6 +1,6 @@ /* ** Fast function call recorder. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_FFRECORD_H diff --git a/src/lj_frame.h b/src/lj_frame.h index fb533b0e..eb5df307 100644 --- a/src/lj_frame.h +++ b/src/lj_frame.h @@ -1,6 +1,6 @@ /* ** Stack frames. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_FRAME_H @@ -86,7 +86,11 @@ enum { #define CFRAME_OFS_ERRF (5*4) #define CFRAME_OFS_NRES (4*4) #define CFRAME_OFS_MULTRES (1*4) +#if LJ_NO_UNWIND +#define CFRAME_SIZE (12*8) +#else #define CFRAME_SIZE (10*8) +#endif #define CFRAME_SIZE_JIT (CFRAME_SIZE + 16) #define CFRAME_SHIFT_MULTRES 0 #endif diff --git a/src/lj_func.c b/src/lj_func.c index 9a59b0f0..639dad87 100644 --- a/src/lj_func.c +++ b/src/lj_func.c @@ -1,6 +1,6 @@ /* ** Function handling (prototypes, functions and upvalues). -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -140,7 +140,9 @@ GCfunc *lj_func_newL_empty(lua_State *L, GCproto *pt, GCtab *env) /* NOBARRIER: The GCfunc is new (marked white). */ for (i = 0; i < nuv; i++) { GCupval *uv = func_emptyuv(L); - uv->dhash = (uint32_t)(uintptr_t)pt ^ ((uint32_t)proto_uv(pt)[i] << 24); + int32_t v = proto_uv(pt)[i]; + uv->immutable = ((v / PROTO_UV_IMMUTABLE) & 1); + uv->dhash = (uint32_t)(uintptr_t)pt ^ (v << 24); setgcref(fn->l.uvptr[i], obj2gco(uv)); } fn->l.nupvalues = (uint8_t)nuv; diff --git a/src/lj_func.h b/src/lj_func.h index 88732e83..901751b9 100644 --- a/src/lj_func.h +++ b/src/lj_func.h @@ -1,6 +1,6 @@ /* ** Function handling (prototypes, functions and upvalues). -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_FUNC_H diff --git a/src/lj_gc.c b/src/lj_gc.c index c2bc397d..a5d32ea3 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c @@ -1,6 +1,6 @@ /* ** Garbage collector. -** Copyright (C) 2005-2014 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 @@ -168,12 +168,19 @@ static int gc_traverse_tab(global_State *g, GCtab *t) while ((c = *modestr++)) { if (c == 'k') weak |= LJ_GC_WEAKKEY; else if (c == 'v') weak |= LJ_GC_WEAKVAL; - else if (c == 'K') weak = (int)(~0u & ~LJ_GC_WEAKVAL); } - if (weak > 0) { /* Weak tables are cleared in the atomic phase. */ - t->marked = (uint8_t)((t->marked & ~LJ_GC_WEAK) | weak); - setgcrefr(t->gclist, g->gc.weak); - setgcref(g->gc.weak, obj2gco(t)); + if (weak) { /* Weak tables are cleared in the atomic phase. */ +#if LJ_HASFFI + CTState *cts = ctype_ctsG(g); + if (cts && cts->finalizer == t) { + weak = (int)(~0u & ~LJ_GC_WEAKVAL); + } else +#endif + { + t->marked = (uint8_t)((t->marked & ~LJ_GC_WEAK) | weak); + setgcrefr(t->gclist, g->gc.weak); + setgcref(g->gc.weak, obj2gco(t)); + } } } if (weak == LJ_GC_WEAK) /* Nothing to mark if both keys/values are weak. */ @@ -307,7 +314,7 @@ static size_t propagatemark(global_State *g) if (gc_traverse_tab(g, t) > 0) black2gray(o); /* Keep weak tables gray. */ return sizeof(GCtab) + sizeof(TValue) * t->asize + - sizeof(Node) * (t->hmask + 1); + (t->hmask ? sizeof(Node) * (t->hmask + 1) : 0); } else if (LJ_LIKELY(gct == ~LJ_TFUNC)) { GCfunc *fn = gco2func(o); gc_traverse_func(g, fn); @@ -631,6 +638,8 @@ static size_t gc_onestep(lua_State *L) case GCSsweep: { MSize old = g->gc.total; setmref(g->gc.sweep, gc_sweep(g, mref(g->gc.sweep, GCRef), GCSWEEPMAX)); + lua_assert(old >= g->gc.total); + g->gc.estimate -= old - g->gc.total; if (gcref(*mref(g->gc.sweep, GCRef)) == NULL) { gc_shrink(g, L); if (gcref(g->gc.mmudata)) { /* Need any finalizations? */ @@ -643,8 +652,6 @@ static size_t gc_onestep(lua_State *L) g->gc.debt = 0; } } - lua_assert(old >= g->gc.total); - g->gc.estimate -= old - g->gc.total; return GCSWEEPMAX*GCSWEEPCOST; } case GCSfinalize: diff --git a/src/lj_gc.h b/src/lj_gc.h index c85d0756..57ac7147 100644 --- a/src/lj_gc.h +++ b/src/lj_gc.h @@ -1,6 +1,6 @@ /* ** Garbage collector. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_GC_H diff --git a/src/lj_gdbjit.c b/src/lj_gdbjit.c index 5e7fca1c..eeb017bb 100644 --- a/src/lj_gdbjit.c +++ b/src/lj_gdbjit.c @@ -1,6 +1,6 @@ /* ** Client for the GDB JIT API. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_gdbjit_c @@ -356,6 +356,8 @@ static const ELFheader elfhdr_template = { .eosabi = 2, #elif defined(__OpenBSD__) .eosabi = 12, +#elif defined(__DragonFly__) + .eosabi = 0, #elif (defined(__sun__) && defined(__svr4__)) .eosabi = 6, #else diff --git a/src/lj_gdbjit.h b/src/lj_gdbjit.h index 9ae504fc..bbaa1568 100644 --- a/src/lj_gdbjit.h +++ b/src/lj_gdbjit.h @@ -1,6 +1,6 @@ /* ** Client for the GDB JIT API. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_GDBJIT_H diff --git a/src/lj_ir.c b/src/lj_ir.c index b2170a10..1e4860df 100644 --- a/src/lj_ir.c +++ b/src/lj_ir.c @@ -1,6 +1,6 @@ /* ** SSA IR (Intermediate Representation) emitter. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_ir_c diff --git a/src/lj_ir.h b/src/lj_ir.h index 80763d88..ded3e0eb 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h @@ -1,6 +1,6 @@ /* ** SSA IR (Intermediate Representation) format. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_IR_H diff --git a/src/lj_ircall.h b/src/lj_ircall.h index af30ba8f..44afde3a 100644 --- a/src/lj_ircall.h +++ b/src/lj_ircall.h @@ -1,6 +1,6 @@ /* ** IR CALL* instruction definitions. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_IRCALL_H @@ -112,7 +112,7 @@ typedef struct CCallInfo { _(ANY, lj_gc_step_jit, 2, FS, NIL, CCI_L) \ _(ANY, lj_gc_barrieruv, 2, FS, NIL, 0) \ _(ANY, lj_mem_newgco, 2, FS, P32, CCI_L) \ - _(ANY, lj_math_random_step, 1, FS, NUM, CCI_CASTU64|CCI_NOFPRCLOBBER) \ + _(ANY, lj_math_random_step, 1, FS, NUM, CCI_CASTU64) \ _(ANY, lj_vm_modi, 2, FN, INT, 0) \ _(ANY, sinh, ARG1_FP, N, NUM, 0) \ _(ANY, cosh, ARG1_FP, N, NUM, 0) \ diff --git a/src/lj_iropt.h b/src/lj_iropt.h index e45ae2b7..b5081e06 100644 --- a/src/lj_iropt.h +++ b/src/lj_iropt.h @@ -1,6 +1,6 @@ /* ** Common header for IR emitter and optimizations. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_IROPT_H @@ -142,8 +142,8 @@ LJ_FUNC TRef LJ_FASTCALL lj_opt_narrow_cindex(jit_State *J, TRef key); LJ_FUNC TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc, IROp op); LJ_FUNC TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc); -LJ_FUNC TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vc); -LJ_FUNC TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vc); +LJ_FUNC TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc); +LJ_FUNC TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc); LJ_FUNC IRType lj_opt_narrow_forl(jit_State *J, cTValue *forbase); /* Optimization passes. */ diff --git a/src/lj_jit.h b/src/lj_jit.h index b69e4f4e..0bc62583 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h @@ -1,6 +1,6 @@ /* ** Common definitions for the JIT compiler. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_JIT_H @@ -155,9 +155,15 @@ typedef uint8_t MCode; typedef uint32_t MCode; #endif +/* Linked list of MCode areas. */ +typedef struct MCLink { + MCode *next; /* Next area. */ + size_t size; /* Size of current area. */ +} MCLink; + /* Stack snapshot header. */ typedef struct SnapShot { - uint16_t mapofs; /* Offset into snapshot map. */ + uint32_t mapofs; /* Offset into snapshot map. */ IRRef1 ref; /* First IR ref for this snapshot. */ uint8_t nslots; /* Number of valid slots. */ uint8_t topslot; /* Maximum frame extent. */ @@ -211,14 +217,12 @@ typedef enum { /* Trace object. */ typedef struct GCtrace { GCHeader; - uint8_t topslot; /* Top stack slot already checked to be allocated. */ - uint8_t linktype; /* Type of link. */ + uint16_t nsnap; /* Number of snapshots. */ IRRef nins; /* Next IR instruction. Biased with REF_BIAS. */ GCRef gclist; IRIns *ir; /* IR instructions/constants. Biased with REF_BIAS. */ IRRef nk; /* Lowest IR constant. Biased with REF_BIAS. */ - uint16_t nsnap; /* Number of snapshots. */ - uint16_t nsnapmap; /* Number of snapshot map elements. */ + uint32_t nsnapmap; /* Number of snapshot map elements. */ SnapShot *snap; /* Snapshot array. */ SnapEntry *snapmap; /* Snapshot map. */ GCRef startpt; /* Starting prototype. */ @@ -235,6 +239,8 @@ typedef struct GCtrace { TraceNo1 nextroot; /* Next root trace for same prototype. */ TraceNo1 nextside; /* Next side trace of same root trace. */ uint8_t sinktags; /* Trace has SINK tags. */ + uint8_t topslot; /* Top stack slot already checked to be allocated. */ + uint8_t linktype; /* Type of link. */ uint8_t unused1; #ifdef LUAJIT_USE_GDBJIT void *gdbjit_entry; /* GDB JIT entry. */ @@ -279,6 +285,7 @@ typedef struct BPropEntry { /* Scalar evolution analysis cache. */ typedef struct ScEvEntry { + MRef pc; /* Bytecode PC of FORI. */ IRRef1 idx; /* Index reference. */ IRRef1 start; /* Constant start reference. */ IRRef1 stop; /* Constant stop reference. */ diff --git a/src/lj_lex.c b/src/lj_lex.c index 4fa39313..36603168 100644 --- a/src/lj_lex.c +++ b/src/lj_lex.c @@ -1,6 +1,6 @@ /* ** Lexical analyzer. -** Copyright (C) 2005-2014 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 @@ -378,6 +378,7 @@ int lj_lex_setup(lua_State *L, LexState *ls) ls->vtop = 0; ls->bcstack = NULL; ls->sizebcstack = 0; + ls->token = 0; ls->lookahead = TK_eof; /* No look-ahead token. */ ls->linenumber = 1; ls->lastline = 1; diff --git a/src/lj_lex.h b/src/lj_lex.h index a7ff29a0..41c03f93 100644 --- a/src/lj_lex.h +++ b/src/lj_lex.h @@ -1,6 +1,6 @@ /* ** Lexical analyzer. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_LEX_H diff --git a/src/lj_lib.c b/src/lj_lib.c index 76c8a064..a1bb6a2a 100644 --- a/src/lj_lib.c +++ b/src/lj_lib.c @@ -1,6 +1,6 @@ /* ** Library function support. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_lib_c diff --git a/src/lj_lib.h b/src/lj_lib.h index daacb921..aa874076 100644 --- a/src/lj_lib.h +++ b/src/lj_lib.h @@ -1,6 +1,6 @@ /* ** Library function support. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_LIB_H diff --git a/src/lj_load.c b/src/lj_load.c index edfdc903..20be8ebe 100644 --- a/src/lj_load.c +++ b/src/lj_load.c @@ -1,6 +1,6 @@ /* ** Load and dump code. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include diff --git a/src/lj_mcode.c b/src/lj_mcode.c index 5a732960..5ea89f66 100644 --- a/src/lj_mcode.c +++ b/src/lj_mcode.c @@ -1,6 +1,6 @@ /* ** Machine code management. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_mcode_c @@ -145,7 +145,7 @@ static void mcode_free(jit_State *J, void *p, size_t sz) /* -- MCode area protection ----------------------------------------------- */ -/* Define this ONLY if the page protection twiddling becomes a bottleneck. */ +/* Define this ONLY if page protection twiddling becomes a bottleneck. */ #ifdef LUAJIT_UNPROTECT_MCODE /* It's generally considered to be a potential security risk to have @@ -204,8 +204,8 @@ static void mcode_protect(jit_State *J, int prot) /* -- MCode area allocation ----------------------------------------------- */ -#if LJ_TARGET_X64 -#define mcode_validptr(p) ((p) && (uintptr_t)(p) < (uintptr_t)1<<47) +#if LJ_64 +#define mcode_validptr(p) (p) #else #define mcode_validptr(p) ((p) && (uintptr_t)(p) < 0xffff0000) #endif @@ -230,7 +230,8 @@ static void *mcode_alloc(jit_State *J, size_t sz) /* First try a contiguous area below the last one. */ uintptr_t hint = J->mcarea ? (uintptr_t)J->mcarea - sz : 0; int i; - for (i = 0; i < 32; i++) { /* 32 attempts ought to be enough ... */ + /* Limit probing iterations, depending on the available pool size. */ + for (i = 0; i < LJ_TARGET_JUMPRANGE; i++) { if (mcode_validptr(hint)) { void *p = mcode_alloc_at(J, hint, sz, MCPROT_GEN); @@ -239,11 +240,11 @@ static void *mcode_alloc(jit_State *J, size_t sz) return p; if (p) mcode_free(J, p, sz); /* Free badly placed area. */ } - /* Next try probing pseudo-random addresses. */ + /* Next try probing 64K-aligned pseudo-random addresses. */ do { - hint = (0x78fb ^ LJ_PRNG_BITS(J, 15)) << 16; /* 64K aligned. */ - } while (!(hint + sz < range)); - hint = target + hint - (range>>1); + hint = LJ_PRNG_BITS(J, LJ_TARGET_JUMPRANGE-16) << 16; + } while (!(hint + sz < range+range)); + hint = target + hint - range; } lj_trace_err(J, LJ_TRERR_MCODEAL); /* Give up. OS probably ignores hints? */ return NULL; @@ -252,18 +253,25 @@ static void *mcode_alloc(jit_State *J, size_t sz) #else /* All memory addresses are reachable by relative jumps. */ -#define mcode_alloc(J, sz) mcode_alloc_at((J), 0, (sz), MCPROT_GEN) +static void *mcode_alloc(jit_State *J, size_t sz) +{ +#ifdef __OpenBSD__ + /* Allow better executable memory allocation for OpenBSD W^X mode. */ + void *p = mcode_alloc_at(J, 0, sz, MCPROT_RUN); + if (p && mcode_setprot(p, sz, MCPROT_GEN)) { + mcode_free(J, p, sz); + return NULL; + } + return p; +#else + return mcode_alloc_at(J, 0, sz, MCPROT_GEN); +#endif +} #endif /* -- MCode area management ----------------------------------------------- */ -/* Linked list of MCode areas. */ -typedef struct MCLink { - MCode *next; /* Next area. */ - size_t size; /* Size of current area. */ -} MCLink; - /* Allocate a new MCode area. */ static void mcode_allocarea(jit_State *J) { diff --git a/src/lj_mcode.h b/src/lj_mcode.h index 89344fc7..f0847e93 100644 --- a/src/lj_mcode.h +++ b/src/lj_mcode.h @@ -1,6 +1,6 @@ /* ** Machine code management. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_MCODE_H diff --git a/src/lj_meta.c b/src/lj_meta.c index 0a526671..10e34984 100644 --- a/src/lj_meta.c +++ b/src/lj_meta.c @@ -1,6 +1,6 @@ /* ** Metamethod handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h diff --git a/src/lj_meta.h b/src/lj_meta.h index 8d7c2cd4..e061d99e 100644 --- a/src/lj_meta.h +++ b/src/lj_meta.h @@ -1,6 +1,6 @@ /* ** Metamethod handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_META_H diff --git a/src/lj_obj.c b/src/lj_obj.c index c7f3bc12..4779d26d 100644 --- a/src/lj_obj.c +++ b/src/lj_obj.c @@ -1,6 +1,6 @@ /* ** Miscellaneous object handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_obj_c diff --git a/src/lj_obj.h b/src/lj_obj.h index cc999aa4..2ee526cf 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h @@ -1,6 +1,6 @@ /* ** LuaJIT VM tags, values and objects. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -816,14 +816,22 @@ static LJ_AINLINE int32_t lj_num2bit(lua_Number n) #define lj_num2int(n) ((int32_t)(n)) #endif +/* +** This must match the JIT backend behavior. In particular for archs +** that don't have a common hardware instruction for this conversion. +** Note that signed FP to unsigned int conversions have an undefined +** result and should never be relied upon in portable FFI code. +** See also: C99 or C11 standard, 6.3.1.4, footnote of (1). +*/ static LJ_AINLINE uint64_t lj_num2u64(lua_Number n) { -#ifdef _MSC_VER - if (n >= 9223372036854775808.0) /* They think it's a feature. */ - return (uint64_t)(int64_t)(n - 18446744073709551616.0); - else +#if LJ_TARGET_X86ORX64 || LJ_TARGET_MIPS + int64_t i = (int64_t)n; + if (i < 0) i = (int64_t)(n - 18446744073709551616.0); + return (uint64_t)i; +#else + return (uint64_t)n; #endif - return (uint64_t)n; } static LJ_AINLINE int32_t numberVint(cTValue *o) diff --git a/src/lj_opt_dce.c b/src/lj_opt_dce.c index be801894..2417f324 100644 --- a/src/lj_opt_dce.c +++ b/src/lj_opt_dce.c @@ -1,6 +1,6 @@ /* ** DCE: Dead Code Elimination. Pre-LOOP only -- ASM already performs DCE. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_dce_c @@ -69,6 +69,7 @@ void lj_opt_dce(jit_State *J) if ((J->flags & JIT_F_OPT_DCE)) { dce_marksnap(J); dce_propagate(J); + memset(J->bpropcache, 0, sizeof(J->bpropcache)); /* Invalidate cache. */ } } diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 8a5b41cc..5dc7ae3d 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -2,7 +2,7 @@ ** FOLD: Constant Folding, Algebraic Simplifications and Reassociation. ** ABCelim: Array Bounds Check Elimination. ** CSE: Common-Subexpression Elimination. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_fold_c @@ -444,14 +444,14 @@ LJFOLDF(kfold_int64comp) #if LJ_HASFFI uint64_t a = ir_k64(fleft)->u64, b = ir_k64(fright)->u64; switch ((IROp)fins->o) { - case IR_LT: return CONDFOLD(a < b); - case IR_GE: return CONDFOLD(a >= b); - case IR_LE: return CONDFOLD(a <= b); - case IR_GT: return CONDFOLD(a > b); - case IR_ULT: return CONDFOLD((uint64_t)a < (uint64_t)b); - case IR_UGE: return CONDFOLD((uint64_t)a >= (uint64_t)b); - case IR_ULE: return CONDFOLD((uint64_t)a <= (uint64_t)b); - case IR_UGT: return CONDFOLD((uint64_t)a > (uint64_t)b); + case IR_LT: return CONDFOLD((int64_t)a < (int64_t)b); + case IR_GE: return CONDFOLD((int64_t)a >= (int64_t)b); + case IR_LE: return CONDFOLD((int64_t)a <= (int64_t)b); + case IR_GT: return CONDFOLD((int64_t)a > (int64_t)b); + case IR_ULT: return CONDFOLD(a < b); + case IR_UGE: return CONDFOLD(a >= b); + case IR_ULE: return CONDFOLD(a <= b); + case IR_UGT: return CONDFOLD(a > b); default: lua_assert(0); return FAILFOLD; } #else @@ -505,13 +505,14 @@ LJFOLDF(kfold_strref_snew) } else { /* Reassociate: strref(snew(strref(str, a), len), b) ==> strref(str, a+b) */ IRIns *ir = IR(fleft->op1); - IRRef1 str = ir->op1; /* IRIns * is not valid across emitir. */ - lua_assert(ir->o == IR_STRREF); - PHIBARRIER(ir); - fins->op2 = emitir(IRTI(IR_ADD), ir->op2, fins->op2); /* Clobbers fins! */ - fins->op1 = str; - fins->ot = IRT(IR_STRREF, IRT_P32); - return RETRYFOLD; + if (ir->o == IR_STRREF) { + IRRef1 str = ir->op1; /* IRIns * is not valid across emitir. */ + PHIBARRIER(ir); + fins->op2 = emitir(IRTI(IR_ADD), ir->op2, fins->op2); /* Clobbers fins! */ + fins->op1 = str; + fins->ot = IRT(IR_STRREF, IRT_P32); + return RETRYFOLD; + } } return NEXTFOLD; } @@ -1005,11 +1006,16 @@ LJFOLDF(simplify_conv_flt_num) LJFOLD(TOBIT CONV KNUM) LJFOLDF(simplify_tobit_conv) { - if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT || - (fleft->op2 & IRCONV_SRCMASK) == IRT_U32) { - /* Fold even across PHI to avoid expensive num->int conversions in loop. */ + /* Fold even across PHI to avoid expensive num->int conversions in loop. */ + if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT) { lua_assert(irt_isnum(fleft->t)); return fleft->op1; + } else if ((fleft->op2 & IRCONV_SRCMASK) == IRT_U32) { + lua_assert(irt_isnum(fleft->t)); + fins->o = IR_CONV; + fins->op1 = fleft->op1; + fins->op2 = (IRT_INT<<5)|IRT_U32; + return RETRYFOLD; } return NEXTFOLD; } @@ -1046,7 +1052,7 @@ LJFOLDF(simplify_conv_sext) if (ref == J->scev.idx) { IRRef lo = J->scev.dir ? J->scev.start : J->scev.stop; lua_assert(irt_isint(J->scev.t)); - if (lo && IR(lo)->i + ofs >= 0) { + if (lo && IR(lo)->o == IR_KINT && IR(lo)->i + ofs >= 0) { ok_reduce: #if LJ_TARGET_X64 /* Eliminate widening. All 32 bit ops do an implicit zero-extension. */ @@ -1825,7 +1831,8 @@ LJFOLDF(merge_eqne_snew_kgc) if (len <= FOLD_SNEW_MAX_LEN) { IROp op = (IROp)fins->o; IRRef strref = fleft->op1; - lua_assert(IR(strref)->o == IR_STRREF); + if (IR(strref)->o != IR_STRREF) + return NEXTFOLD; if (op == IR_EQ) { emitir(IRTGI(IR_EQ), fleft->op2, lj_ir_kint(J, len)); /* Caveat: fins/fleft/fright is no longer valid after emitir. */ diff --git a/src/lj_opt_loop.c b/src/lj_opt_loop.c index fa001151..cc881110 100644 --- a/src/lj_opt_loop.c +++ b/src/lj_opt_loop.c @@ -1,6 +1,6 @@ /* ** LOOP: Loop Optimizations. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_loop_c @@ -223,7 +223,7 @@ static void loop_subst_snap(jit_State *J, SnapShot *osnap, } J->guardemit.irt = 0; /* Setup new snapshot. */ - snap->mapofs = (uint16_t)nmapofs; + snap->mapofs = (uint32_t)nmapofs; snap->ref = (IRRef1)J->cur.nins; snap->nslots = nslots; snap->topslot = osnap->topslot; @@ -251,7 +251,7 @@ static void loop_subst_snap(jit_State *J, SnapShot *osnap, nmap += nn; while (omap < nextmap) /* Copy PC + frame links. */ *nmap++ = *omap++; - J->cur.nsnapmap = (uint16_t)(nmap - J->cur.snapmap); + J->cur.nsnapmap = (uint32_t)(nmap - J->cur.snapmap); } /* Unroll loop. */ @@ -362,7 +362,7 @@ static void loop_unroll(jit_State *J) } } if (!irt_isguard(J->guardemit)) /* Drop redundant snapshot. */ - J->cur.nsnapmap = (uint16_t)J->cur.snap[--J->cur.nsnap].mapofs; + J->cur.nsnapmap = (uint32_t)J->cur.snap[--J->cur.nsnap].mapofs; lua_assert(J->cur.nsnapmap <= J->sizesnapmap); *psentinel = J->cur.snapmap[J->cur.snap[0].nent]; /* Restore PC. */ @@ -376,7 +376,7 @@ static void loop_undo(jit_State *J, IRRef ins, SnapNo nsnap, MSize nsnapmap) SnapShot *snap = &J->cur.snap[nsnap-1]; SnapEntry *map = J->cur.snapmap; map[snap->mapofs + snap->nent] = map[J->cur.snap[0].nent]; /* Restore PC. */ - J->cur.nsnapmap = (uint16_t)nsnapmap; + J->cur.nsnapmap = (uint32_t)nsnapmap; J->cur.nsnap = nsnap; J->guardemit.irt = 0; lj_ir_rollback(J, ins); diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c index c8cdc3e5..9f714056 100644 --- a/src/lj_opt_mem.c +++ b/src/lj_opt_mem.c @@ -3,7 +3,7 @@ ** AA: Alias Analysis using high-level semantic disambiguation. ** FWD: Load Forwarding (L2L) + Store Forwarding (S2L). ** DSE: Dead-Store Elimination. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_mem_c @@ -740,21 +740,19 @@ TRef LJ_FASTCALL lj_opt_fwd_xload(jit_State *J) case ALIAS_MUST: /* Emit conversion if the loaded type doesn't match the forwarded type. */ if (!irt_sametype(fins->t, IR(store->op2)->t)) { - IRType st = irt_type(fins->t); - if (st == IRT_I8 || st == IRT_I16) { /* Trunc + sign-extend. */ - st |= IRCONV_SEXT; - } else if (st == IRT_U8 || st == IRT_U16) { /* Trunc + zero-extend. */ - } else if (st == IRT_INT) { - st = irt_type(IR(store->op2)->t); /* Needs dummy CONV.int.*. */ - } else { /* I64/U64 are boxed, U32 is hidden behind a CONV.num.u32. */ - goto store_fwd; + IRType dt = irt_type(fins->t), st = irt_type(IR(store->op2)->t); + if (dt == IRT_I8 || dt == IRT_I16) { /* Trunc + sign-extend. */ + st = dt | IRCONV_SEXT; + dt = IRT_INT; + } else if (dt == IRT_U8 || dt == IRT_U16) { /* Trunc + zero-extend. */ + st = dt; + dt = IRT_INT; } - fins->ot = IRTI(IR_CONV); + fins->ot = IRT(IR_CONV, dt); fins->op1 = store->op2; - fins->op2 = (IRT_INT<<5)|st; + fins->op2 = (dt<<5)|st; return RETRYFOLD; } - store_fwd: return store->op2; /* Store forwarding. */ } ref = store->prev; @@ -795,6 +793,7 @@ TRef LJ_FASTCALL lj_opt_dse_xstore(jit_State *J) IRRef ref = *refp; if (J->chain[IR_CALLXS] > lim) lim = J->chain[IR_CALLXS]; if (J->chain[IR_XBAR] > lim) lim = J->chain[IR_XBAR]; + if (J->chain[IR_XSNEW] > lim) lim = J->chain[IR_XSNEW]; while (ref > lim) { /* Search for redundant or conflicting stores. */ IRIns *store = IR(ref); switch (aa_xref(J, xr, fins, store)) { diff --git a/src/lj_opt_narrow.c b/src/lj_opt_narrow.c index 2cecf65d..73365953 100644 --- a/src/lj_opt_narrow.c +++ b/src/lj_opt_narrow.c @@ -1,7 +1,7 @@ /* ** NARROW: Narrowing of numbers to integers (double to int32_t). ** STRIPOV: Stripping of overflow checks. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_narrow_c @@ -205,7 +205,6 @@ typedef struct NarrowConv { jit_State *J; /* JIT compiler state. */ NarrowIns *sp; /* Current stack pointer. */ NarrowIns *maxsp; /* Maximum stack pointer minus redzone. */ - int lim; /* Limit on the number of emitted conversions. */ IRRef mode; /* Conversion mode (IRCONV_*). */ IRType t; /* Destination type: IRT_INT or IRT_I64. */ NarrowIns stack[NARROW_MAX_STACK]; /* Stack holding stack-machine code. */ @@ -247,10 +246,16 @@ static void narrow_stripov_backprop(NarrowConv *nc, IRRef ref, int depth) if (bp) { ref = bp->val; } else if (++depth < NARROW_MAX_BACKPROP && nc->sp < nc->maxsp) { + NarrowIns *savesp = nc->sp; narrow_stripov_backprop(nc, ir->op1, depth); - narrow_stripov_backprop(nc, ir->op2, depth); - *nc->sp++ = NARROWINS(IRT(ir->o - IR_ADDOV + IR_ADD, IRT_INT), ref); - return; + if (nc->sp < nc->maxsp) { + narrow_stripov_backprop(nc, ir->op2, depth); + if (nc->sp < nc->maxsp) { + *nc->sp++ = NARROWINS(IRT(ir->o - IR_ADDOV + IR_ADD, IRT_INT), ref); + return; + } + } + nc->sp = savesp; /* Path too deep, need to backtrack. */ } } *nc->sp++ = NARROWINS(NARROW_REF, ref); @@ -263,6 +268,8 @@ static int narrow_conv_backprop(NarrowConv *nc, IRRef ref, int depth) IRIns *ir = IR(ref); IRRef cref; + if (nc->sp >= nc->maxsp) return 10; /* Path too deep. */ + /* Check the easy cases first. */ if (ir->o == IR_CONV && (ir->op2 & IRCONV_SRCMASK) == IRT_INT) { if ((nc->mode & IRCONV_CONVMASK) <= IRCONV_ANY) @@ -334,7 +341,7 @@ static int narrow_conv_backprop(NarrowConv *nc, IRRef ref, int depth) NarrowIns *savesp = nc->sp; int count = narrow_conv_backprop(nc, ir->op1, depth); count += narrow_conv_backprop(nc, ir->op2, depth); - if (count <= nc->lim) { /* Limit total number of conversions. */ + if (count <= 1) { /* Limit total number of conversions. */ *nc->sp++ = NARROWINS(IRT(ir->o, nc->t), ref); return count; } @@ -406,12 +413,10 @@ TRef LJ_FASTCALL lj_opt_narrow_convert(jit_State *J) nc.t = irt_type(fins->t); if (fins->o == IR_TOBIT) { nc.mode = IRCONV_TOBIT; /* Used only in the backpropagation cache. */ - nc.lim = 2; /* TOBIT can use a more optimistic rule. */ } else { nc.mode = fins->op2; - nc.lim = 1; } - if (narrow_conv_backprop(&nc, fins->op1, 0) <= nc.lim) + if (narrow_conv_backprop(&nc, fins->op1, 0) <= 1) return narrow_conv_emit(J, &nc); } return NEXTFOLD; @@ -496,8 +501,7 @@ TRef LJ_FASTCALL lj_opt_narrow_cindex(jit_State *J, TRef tr) { lua_assert(tref_isnumber(tr)); if (tref_isnum(tr)) - return emitir(IRT(IR_CONV, IRT_INTP), tr, - (IRT_INTP<<5)|IRT_NUM|IRCONV_TRUNC|IRCONV_ANY); + return emitir(IRT(IR_CONV, IRT_INTP), tr, (IRT_INTP<<5)|IRT_NUM|IRCONV_ANY); /* Undefined overflow semantics allow stripping of ADDOV, SUBOV and MULOV. */ return narrow_stripov(J, tr, IR_MULOV, LJ_64 ? ((IRT_INTP<<5)|IRT_INT|IRCONV_SEXT) : @@ -513,18 +517,24 @@ static int numisint(lua_Number n) return (n == (lua_Number)lj_num2int(n)); } +/* Convert string to number. Error out for non-numeric string values. */ +static TRef conv_str_tonum(jit_State *J, TRef tr, TValue *o) +{ + if (tref_isstr(tr)) { + tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0); + /* Would need an inverted STRTO for this rare and useless case. */ + if (!lj_strscan_num(strV(o), o)) /* Convert in-place. Value used below. */ + lj_trace_err(J, LJ_TRERR_BADTYPE); /* Punt if non-numeric. */ + } + return tr; +} + /* Narrowing of arithmetic operations. */ TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc, IROp op) { - if (tref_isstr(rb)) { - rb = emitir(IRTG(IR_STRTO, IRT_NUM), rb, 0); - lj_strscan_num(strV(vb), vb); - } - if (tref_isstr(rc)) { - rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0); - lj_strscan_num(strV(vc), vc); - } + rb = conv_str_tonum(J, rb, vb); + rc = conv_str_tonum(J, rc, vc); /* Must not narrow MUL in non-DUALNUM variant, because it loses -0. */ if ((op >= IR_ADD && op <= (LJ_DUALNUM ? IR_MUL : IR_SUB)) && tref_isinteger(rb) && tref_isinteger(rc) && @@ -539,10 +549,7 @@ TRef lj_opt_narrow_arith(jit_State *J, TRef rb, TRef rc, /* Narrowing of unary minus operator. */ TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc) { - if (tref_isstr(rc)) { - rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0); - lj_strscan_num(strV(vc), vc); - } + rc = conv_str_tonum(J, rc, vc); if (tref_isinteger(rc)) { if ((uint32_t)numberVint(vc) != 0x80000000u) return emitir(IRTGI(IR_SUBOV), lj_ir_kint(J, 0), rc); @@ -552,11 +559,11 @@ TRef lj_opt_narrow_unm(jit_State *J, TRef rc, TValue *vc) } /* Narrowing of modulo operator. */ -TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vc) +TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc) { TRef tmp; - if (tvisstr(vc) && !lj_strscan_num(strV(vc), vc)) - lj_trace_err(J, LJ_TRERR_BADTYPE); + rb = conv_str_tonum(J, rb, vb); + rc = conv_str_tonum(J, rc, vc); if ((LJ_DUALNUM || (J->flags & JIT_F_OPT_NARROW)) && tref_isinteger(rb) && tref_isinteger(rc) && (tvisint(vc) ? intV(vc) != 0 : !tviszero(vc))) { @@ -573,10 +580,11 @@ TRef lj_opt_narrow_mod(jit_State *J, TRef rb, TRef rc, TValue *vc) } /* Narrowing of power operator or math.pow. */ -TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vc) +TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vb, TValue *vc) { - if (tvisstr(vc) && !lj_strscan_num(strV(vc), vc)) - lj_trace_err(J, LJ_TRERR_BADTYPE); + rb = conv_str_tonum(J, rb, vb); + rb = lj_ir_tonum(J, rb); /* Left arg is always treated as an FP number. */ + rc = conv_str_tonum(J, rc, vc); /* Narrowing must be unconditional to preserve (-x)^i semantics. */ if (tvisint(vc) || numisint(numV(vc))) { int checkrange = 0; @@ -587,8 +595,6 @@ TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vc) checkrange = 1; } if (!tref_isinteger(rc)) { - if (tref_isstr(rc)) - rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0); /* Guarded conversion to integer! */ rc = emitir(IRTGI(IR_CONV), rc, IRCONV_INT_NUM|IRCONV_CHECK); } diff --git a/src/lj_opt_sink.c b/src/lj_opt_sink.c index 3a333461..4efe395e 100644 --- a/src/lj_opt_sink.c +++ b/src/lj_opt_sink.c @@ -1,6 +1,6 @@ /* ** SINK: Allocation Sinking and Store Sinking. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_sink_c @@ -100,8 +100,8 @@ static void sink_mark_ins(jit_State *J) (LJ_32 && ir+1 < irlast && (ir+1)->o == IR_HIOP && !sink_checkphi(J, ir, (ir+1)->op2)))) irt_setmark(ir->t); /* Mark ineligible allocation. */ - /* fallthrough */ #endif + /* fallthrough */ case IR_USTORE: irt_setmark(IR(ir->op2)->t); /* Mark stored value. */ break; @@ -153,10 +153,9 @@ static void sink_remark_phi(jit_State *J) remark = 0; for (ir = IR(J->cur.nins-1); ir->o == IR_PHI; ir--) { IRIns *irl = IR(ir->op1), *irr = IR(ir->op2); - if (((irl->t.irt ^ irr->t.irt) & IRT_MARK)) - remark = 1; - else if (irl->prev == irr->prev) + if (!((irl->t.irt ^ irr->t.irt) & IRT_MARK) && irl->prev == irr->prev) continue; + remark |= (~(irl->t.irt & irr->t.irt) & IRT_MARK); irt_setmark(IR(ir->op1)->t); irt_setmark(IR(ir->op2)->t); } diff --git a/src/lj_opt_split.c b/src/lj_opt_split.c index 99d10584..8d7cd4c2 100644 --- a/src/lj_opt_split.c +++ b/src/lj_opt_split.c @@ -1,6 +1,6 @@ /* ** SPLIT: Split 64 bit IR instructions into 32 bit IR instructions. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_split_c @@ -471,7 +471,8 @@ static void split_ir(jit_State *J) } #endif else if (st == IRT_I64 || st == IRT_U64) { /* 64/64 bit cast. */ - /* Drop cast, since assembler doesn't care. */ + /* Drop cast, since assembler doesn't care. But fwd both parts. */ + hi = hiref; goto fwdlo; } else if ((ir->op2 & IRCONV_SEXT)) { /* Sign-extend to 64 bit. */ IRRef k31 = lj_ir_kint(J, 31); diff --git a/src/lj_parse.c b/src/lj_parse.c index e8aafba2..67854951 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c @@ -1,6 +1,6 @@ /* ** Lua parser (source code -> bytecode). -** Copyright (C) 2005-2014 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 @@ -685,10 +685,12 @@ static BCPos bcemit_jmp(FuncState *fs) BCPos j = fs->pc - 1; BCIns *ip = &fs->bcbase[j].ins; fs->jpc = NO_JMP; - if ((int32_t)j >= (int32_t)fs->lasttarget && bc_op(*ip) == BC_UCLO) + if ((int32_t)j >= (int32_t)fs->lasttarget && bc_op(*ip) == BC_UCLO) { setbc_j(ip, NO_JMP); - else + fs->lasttarget = j+1; + } else { j = bcemit_AJ(fs, BC_JMP, fs->freereg, NO_JMP); + } jmp_append(fs, &j, jpc); return j; } @@ -1278,12 +1280,14 @@ static void fscope_end(FuncState *fs) MSize idx = gola_new(ls, NAME_BREAK, VSTACK_LABEL, fs->pc); ls->vtop = idx; /* Drop break label immediately. */ gola_resolve(ls, bl, idx); + } else { /* Need the fixup step to propagate the breaks. */ + gola_fixup(ls, bl); return; - } /* else: need the fixup step to propagate the breaks. */ - } else if (!(bl->flags & FSCOPE_GOLA)) { - return; + } + } + if ((bl->flags & FSCOPE_GOLA)) { + gola_fixup(ls, bl); } - gola_fixup(ls, bl); } /* Mark scope as having an upvalue. */ @@ -2205,6 +2209,8 @@ static void assign_adjust(LexState *ls, BCReg nvars, BCReg nexps, ExpDesc *e) bcemit_nil(fs, reg, (BCReg)extra); } } + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* Drop leftover regs. */ } /* Recursively parse assignment statement. */ @@ -2238,8 +2244,6 @@ static void parse_assignment(LexState *ls, LHSVarList *lh, BCReg nvars) return; } assign_adjust(ls, nvars, nexps, &e); - if (nexps > nvars) - ls->fs->freereg -= nexps - nvars; /* Drop leftover regs. */ } /* Assign RHS to LHS and recurse downwards. */ expr_init(&e, VNONRELOC, ls->fs->freereg-1); @@ -2692,7 +2696,8 @@ static int parse_stmt(LexState *ls) lj_lex_next(ls); parse_goto(ls); break; - } /* else: fallthrough */ + } + /* fallthrough */ default: parse_call_assign(ls); break; diff --git a/src/lj_parse.h b/src/lj_parse.h index 532657a0..ceeab699 100644 --- a/src/lj_parse.h +++ b/src/lj_parse.h @@ -1,6 +1,6 @@ /* ** Lua parser (source code -> bytecode). -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_PARSE_H diff --git a/src/lj_record.c b/src/lj_record.c index c6848fc0..bc4e8a6d 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -1,6 +1,6 @@ /* ** Trace recorder (bytecode -> SSA IR). -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_record_c @@ -81,9 +81,9 @@ static void rec_check_slots(jit_State *J) BCReg s, nslots = J->baseslot + J->maxslot; int32_t depth = 0; cTValue *base = J->L->base - J->baseslot; - lua_assert(J->baseslot >= 1 && J->baseslot < LJ_MAX_JSLOTS); + lua_assert(J->baseslot >= 1); lua_assert(J->baseslot == 1 || (J->slot[J->baseslot-1] & TREF_FRAME)); - lua_assert(nslots < LJ_MAX_JSLOTS); + lua_assert(nslots <= LJ_MAX_JSLOTS); for (s = 0; s < nslots; s++) { TRef tr = J->slot[s]; if (tr) { @@ -421,6 +421,7 @@ static void rec_for_loop(jit_State *J, const BCIns *fori, ScEvEntry *scev, J->base[ra+FORL_IDX] = idx = emitir(IRT(IR_ADD, t), idx, step); J->base[ra+FORL_EXT] = idx; scev->idx = tref_ref(idx); + setmref(scev->pc, fori); J->maxslot = ra+FORL_EXT+1; } @@ -436,7 +437,7 @@ static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl) IRType t; if (isforl) { /* Handle FORL/JFORL opcodes. */ TRef idx = tr[FORL_IDX]; - if (tref_ref(idx) == J->scev.idx) { + if (mref(J->scev.pc, const BCIns) == fori && tref_ref(idx) == J->scev.idx) { t = J->scev.t.irt; stop = J->scev.stop; idx = emitir(IRT(IR_ADD, t), idx, J->scev.step); @@ -632,6 +633,8 @@ void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs) J->framedepth++; J->base += func+1; J->baseslot += func+1; + if (J->baseslot + J->maxslot >= LJ_MAX_JSLOTS) + lj_trace_err(J, LJ_TRERR_STACKOV); } /* Record tail call. */ @@ -686,7 +689,7 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) (void)getslot(J, rbase+i); /* Ensure all results have a reference. */ while (frame_ispcall(frame)) { /* Immediately resolve pcall() returns. */ BCReg cbase = (BCReg)frame_delta(frame); - if (--J->framedepth < 0) + if (--J->framedepth <= 0) lj_trace_err(J, LJ_TRERR_NYIRETL); lua_assert(J->baseslot > 1); gotresults++; @@ -744,6 +747,8 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) } else if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))) { /* Return to lower frame would leave the loop in a root trace. */ lj_trace_err(J, LJ_TRERR_LLEAVE); + } else if (J->needsnap) { /* Tailcalled to ff with side-effects. */ + lj_trace_err(J, LJ_TRERR_NYIRETL); /* No way to insert snapshot here. */ } else { /* Return to lower frame. Guard for the target we return to. */ TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame)); @@ -1059,7 +1064,7 @@ static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize) lua_assert(irt_isint(J->scev.t) && ir->o == IR_SLOAD); stop = numberVint(&(J->L->base - J->baseslot)[ir->op1 + FORL_STOP]); /* Runtime value for stop of loop is within bounds? */ - if ((int64_t)stop + ofs < (int64_t)asize) { + if ((uint64_t)stop + ofs < (uint64_t)asize) { /* Emit invariant bounds check for stop. */ emitir(IRTG(IR_ABC, IRT_P32), asizeref, ofs == 0 ? J->scev.stop : emitir(IRTI(IR_ADD), J->scev.stop, ofsref)); @@ -1340,13 +1345,17 @@ static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val) /* Note: this effectively limits LJ_MAX_UPVAL to 127. */ uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff); if (!uvp->closed) { + uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_P32), fn, uv)); /* In current stack? */ if (uvval(uvp) >= tvref(J->L->stack) && uvval(uvp) < tvref(J->L->maxstack)) { int32_t slot = (int32_t)(uvval(uvp) - (J->L->base - J->baseslot)); if (slot >= 0) { /* Aliases an SSA slot? */ + emitir(IRTG(IR_EQ, IRT_P32), + REF_BASE, + emitir(IRT(IR_ADD, IRT_P32), uref, + lj_ir_kint(J, (slot - 1) * -8))); slot -= (int32_t)J->baseslot; /* Note: slot number may be negative! */ - /* NYI: add IR to guard that it's still aliasing the same slot. */ if (val == 0) { return getslot(J, slot); } else { @@ -1356,7 +1365,9 @@ static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val) } } } - uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_P32), fn, uv)); + emitir(IRTG(IR_UGT, IRT_P32), + emitir(IRT(IR_SUB, IRT_P32), uref, REF_BASE), + lj_ir_kint(J, (J->baseslot + J->maxslot) * 8)); } else { needbarrier = 1; uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_P32), fn, uv)); @@ -1487,8 +1498,11 @@ static int select_detect(jit_State *J) BCIns ins = J->pc[1]; if (bc_op(ins) == BC_CALLM && bc_b(ins) == 2 && bc_c(ins) == 1) { cTValue *func = &J->L->base[bc_a(ins)]; - if (tvisfunc(func) && funcV(func)->c.ffid == FF_select) + if (tvisfunc(func) && funcV(func)->c.ffid == FF_select) { + TRef kfunc = lj_ir_kfunc(J, funcV(func)); + emitir(IRTG(IR_EQ, IRT_FUNC), getslot(J, bc_a(ins)), kfunc); return 1; + } } return 0; } @@ -1878,14 +1892,14 @@ void lj_record_ins(jit_State *J) case BC_MODVN: case BC_MODVV: recmod: if (tref_isnumber_str(rb) && tref_isnumber_str(rc)) - rc = lj_opt_narrow_mod(J, rb, rc, rcv); + rc = lj_opt_narrow_mod(J, rb, rc, rbv, rcv); else rc = rec_mm_arith(J, &ix, MM_mod); break; case BC_POW: if (tref_isnumber_str(rb) && tref_isnumber_str(rc)) - rc = lj_opt_narrow_pow(J, lj_ir_tonum(J, rb), rc, rcv); + rc = lj_opt_narrow_pow(J, rb, rc, rbv, rcv); else rc = rec_mm_arith(J, &ix, MM_pow); break; @@ -2153,6 +2167,7 @@ void lj_record_setup(jit_State *J) memset(J->chain, 0, sizeof(J->chain)); memset(J->bpropcache, 0, sizeof(J->bpropcache)); J->scev.idx = REF_NIL; + setmref(J->scev.pc, NULL); J->baseslot = 1; /* Invoking function is at base[-1]. */ J->base = J->slot + J->baseslot; diff --git a/src/lj_record.h b/src/lj_record.h index 940e105f..2bbbde5b 100644 --- a/src/lj_record.h +++ b/src/lj_record.h @@ -1,6 +1,6 @@ /* ** Trace recorder (bytecode -> SSA IR). -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_RECORD_H diff --git a/src/lj_snap.c b/src/lj_snap.c index 1c978c26..73f25004 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c @@ -1,6 +1,6 @@ /* ** Snapshot handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_snap_c @@ -26,9 +26,6 @@ #include "lj_cdata.h" #endif -/* Some local macros to save typing. Undef'd at the end. */ -#define IR(ref) (&J->cur.ir[(ref)]) - /* Pass IR on to next optimization in chain (FOLD). */ #define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J)) @@ -73,7 +70,7 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) IRRef ref = tref_ref(tr); if (ref) { SnapEntry sn = SNAP_TR(s, tr); - IRIns *ir = IR(ref); + IRIns *ir = &J->cur.ir[ref]; if (!(sn & (SNAP_CONT|SNAP_FRAME)) && ir->o == IR_SLOAD && ir->op1 == s && ref > retf) { /* No need to snapshot unmodified non-inherited slots. */ @@ -104,8 +101,6 @@ static BCReg snapshot_framelinks(jit_State *J, SnapEntry *map) if (frame_islua(frame)) { map[f++] = SNAP_MKPC(frame_pc(frame)); frame = frame_prevl(frame); - if (frame + funcproto(frame_func(frame))->framesize > ftop) - ftop = frame + funcproto(frame_func(frame))->framesize; } else if (frame_iscont(frame)) { map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); map[f++] = SNAP_MKPC(frame_contpc(frame)); @@ -114,7 +109,10 @@ static BCReg snapshot_framelinks(jit_State *J, SnapEntry *map) lua_assert(!frame_isc(frame)); map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); frame = frame_prevd(frame); + continue; } + if (frame + funcproto(frame_func(frame))->framesize > ftop) + ftop = frame + funcproto(frame_func(frame))->framesize; } lua_assert(f == (MSize)(1 + J->framedepth)); return (BCReg)(ftop - lim); @@ -131,12 +129,12 @@ static void snapshot_stack(jit_State *J, SnapShot *snap, MSize nsnapmap) p = &J->cur.snapmap[nsnapmap]; nent = snapshot_slots(J, p, nslots); snap->topslot = (uint8_t)snapshot_framelinks(J, p + nent); - snap->mapofs = (uint16_t)nsnapmap; + snap->mapofs = (uint32_t)nsnapmap; snap->ref = (IRRef1)J->cur.nins; snap->nent = (uint8_t)nent; snap->nslots = (uint8_t)nslots; snap->count = 0; - J->cur.nsnapmap = (uint16_t)(nsnapmap + nent + 1 + J->framedepth); + J->cur.nsnapmap = (uint32_t)(nsnapmap + nent + 1 + J->framedepth); } /* Add or merge a snapshot. */ @@ -296,7 +294,7 @@ void lj_snap_shrink(jit_State *J) snap->nent = (uint8_t)m; nlim = J->cur.nsnapmap - snap->mapofs - 1; while (n <= nlim) map[m++] = map[n++]; /* Move PC + frame links down. */ - J->cur.nsnapmap = (uint16_t)(snap->mapofs + m); /* Free up space in map. */ + J->cur.nsnapmap = (uint32_t)(snap->mapofs + m); /* Free up space in map. */ } /* -- Snapshot access ----------------------------------------------------- */ @@ -403,24 +401,24 @@ static TRef snap_pref(jit_State *J, GCtrace *T, SnapEntry *map, MSize nmax, } /* Check whether a sunk store corresponds to an allocation. Slow path. */ -static int snap_sunk_store2(jit_State *J, IRIns *ira, IRIns *irs) +static int snap_sunk_store2(GCtrace *T, IRIns *ira, IRIns *irs) { if (irs->o == IR_ASTORE || irs->o == IR_HSTORE || irs->o == IR_FSTORE || irs->o == IR_XSTORE) { - IRIns *irk = IR(irs->op1); + IRIns *irk = &T->ir[irs->op1]; if (irk->o == IR_AREF || irk->o == IR_HREFK) - irk = IR(irk->op1); - return (IR(irk->op1) == ira); + irk = &T->ir[irk->op1]; + return (&T->ir[irk->op1] == ira); } return 0; } /* Check whether a sunk store corresponds to an allocation. Fast path. */ -static LJ_AINLINE int snap_sunk_store(jit_State *J, IRIns *ira, IRIns *irs) +static LJ_AINLINE int snap_sunk_store(GCtrace *T, IRIns *ira, IRIns *irs) { if (irs->s != 255) return (ira + irs->s == irs); /* Fast check. */ - return snap_sunk_store2(J, ira, irs); + return snap_sunk_store2(T, ira, irs); } /* Replay snapshot state to setup side trace. */ @@ -483,7 +481,7 @@ void lj_snap_replay(jit_State *J, GCtrace *T) } else { IRIns *irs; for (irs = ir+1; irs < irlast; irs++) - if (irs->r == RID_SINK && snap_sunk_store(J, ir, irs)) { + if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { if (snap_pref(J, T, map, nent, seen, irs->op2) == 0) snap_pref(J, T, map, nent, seen, T->ir[irs->op2].op1); else if ((LJ_SOFTFP || (LJ_32 && LJ_HASFFI)) && @@ -517,13 +515,13 @@ void lj_snap_replay(jit_State *J, GCtrace *T) op2 = emitir_raw(IRT(IR_HIOP, IRT_I64), op2, snap_pref(J, T, map, nent, seen, (ir+1)->op2)); } - J->slot[snap_slot(sn)] = emitir(ir->ot, op1, op2); + J->slot[snap_slot(sn)] = emitir(ir->ot & ~(IRT_MARK|IRT_ISPHI), op1, op2); } else { IRIns *irs; TRef tr = emitir(ir->ot, op1, op2); J->slot[snap_slot(sn)] = tr; for (irs = ir+1; irs < irlast; irs++) - if (irs->r == RID_SINK && snap_sunk_store(J, ir, irs)) { + if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { IRIns *irr = &T->ir[irs->op1]; TRef val, key = irr->op2, tmp = tr; if (irr->o != IR_FREF) { @@ -725,7 +723,7 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex, } else { IRIns *irs, *irlast = &T->ir[T->snap[snapno].ref]; for (irs = ir+1; irs < irlast; irs++) - if (irs->r == RID_SINK && snap_sunk_store(J, ir, irs)) { + if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { IRIns *iro = &T->ir[T->ir[irs->op1].op2]; uint8_t *p = (uint8_t *)cd; CTSize szs; @@ -758,7 +756,7 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex, settabV(J->L, o, t); irlast = &T->ir[T->snap[snapno].ref]; for (irs = ir+1; irs < irlast; irs++) - if (irs->r == RID_SINK && snap_sunk_store(J, ir, irs)) { + if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { IRIns *irk = &T->ir[irs->op1]; TValue tmp, *val; lua_assert(irs->o == IR_ASTORE || irs->o == IR_HSTORE || @@ -858,7 +856,6 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) return pc; } -#undef IR #undef emitir_raw #undef emitir diff --git a/src/lj_snap.h b/src/lj_snap.h index 1b2d74da..2c9ae3d6 100644 --- a/src/lj_snap.h +++ b/src/lj_snap.h @@ -1,6 +1,6 @@ /* ** Snapshot handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_SNAP_H diff --git a/src/lj_state.c b/src/lj_state.c index f972fdce..f8913519 100644 --- a/src/lj_state.c +++ b/src/lj_state.c @@ -1,6 +1,6 @@ /* ** State and stack handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -175,7 +175,7 @@ static void close_state(lua_State *L) g->allocf(g->allocd, G2GG(g), sizeof(GG_State), 0); } -#if LJ_64 +#if LJ_64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC)) lua_State *lj_state_newstate(lua_Alloc f, void *ud) #else LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) diff --git a/src/lj_state.h b/src/lj_state.h index 74249d9b..d5b476b2 100644 --- a/src/lj_state.h +++ b/src/lj_state.h @@ -1,6 +1,6 @@ /* ** State and stack handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_STATE_H diff --git a/src/lj_str.c b/src/lj_str.c index aead8b53..aae6ec5b 100644 --- a/src/lj_str.c +++ b/src/lj_str.c @@ -1,6 +1,6 @@ /* ** String handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h diff --git a/src/lj_str.h b/src/lj_str.h index 1602c980..be04a975 100644 --- a/src/lj_str.h +++ b/src/lj_str.h @@ -1,6 +1,6 @@ /* ** String handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_STR_H diff --git a/src/lj_strscan.c b/src/lj_strscan.c index a21c414a..f1e34a3d 100644 --- a/src/lj_strscan.c +++ b/src/lj_strscan.c @@ -1,6 +1,6 @@ /* ** String scanning. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include @@ -199,7 +199,7 @@ static StrScanFmt strscan_dec(const uint8_t *p, TValue *o, *xip++ = d + ((*p != '.' ? *p : *++p) & 15); p++; } /* Scan and realign trailing digit. */ - if (i) *xip++ = 10 * ((*p != '.' ? *p : *++p) & 15), ex10--, p++; + if (i) *xip++ = 10 * ((*p != '.' ? *p : *++p) & 15), ex10--, dig++, p++; /* Summarize rounding-effect of excess digits. */ if (dig > STRSCAN_MAXDIG) { @@ -289,14 +289,15 @@ static StrScanFmt strscan_dec(const uint8_t *p, TValue *o, /* Scale down until no more than 17 or 18 integer part digits remain. */ while (idig > 9) { - uint32_t i, cy = 0; + uint32_t i = hi, cy = 0; ex2 += 6; - for (i = hi; i != lo; i = DNEXT(i)) { + do { cy += xi[i]; xi[i] = (cy >> 6); cy = 100 * (cy & 0x3f); if (xi[i] == 0 && i == hi) hi = DNEXT(hi), idig--; - } + i = DNEXT(i); + } while (i != lo); while (cy) { if (hi == lo) { xi[DPREV(lo)] |= 1; break; } xi[lo] = (cy >> 6); lo = DNEXT(lo); diff --git a/src/lj_strscan.h b/src/lj_strscan.h index 15abd6af..6fb0dda0 100644 --- a/src/lj_strscan.h +++ b/src/lj_strscan.h @@ -1,6 +1,6 @@ /* ** String scanning. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_STRSCAN_H diff --git a/src/lj_tab.c b/src/lj_tab.c index fc7d0f1c..f2f3c0b0 100644 --- a/src/lj_tab.c +++ b/src/lj_tab.c @@ -1,6 +1,6 @@ /* ** Table handling. -** Copyright (C) 2005-2014 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 @@ -457,6 +457,29 @@ TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key) freenode->next = nn->next; nn->next = n->next; setmref(n->next, nn); + /* + ** Rechaining a resurrected string key creates a new dilemma: + ** Another string key may have originally been resurrected via + ** _any_ of the previous nodes as a chain anchor. Including + ** a node that had to be moved, which makes them unreachable. + ** It's not feasible to check for all previous nodes, so rechain + ** any string key that's currently in a non-main positions. + */ + while ((nn = nextnode(freenode))) { + if (tvisstr(&nn->key) && !tvisnil(&nn->val)) { + Node *mn = hashstr(t, strV(&nn->key)); + if (mn != freenode) { + freenode->next = nn->next; + nn->next = mn->next; + setmref(mn->next, nn); + } else { + freenode = nn; + } + } else { + freenode = nn; + } + } + break; } else { freenode = nn; } diff --git a/src/lj_tab.h b/src/lj_tab.h index 44b1bbbd..36ce7cdd 100644 --- a/src/lj_tab.h +++ b/src/lj_tab.h @@ -1,6 +1,6 @@ /* ** Table handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TAB_H diff --git a/src/lj_target.h b/src/lj_target.h index 820a97a4..53bfa6bf 100644 --- a/src/lj_target.h +++ b/src/lj_target.h @@ -1,6 +1,6 @@ /* ** Definitions for target CPU. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_H diff --git a/src/lj_target_arm.h b/src/lj_target_arm.h index 63a0c925..d02cbf86 100644 --- a/src/lj_target_arm.h +++ b/src/lj_target_arm.h @@ -1,6 +1,6 @@ /* ** Definitions for ARM CPUs. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_ARM_H diff --git a/src/lj_target_mips.h b/src/lj_target_mips.h index e0fc152d..bed174b8 100644 --- a/src/lj_target_mips.h +++ b/src/lj_target_mips.h @@ -1,6 +1,6 @@ /* ** Definitions for MIPS CPUs. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_MIPS_H @@ -28,6 +28,7 @@ enum { RID_MAX, RID_ZERO = RID_R0, RID_TMP = RID_RA, + RID_GP = RID_R28, /* Calling conventions. */ RID_RET = RID_R2, @@ -62,10 +63,10 @@ enum { /* -- Register sets ------------------------------------------------------- */ -/* Make use of all registers, except ZERO, TMP, SP, SYS1, SYS2 and JGL. */ +/* Make use of all registers, except ZERO, TMP, SP, SYS1, SYS2, JGL and GP. */ #define RSET_FIXED \ (RID2RSET(RID_ZERO)|RID2RSET(RID_TMP)|RID2RSET(RID_SP)|\ - RID2RSET(RID_SYS1)|RID2RSET(RID_SYS2)|RID2RSET(RID_JGL)) + RID2RSET(RID_SYS1)|RID2RSET(RID_SYS2)|RID2RSET(RID_JGL)|RID2RSET(RID_GP)) #define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR) - RSET_FIXED) #define RSET_FPR \ (RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\ @@ -77,7 +78,7 @@ enum { #define RSET_SCRATCH_GPR \ (RSET_RANGE(RID_R1, RID_R15+1)|\ - RID2RSET(RID_R24)|RID2RSET(RID_R25)|RID2RSET(RID_R28)) + RID2RSET(RID_R24)|RID2RSET(RID_R25)) #define RSET_SCRATCH_FPR \ (RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\ RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\ diff --git a/src/lj_target_ppc.h b/src/lj_target_ppc.h index 475e0465..e57e27df 100644 --- a/src/lj_target_ppc.h +++ b/src/lj_target_ppc.h @@ -1,6 +1,6 @@ /* ** Definitions for PPC CPUs. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_PPC_H diff --git a/src/lj_target_x86.h b/src/lj_target_x86.h index 41f401b0..4426cc8c 100644 --- a/src/lj_target_x86.h +++ b/src/lj_target_x86.h @@ -1,6 +1,6 @@ /* ** Definitions for x86 and x64 CPUs. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_X86_H diff --git a/src/lj_trace.c b/src/lj_trace.c index 9e5e400f..6f8dc1a4 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c @@ -1,6 +1,6 @@ /* ** Trace management. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_trace_c @@ -117,15 +117,22 @@ static void perftools_addtrace(GCtrace *T) } #endif -/* Save current trace by copying and compacting it. */ -static void trace_save(jit_State *J) +/* Allocate space for copy of trace. */ +static GCtrace *trace_save_alloc(jit_State *J) { size_t sztr = ((sizeof(GCtrace)+7)&~7); size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns); size_t sz = sztr + szins + J->cur.nsnap*sizeof(SnapShot) + J->cur.nsnapmap*sizeof(SnapEntry); - GCtrace *T = lj_mem_newt(J->L, (MSize)sz, GCtrace); + return lj_mem_newt(J->L, (MSize)sz, GCtrace); +} + +/* Save current trace by copying and compacting it. */ +static void trace_save(jit_State *J, GCtrace *T) +{ + size_t sztr = ((sizeof(GCtrace)+7)&~7); + size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns); char *p = (char *)T + sztr; memcpy(T, &J->cur, sizeof(GCtrace)); setgcrefr(T->nextgc, J2G(J)->gc.root); @@ -417,6 +424,7 @@ static void trace_stop(jit_State *J) BCOp op = bc_op(J->cur.startins); GCproto *pt = &gcref(J->cur.startpt)->pt; TraceNo traceno = J->cur.traceno; + GCtrace *T = trace_save_alloc(J); /* Do this first. May throw OOM. */ lua_State *L; switch (op) { @@ -461,7 +469,7 @@ static void trace_stop(jit_State *J) /* Commit new mcode only after all patching is done. */ lj_mcode_commit(J, J->cur.mcode); J->postproc = LJ_POST_NONE; - trace_save(J); + trace_save(J, T); L = J->L; lj_vmevent_send(L, TRACE, @@ -607,6 +615,7 @@ static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud) } lj_opt_split(J); lj_opt_sink(J); + if (!J->loopref) J->cur.snap[J->cur.nsnap-1].count = SNAPCOUNT_DONE; J->state = LJ_TRACE_ASM; break; diff --git a/src/lj_trace.h b/src/lj_trace.h index f3109081..edc7af0d 100644 --- a/src/lj_trace.h +++ b/src/lj_trace.h @@ -1,6 +1,6 @@ /* ** Trace management. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TRACE_H diff --git a/src/lj_traceerr.h b/src/lj_traceerr.h index 521560a1..f920e5ed 100644 --- a/src/lj_traceerr.h +++ b/src/lj_traceerr.h @@ -1,6 +1,6 @@ /* ** Trace compiler error messages. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* This file may be included multiple times with different TREDEF macros. */ @@ -23,7 +23,7 @@ TREDEF(BADTYPE, "bad argument type") TREDEF(CJITOFF, "JIT compilation disabled for function") TREDEF(CUNROLL, "call unroll limit reached") TREDEF(DOWNREC, "down-recursion, restarting") -TREDEF(NYICF, "NYI: C function %p") +TREDEF(NYICF, "NYI: C function %s") TREDEF(NYIFF, "NYI: FastFunc %s") TREDEF(NYIFFU, "NYI: unsupported variant of FastFunc %s") TREDEF(NYIRETL, "NYI: return to lower frame") diff --git a/src/lj_udata.c b/src/lj_udata.c index 6cd357ec..bd0321b8 100644 --- a/src/lj_udata.c +++ b/src/lj_udata.c @@ -1,6 +1,6 @@ /* ** Userdata handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_udata_c diff --git a/src/lj_udata.h b/src/lj_udata.h index e03d9a3a..f271a42d 100644 --- a/src/lj_udata.h +++ b/src/lj_udata.h @@ -1,6 +1,6 @@ /* ** Userdata handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_UDATA_H diff --git a/src/lj_vm.h b/src/lj_vm.h index 4a8f03f0..3ffa76bf 100644 --- a/src/lj_vm.h +++ b/src/lj_vm.h @@ -1,6 +1,6 @@ /* ** Assembler VM interface definitions. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_VM_H diff --git a/src/lj_vmevent.c b/src/lj_vmevent.c index e14ad5b6..7b6d7bf3 100644 --- a/src/lj_vmevent.c +++ b/src/lj_vmevent.c @@ -1,6 +1,6 @@ /* ** VM event handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #include diff --git a/src/lj_vmevent.h b/src/lj_vmevent.h index 51bae015..050fb4dd 100644 --- a/src/lj_vmevent.h +++ b/src/lj_vmevent.h @@ -1,6 +1,6 @@ /* ** VM event handling. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_VMEVENT_H diff --git a/src/lj_vmmath.c b/src/lj_vmmath.c index 63886aa7..73fc667f 100644 --- a/src/lj_vmmath.c +++ b/src/lj_vmmath.c @@ -1,6 +1,6 @@ /* ** Math helper functions for assembler VM. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #define lj_vmmath_c diff --git a/src/ljamalg.c b/src/ljamalg.c index 52a86153..654fe82f 100644 --- a/src/ljamalg.c +++ b/src/ljamalg.c @@ -1,6 +1,6 @@ /* ** LuaJIT core and libraries amalgamation. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ /* diff --git a/src/luaconf.h.orig b/src/luaconf.h.orig index affb7da8..b33e91b7 100644 --- a/src/luaconf.h.orig +++ b/src/luaconf.h.orig @@ -1,6 +1,6 @@ /* ** Configuration header. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef luaconf_h @@ -37,7 +37,7 @@ #endif #define LUA_LROOT "/usr/local" #define LUA_LUADIR "/lua/5.1/" -#define LUA_LJDIR "/luajit-2.0.3/" +#define LUA_LJDIR "/luajit-2.0.5/" #ifdef LUA_ROOT #define LUA_JROOT LUA_ROOT diff --git a/src/luajit.c b/src/luajit.c index 4cccf04e..9ede59c1 100644 --- a/src/luajit.c +++ b/src/luajit.c @@ -1,6 +1,6 @@ /* ** LuaJIT frontend. Runs commands, scripts, read-eval-print (REPL) etc. -** Copyright (C) 2005-2014 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 @@ -151,6 +151,7 @@ static void print_jit_status(lua_State *L) fputs(s, stdout); } putc('\n', stdout); + lua_settop(L, 0); /* clear stack */ } static int getargs(lua_State *L, char **argv, int n) @@ -301,17 +302,17 @@ static int loadjitmodule(lua_State *L) lua_concat(L, 2); if (lua_pcall(L, 1, 1, 0)) { const char *msg = lua_tostring(L, -1); - if (msg && !strncmp(msg, "module ", 7)) { - err: - l_message(progname, - "unknown luaJIT command or jit.* modules not installed"); - return 1; - } else { - return report(L, 1); - } + if (msg && !strncmp(msg, "module ", 7)) + goto nomodule; + return report(L, 1); } lua_getfield(L, -1, "start"); - if (lua_isnil(L, -1)) goto err; + if (lua_isnil(L, -1)) { + nomodule: + l_message(progname, + "unknown luaJIT command or jit.* modules not installed"); + return 1; + } lua_remove(L, -2); /* Drop module table. */ return 0; } @@ -419,6 +420,7 @@ static int collectargs(char **argv, int *flags) break; case 'e': *flags |= FLAGS_EXEC; + /* fallthrough */ case 'j': /* LuaJIT extension */ case 'l': *flags |= FLAGS_OPTION; diff --git a/src/luajit.h b/src/luajit.h index be721cf4..c5ff3acb 100644 --- a/src/luajit.h +++ b/src/luajit.h @@ -1,7 +1,7 @@ /* ** LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/ ** -** Copyright (C) 2005-2014 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 @@ -30,10 +30,10 @@ #include "lua.h" -#define LUAJIT_VERSION "LuaJIT 2.0.3" -#define LUAJIT_VERSION_NUM 20003 /* Version 2.0.3 = 02.00.03. */ -#define LUAJIT_VERSION_SYM luaJIT_version_2_0_3 -#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2014 Mike Pall" +#define LUAJIT_VERSION "LuaJIT 2.0.5" +#define LUAJIT_VERSION_NUM 20005 /* Version 2.0.5 = 02.00.05. */ +#define LUAJIT_VERSION_SYM luaJIT_version_2_0_5 +#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2017 Mike Pall" #define LUAJIT_URL "http://luajit.org/" /* Modes for luaJIT_setmode. */ diff --git a/src/lualib.h b/src/lualib.h index 1c1e3179..bfc130a1 100644 --- a/src/lualib.h +++ b/src/lualib.h @@ -1,6 +1,6 @@ /* ** Standard library header. -** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LUALIB_H diff --git a/src/msvcbuild.bat b/src/msvcbuild.bat index 9160e0f8..bd0c4c5f 100644 --- a/src/msvcbuild.bat +++ b/src/msvcbuild.bat @@ -1,5 +1,5 @@ @rem Script to build LuaJIT with MSVC. -@rem Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +@rem Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h @rem @rem Either open a "Visual Studio .NET Command Prompt" @rem (Note that the Express Edition does not contain an x64 compiler) @@ -14,7 +14,7 @@ @if not defined INCLUDE goto :FAIL @setlocal -@set LJCOMPILE=cl /nologo /c /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE +@set LJCOMPILE=cl /nologo /c /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_STDIO_INLINE=__declspec(dllexport)__inline @set LJLINK=link /nologo @set LJMT=mt /nologo @set LJLIB=lib /nologo /nodefaultlib @@ -98,6 +98,8 @@ if exist luajit.exe.manifest^ %LJMT% -manifest luajit.exe.manifest -outputresource:luajit.exe @del *.obj *.manifest minilua.exe buildvm.exe +@del host\buildvm_arch.h +@del lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h @echo. @echo === Successfully built LuaJIT for Windows/%LJARCH% === diff --git a/src/ps4build.bat b/src/ps4build.bat index 42fc9a64..337a44fa 100644 --- a/src/ps4build.bat +++ b/src/ps4build.bat @@ -27,11 +27,11 @@ if exist minilua.exe.manifest^ @minilua @if not errorlevel 8 goto :FAIL -@set DASMFLAGS=-D P64 +@set DASMFLAGS=-D P64 -D NO_UNWIND minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h vm_x86.dasc @if errorlevel 1 goto :BAD -%LJCOMPILE% /I "." /I %DASMDIR% -DLUAJIT_TARGET=LUAJIT_ARCH_X64 -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI host\buildvm*.c +%LJCOMPILE% /I "." /I %DASMDIR% -DLUAJIT_TARGET=LUAJIT_ARCH_X64 -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLUAJIT_NO_UNWIND host\buildvm*.c @if errorlevel 1 goto :BAD %LJLINK% /out:buildvm.exe buildvm*.obj @if errorlevel 1 goto :BAD diff --git a/src/psvitabuild.bat b/src/psvitabuild.bat new file mode 100644 index 00000000..3991dc65 --- /dev/null +++ b/src/psvitabuild.bat @@ -0,0 +1,93 @@ +@rem Script to build LuaJIT with the PS Vita SDK. +@rem Donated to the public domain. +@rem +@rem Open a "Visual Studio .NET Command Prompt" (32 bit host compiler) +@rem Then cd to this directory and run this script. + +@if not defined INCLUDE goto :FAIL +@if not defined SCE_PSP2_SDK_DIR goto :FAIL + +@setlocal +@rem ---- Host compiler ---- +@set LJCOMPILE=cl /nologo /c /MD /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE +@set LJLINK=link /nologo +@set LJMT=mt /nologo +@set DASMDIR=..\dynasm +@set DASM=%DASMDIR%\dynasm.lua +@set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c + +%LJCOMPILE% host\minilua.c +@if errorlevel 1 goto :BAD +%LJLINK% /out:minilua.exe minilua.obj +@if errorlevel 1 goto :BAD +if exist minilua.exe.manifest^ + %LJMT% -manifest minilua.exe.manifest -outputresource:minilua.exe + +@rem Check for 32 bit host compiler. +@minilua +@if errorlevel 8 goto :FAIL + +@set DASMFLAGS=-D FPU -D HFABI +minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h vm_arm.dasc +@if errorlevel 1 goto :BAD + +%LJCOMPILE% /I "." /I %DASMDIR% -DLUAJIT_TARGET=LUAJIT_ARCH_ARM -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLJ_TARGET_PSVITA=1 host\buildvm*.c +@if errorlevel 1 goto :BAD +%LJLINK% /out:buildvm.exe buildvm*.obj +@if errorlevel 1 goto :BAD +if exist buildvm.exe.manifest^ + %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe + +buildvm -m elfasm -o lj_vm.s +@if errorlevel 1 goto :BAD +buildvm -m bcdef -o lj_bcdef.h %ALL_LIB% +@if errorlevel 1 goto :BAD +buildvm -m ffdef -o lj_ffdef.h %ALL_LIB% +@if errorlevel 1 goto :BAD +buildvm -m libdef -o lj_libdef.h %ALL_LIB% +@if errorlevel 1 goto :BAD +buildvm -m recdef -o lj_recdef.h %ALL_LIB% +@if errorlevel 1 goto :BAD +buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB% +@if errorlevel 1 goto :BAD +buildvm -m folddef -o lj_folddef.h lj_opt_fold.c +@if errorlevel 1 goto :BAD + +@rem ---- Cross compiler ---- +@set LJCOMPILE="%SCE_PSP2_SDK_DIR%\host_tools\build\bin\psp2snc" -c -w -DLUAJIT_DISABLE_FFI -DLUAJIT_USE_SYSMALLOC +@set LJLIB="%SCE_PSP2_SDK_DIR%\host_tools\build\bin\psp2ld32" -r --output= +@set INCLUDE="" + +"%SCE_PSP2_SDK_DIR%\host_tools\build\bin\psp2as" -o lj_vm.o lj_vm.s + +@if "%1" neq "debug" goto :NODEBUG +@shift +@set LJCOMPILE=%LJCOMPILE% -g -O0 +@set TARGETLIB=libluajitD.a +goto :BUILD +:NODEBUG +@set LJCOMPILE=%LJCOMPILE% -O2 +@set TARGETLIB=libluajit.a +:BUILD +del %TARGETLIB% + +%LJCOMPILE% ljamalg.c +@if errorlevel 1 goto :BAD +%LJLIB%%TARGETLIB% ljamalg.o lj_vm.o +@if errorlevel 1 goto :BAD + +@del *.o *.obj *.manifest minilua.exe buildvm.exe +@echo. +@echo === Successfully built LuaJIT for PS Vita === + +@goto :END +:BAD +@echo. +@echo ******************************************************* +@echo *** Build FAILED -- Please check the error messages *** +@echo ******************************************************* +@goto :END +:FAIL +@echo To run this script you must open a "Visual Studio .NET Command Prompt" +@echo (32 bit host compiler). The PS Vita SDK must be installed, too. +:END diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc index 82cba909..be5540ce 100644 --- a/src/vm_arm.dasc +++ b/src/vm_arm.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for ARM CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h | |.arch arm |.section code_op, code_sub @@ -335,7 +335,7 @@ static void build_subroutines(BuildCtx *ctx) | // - The GC shrinks the stack in between. | // - A return back from a lua_call() with (high) nresults adjustment. | str BASE, L->top // Save current top held in BASE (yes). - | mov CARG2, KBASE + | lsr CARG2, KBASE, #3 | mov CARG1, L | bl extern lj_state_growstack // (lua_State *L, int n) | ldr BASE, L->top // Need the (realloced) L->top in BASE. @@ -389,7 +389,7 @@ static void build_subroutines(BuildCtx *ctx) | str BASE, L->base | add PC, PC, #4 // Must point after first instruction. | str RC, L->top - | lsr CARG3, RA, #3 + | lsr CARG2, RA, #3 |2: | // L->base = new base, L->top = top | str PC, SAVE_PC @@ -539,9 +539,8 @@ static void build_subroutines(BuildCtx *ctx) |1: | beq ->cont_ffi_callback // cont = 1: return from FFI callback. | // cont = 0: tailcall from C function. - | ldr CARG3, [BASE, FRAME_FUNC] - | sub CARG4, CARG4, #16 - | sub RC, CARG4, BASE + | sub CARG4, CARG4, #16 + | sub RC, CARG4, BASE | b ->vm_call_tail |.endif | @@ -3241,10 +3240,10 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | mvn RC, RC | ldr UPVAL:CARG2, [LFUNC:CARG2, RA] | ldr STR:CARG3, [KBASE, RC, lsl #2] - | mvn CARG4, #~LJ_TSTR | ldrb RB, UPVAL:CARG2->marked - | ldr CARG2, UPVAL:CARG2->v | ldrb RC, UPVAL:CARG2->closed + | ldr CARG2, UPVAL:CARG2->v + | mvn CARG4, #~LJ_TSTR | tst RB, #LJ_GC_BLACK // isblack(uv) | ldrb RB, STR:CARG3->marked | strd CARG34, [CARG2] diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc index 0ec13e60..3f9c98c1 100644 --- a/src/vm_mips.dasc +++ b/src/vm_mips.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for MIPS CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h | |.arch mips |.section code_op, code_sub @@ -398,7 +398,7 @@ static void build_subroutines(BuildCtx *ctx) | // - A return back from a lua_call() with (high) nresults adjustment. | load_got lj_state_growstack | move MULTRES, RD - | move CARG2, TMP2 + | srl CARG2, TMP2, 3 | call_intern lj_state_growstack // (lua_State *L, int n) |. move CARG1, L | lw TMP2, SAVE_NRES @@ -1621,6 +1621,7 @@ static void build_subroutines(BuildCtx *ctx) | |.ffunc string_char // Only handle the 1-arg case here. | ffgccheck + |. nop | lw CARG3, HI(BASE) | ldc1 FARG1, 0(BASE) | li AT, 8 @@ -1648,6 +1649,7 @@ static void build_subroutines(BuildCtx *ctx) | |.ffunc string_sub | ffgccheck + |. nop | addiu AT, NARGS8:RC, -16 | lw CARG3, 16+HI(BASE) | ldc1 f0, 16(BASE) @@ -1697,6 +1699,7 @@ static void build_subroutines(BuildCtx *ctx) | |.ffunc string_rep // Only handle the 1-char case inline. | ffgccheck + |. nop | lw TMP0, HI(BASE) | addiu AT, NARGS8:RC, -16 // Exactly 2 arguments. | lw CARG4, 8+HI(BASE) @@ -1731,6 +1734,7 @@ static void build_subroutines(BuildCtx *ctx) | |.ffunc string_reverse | ffgccheck + |. nop | lw CARG3, HI(BASE) | lw STR:CARG1, LO(BASE) | beqz NARGS8:RC, ->fff_fallback @@ -1756,6 +1760,7 @@ static void build_subroutines(BuildCtx *ctx) |.macro ffstring_case, name, lo | .ffunc name | ffgccheck + |. nop | lw CARG3, HI(BASE) | lw STR:CARG1, LO(BASE) | beqz NARGS8:RC, ->fff_fallback @@ -3614,24 +3619,24 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) case BC_ISNEXT: | // RA = base*8, RD = target (points to ITERN) | addu RA, BASE, RA - | lw TMP0, -24+HI(RA) - | lw CFUNC:TMP1, -24+LO(RA) - | lw TMP2, -16+HI(RA) - | lw TMP3, -8+HI(RA) + | srl TMP0, RD, 1 + | lw CARG1, -24+HI(RA) + | lw CFUNC:CARG2, -24+LO(RA) + | addu TMP0, PC, TMP0 + | lw CARG3, -16+HI(RA) + | lw CARG4, -8+HI(RA) | li AT, LJ_TFUNC - | bne TMP0, AT, >5 - |. addiu TMP2, TMP2, -LJ_TTAB - | lbu TMP1, CFUNC:TMP1->ffid - | addiu TMP3, TMP3, -LJ_TNIL - | srl TMP0, RD, 1 - | or TMP2, TMP2, TMP3 - | addiu TMP1, TMP1, -FF_next_N - | addu TMP0, PC, TMP0 - | or TMP1, TMP1, TMP2 - | bnez TMP1, >5 - |. lui TMP2, (-(BCBIAS_J*4 >> 16) & 65535) + | bne CARG1, AT, >5 + |. lui TMP2, (-(BCBIAS_J*4 >> 16) & 65535) + | lbu CARG2, CFUNC:CARG2->ffid + | addiu CARG3, CARG3, -LJ_TTAB + | addiu CARG4, CARG4, -LJ_TNIL + | or CARG3, CARG3, CARG4 + | addiu CARG2, CARG2, -FF_next_N + | or CARG2, CARG2, CARG3 + | bnez CARG2, >5 + |. lui TMP1, 0xfffe | addu PC, TMP0, TMP2 - | lui TMP1, 0xfffe | ori TMP1, TMP1, 0x7fff | sw r0, -8+LO(RA) // Initialize control var. | sw TMP1, -8+HI(RA) @@ -3641,7 +3646,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | li TMP3, BC_JMP | li TMP1, BC_ITERC | sb TMP3, -4+OFS_OP(PC) - | addu PC, TMP0, TMP2 + | addu PC, TMP0, TMP2 | b <1 |. sb TMP1, OFS_OP(PC) break; @@ -4165,6 +4170,7 @@ static void emit_asm_debug(BuildCtx *ctx) "\t.align 2\n" ".LEFDE1:\n\n", (int)ctx->codesz - fcofs); #endif +#if !LJ_NO_UNWIND fprintf(ctx->fp, "\t.section .eh_frame,\"aw\",@progbits\n"); fprintf(ctx->fp, "\t.globl lj_err_unwind_dwarf\n" @@ -4232,6 +4238,7 @@ static void emit_asm_debug(BuildCtx *ctx) "\t.byte 0xd\n\t.uleb128 0x10\n" "\t.align 2\n" ".LEFDE3:\n\n", (int)ctx->codesz - fcofs); +#endif #endif break; default: diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc index da75f556..91f50037 100644 --- a/src/vm_ppc.dasc +++ b/src/vm_ppc.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for PowerPC CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h | |.arch ppc |.section code_op, code_sub @@ -75,6 +75,29 @@ |.endif |.endmacro | +|.macro clrso, reg +|.if PPE +| li reg, 0 +| mtxer reg +|.else +| mcrxr cr0 +|.endif +|.endmacro +| +|.macro checkov, reg, noov +|.if PPE +| mfxer reg +| add reg, reg, reg +| cmpwi reg, 0 +| li reg, 0 +| mtxer reg +| bgey noov +|.else +| mcrxr cr0 +| bley noov +|.endif +|.endmacro +| |//----------------------------------------------------------------------- | |// Fixed register assignments for the interpreter. @@ -563,7 +586,7 @@ static void build_subroutines(BuildCtx *ctx) | // - A return back from a lua_call() with (high) nresults adjustment. | stp BASE, L->top // Save current top held in BASE (yes). | mr SAVE0, RD - | mr CARG2, TMP2 + | srwi CARG2, TMP2, 3 | mr CARG1, L | bl extern lj_state_growstack // (lua_State *L, int n) | lwz TMP2, SAVE_NRES @@ -2587,7 +2610,7 @@ static void build_subroutines(BuildCtx *ctx) | stw CARG2, DISPATCH_GL(vmstate)(DISPATCH) | savex_ 0,1,2,3 | stw CARG1, 0(sp) // Store extended stack chain. - | mcrxr cr0 // Clear SO flag. + | clrso TMP1 | savex_ 4,5,6,7 | addi CARG2, sp, 16+32*8+32*4 // Recompute original value of sp. | savex_ 8,9,10,11 @@ -2706,7 +2729,7 @@ static void build_subroutines(BuildCtx *ctx) | cmpwi CARG2, 0 | li CARG1, 0 | beqlr - | mcrxr cr0 // Clear SO for -2147483648 % -1 and return 0. + | clrso TMP0 // Clear SO for -2147483648 % -1 and return 0. | blr | |//----------------------------------------------------------------------- @@ -3309,7 +3332,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) |4: |.if not GPR64 | // Potential overflow. - | mcrxr cr0; bley <1 // Ignore unrelated overflow. + | checkov TMP1, <1 // Ignore unrelated overflow. |.endif | lus TMP1, 0x41e0 // 2^31. | li TMP0, 0 @@ -3494,7 +3517,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) |2: | ins_next2 |4: // Overflow. - | mcrxr cr0; bley <1 // Ignore unrelated overflow. + | checkov TMP0, <1 // Ignore unrelated overflow. | ins_arithfallback b |5: // FP variant. ||if (vk == 1) { @@ -4692,7 +4715,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | b <1 if (vk) { |6: // Potential overflow. - | mcrxr cr0; bley <4 // Ignore unrelated overflow. + | checkov TMP0, <4 // Ignore unrelated overflow. | b <2 } |.endif @@ -4832,7 +4855,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | // Traces on PPC don't store the trace number, so use 0. | stw ZERO, DISPATCH_GL(vmstate)(DISPATCH) | lwzx TRACE:TMP2, TMP1, RD - | mcrxr cr0 // Clear SO flag. + | clrso TMP1 | lp TMP2, TRACE:TMP2->mcode | stw BASE, DISPATCH_GL(jit_base)(DISPATCH) | mtctr TMP2 diff --git a/src/vm_ppcspe.dasc b/src/vm_ppcspe.dasc index adcec244..2a57a41f 100644 --- a/src/vm_ppcspe.dasc +++ b/src/vm_ppcspe.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for PowerPC/e500 CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h | |.arch ppc |.section code_op, code_sub diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc index 8a9b536d..359ad4f4 100644 --- a/src/vm_x86.dasc +++ b/src/vm_x86.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for x86 CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h | |.if P64 |.arch x64 @@ -222,6 +222,9 @@ |.define CFRAME_SPACE, aword*5 // Delta for rsp (see <--). |.macro saveregs_ | push rbx; push r15; push r14 +|.if NO_UNWIND +| push r13; push r12 +|.endif | sub rsp, CFRAME_SPACE |.endmacro |.macro saveregs @@ -229,15 +232,28 @@ |.endmacro |.macro restoreregs | add rsp, CFRAME_SPACE +|.if NO_UNWIND +| pop r12; pop r13 +|.endif | pop r14; pop r15; pop rbx; pop rbp |.endmacro | |//----- 16 byte aligned, +|.if NO_UNWIND +|.define SAVE_RET, aword [rsp+aword*11] //<-- rsp entering interpreter. +|.define SAVE_R4, aword [rsp+aword*10] +|.define SAVE_R3, aword [rsp+aword*9] +|.define SAVE_R2, aword [rsp+aword*8] +|.define SAVE_R1, aword [rsp+aword*7] +|.define SAVE_RU2, aword [rsp+aword*6] +|.define SAVE_RU1, aword [rsp+aword*5] //<-- rsp after register saves. +|.else |.define SAVE_RET, aword [rsp+aword*9] //<-- rsp entering interpreter. |.define SAVE_R4, aword [rsp+aword*8] |.define SAVE_R3, aword [rsp+aword*7] |.define SAVE_R2, aword [rsp+aword*6] |.define SAVE_R1, aword [rsp+aword*5] //<-- rsp after register saves. +|.endif |.define SAVE_CFRAME, aword [rsp+aword*4] |.define SAVE_PC, dword [rsp+dword*7] |.define SAVE_L, dword [rsp+dword*6] @@ -1617,7 +1633,7 @@ static void build_subroutines(BuildCtx *ctx) | mov RD, 1+3 | jmp ->fff_res | - |.ffunc_1 ipairs_aux + |.ffunc_2 ipairs_aux | cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback | cmp dword [BASE+12], LJ_TISNUM |.if DUALNUM @@ -2198,7 +2214,7 @@ static void build_subroutines(BuildCtx *ctx) |.endif | |.ffunc_nnr math_fmod - |1: ; fprem; fnstsw ax; sahf; jp <1 + |1: ; fprem; fnstsw ax; and ax, 0x400; jnz <1 | fpop1 | jmp ->fff_resn | @@ -2564,8 +2580,8 @@ static void build_subroutines(BuildCtx *ctx) | |.define TOBIT_BIAS, 0x59c00000 // 2^52 + 2^51 (float, not double!). | - |.macro .ffunc_bit, name, kind - | .ffunc_1 name + |.macro .ffunc_bit, name, kind, fdef + | fdef name |.if kind == 2 |.if SSE | sseconst_tobit xmm1, RBa @@ -2608,6 +2624,10 @@ static void build_subroutines(BuildCtx *ctx) |2: |.endmacro | + |.macro .ffunc_bit, name, kind + | .ffunc_bit name, kind, .ffunc_1 + |.endmacro + | |.ffunc_bit bit_tobit, 0 |.if DUALNUM or SSE |.if not SSE @@ -2681,7 +2701,7 @@ static void build_subroutines(BuildCtx *ctx) | |.macro .ffunc_bit_sh, name, ins |.if DUALNUM - | .ffunc_bit name, 1 + | .ffunc_bit name, 1, .ffunc_2 | // Note: no inline conversion from number for 2nd argument! | cmp dword [BASE+12], LJ_TISNUM; jne ->fff_fallback | mov RA, dword [BASE+8] @@ -5320,8 +5340,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | jnz <4 | movzx RA, PC_RA | not RAa - | lea RA, [BASE+RA*8] - | mov LFUNC:KBASE, [RA-8] // Need to prepare KBASE. + | mov LFUNC:KBASE, [BASE+RA*8-8] // Need to prepare KBASE. | mov KBASE, LFUNC:KBASE->pc | mov KBASE, [KBASE+PC2PROTO(k)] | jmp <4 @@ -6116,6 +6135,10 @@ static void emit_asm_debug(BuildCtx *ctx) "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */ "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */ "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */ +#if LJ_NO_UNWIND + "\t.byte 0x8d\n\t.uleb128 0x6\n" /* offset r13 */ + "\t.byte 0x8c\n\t.uleb128 0x7\n" /* offset r12 */ +#endif #else "\t.long .Lbegin\n" "\t.long %d\n" @@ -6151,6 +6174,7 @@ static void emit_asm_debug(BuildCtx *ctx) "\t.align " SZPTR "\n" ".LEFDE1:\n\n", (int)ctx->codesz - fcofs); #endif +#if !LJ_NO_UNWIND #if (defined(__sun__) && defined(__svr4__)) #if LJ_64 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@unwind\n"); @@ -6238,8 +6262,10 @@ static void emit_asm_debug(BuildCtx *ctx) #endif "\t.align " SZPTR "\n" ".LEFDE3:\n\n", (int)ctx->codesz - fcofs); +#endif #endif break; +#if !LJ_NO_UNWIND /* Mental note: never let Apple design an assembler. ** Or a linker. Or a plastic case. But I digress. */ @@ -6367,6 +6393,7 @@ static void emit_asm_debug(BuildCtx *ctx) #endif } break; +#endif default: /* Difficult for other modes. */ break; }