Browse Source

Update LuaJIT to the latest 2.1.0 source (1d8b747)

Alex Szpakowski 5 years ago
parent
commit
72540d2d5a
100 changed files with 2213 additions and 2460 deletions
  1. 1 1
      CMakeLists.txt
  2. 4 4
      libs/LuaJIT/COPYRIGHT
  3. 3 3
      libs/LuaJIT/Makefile
  4. 2 2
      libs/LuaJIT/README
  5. 1 1
      libs/LuaJIT/doc/bluequad-print.css
  6. 1 1
      libs/LuaJIT/doc/bluequad.css
  7. 0 882
      libs/LuaJIT/doc/changes.html
  8. 8 13
      libs/LuaJIT/doc/contact.html
  9. 5 10
      libs/LuaJIT/doc/ext_c_api.html
  10. 5 10
      libs/LuaJIT/doc/ext_ffi.html
  11. 6 11
      libs/LuaJIT/doc/ext_ffi_api.html
  12. 8 13
      libs/LuaJIT/doc/ext_ffi_semantics.html
  13. 7 12
      libs/LuaJIT/doc/ext_ffi_tutorial.html
  14. 5 10
      libs/LuaJIT/doc/ext_jit.html
  15. 5 10
      libs/LuaJIT/doc/ext_profiler.html
  16. 10 15
      libs/LuaJIT/doc/extensions.html
  17. 48 29
      libs/LuaJIT/doc/faq.html
  18. 9 14
      libs/LuaJIT/doc/install.html
  19. 9 14
      libs/LuaJIT/doc/luajit.html
  20. 6 11
      libs/LuaJIT/doc/running.html
  21. 5 21
      libs/LuaJIT/doc/status.html
  22. 1 1
      libs/LuaJIT/dynasm/dasm_arm.h
  23. 1 1
      libs/LuaJIT/dynasm/dasm_arm.lua
  24. 1 1
      libs/LuaJIT/dynasm/dasm_arm64.h
  25. 1 1
      libs/LuaJIT/dynasm/dasm_arm64.lua
  26. 8 7
      libs/LuaJIT/dynasm/dasm_mips.h
  27. 401 228
      libs/LuaJIT/dynasm/dasm_mips.lua
  28. 1 1
      libs/LuaJIT/dynasm/dasm_mips64.lua
  29. 1 1
      libs/LuaJIT/dynasm/dasm_ppc.h
  30. 1 1
      libs/LuaJIT/dynasm/dasm_ppc.lua
  31. 1 1
      libs/LuaJIT/dynasm/dasm_proto.h
  32. 1 1
      libs/LuaJIT/dynasm/dasm_x64.lua
  33. 8 5
      libs/LuaJIT/dynasm/dasm_x86.h
  34. 2 2
      libs/LuaJIT/dynasm/dasm_x86.lua
  35. 5 4
      libs/LuaJIT/dynasm/dynasm.lua
  36. 4 4
      libs/LuaJIT/etc/luajit.1
  37. 1 1
      libs/LuaJIT/etc/luajit.pc
  38. 11 14
      libs/LuaJIT/src/Makefile
  39. 36 31
      libs/LuaJIT/src/Makefile.dep
  40. 1 1
      libs/LuaJIT/src/host/buildvm.c
  41. 1 1
      libs/LuaJIT/src/host/buildvm.h
  42. 1 12
      libs/LuaJIT/src/host/buildvm_asm.c
  43. 1 1
      libs/LuaJIT/src/host/buildvm_fold.c
  44. 1 1
      libs/LuaJIT/src/host/buildvm_lib.c
  45. 2 15
      libs/LuaJIT/src/host/buildvm_peobj.c
  46. 1 1
      libs/LuaJIT/src/host/genlibbc.lua
  47. 1 1
      libs/LuaJIT/src/host/genminilua.lua
  48. 1 1
      libs/LuaJIT/src/jit/bc.lua
  49. 46 42
      libs/LuaJIT/src/jit/bcsave.lua
  50. 1 1
      libs/LuaJIT/src/jit/dis_arm.lua
  51. 1 1
      libs/LuaJIT/src/jit/dis_arm64.lua
  52. 1 1
      libs/LuaJIT/src/jit/dis_arm64be.lua
  53. 273 22
      libs/LuaJIT/src/jit/dis_mips.lua
  54. 1 1
      libs/LuaJIT/src/jit/dis_mips64.lua
  55. 1 1
      libs/LuaJIT/src/jit/dis_mips64el.lua
  56. 17 0
      libs/LuaJIT/src/jit/dis_mips64r6.lua
  57. 17 0
      libs/LuaJIT/src/jit/dis_mips64r6el.lua
  58. 1 1
      libs/LuaJIT/src/jit/dis_mipsel.lua
  59. 1 1
      libs/LuaJIT/src/jit/dis_ppc.lua
  60. 1 1
      libs/LuaJIT/src/jit/dis_x64.lua
  61. 1 1
      libs/LuaJIT/src/jit/dis_x86.lua
  62. 5 3
      libs/LuaJIT/src/jit/dump.lua
  63. 1 1
      libs/LuaJIT/src/jit/p.lua
  64. 1 1
      libs/LuaJIT/src/jit/v.lua
  65. 1 1
      libs/LuaJIT/src/jit/zone.lua
  66. 3 7
      libs/LuaJIT/src/lib_aux.c
  67. 8 6
      libs/LuaJIT/src/lib_base.c
  68. 1 1
      libs/LuaJIT/src/lib_bit.c
  69. 9 8
      libs/LuaJIT/src/lib_debug.c
  70. 2 2
      libs/LuaJIT/src/lib_ffi.c
  71. 1 1
      libs/LuaJIT/src/lib_init.c
  72. 11 5
      libs/LuaJIT/src/lib_io.c
  73. 40 52
      libs/LuaJIT/src/lib_jit.c
  74. 27 52
      libs/LuaJIT/src/lib_math.c
  75. 1 1
      libs/LuaJIT/src/lib_os.c
  76. 13 8
      libs/LuaJIT/src/lib_package.c
  77. 5 5
      libs/LuaJIT/src/lib_string.c
  78. 1 1
      libs/LuaJIT/src/lib_table.c
  79. 0 41
      libs/LuaJIT/src/lj.supp
  80. 47 52
      libs/LuaJIT/src/lj_alloc.c
  81. 2 1
      libs/LuaJIT/src/lj_alloc.h
  82. 119 74
      libs/LuaJIT/src/lj_api.c
  83. 106 21
      libs/LuaJIT/src/lj_arch.h
  84. 159 90
      libs/LuaJIT/src/lj_asm.c
  85. 1 1
      libs/LuaJIT/src/lj_asm.h
  86. 91 73
      libs/LuaJIT/src/lj_asm_arm.h
  87. 74 90
      libs/LuaJIT/src/lj_asm_arm64.h
  88. 198 118
      libs/LuaJIT/src/lj_asm_mips.h
  89. 82 63
      libs/LuaJIT/src/lj_asm_ppc.h
  90. 118 137
      libs/LuaJIT/src/lj_asm_x86.h
  91. 28 0
      libs/LuaJIT/src/lj_assert.c
  92. 1 1
      libs/LuaJIT/src/lj_bc.c
  93. 1 1
      libs/LuaJIT/src/lj_bc.h
  94. 1 1
      libs/LuaJIT/src/lj_bcdump.h
  95. 16 16
      libs/LuaJIT/src/lj_bcread.c
  96. 20 6
      libs/LuaJIT/src/lj_bcwrite.c
  97. 3 3
      libs/LuaJIT/src/lj_buf.c
  98. 1 1
      libs/LuaJIT/src/lj_buf.h
  99. 9 14
      libs/LuaJIT/src/lj_carith.c
  100. 1 2
      libs/LuaJIT/src/lj_carith.h

+ 1 - 1
CMakeLists.txt

@@ -167,7 +167,7 @@ endif()
 
 
 set(MEGA_ZLIB_VER "1.2.11")
 set(MEGA_ZLIB_VER "1.2.11")
 set(MEGA_LUA51_VER "5.1.5")
 set(MEGA_LUA51_VER "5.1.5")
-set(MEGA_LUAJIT_VER "2.1.0-0bee44c")
+set(MEGA_LUAJIT_VER "2.1.0-1d8b747")
 set(MEGA_LIBOGG_VER "1.3.2")
 set(MEGA_LIBOGG_VER "1.3.2")
 set(MEGA_LIBVORBIS_VER "1.3.5")
 set(MEGA_LIBVORBIS_VER "1.3.5")
 set(MEGA_LIBTHEORA_VER "1.1.1")
 set(MEGA_LIBTHEORA_VER "1.1.1")

+ 4 - 4
libs/LuaJIT/COPYRIGHT

@@ -1,7 +1,7 @@
 ===============================================================================
 ===============================================================================
-LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
+LuaJIT -- a Just-In-Time Compiler for Lua. https://luajit.org/
 
 
-Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 of this software and associated documentation files (the "Software"), to deal
@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 THE SOFTWARE.
 
 
-[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
+[ MIT license: https://www.opensource.org/licenses/mit-license.php ]
 
 
 ===============================================================================
 ===============================================================================
 [ LuaJIT includes code from Lua 5.1/5.2, which has this license statement: ]
 [ LuaJIT includes code from Lua 5.1/5.2, which has this license statement: ]
@@ -51,6 +51,6 @@ THE SOFTWARE.
 
 
 This is a version (aka dlmalloc) of malloc/free/realloc written by
 This is a version (aka dlmalloc) of malloc/free/realloc written by
 Doug Lea and released to the public domain, as explained at
 Doug Lea and released to the public domain, as explained at
-http://creativecommons.org/licenses/publicdomain
+https://creativecommons.org/licenses/publicdomain
 
 
 ===============================================================================
 ===============================================================================

+ 3 - 3
libs/LuaJIT/Makefile

@@ -10,7 +10,7 @@
 # For MSVC, please follow the instructions given in src/msvcbuild.bat.
 # For MSVC, please follow the instructions given in src/msvcbuild.bat.
 # For MinGW and Cygwin, cd to src and run make with the Makefile there.
 # For MinGW and Cygwin, cd to src and run make with the Makefile there.
 #
 #
-# Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+# Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 ##############################################################################
 ##############################################################################
 
 
 MAJVER=  2
 MAJVER=  2
@@ -75,7 +75,7 @@ SYMLINK= ln -sf
 INSTALL_X= install -m 0755
 INSTALL_X= install -m 0755
 INSTALL_F= install -m 0644
 INSTALL_F= install -m 0644
 UNINSTALL= $(RM)
 UNINSTALL= $(RM)
-LDCONFIG= ldconfig -n
+LDCONFIG= ldconfig -n 2>/dev/null
 SED_PC= sed -e "s|^prefix=.*|prefix=$(PREFIX)|" \
 SED_PC= sed -e "s|^prefix=.*|prefix=$(PREFIX)|" \
             -e "s|^multilib=.*|multilib=$(MULTILIB)|"
             -e "s|^multilib=.*|multilib=$(MULTILIB)|"
 
 
@@ -121,7 +121,7 @@ install: $(INSTALL_DEP)
 	$(RM) $(INSTALL_DYN) $(INSTALL_SHORT1) $(INSTALL_SHORT2)
 	$(RM) $(INSTALL_DYN) $(INSTALL_SHORT1) $(INSTALL_SHORT2)
 	cd src && test -f $(FILE_SO) && \
 	cd src && test -f $(FILE_SO) && \
 	  $(INSTALL_X) $(FILE_SO) $(INSTALL_DYN) && \
 	  $(INSTALL_X) $(FILE_SO) $(INSTALL_DYN) && \
-	  $(LDCONFIG) $(INSTALL_LIB) && \
+	  ( $(LDCONFIG) $(INSTALL_LIB) || : ) && \
 	  $(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT1) && \
 	  $(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT1) && \
 	  $(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT2) || :
 	  $(SYMLINK) $(INSTALL_SONAME) $(INSTALL_SHORT2) || :
 	cd etc && $(INSTALL_F) $(FILE_MAN) $(INSTALL_MAN)
 	cd etc && $(INSTALL_F) $(FILE_MAN) $(INSTALL_MAN)

+ 2 - 2
libs/LuaJIT/README

@@ -3,9 +3,9 @@ README for LuaJIT 2.1.0-beta3
 
 
 LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
 LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
 
 
-Project Homepage: http://luajit.org/
+Project Homepage: https://luajit.org/
 
 
-LuaJIT is Copyright (C) 2005-2017 Mike Pall.
+LuaJIT is Copyright (C) 2005-2020 Mike Pall.
 LuaJIT is free software, released under the MIT license.
 LuaJIT is free software, released under the MIT license.
 See full Copyright Notice in the COPYRIGHT file or in luajit.h.
 See full Copyright Notice in the COPYRIGHT file or in luajit.h.
 
 

+ 1 - 1
libs/LuaJIT/doc/bluequad-print.css

@@ -1,4 +1,4 @@
-/* Copyright (C) 2004-2018 Mike Pall.
+/* Copyright (C) 2004-2020 Mike Pall.
  *
  *
  * You are welcome to use the general ideas of this design for your own sites.
  * You are welcome to use the general ideas of this design for your own sites.
  * But please do not steal the stylesheet, the layout or the color scheme.
  * But please do not steal the stylesheet, the layout or the color scheme.

+ 1 - 1
libs/LuaJIT/doc/bluequad.css

@@ -1,4 +1,4 @@
-/* Copyright (C) 2004-2018 Mike Pall.
+/* Copyright (C) 2004-2020 Mike Pall.
  *
  *
  * You are welcome to use the general ideas of this design for your own sites.
  * You are welcome to use the general ideas of this design for your own sites.
  * But please do not steal the stylesheet, the layout or the color scheme.
  * But please do not steal the stylesheet, the layout or the color scheme.

+ 0 - 882
libs/LuaJIT/doc/changes.html

@@ -1,882 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<title>LuaJIT Change History</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
-<meta name="Language" content="en">
-<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
-<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
-<style type="text/css">
-div.major { max-width: 600px; padding: 1em; margin: 1em 0 1em 0; }
-</style>
-</head>
-<body>
-<div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
-</div>
-<div id="head">
-<h1>LuaJIT Change History</h1>
-</div>
-<div id="nav">
-<ul><li>
-<a href="luajit.html">LuaJIT</a>
-<ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
-</li><li>
-<a href="install.html">Installation</a>
-</li><li>
-<a href="running.html">Running</a>
-</li></ul>
-</li><li>
-<a href="extensions.html">Extensions</a>
-<ul><li>
-<a href="ext_ffi.html">FFI Library</a>
-<ul><li>
-<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
-</li><li>
-<a href="ext_ffi_api.html">ffi.* API</a>
-</li><li>
-<a href="ext_ffi_semantics.html">FFI Semantics</a>
-</li></ul>
-</li><li>
-<a href="ext_jit.html">jit.* Library</a>
-</li><li>
-<a href="ext_c_api.html">Lua/C API</a>
-</li><li>
-<a href="ext_profiler.html">Profiler</a>
-</li></ul>
-</li><li>
-<a href="status.html">Status</a>
-<ul><li>
-<a class="current" href="changes.html">Changes</a>
-</li></ul>
-</li><li>
-<a href="faq.html">FAQ</a>
-</li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
-<a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
-</li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
-</li></ul>
-</div>
-<div id="main">
-<p>
-This is a list of changes between the released versions of LuaJIT.<br>
-The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT&nbsp;2.0.5</strong>.<br>
-</p>
-<p>
-Please check the
-<a href="http://luajit.org/changes.html"><span class="ext">&raquo;</span>&nbsp;Online Change History</a>
-to see whether newer versions are available.
-</p>
-
-<div class="major" style="background: #d0d0ff;">
-<h2 id="LuaJIT-2.1.0-beta3">LuaJIT 2.1.0-beta3 &mdash; 2017-05-01</h2>
-<ul>
-<li>Rewrite memory block allocator.</li>
-<li>Add various extension from Lua 5.2/5.3.</li>
-<li>Remove old Lua 5.0 compatibility defines.</li>
-<li>Set arg table before evaluating <tt>LUA_INIT</tt> and <tt>-e</tt> chunks.</li>
-<li>Fix FOLD rules for <tt>math.abs()</tt> and FP negation.</li>
-<li>Fix soft-float <tt>math.abs()</tt> and negation.</li>
-<li>Fix formatting of some small denormals at low precision.</li>
-<li>LJ_GC64: Add JIT compiler support.</li>
-<li>x64/LJ_GC64: Add JIT compiler backend.</li>
-<li>x86/x64: Generate BMI2 shifts and rotates, if available.</li>
-<li>Windows/x86: Add full exception interoperability.</li>
-<li>ARM64: Add big-endian support.</li>
-<li>ARM64: Add JIT compiler backend.</li>
-<li>MIPS: Fix <tt>TSETR</tt> barrier.</li>
-<li>MIPS: Support MIPS16 interlinking.</li>
-<li>MIPS soft-float: Fix code generation for <tt>HREF</tt>.</li>
-<li>MIPS64: Add MIPS64 hard-float JIT compiler backend.</li>
-<li>MIPS64: Add MIPS64 hard-float/soft-float support to interpreter.</li>
-<li>FFI: Compile bitfield loads/stores.</li>
-<li>Various fixes common with the 2.0 branch.</li>
-</ul>
-
-<h2 id="LuaJIT-2.1.0-beta2">LuaJIT 2.1.0-beta2 &mdash; 2016-03-03</h2>
-<ul>
-<li>Enable trace stitching.</li>
-<li>Use internal implementation for converting FP numbers to strings.</li>
-<li>Parse Unicode escape <tt>'\u{XX...}'</tt> in string literals.</li>
-<li>Add MIPS soft-float support.</li>
-<li>Switch MIPS port to dual-number mode.</li>
-<li>x86/x64: Add support for AES-NI, AVX and AVX2 to DynASM.</li>
-<li>FFI: Add <tt>ssize_t</tt> declaration.</li>
-<li>FFI: Parse <tt>#line NN</tt> and <tt>#NN</tt>.</li>
-<li>Various minor fixes.</li>
-</ul>
-
-<h2 id="LuaJIT-2.1.0-beta1">LuaJIT 2.1.0-beta1 &mdash; 2015-08-25</h2>
-<p>
-This is a brief summary of the major changes in LuaJIT 2.1 compared to 2.0.
-Please take a look at the commit history for more details.
-</p>
-<ul>
-<li>Changes to the VM core:
-<ul>
-<li>Add low-overhead profiler (<tt>-jp</tt>).</li>
-<li>Add <tt>LJ_GC64</tt> mode: 64 bit GC object references (really: 47 bit). Interpreter-only for now.</li>
-<li>Add <tt>LJ_FR2</tt> mode: Two-slot frame info. Required by <tt>LJ_GC64</tt> mode.</li>
-<li>Add <tt>table.new()</tt> and <tt>table.clear()</tt>.</li>
-<li>Parse binary number literals (<tt>0bxxx</tt>).</li>
-</ul></li>
-<li>Improvements to the JIT compiler:
-<ul>
-<li>Add trace stitching (disabled for now).</li>
-<li>Compile various builtins: <tt>string.char()</tt>, <tt>string.reverse()</tt>, <tt>string.lower()</tt>, <tt>string.upper()</tt>, <tt>string.rep()</tt>, <tt>string.format()</tt>, <tt>table.concat()</tt>, <tt>bit.tohex()</tt>, <tt>getfenv(0)</tt>, <tt>debug.getmetatable()</tt>.</li>
-<li>Compile <tt>string.find()</tt> for fixed string searches (no patterns).</li>
-<li>Compile <tt>BC_TSETM</tt>, e.g. <tt>{1,2,3,f()}</tt>.</li>
-<li>Compile string concatenations (<tt>BC_CAT</tt>).</li>
-<li>Compile <tt>__concat</tt> metamethod.</li>
-<li>Various minor optimizations.</li>
-</ul></li>
-<li>Internal Changes:
-<ul>
-<li>Add support for embedding LuaJIT bytecode for builtins.</li>
-<li>Replace various builtins with embedded bytecode.</li>
-<li>Refactor string buffers and string formatting.</li>
-<li>Remove obsolete non-truncating number to integer conversions.</li>
-</ul></li>
-<li>Ports:
-<ul>
-<li>Add Xbox One port (<tt>LJ_GC64</tt> mode).</li>
-<li>ARM64: Add port of the interpreter (<tt>LJ_GC64</tt> mode).</li>
-<li>x64: Add separate port of the interpreter to <tt>LJ_GC64</tt> mode.</li>
-<li>x86/x64: Drop internal x87 math functions. Use libm functions.</li>
-<li>x86: Remove x87 support from interpreter. SSE2 is mandatory now.</li>
-<li>PPC/e500: Drop support for this architecture.</li>
-</ul></li>
-<li>FFI library:
-<ul>
-<li>FFI: Add 64 bit bitwise operations.</li>
-<li>FFI: Compile VLA/VLS and large cdata allocations with default initialization.</li>
-<li>FFI: Compile conversions from functions to function pointers.</li>
-<li>FFI: Compile lightuserdata to <tt>void *</tt> conversion.</li>
-<li>FFI: Compile <tt>ffi.gc(cdata, nil)</tt>, too.</li>
-<li>FFI: Add <tt>ffi.typeinfo()</tt>.</li>
-</ul></li>
-</ul>
-</div>
-
-<div class="major" style="background: #ffffd0;">
-<h2 id="LuaJIT-2.0.5">LuaJIT 2.0.5 &mdash; 2017-05-01</h2>
-<ul>
-<li>Add workaround for MSVC 2015 stdio changes.</li>
-<li>Limit mcode alloc probing, depending on the available pool size.</li>
-<li>Fix overly restrictive range calculation in mcode allocation.</li>
-<li>Fix out-of-scope goto handling in parser.</li>
-<li>Remove internal <tt>__mode = "K"</tt> and replace with safe check.</li>
-<li>Add "proto" field to <tt>jit.util.funcinfo()</tt>.</li>
-<li>Fix GC step size calculation.</li>
-<li>Initialize <tt>uv-&gt;immutable</tt> for upvalues of loaded chunks.</li>
-<li>Fix for cdata vs. non-cdata arithmetics/comparisons.</li>
-<li>Drop leftover regs in 'for' iterator assignment, too.</li>
-<li>Fix PHI remarking in SINK pass.</li>
-<li>Don't try to record outermost <tt>pcall()</tt> return to lower frame.</li>
-<li>Add guard for obscure aliasing between open upvalues and SSA slots.</li>
-<li>Remove assumption that <tt>lj_math_random_step()</tt> doesn't clobber FPRs.</li>
-<li>Fix handling of non-numeric strings in arithmetic coercions.</li>
-<li>Fix recording of <tt>select(n, ...)</tt> with off-trace varargs</li>
-<li>Fix install for cross-builds.</li>
-<li>Don't allocate unused 2nd result register in JIT compiler backend.</li>
-<li>Drop marks from replayed instructions when sinking.</li>
-<li>Fix unsinking check.</li>
-<li>Properly handle OOM in <tt>trace_save()</tt>.</li>
-<li>Limit number of arguments given to <tt>io.lines()</tt> and <tt>fp:lines()</tt>.</li>
-<li>Fix narrowing of <tt>TOBIT</tt>.</li>
-<li>OSX: Fix build with recent XCode.</li>
-<li>x86/x64: Don't spill an explicit <tt>REF_BASE</tt> in the IR.</li>
-<li>x86/x64: Fix instruction length decoder.</li>
-<li>x86/x64: Search for exit jumps with instruction length decoder.</li>
-<li>ARM: Fix <tt>BLX</tt> encoding for Thumb interworking calls.</li>
-<li>MIPS: Don't use <tt>RID_GP</tt> as a scratch register.</li>
-<li>MIPS: Fix emitted code for U32 to float conversion.</li>
-<li>MIPS: Backport workaround for compact unwind tables.</li>
-<li>MIPS: Fix cross-endian jit.bcsave.</li>
-<li>MIPS: Fix <tt>BC_ISNEXT</tt> fallback path.</li>
-<li>MIPS: Fix use of ffgccheck delay slots in interpreter.</li>
-<li>FFI: Fix FOLD rules for <tt>int64_t</tt> comparisons.</li>
-<li>FFI: Fix SPLIT pass for <tt>CONV i64.u64</tt>.</li>
-<li>FFI: Fix <tt>ipairs()</tt> recording.</li>
-<li>FFI: Don't propagate qualifiers into subtypes of complex.</li>
-</ul>
-
-<h2 id="LuaJIT-2.0.4">LuaJIT 2.0.4 &mdash; 2015-05-14</h2>
-<ul>
-<li>Fix stack check in narrowing optimization.</li>
-<li>Fix Lua/C API typecheck error for special indexes.</li>
-<li>Fix string to number conversion.</li>
-<li>Fix lexer error for chunks without tokens.</li>
-<li>Don't compile <tt>IR_RETF</tt> after <tt>CALLT</tt> to ff with-side effects.</li>
-<li>Fix <tt>BC_UCLO</tt>/<tt>BC_JMP</tt> join optimization in Lua parser.</li>
-<li>Fix corner case in string to number conversion.</li>
-<li>Gracefully handle <tt>lua_error()</tt> for a suspended coroutine.</li>
-<li>Avoid error messages when building with Clang.</li>
-<li>Fix snapshot #0 handling for traces with a stack check on entry.</li>
-<li>Fix fused constant loads under high register pressure.</li>
-<li>Invalidate backpropagation cache after DCE.</li>
-<li>Fix ABC elimination.</li>
-<li>Fix debug info for main chunk of stripped bytecode.</li>
-<li>Fix FOLD rule for <tt>string.sub(s, ...) == k</tt>.</li>
-<li>Fix FOLD rule for <tt>STRREF</tt> of <tt>SNEW</tt>.</li>
-<li>Fix frame traversal while searching for error function.</li>
-<li>Prevent GC estimate miscalculation due to buffer growth.</li>
-<li>Prevent adding side traces for stack checks.</li>
-<li>Fix top slot calculation for snapshots with continuations.</li>
-<li>Fix check for reuse of SCEV results in <tt>FORL</tt>.</li>
-<li>Add PS Vita port.</li>
-<li>Fix compatibility issues with Illumos.</li>
-<li>Fix DragonFly build (unsupported).</li>
-<li>OpenBSD/x86: Better executable memory allocation for W^X mode.</li>
-<li>x86: Fix argument checks for <tt>ipairs()</tt> iterator.</li>
-<li>x86: <tt>lj_math_random_step()</tt> clobbers XMM regs on OSX Clang.</li>
-<li>x86: Fix code generation for unused result of <tt>math.random()</tt>.</li>
-<li>x64: Allow building with <tt>LUAJIT_USE_SYSMALLOC</tt> and <tt>LUAJIT_USE_VALGRIND</tt>.</li>
-<li>x86/x64: Fix argument check for bit shifts.</li>
-<li>x86/x64: Fix code generation for fused test/arith ops.</li>
-<li>ARM: Fix write barrier check in <tt>BC_USETS</tt>.</li>
-<li>PPC: Fix red zone overflow in machine code generation.</li>
-<li>PPC: Don't use <tt>mcrxr</tt> on PPE.</li>
-<li>Various archs: Fix excess stack growth in interpreter.</li>
-<li>FFI: Fix FOLD rule for <tt>TOBIT</tt> + <tt>CONV num.u32</tt>.</li>
-<li>FFI: Prevent DSE across <tt>ffi.string()</tt>.</li>
-<li>FFI: No meta fallback when indexing pointer to incomplete struct.</li>
-<li>FFI: Fix initialization of unions of subtypes.</li>
-<li>FFI: Fix cdata vs. non-cdata arithmetic and comparisons.</li>
-<li>FFI: Fix <tt>__index</tt>/<tt>__newindex</tt> metamethod resolution for ctypes.</li>
-<li>FFI: Fix compilation of reference field access.</li>
-<li>FFI: Fix frame traversal for backtraces with FFI callbacks.</li>
-<li>FFI: Fix recording of indexing a struct pointer ctype object itself.</li>
-<li>FFI: Allow non-scalar cdata to be compared for equality by address.</li>
-<li>FFI: Fix pseudo type conversions for type punning.</li>
-</ul>
-
-<h2 id="LuaJIT-2.0.3">LuaJIT 2.0.3 &mdash; 2014-03-12</h2>
-<ul>
-<li>Add PS4 port.</li>
-<li>Add support for multilib distro builds.</li>
-<li>Fix OSX build.</li>
-<li>Fix MinGW build.</li>
-<li>Fix Xbox 360 build.</li>
-<li>Improve ULOAD forwarding for open upvalues.</li>
-<li>Fix GC steps threshold handling when called by JIT-compiled code.</li>
-<li>Fix argument checks for <tt>math.deg()</tt> and <tt>math.rad()</tt>.</li>
-<li>Fix <tt>jit.flush(func|true)</tt>.</li>
-<li>Respect <tt>jit.off(func)</tt> when returning to a function, too.</li>
-<li>Fix compilation of <tt>string.byte(s, nil, n)</tt>.</li>
-<li>Fix line number for relocated bytecode after closure fixup</li>
-<li>Fix frame traversal for backtraces.</li>
-<li>Fix ABC elimination.</li>
-<li>Fix handling of redundant PHIs.</li>
-<li>Fix snapshot restore for exit to function header.</li>
-<li>Fix type punning alias analysis for constified pointers</li>
-<li>Fix call unroll checks in the presence of metamethod frames.</li>
-<li>Fix initial maxslot for down-recursive traces.</li>
-<li>Prevent BASE register coalescing if parent uses <tt>IR_RETF</tt>.</li>
-<li>Don't purge modified function from stack slots in <tt>BC_RET</tt>.</li>
-<li>Fix recording of <tt>BC_VARG</tt>.</li>
-<li>Don't access dangling reference to reallocated IR.</li>
-<li>Fix frame depth display for bytecode dump in <tt>-jdump</tt>.</li>
-<li>ARM: Fix register allocation when rematerializing FPRs.</li>
-<li>x64: Fix store to upvalue for lightuserdata values.</li>
-<li>FFI: Add missing GC steps for callback argument conversions.</li>
-<li>FFI: Properly unload loaded DLLs.</li>
-<li>FFI: Fix argument checks for <tt>ffi.string()</tt>.</li>
-<li>FFI/x64: Fix passing of vector arguments to calls.</li>
-<li>FFI: Rehash finalizer table after GC cycle, if needed.</li>
-<li>FFI: Fix <tt>cts-&gt;L</tt> for cdata unsinking in snapshot restore.</li>
-</ul>
-
-<h2 id="LuaJIT-2.0.2">LuaJIT 2.0.2 &mdash; 2013-06-03</h2>
-<ul>
-<li>Fix memory access check for fast string interning.</li>
-<li>Fix MSVC intrinsics for older versions.</li>
-<li>Add missing GC steps for <tt>io.*</tt> functions.</li>
-<li>Fix spurious red zone overflows in machine code generation.</li>
-<li>Fix jump-range constrained mcode allocation.</li>
-<li>Inhibit DSE for implicit loads via calls.</li>
-<li>Fix builtin string to number conversion for overflow digits.</li>
-<li>Fix optional argument handling while recording builtins.</li>
-<li>Fix optional argument handling in <tt>table.concat()</tt>.</li>
-<li>Add partial support for building with MingW64 GCC 4.8-SEH.</li>
-<li>Add missing PHI barrier to <tt>string.sub(str, a, b) == kstr</tt> FOLD rule.</li>
-<li>Fix compatibility issues with Illumos.</li>
-<li>ARM: Fix cache flush/sync for exit stubs of JIT-compiled code.</li>
-<li>MIPS: Fix cache flush/sync for JIT-compiled code jump area.</li>
-<li>PPC: Add <tt>plt</tt> suffix for external calls from assembler code.</li>
-<li>FFI: Fix snapshot substitution in SPLIT pass.</li>
-<li>FFI/x86: Fix register allocation for 64 bit comparisons.</li>
-<li>FFI: Fix tailcall in lowest frame to C&nbsp;function with bool result.</li>
-<li>FFI: Ignore <tt>long</tt> type specifier in <tt>ffi.istype()</tt>.</li>
-<li>FFI: Fix calling conventions for 32 bit OSX and iOS simulator (struct returns).</li>
-<li>FFI: Fix calling conventions for ARM hard-float EABI (nested structs).</li>
-<li>FFI: Improve error messages for arithmetic and comparison operators.</li>
-<li>FFI: Insert no-op type conversion for pointer to integer cast.</li>
-<li>FFI: Fix unroll limit for <tt>ffi.fill()</tt>.</li>
-<li>FFI: Must sink <tt>XBAR</tt> together with <tt>XSTORE</tt>s.</li>
-<li>FFI: Preserve intermediate string for <tt>const&nbsp;char&nbsp;*</tt> conversion.</li>
-</ul>
-
-<h2 id="LuaJIT-2.0.1">LuaJIT 2.0.1 &mdash; 2013-02-19</h2>
-<ul>
-<li>Don't clear frame for out-of-memory error.</li>
-<li>Leave hook when resume catches error thrown from hook.</li>
-<li>Add missing GC steps for template table creation.</li>
-<li>Fix discharge order of comparisons in Lua parser.</li>
-<li>Improve buffer handling for <tt>io.read()</tt>.</li>
-<li>OSX: Add support for Mach-O object files to <tt>-b</tt> option.</li>
-<li>Fix PS3 port.</li>
-<li>Fix/enable Xbox 360 port.</li>
-<li>x86/x64: Always mark ref for shift count as non-weak.</li>
-<li>x64: Don't fuse implicitly 32-to-64 extended operands.</li>
-<li>ARM: Fix armhf call argument handling.</li>
-<li>ARM: Fix code generation for integer math.min/math.max.</li>
-<li>PPC/e500: Fix <tt>lj_vm_floor()</tt> for Inf/NaN.</li>
-<li>FFI: Change priority of table initializer variants for structs.</li>
-<li>FFI: Fix code generation for bool call result check on x86/x64.</li>
-<li>FFI: Load FFI library on-demand for bytecode with cdata literals.</li>
-<li>FFI: Fix handling of qualified transparent structs/unions.</li>
-</ul>
-
-<h2 id="LuaJIT-2.0.0">LuaJIT 2.0.0 &mdash; 2012-11-08</h2>
-<ul>
-<li>Correctness and completeness:
-<ul>
-  <li>Fix Android/x86 build.</li>
-  <li>Fix recording of equality comparisons with <tt>__eq</tt> metamethods.</li>
-  <li>Fix detection of immutable upvalues.</li>
-  <li>Replace error with PANIC for callbacks from JIT-compiled code.</li>
-  <li>Fix builtin string to number conversion for <tt>INT_MIN</tt>.</li>
-  <li>Don't create unneeded array part for template tables.</li>
-  <li>Fix <tt>CONV.num.int</tt> sinking.</li>
-  <li>Don't propagate implicitly widened number to index metamethods.</li>
-  <li>ARM: Fix ordered comparisons of number vs. non-number.</li>
-  <li>FFI: Fix code generation for replay of sunk float fields.</li>
-  <li>FFI: Fix signedness of bool.</li>
-  <li>FFI: Fix recording of bool call result check on x86/x64.</li>
-  <li>FFI: Fix stack-adjustment for <tt>__thiscall</tt> callbacks.</li>
-</ul></li>
-</ul>
-
-<h2 id="LuaJIT-2.0.0-beta11">LuaJIT 2.0.0-beta11 &mdash; 2012-10-16</h2>
-<ul>
-<li>New features:
-<ul>
-  <li>Use ARM VFP instructions, if available (build-time detection).</li>
-  <li>Add support for ARM hard-float EABI (<tt>armhf</tt>).</li>
-  <li>Add PS3 port.</li>
-  <li>Add many features from Lua&nbsp;5.2, e.g. <tt>goto</tt>/labels.
-  Refer to <a href="extensions.html#lua52">this list</a>.</li>
-  <li>FFI: Add parameterized C types.</li>
-  <li>FFI: Add support for copy constructors.</li>
-  <li>FFI: Equality comparisons never raise an error (treat as unequal instead).</li>
-  <li>FFI: Box all accessed or returned enums.</li>
-  <li>FFI: Check for <tt>__new</tt> metamethod when calling a constructor.</li>
-  <li>FFI: Handle <tt>__pairs</tt>/<tt>__ipairs</tt> metamethods for cdata objects.</li>
-  <li>FFI: Convert <tt>io.*</tt> file handle to <tt>FILE *</tt> pointer (but as a <tt>void *</tt>).</li>
-  <li>FFI: Detect and support type punning through unions.</li>
-  <li>FFI: Improve various error messages.</li>
-</ul></li>
-<li>Build-system reorganization:
-<ul>
-  <li>Reorganize directory layout:<br>
-  <tt>lib/*</tt> &rarr; <tt>src/jit/*</tt><br>
-  <tt>src/buildvm_*.dasc</tt> &rarr; <tt>src/vm_*.dasc</tt><br>
-  <tt>src/buildvm_*.h</tt> &rarr; removed<br>
-  <tt>src/buildvm*</tt> &rarr; <tt>src/host/*</tt></li>
-  <li>Add minified Lua interpreter plus Lua BitOp (<tt>minilua</tt>) to run DynASM.</li>
-  <li>Change DynASM bit operations to use Lua BitOp</li>
-  <li>Translate only <tt>vm_*.dasc</tt> for detected target architecture.</li>
-  <li>Improve target detection for <tt>msvcbuild.bat</tt>.</li>
-  <li>Fix build issues on Cygwin and MinGW with optional MSys.</li>
-  <li>Handle cross-compiles with FPU/no-FPU or hard-fp/soft-fp ABI mismatch.</li>
-  <li>Remove some library functions for no-JIT/no-FFI builds.</li>
-  <li>Add uninstall target to top-level Makefile.</li>
-</ul></li>
-<li>Correctness and completeness:
-<ul>
-  <li>Preserve snapshot #0 PC for all traces.</li>
-  <li>Fix argument checks for <tt>coroutine.create()</tt>.</li>
-  <li>Command line prints version and JIT status to <tt>stdout</tt>, not <tt>stderr</tt>.</li>
-  <li>Fix userdata <tt>__gc</tt> separations at Lua state close.</li>
-  <li>Fix <tt>TDUP</tt> to <tt>HLOAD</tt> forwarding for <tt>LJ_DUALNUM</tt> builds.</li>
-  <li>Fix buffer check in bytecode writer.</li>
-  <li>Make <tt>os.date()</tt> thread-safe.</li>
-  <li>Add missing declarations for MSVC intrinsics.</li>
-  <li>Fix dispatch table modifications for return hooks.</li>
-  <li>Workaround for MSVC conversion bug (<tt>double</tt> &rarr; <tt>uint32_t</tt> &rarr; <tt>int32_t</tt>).</li>
-  <li>Fix FOLD rule <tt>(i-j)-i => 0-j</tt>.</li>
-  <li>Never use DWARF unwinder on Windows.</li>
-  <li>Fix shrinking of direct mapped blocks in builtin allocator.</li>
-  <li>Limit recursion depth in <tt>string.match()</tt> et al.</li>
-  <li>Fix late despecialization of <tt>ITERN</tt> after loop has been entered.</li>
-  <li>Fix <tt>'f'</tt> and <tt>'L'</tt> options for <tt>debug.getinfo()</tt> and <tt>lua_getinfo()</tt>.</li>
-  <li>Fix <tt>package.searchpath()</tt>.</li>
-  <li>OSX: Change dylib names to be consistent with other platforms.</li>
-  <li>Android: Workaround for broken <tt>sprintf("%g",&nbsp;-0.0)</tt>.</li>
-  <li>x86: Remove support for ancient CPUs without <tt>CMOV</tt> (before Pentium Pro).</li>
-  <li>x86: Fix register allocation for calls returning register pair.</li>
-  <li>x86/x64: Fix fusion of unsigned byte comparisons with swapped operands.</li>
-  <li>ARM: Fix <tt>tonumber()</tt> argument check.</li>
-  <li>ARM: Fix modulo operator and <tt>math.floor()</tt>/<tt>math.ceil()</tt> for <tt>inf</tt>/<tt>nan</tt>.</li>
-  <li>ARM: Invoke SPLIT pass for leftover <tt>IR_TOBIT</tt>.</li>
-  <li>ARM: Fix BASE register coalescing.</li>
-  <li>PPC: Fix interpreter state setup in callbacks.</li>
-  <li>PPC: Fix <tt>string.sub()</tt> range check.</li>
-  <li>MIPS: Support generation of MIPS/MIPSEL bytecode object files.</li>
-  <li>MIPS: Fix calls to <tt>floor()</tt>/<tt>ceil()</tt><tt>/trunc()</tt>.</li>
-  <li>ARM/PPC: Detect more target architecture variants.</li>
-  <li>ARM/PPC/e500/MIPS: Fix tailcalls from fast functions, esp. <tt>tostring()</tt>.</li>
-  <li>ARM/PPC/MIPS: Fix rematerialization of FP constants.</li>
-  <li>FFI: Don't call <tt>FreeLibrary()</tt> on our own EXE/DLL.</li>
-  <li>FFI: Resolve metamethods for constructors, too.</li>
-  <li>FFI: Properly disable callbacks on iOS (would require executable memory).</li>
-  <li>FFI: Fix cdecl string parsing during recording.</li>
-  <li>FFI: Show address pointed to for <tt>tostring(ref)</tt>, too.</li>
-  <li>FFI: Fix alignment of C call argument/return structure.</li>
-  <li>FFI: Initialize all fields of standard types.</li>
-  <li>FFI: Fix callback handling when new C&nbsp;types are declared in callback.</li>
-  <li>FFI: Fix recording of constructors for pointers.</li>
-  <li>FFI: Always resolve metamethods for pointers to structs.</li>
-  <li>FFI: Correctly propagate alignment when interning nested types.</li>
-</ul></li>
-<li>Structural and performance enhancements:
-<ul>
-  <li>Add allocation sinking and store sinking optimization.</li>
-  <li>Constify immutable upvalues.</li>
-  <li>Add builtin string to integer or FP number conversion. Improves cross-platform consistency and correctness.</li>
-  <li>Create string hash slots in template tables for non-const values, too. Avoids later table resizes.</li>
-  <li>Eliminate <tt>HREFK</tt> guard for template table references.</li>
-  <li>Add various new FOLD rules.</li>
-  <li>Don't use stack unwinding for <tt>lua_yield()</tt> (slow on x64).</li>
-  <li>ARM, PPC, MIPS: Improve <tt>XLOAD</tt> operand fusion and register hinting.</li>
-  <li>PPC, MIPS: Compile <tt>math.sqrt()</tt> to sqrt instruction, if available.</li>
-  <li>FFI: Fold <tt>KPTR</tt> + constant offset in SPLIT pass.</li>
-  <li>FFI: Optimize/inline <tt>ffi.copy()</tt> and <tt>ffi.fill()</tt>.</li>
-  <li>FFI: Compile and optimize array/struct copies.</li>
-  <li>FFI: Compile <tt>ffi.typeof(cdata|ctype)</tt>, <tt>ffi.sizeof()</tt>, <tt>ffi.alignof()</tt>, <tt>ffi.offsetof()</tt> and <tt>ffi.gc()</tt>.</li>
-</ul></li>
-</ul>
-
-<h2 id="LuaJIT-2.0.0-beta10">LuaJIT 2.0.0-beta10 &mdash; 2012-05-09</h2>
-<ul>
-<li>New features:
-<ul>
-<li>The MIPS of LuaJIT is complete. It requires a CPU conforming to the
-MIPS32&nbsp;R1 architecture with hardware FPU. O32 hard-fp ABI,
-little-endian or big-endian.</li>
-<li>Auto-detect target arch via cross-compiler. No need for
-<tt>TARGET=arch</tt> anymore.</li>
-<li>Make DynASM compatible with Lua 5.2.</li>
-<li>From Lua 5.2: Try <tt>__tostring</tt> metamethod on non-string error
-messages..</li>
-</ul></li>
-<li>Correctness and completeness:
-<ul>
-<li>Fix parsing of hex literals with exponents.</li>
-<li>Fix bytecode dump for certain number constants.</li>
-<li>Fix argument type in error message for relative arguments.</li>
-<li>Fix argument error handling on Lua stacks without a frame.</li>
-<li>Add missing mcode limit check in assembler backend.</li>
-<li>Fix compilation on OpenBSD.</li>
-<li>Avoid recursive GC steps after GC-triggered trace exit.</li>
-<li>Replace <tt>&lt;unwind.h&gt;</tt> definitions with our own.</li>
-<li>Fix OSX build issues. Bump minimum required OSX version to 10.4.</li>
-<li>Fix discharge order of comparisons in Lua parser.</li>
-<li>Ensure running <tt>__gc</tt> of userdata created in <tt>__gc</tt>
-at state close.</li>
-<li>Limit number of userdata <tt>__gc</tt> separations at state close.</li>
-<li>Fix bytecode <tt>JMP</tt> slot range when optimizing
-<tt>and</tt>/<tt>or</tt> with constant LHS.</li>
-<li>Fix DSE of <tt>USTORE</tt>.</li>
-<li>Make <tt>lua_concat()</tt> work from C&nbsp;hook with partial frame.</li>
-<li>Add required PHIs for implicit conversions, e.g. via <tt>XREF</tt>
-forwarding.</li>
-<li>Add more comparison variants to Valgrind suppressions file.</li>
-<li>Disable loading bytecode with an extra header (BOM or <tt>#!</tt>).</li>
-<li>Fix PHI stack slot syncing.</li>
-<li>ARM: Reorder type/value tests to silence Valgrind.</li>
-<li>ARM: Fix register allocation for <tt>ldrd</tt>-optimized
-<tt>HREFK</tt>.</li>
-<li>ARM: Fix conditional branch fixup for <tt>OBAR</tt>.</li>
-<li>ARM: Invoke SPLIT pass for <tt>double</tt> args in FFI call.</li>
-<li>ARM: Handle all <tt>CALL*</tt> ops with <tt>double</tt> results in
-SPLIT pass.</li>
-<li>ARM: Fix rejoin of <tt>POW</tt> in SPLIT pass.</li>
-<li>ARM: Fix compilation of <tt>math.sinh</tt>, <tt>math.cosh</tt>,
-<tt>math.tanh</tt>.</li>
-<li>ARM, PPC: Avoid pointless arg clearing in <tt>BC_IFUNCF</tt>.</li>
-<li>PPC: Fix resume after yield from hook.</li>
-<li>PPC: Fix argument checking for <tt>rawget()</tt>.</li>
-<li>PPC: Fix fusion of floating-point <tt>XLOAD</tt>/<tt>XSTORE</tt>.</li>
-<li>PPC: Fix <tt>HREFK</tt> code generation for huge tables.</li>
-<li>PPC: Use builtin D-Cache/I-Cache sync code.</li>
-</ul></li>
-<li>FFI library:
-<ul>
-<li>Ignore empty statements in <tt>ffi.cdef()</tt>.</li>
-<li>Ignore number parsing errors while skipping definitions.</li>
-<li>Don't touch frame in callbacks with tailcalls to fast functions.</li>
-<li>Fix library unloading on POSIX systems.</li>
-<li>Finalize cdata before userdata when closing the state.</li>
-<li>Change <tt>ffi.load()</tt> library name resolution for Cygwin.</li>
-<li>Fix resolving of function name redirects on Windows/x86.</li>
-<li>Fix symbol resolving error messages on Windows.</li>
-<li>Fix blacklisting of C functions calling callbacks.</li>
-<li>Fix result type of pointer difference.</li>
-<li>Use correct PC in FFI metamethod error message.</li>
-<li>Allow <tt>'typedef _Bool int BOOL;'</tt> for the Windows API.</li>
-<li>Don't record test for bool result of call, if ignored.</li>
-</ul></li>
-</ul>
-
-<h2 id="LuaJIT-2.0.0-beta9">LuaJIT 2.0.0-beta9 &mdash; 2011-12-14</h2>
-<ul>
-<li>New features:
-<ul>
-<li>PPC port of LuaJIT is complete. Default is the dual-number port
-(usually faster). Single-number port selectable via <tt>src/Makefile</tt>
-at build time.</li>
-<li>Add FFI callback support.</li>
-<li>Extend <tt>-b</tt> to generate <tt>.c</tt>, <tt>.h</tt> or <tt>.obj/.o</tt>
-files with embedded bytecode.</li>
-<li>Allow loading embedded bytecode with <tt>require()</tt>.</li>
-<li>From Lua 5.2: Change to <tt>'\z'</tt> escape. Reject undefined escape
-sequences.</li>
-</ul></li>
-<li>Correctness and completeness:
-<ul>
-<li>Fix OSX 10.7 build. Fix <tt>install_name</tt> and versioning on OSX.</li>
-<li>Fix iOS build.</li>
-<li>Install <tt>dis_arm.lua</tt>, too.</li>
-<li>Mark installed shared library as executable.</li>
-<li>Add debug option to <tt>msvcbuild.bat</tt> and improve error handling.</li>
-<li>Fix data-flow analysis for iterators.</li>
-<li>Fix forced unwinding triggered by external unwinder.</li>
-<li>Record missing <tt>for</tt> loop slot loads (return to lower frame).</li>
-<li>Always use ANSI variants of Windows system functions.</li>
-<li>Fix GC barrier for multi-result table constructor (<tt>TSETM</tt>).</li>
-<li>Fix/add various FOLD rules.</li>
-<li>Add potential PHI for number conversions due to type instability.</li>
-<li>Do not eliminate PHIs only referenced from other PHIs.</li>
-<li>Correctly anchor implicit number to string conversions in Lua/C API.</li>
-<li>Fix various stack limit checks.</li>
-<li>x64: Use thread-safe exceptions for external unwinding (GCC platforms).</li>
-<li>x64: Fix result type of cdata index conversions.</li>
-<li>x64: Fix <tt>math.random()</tt> and <tt>bit.bswap()</tt> code generation.</li>
-<li>x64: Fix <tt>lightuserdata</tt> comparisons.</li>
-<li>x64: Always extend stack-passed arguments to pointer size.</li>
-<li>ARM: Many fixes to code generation backend.</li>
-<li>PPC/e500: Fix dispatch for binop metamethods.</li>
-<li>PPC/e500: Save/restore condition registers when entering/leaving the VM.</li>
-<li>PPC/e500: Fix write barrier in stores of strings to upvalues.</li>
-</ul></li>
-<li>FFI library:
-<ul>
-<li>Fix C comment parsing.</li>
-<li>Fix snapshot optimization for cdata comparisons.</li>
-<li>Fix recording of const/enum lookups in namespaces.</li>
-<li>Fix call argument and return handling for <tt>I8/U8/I16/U16</tt> types.</li>
-<li>Fix unfused loads of float fields.</li>
-<li>Fix <tt>ffi.string()</tt> recording.</li>
-<li>Save <tt>GetLastError()</tt> around <tt>ffi.load()</tt> and symbol
-resolving, too.</li>
-<li>Improve ld script detection in <tt>ffi.load()</tt>.</li>
-<li>Record loads/stores to external variables in namespaces.</li>
-<li>Compile calls to stdcall, fastcall and vararg functions.</li>
-<li>Treat function ctypes like pointers in comparisons.</li>
-<li>Resolve <tt>__call</tt> metamethod for pointers, too.</li>
-<li>Record C function calls with bool return values.</li>
-<li>Record <tt>ffi.errno()</tt>.</li>
-<li>x86: Fix number to <tt>uint32_t</tt> conversion rounding.</li>
-<li>x86: Fix 64 bit arithmetic in assembler backend.</li>
-<li>x64: Fix struct-by-value calling conventions.</li>
-<li>ARM: Ensure invocation of SPLIT pass for float conversions.</li>
-</ul></li>
-<li>Structural and performance enhancements:
-<ul>
-<li>Display trace types with <tt>-jv</tt> and <tt>-jdump</tt>.</li>
-<li>Record isolated calls. But prefer recording loops over calls.</li>
-<li>Specialize to prototype for non-monomorphic functions. Solves the
-trace-explosion problem for closure-heavy programming styles.</li>
-<li>Always generate a portable <tt>vmdef.lua</tt>. Easier for distros.</li>
-</ul></li>
-</ul>
-
-<h2 id="LuaJIT-2.0.0-beta8">LuaJIT 2.0.0-beta8 &mdash; 2011-06-23</h2>
-<ul>
-<li>New features:
-<ul>
-<li>Soft-float ARM port of LuaJIT is complete.</li>
-<li>Add support for bytecode loading/saving and <tt>-b</tt> command line
-option.</li>
-<li>From Lua 5.2: <tt>__len</tt> metamethod for tables
-(disabled by default).</li>
-</ul></li>
-<li>Correctness and completeness:
-<ul>
-<li>ARM: Misc. fixes for interpreter.</li>
-<li>x86/x64: Fix <tt>bit.*</tt> argument checking in interpreter.</li>
-<li>Catch early out-of-memory in memory allocator initialization.</li>
-<li>Fix data-flow analysis for paths leading to an upvalue close.</li>
-<li>Fix check for missing arguments in <tt>string.format()</tt>.</li>
-<li>Fix Solaris/x86 build (note: not a supported target).</li>
-<li>Fix recording of loops with instable directions in side traces.</li>
-<li>x86/x64: Fix fusion of comparisons with <tt>u8</tt>/<tt>u16</tt>
-<tt>XLOAD</tt>.</li>
-<li>x86/x64: Fix register allocation for variable shifts.</li>
-</ul></li>
-<li>FFI library:
-<ul>
-<li>Add <tt>ffi.errno()</tt>. Save <tt>errno</tt>/<tt>GetLastError()</tt>
-around allocations etc.</li>
-<li>Fix <tt>__gc</tt> for VLA/VLS cdata objects.</li>
-<li>Fix recording of casts from 32 bit cdata pointers to integers.</li>
-<li><tt>tonumber(cdata)</tt> returns <tt>nil</tt> for non-numbers.</li>
-<li>Show address pointed to for <tt>tostring(pointer)</tt>.</li>
-<li>Print <tt>NULL</tt> pointers as <tt>"cdata&lt;... *&gt;: NULL"</tt>.</li>
-<li>Support <tt>__tostring</tt> metamethod for pointers to structs, too.</li>
-</ul></li>
-<li>Structural and performance enhancements:
-<ul>
-<li>More tuning for loop unrolling heuristics.</li>
-<li>Flatten and compress in-memory debug info (saves ~70%).</li>
-</ul></li>
-</ul>
-
-<h2 id="LuaJIT-2.0.0-beta7">LuaJIT 2.0.0-beta7 &mdash; 2011-05-05</h2>
-<ul>
-<li>New features:
-<ul>
-<li>ARM port of the LuaJIT interpreter is complete.</li>
-<li>FFI library: Add <tt>ffi.gc()</tt>, <tt>ffi.metatype()</tt>,
-<tt>ffi.istype()</tt>.</li>
-<li>FFI library: Resolve ld script redirection in <tt>ffi.load()</tt>.</li>
-<li>From Lua 5.2: <tt>package.searchpath()</tt>, <tt>fp:read("*L")</tt>,
-<tt>load(string)</tt>.</li>
-<li>From Lua 5.2, disabled by default: empty statement,
-<tt>table.unpack()</tt>, modified <tt>coroutine.running()</tt>.</li>
-</ul></li>
-<li>Correctness and completeness:
-<ul>
-<li>FFI library: numerous fixes.</li>
-<li>Fix type mismatches in store-to-load forwarding.</li>
-<li>Fix error handling within metamethods.</li>
-<li>Fix <tt>table.maxn()</tt>.</li>
-<li>Improve accuracy of <tt>x^-k</tt> on x64.</li>
-<li>Fix code generation for Intel Atom in x64 mode.</li>
-<li>Fix narrowing of POW.</li>
-<li>Fix recording of retried fast functions.</li>
-<li>Fix code generation for <tt>bit.bnot()</tt> and multiplies.</li>
-<li>Fix error location within cpcall frames.</li>
-<li>Add workaround for old libgcc unwind bug.</li>
-<li>Fix <tt>lua_yield()</tt> and <tt>getmetatable(lightuserdata)</tt> on x64.</li>
-<li>Misc. fixes for PPC/e500 interpreter.</li>
-<li>Fix stack slot updates for down-recursion.</li>
-</ul></li>
-<li>Structural and performance enhancements:
-<ul>
-<li>Add dual-number mode (int/double) for the VM. Enabled for ARM.</li>
-<li>Improve narrowing of arithmetic operators and <tt>for</tt> loops.</li>
-<li>Tune loop unrolling heuristics and increase trace recorder limits.</li>
-<li>Eliminate dead slots in snapshots using bytecode data-flow analysis.</li>
-<li>Avoid phantom stores to proxy tables.</li>
-<li>Optimize lookups in empty proxy tables.</li>
-<li>Improve bytecode optimization of <tt>and</tt>/<tt>or</tt> operators.</li>
-</ul></li>
-</ul>
-
-<h2 id="LuaJIT-2.0.0-beta6">LuaJIT 2.0.0-beta6 &mdash; 2011-02-11</h2>
-<ul>
-<li>New features:
-<ul>
-<li>PowerPC/e500v2 port of the LuaJIT interpreter is complete.</li>
-<li>Various minor features from Lua 5.2: Hex escapes in literals,
-<tt>'\*'</tt> escape, reversible <tt>string.format("%q",s)</tt>,
-<tt>"%g"</tt> pattern, <tt>table.sort</tt> checks callbacks,
-<tt>os.exit(status|true|false[,close])</tt>.</li>
-<li>Lua 5.2 <tt>__pairs</tt> and <tt>__ipairs</tt> metamethods
-(disabled by default).</li>
-<li>Initial release of the FFI library.</li>
-</ul></li>
-<li>Correctness and completeness:
-<ul>
-<li>Fix <tt>string.format()</tt> for non-finite numbers.</li>
-<li>Fix memory leak when compiled to use the built-in allocator.</li>
-<li>x86/x64: Fix unnecessary resize in <tt>TSETM</tt> bytecode.</li>
-<li>Fix various GC issues with traces and <tt>jit.flush()</tt>.</li>
-<li>x64: Fix fusion of indexes for array references.</li>
-<li>x86/x64: Fix stack overflow handling for coroutine results.</li>
-<li>Enable low-2GB memory allocation on FreeBSD/x64.</li>
-<li>Fix <tt>collectgarbage("count")</tt> result if more than 2GB is in use.</li>
-<li>Fix parsing of hex floats.</li>
-<li>x86/x64: Fix loop branch inversion with trailing
-<tt>HREF+NE/EQ</tt>.</li>
-<li>Add <tt>jit.os</tt> string.</li>
-<li><tt>coroutine.create()</tt> permits running C functions, too.</li>
-<li>Fix OSX build to work with newer ld64 versions.</li>
-<li>Fix bytecode optimization of <tt>and</tt>/<tt>or</tt> operators.</li>
-</ul></li>
-<li>Structural and performance enhancements:
-<ul>
-<li>Emit specialized bytecode for <tt>pairs()</tt>/<tt>next()</tt>.</li>
-<li>Improve bytecode coalescing of <tt>nil</tt> constants.</li>
-<li>Compile calls to vararg functions.</li>
-<li>Compile <tt>select()</tt>.</li>
-<li>Improve alias analysis, esp. for loads from allocations.</li>
-<li>Tuning of various compiler heuristics.</li>
-<li>Refactor and extend IR conversion instructions.</li>
-<li>x86/x64: Various backend enhancements related to the FFI.</li>
-<li>Add SPLIT pass to split 64 bit IR instructions for 32 bit CPUs.</li>
-</ul></li>
-</ul>
-
-<h2 id="LuaJIT-2.0.0-beta5">LuaJIT 2.0.0-beta5 &mdash; 2010-08-24</h2>
-<ul>
-<li>Correctness and completeness:
-<ul>
-<li>Fix trace exit dispatch to function headers.</li>
-<li>Fix Windows and OSX builds with LUAJIT_DISABLE_JIT.</li>
-<li>Reorganize and fix placement of generated machine code on x64.</li>
-<li>Fix TNEW in x64 interpreter.</li>
-<li>Do not eliminate PHIs for values only referenced from side exits.</li>
-<li>OS-independent canonicalization of strings for non-finite numbers.</li>
-<li>Fix <tt>string.char()</tt> range check on x64.</li>
-<li>Fix <tt>tostring()</tt> resolving within <tt>print()</tt>.</li>
-<li>Fix error handling for <tt>next()</tt>.</li>
-<li>Fix passing of constant arguments to external calls on x64.</li>
-<li>Fix interpreter argument check for two-argument SSE math functions.</li>
-<li>Fix C frame chain corruption caused by <tt>lua_cpcall()</tt>.</li>
-<li>Fix return from <tt>pcall()</tt> within active hook.</li>
-</ul></li>
-<li>Structural and performance enhancements:
-<ul>
-<li>Replace on-trace GC frame syncing with interpreter exit.</li>
-<li>Improve hash lookup specialization by not removing dead keys during GC.</li>
-<li>Turn traces into true GC objects.</li>
-<li>Avoid starting a GC cycle immediately after library init.</li>
-<li>Add weak guards to improve dead-code elimination.</li>
-<li>Speed up string interning.</li>
-</ul></li>
-</ul>
-
-<h2 id="LuaJIT-2.0.0-beta4">LuaJIT 2.0.0-beta4 &mdash; 2010-03-28</h2>
-<ul>
-<li>Correctness and completeness:
-<ul>
-<li>Fix precondition for on-trace creation of table keys.</li>
-<li>Fix <tt>{f()}</tt> on x64 when table is resized.</li>
-<li>Fix folding of ordered comparisons with same references.</li>
-<li>Fix snapshot restores for multi-result bytecodes.</li>
-<li>Fix potential hang when recording bytecode with nested closures.</li>
-<li>Fix recording of <tt>getmetatable()</tt>, <tt>tonumber()</tt> and bad argument types.</li>
-<li>Fix SLOAD fusion across returns to lower frames.</li>
-</ul></li>
-<li>Structural and performance enhancements:
-<ul>
-<li>Add array bounds check elimination. <tt>-Oabc</tt> is enabled by default.</li>
-<li>More tuning for x64, e.g. smaller table objects.</li>
-</ul></li>
-</ul>
-
-<h2 id="LuaJIT-2.0.0-beta3">LuaJIT 2.0.0-beta3 &mdash; 2010-03-07</h2>
-<ul>
-<li>LuaJIT x64 port:
-<ul>
-<li>Port integrated memory allocator to Linux/x64, Windows/x64 and OSX/x64.</li>
-<li>Port interpreter and JIT compiler to x64.</li>
-<li>Port DynASM to x64.</li>
-<li>Many 32/64 bit cleanups in the VM.</li>
-<li>Allow building the interpreter with either x87 or SSE2 arithmetics.</li>
-<li>Add external unwinding and C++ exception interop (default on x64).</li>
-</ul></li>
-<li>Correctness and completeness:
-<ul>
-<li>Fix constructor bytecode generation for certain conditional values.</li>
-<li>Fix some cases of ordered string comparisons.</li>
-<li>Fix <tt>lua_tocfunction()</tt>.</li>
-<li>Fix cutoff register in JMP bytecode for some conditional expressions.</li>
-<li>Fix PHI marking algorithm for references from variant slots.</li>
-<li>Fix <tt>package.cpath</tt> for non-default PREFIX.</li>
-<li>Fix DWARF2 frame unwind information for interpreter on OSX.</li>
-<li>Drive the GC forward on string allocations in the parser.</li>
-<li>Implement call/return hooks (zero-cost if disabled).</li>
-<li>Implement yield from C hooks.</li>
-<li>Disable JIT compiler on older non-SSE2 CPUs instead of aborting.</li>
-</ul></li>
-<li>Structural and performance enhancements:
-<ul>
-<li>Compile recursive code (tail-, up- and down-recursion).</li>
-<li>Improve heuristics for bytecode penalties and blacklisting.</li>
-<li>Split CALL/FUNC recording and clean up fast function call semantics.</li>
-<li>Major redesign of internal function call handling.</li>
-<li>Improve FOR loop const specialization and integerness checks.</li>
-<li>Switch to pre-initialized stacks. Avoid frame-clearing.</li>
-<li>Colocation of prototypes and related data: bytecode, constants, debug info.</li>
-<li>Cleanup parser and streamline bytecode generation.</li>
-<li>Add support for weak IR references to register allocator.</li>
-<li>Switch to compressed, extensible snapshots.</li>
-<li>Compile returns to frames below the start frame.</li>
-<li>Improve alias analysis of upvalues using a disambiguation hash value.</li>
-<li>Compile floor/ceil/trunc to SSE2 helper calls or SSE4.1 instructions.</li>
-<li>Add generic C call handling to IR and backend.</li>
-<li>Improve KNUM fuse vs. load heuristics.</li>
-<li>Compile various <tt>io.*()</tt> functions.</li>
-<li>Compile <tt>math.sinh()</tt>, <tt>math.cosh()</tt>, <tt>math.tanh()</tt>
-and <tt>math.random()</tt>.</li>
-</ul></li>
-</ul>
-
-<h2 id="LuaJIT-2.0.0-beta2">LuaJIT 2.0.0-beta2 &mdash; 2009-11-09</h2>
-<ul>
-<li>Reorganize build system. Build static+shared library on POSIX.</li>
-<li>Allow C++ exception conversion on all platforms
-using a wrapper function.</li>
-<li>Automatically catch C++ exceptions and rethrow Lua error
-(DWARF2 only).</li>
-<li>Check for the correct x87 FPU precision at strategic points.</li>
-<li>Always use wrappers for libm functions.</li>
-<li>Resurrect metamethod name strings before copying them.</li>
-<li>Mark current trace, even if compiler is idle.</li>
-<li>Ensure FILE metatable is created only once.</li>
-<li>Fix type comparisons when different integer types are involved.</li>
-<li>Fix <tt>getmetatable()</tt> recording.</li>
-<li>Fix TDUP with dead keys in template table.</li>
-<li><tt>jit.flush(tr)</tt> returns status.
-Prevent manual flush of a trace that's still linked.</li>
-<li>Improve register allocation heuristics for invariant references.</li>
-<li>Compile the push/pop variants of <tt>table.insert()</tt> and
-<tt>table.remove()</tt>.</li>
-<li>Compatibility with MSVC <tt>link&nbsp/debug</tt>.</li>
-<li>Fix <tt>lua_iscfunction()</tt>.</li>
-<li>Fix <tt>math.random()</tt> when compiled with <tt>-fpic</tt> (OSX).</li>
-<li>Fix <tt>table.maxn()</tt>.</li>
-<li>Bump <tt>MACOSX_DEPLOYMENT_TARGET</tt> to <tt>10.4</tt></li>
-<li><tt>luaL_check*()</tt> and <tt>luaL_opt*()</tt> now support
-negative arguments, too.<br>
-This matches the behavior of Lua 5.1, but not the specification.</li>
-</ul>
-
-<h2 id="LuaJIT-2.0.0-beta1">LuaJIT 2.0.0-beta1 &mdash; 2009-10-31</h2>
-<ul>
-<li>This is the first public release of LuaJIT 2.0.</li>
-<li>The whole VM has been rewritten from the ground up, so there's
-no point in listing differences over earlier versions.</li>
-</ul>
-</div>
-<br class="flush">
-</div>
-<div id="foot">
-<hr class="hide">
-Copyright &copy; 2005-2018
-<span class="noprint">
-&middot;
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>

+ 8 - 13
libs/LuaJIT/doc/contact.html

@@ -3,14 +3,14 @@
 <head>
 <head>
 <title>Contact</title>
 <title>Contact</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1>Contact</h1>
 <h1>Contact</h1>
@@ -19,7 +19,7 @@
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -45,28 +45,23 @@
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
 <p>
 <p>
 If you want to report bugs, propose fixes or suggest enhancements,
 If you want to report bugs, propose fixes or suggest enhancements,
 please use the
 please use the
-<a href="https://github.com/LuaJIT/LuaJIT/issues">GitHub issue tracker</a>.
+<a href="https://github.com/LuaJIT/LuaJIT/issues"><span class="ext">&raquo;</span>&nbsp;GitHub issue tracker</a>.
 </p>
 </p>
 <p>
 <p>
 Please send general questions to the
 Please send general questions to the
-<a href="http://luajit.org/list.html"><span class="ext">&raquo;</span>&nbsp;LuaJIT mailing list</a>.
+<a href="https://luajit.org/list.html"><span class="ext">&raquo;</span>&nbsp;LuaJIT mailing list</a>.
 </p>
 </p>
 <p>
 <p>
 You can also send any questions you have directly to me:
 You can also send any questions you have directly to me:
@@ -92,7 +87,7 @@ xD("fyZKB8xv\"FJytmz8.KAB0u52D")
 <h2>Copyright</h2>
 <h2>Copyright</h2>
 <p>
 <p>
 All documentation is
 All documentation is
-Copyright &copy; 2005-2018 Mike Pall.
+Copyright &copy; 2005-2020 Mike Pall.
 </p>
 </p>
 
 
 
 
@@ -100,7 +95,7 @@ Copyright &copy; 2005-2018 Mike Pall.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 5 - 10
libs/LuaJIT/doc/ext_c_api.html

@@ -3,14 +3,14 @@
 <head>
 <head>
 <title>Lua/C API Extensions</title>
 <title>Lua/C API Extensions</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1>Lua/C API Extensions</h1>
 <h1>Lua/C API Extensions</h1>
@@ -19,7 +19,7 @@
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -45,17 +45,12 @@
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
@@ -178,7 +173,7 @@ Also note that this mechanism is not without overhead.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 5 - 10
libs/LuaJIT/doc/ext_ffi.html

@@ -3,14 +3,14 @@
 <head>
 <head>
 <title>FFI Library</title>
 <title>FFI Library</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1>FFI Library</h1>
 <h1>FFI Library</h1>
@@ -19,7 +19,7 @@
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -45,17 +45,12 @@
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
@@ -321,7 +316,7 @@ without undue conversion penalties.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 6 - 11
libs/LuaJIT/doc/ext_ffi_api.html

@@ -3,7 +3,7 @@
 <head>
 <head>
 <title>ffi.* API Functions</title>
 <title>ffi.* API Functions</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -15,7 +15,7 @@ td.abiparam { font-weight: bold; width: 6em; }
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1><tt>ffi.*</tt> API Functions</h1>
 <h1><tt>ffi.*</tt> API Functions</h1>
@@ -24,7 +24,7 @@ td.abiparam { font-weight: bold; width: 6em; }
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -50,17 +50,12 @@ td.abiparam { font-weight: bold; width: 6em; }
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
@@ -260,7 +255,7 @@ contents of an <tt>__index</tt> table (if any) may be modified
 afterwards. The associated metatable automatically applies to all uses
 afterwards. The associated metatable automatically applies to all uses
 of this type, no matter how the objects are created or where they
 of this type, no matter how the objects are created or where they
 originate from. Note that pre-defined operations on types have
 originate from. Note that pre-defined operations on types have
-precedence (e.g. declared field names cannot be overriden).
+precedence (e.g. declared field names cannot be overridden).
 </p>
 </p>
 <p>
 <p>
 All standard Lua metamethods are implemented. These are called directly,
 All standard Lua metamethods are implemented. These are called directly,
@@ -561,7 +556,7 @@ named <tt>i</tt>.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 8 - 13
libs/LuaJIT/doc/ext_ffi_semantics.html

@@ -3,7 +3,7 @@
 <head>
 <head>
 <title>FFI Semantics</title>
 <title>FFI Semantics</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -15,7 +15,7 @@ td.convop { font-style: italic; width: 40%; }
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1>FFI Semantics</h1>
 <h1>FFI Semantics</h1>
@@ -24,7 +24,7 @@ td.convop { font-style: italic; width: 40%; }
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -50,17 +50,12 @@ td.convop { font-style: italic; width: 40%; }
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
@@ -677,7 +672,7 @@ through unions is explicitly detected and allowed.
 <a href="ext_ffi_api.html#ffi_new">constructor</a>. This is equivalent
 <a href="ext_ffi_api.html#ffi_new">constructor</a>. This is equivalent
 to <tt>ffi.new(ct, ...)</tt>, unless a <tt>__new</tt> metamethod is
 to <tt>ffi.new(ct, ...)</tt>, unless a <tt>__new</tt> metamethod is
 defined. The <tt>__new</tt> metamethod is called with the ctype object
 defined. The <tt>__new</tt> metamethod is called with the ctype object
-plus any other arguments passed to the contructor. Note that you have to
+plus any other arguments passed to the constructor. Note that you have to
 use <tt>ffi.new</tt> inside of it, since calling <tt>ct(...)</tt> would
 use <tt>ffi.new</tt> inside of it, since calling <tt>ct(...)</tt> would
 cause infinite recursion.</li>
 cause infinite recursion.</li>
 
 
@@ -863,7 +858,7 @@ place of a type, you'd need to use <tt>ffi.typeof("int")</tt> instead.
 <p>
 <p>
 The main use for parameterized types are libraries implementing abstract
 The main use for parameterized types are libraries implementing abstract
 data types
 data types
-(<a href="https://www.freelists.org/post/luajit/ffi-type-of-pointer-to,8">example</a>),
+(<a href="https://www.freelists.org/post/luajit/ffi-type-of-pointer-to,8"><span class="ext">&raquo;</span>&nbsp;example</a>),
 similar to what can be achieved with C++ template metaprogramming.
 similar to what can be achieved with C++ template metaprogramming.
 Another use case are derived types of anonymous structs, which avoids
 Another use case are derived types of anonymous structs, which avoids
 pollution of the global struct namespace.
 pollution of the global struct namespace.
@@ -1224,7 +1219,7 @@ suboptimal performance, especially when used in inner loops:
 <li>Table initializers.</li>
 <li>Table initializers.</li>
 <li>Initialization of nested <tt>struct</tt>/<tt>union</tt> types.</li>
 <li>Initialization of nested <tt>struct</tt>/<tt>union</tt> types.</li>
 <li>Non-default initialization of VLA/VLS or large C&nbsp;types
 <li>Non-default initialization of VLA/VLS or large C&nbsp;types
-(&gt; 128&nbsp;bytes or &gt; 16 array elements.</li>
+(&gt; 128&nbsp;bytes or &gt; 16 array elements).</li>
 <li>Bitfield initializations.</li>
 <li>Bitfield initializations.</li>
 <li>Pointer differences for element sizes that are not a power of
 <li>Pointer differences for element sizes that are not a power of
 two.</li>
 two.</li>
@@ -1251,7 +1246,7 @@ compiled.</li>
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 7 - 12
libs/LuaJIT/doc/ext_ffi_tutorial.html

@@ -3,7 +3,7 @@
 <head>
 <head>
 <title>FFI Tutorial</title>
 <title>FFI Tutorial</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -17,7 +17,7 @@ td.idiomlua b { font-weight: normal; color: #2142bf; }
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1>FFI Tutorial</h1>
 <h1>FFI Tutorial</h1>
@@ -26,7 +26,7 @@ td.idiomlua b { font-weight: normal; color: #2142bf; }
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -52,17 +52,12 @@ td.idiomlua b { font-weight: normal; color: #2142bf; }
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
@@ -221,7 +216,7 @@ a fascinating best-selling game is left as an exercise for the reader.
 <h2 id="zlib">Accessing the zlib Compression Library</h2>
 <h2 id="zlib">Accessing the zlib Compression Library</h2>
 <p>
 <p>
 The following code shows how to access the <a
 The following code shows how to access the <a
-href="http://zlib.net/">zlib</a> compression library from Lua code.
+href="https://zlib.net/"><span class="ext">&raquo;</span>&nbsp;zlib</a> compression library from Lua code.
 We'll define two convenience wrapper functions that take a string and
 We'll define two convenience wrapper functions that take a string and
 compress or uncompress it to another string:
 compress or uncompress it to another string:
 </p>
 </p>
@@ -304,7 +299,7 @@ comes pre-installed. Since <tt>ffi.load()</tt> automatically adds any
 missing standard prefixes/suffixes, we can simply load the
 missing standard prefixes/suffixes, we can simply load the
 <tt>"z"</tt> library. On Windows it's named <tt>zlib1.dll</tt> and
 <tt>"z"</tt> library. On Windows it's named <tt>zlib1.dll</tt> and
 you'll have to download it first from the
 you'll have to download it first from the
-<a href="http://zlib.net/"><span class="ext">&raquo;</span>&nbsp;zlib site</a>. The check for
+<a href="https://zlib.net/"><span class="ext">&raquo;</span>&nbsp;zlib site</a>. The check for
 <tt>ffi.os</tt> makes sure we pass the right name to
 <tt>ffi.os</tt> makes sure we pass the right name to
 <tt>ffi.load()</tt>.
 <tt>ffi.load()</tt>.
 </p>
 </p>
@@ -592,7 +587,7 @@ it to a local variable in the function scope is unnecessary.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 5 - 10
libs/LuaJIT/doc/ext_jit.html

@@ -3,14 +3,14 @@
 <head>
 <head>
 <title>jit.* Library</title>
 <title>jit.* Library</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1><tt>jit.*</tt> Library</h1>
 <h1><tt>jit.*</tt> Library</h1>
@@ -19,7 +19,7 @@
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -45,17 +45,12 @@
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
@@ -190,7 +185,7 @@ if you want to know more.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 5 - 10
libs/LuaJIT/doc/ext_profiler.html

@@ -3,14 +3,14 @@
 <head>
 <head>
 <title>Profiler</title>
 <title>Profiler</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1>Profiler</h1>
 <h1>Profiler</h1>
@@ -19,7 +19,7 @@
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -45,17 +45,12 @@
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
@@ -354,7 +349,7 @@ use.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 10 - 15
libs/LuaJIT/doc/extensions.html

@@ -3,7 +3,7 @@
 <head>
 <head>
 <title>Extensions</title>
 <title>Extensions</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -27,7 +27,7 @@ td.excinterop {
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1>Extensions</h1>
 <h1>Extensions</h1>
@@ -36,7 +36,7 @@ td.excinterop {
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -62,25 +62,20 @@ td.excinterop {
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
 <p>
 <p>
 LuaJIT is fully upwards-compatible with Lua 5.1. It supports all
 LuaJIT is fully upwards-compatible with Lua 5.1. It supports all
-<a href="http://www.lua.org/manual/5.1/manual.html#5"><span class="ext">&raquo;</span>&nbsp;standard Lua
+<a href="https://www.lua.org/manual/5.1/manual.html#5"><span class="ext">&raquo;</span>&nbsp;standard Lua
 library functions</a> and the full set of
 library functions</a> and the full set of
-<a href="http://www.lua.org/manual/5.1/manual.html#3"><span class="ext">&raquo;</span>&nbsp;Lua/C API
+<a href="https://www.lua.org/manual/5.1/manual.html#3"><span class="ext">&raquo;</span>&nbsp;Lua/C API
 functions</a>.
 functions</a>.
 </p>
 </p>
 <p>
 <p>
@@ -104,7 +99,7 @@ LuaJIT comes with several built-in extension modules:
 <h3 id="bit"><tt>bit.*</tt> &mdash; Bitwise operations</h3>
 <h3 id="bit"><tt>bit.*</tt> &mdash; Bitwise operations</h3>
 <p>
 <p>
 LuaJIT supports all bitwise operations as defined by
 LuaJIT supports all bitwise operations as defined by
-<a href="http://bitop.luajit.org"><span class="ext">&raquo;</span>&nbsp;Lua BitOp</a>:
+<a href="https://bitop.luajit.org"><span class="ext">&raquo;</span>&nbsp;Lua BitOp</a>:
 </p>
 </p>
 <pre class="code">
 <pre class="code">
 bit.tobit  bit.tohex  bit.bnot    bit.band bit.bor  bit.bxor
 bit.tobit  bit.tohex  bit.bnot    bit.band bit.bor  bit.bxor
@@ -113,7 +108,7 @@ bit.lshift bit.rshift bit.arshift bit.rol  bit.ror  bit.bswap
 <p>
 <p>
 This module is a LuaJIT built-in &mdash; you don't need to download or
 This module is a LuaJIT built-in &mdash; you don't need to download or
 install Lua BitOp. The Lua BitOp site has full documentation for all
 install Lua BitOp. The Lua BitOp site has full documentation for all
-<a href="http://bitop.luajit.org/api.html"><span class="ext">&raquo;</span>&nbsp;Lua BitOp API functions</a>.
+<a href="https://bitop.luajit.org/api.html"><span class="ext">&raquo;</span>&nbsp;Lua BitOp API functions</a>.
 The FFI adds support for
 The FFI adds support for
 <a href="ext_ffi_semantics.html#cdata_arith">64&nbsp;bit bitwise operations</a>,
 <a href="ext_ffi_semantics.html#cdata_arith">64&nbsp;bit bitwise operations</a>,
 using the same API functions.
 using the same API functions.
@@ -413,7 +408,7 @@ the toolchain used to compile LuaJIT:
 </tr>
 </tr>
 <tr class="even">
 <tr class="even">
 <td class="excplatform">Windows/x64</td>
 <td class="excplatform">Windows/x64</td>
-<td class="exccompiler">MSVC or WinSDK</td>
+<td class="exccompiler">MSVC</td>
 <td class="excinterop"><b style="color: #00a000;">Full</b></td>
 <td class="excinterop"><b style="color: #00a000;">Full</b></td>
 </tr>
 </tr>
 <tr class="odd">
 <tr class="odd">
@@ -475,7 +470,7 @@ C++ destructors.</li>
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 48 - 29
libs/LuaJIT/doc/faq.html

@@ -3,7 +3,7 @@
 <head>
 <head>
 <title>Frequently Asked Questions (FAQ)</title>
 <title>Frequently Asked Questions (FAQ)</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -13,7 +13,7 @@ dd { margin-left: 1.5em; }
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1>Frequently Asked Questions (FAQ)</h1>
 <h1>Frequently Asked Questions (FAQ)</h1>
@@ -22,7 +22,7 @@ dd { margin-left: 1.5em; }
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -48,67 +48,62 @@ dd { margin-left: 1.5em; }
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a class="current" href="faq.html">FAQ</a>
 <a class="current" href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
-<dl>
+<dl id="info">
 <dt>Q: Where can I learn more about LuaJIT and Lua?</dt>
 <dt>Q: Where can I learn more about LuaJIT and Lua?</dt>
 <dd>
 <dd>
 <ul style="padding: 0;">
 <ul style="padding: 0;">
-<li>The <a href="http://luajit.org/list.html"><span class="ext">&raquo;</span>&nbsp;LuaJIT mailing list</a> focuses on topics
+<li>The <a href="https://luajit.org/list.html"><span class="ext">&raquo;</span>&nbsp;LuaJIT mailing list</a> focuses on topics
 related to LuaJIT.</li>
 related to LuaJIT.</li>
 <li>The <a href="http://wiki.luajit.org/"><span class="ext">&raquo;</span>&nbsp;LuaJIT wiki</a> gathers community
 <li>The <a href="http://wiki.luajit.org/"><span class="ext">&raquo;</span>&nbsp;LuaJIT wiki</a> gathers community
 resources about LuaJIT.</li>
 resources about LuaJIT.</li>
 <li>News about Lua itself can be found at the
 <li>News about Lua itself can be found at the
-<a href="http://www.lua.org/lua-l.html"><span class="ext">&raquo;</span>&nbsp;Lua mailing list</a>.
+<a href="https://www.lua.org/lua-l.html"><span class="ext">&raquo;</span>&nbsp;Lua mailing list</a>.
 The mailing list archives are worth checking out for older postings
 The mailing list archives are worth checking out for older postings
 about LuaJIT.</li>
 about LuaJIT.</li>
-<li>The <a href="http://lua.org"><span class="ext">&raquo;</span>&nbsp;main Lua.org site</a> has complete
-<a href="http://www.lua.org/docs.html"><span class="ext">&raquo;</span>&nbsp;documentation</a> of the language
+<li>The <a href="https://lua.org"><span class="ext">&raquo;</span>&nbsp;main Lua.org site</a> has complete
+<a href="https://www.lua.org/docs.html"><span class="ext">&raquo;</span>&nbsp;documentation</a> of the language
 and links to books and papers about Lua.</li>
 and links to books and papers about Lua.</li>
 <li>The community-managed <a href="http://lua-users.org/wiki/"><span class="ext">&raquo;</span>&nbsp;Lua Wiki</a>
 <li>The community-managed <a href="http://lua-users.org/wiki/"><span class="ext">&raquo;</span>&nbsp;Lua Wiki</a>
 has information about diverse topics.</li>
 has information about diverse topics.</li>
 </ul>
 </ul>
 </dl>
 </dl>
 
 
-<dl>
+<dl id="tech">
 <dt>Q: Where can I learn more about the compiler technology used by LuaJIT?</dt>
 <dt>Q: Where can I learn more about the compiler technology used by LuaJIT?</dt>
 <dd>
 <dd>
 I'm planning to write more documentation about the internals of LuaJIT.
 I'm planning to write more documentation about the internals of LuaJIT.
 In the meantime, please use the following Google Scholar searches
 In the meantime, please use the following Google Scholar searches
 to find relevant papers:<br>
 to find relevant papers:<br>
-Search for: <a href="http://scholar.google.com/scholar?q=Trace+Compiler"><span class="ext">&raquo;</span>&nbsp;Trace Compiler</a><br>
-Search for: <a href="http://scholar.google.com/scholar?q=JIT+Compiler"><span class="ext">&raquo;</span>&nbsp;JIT Compiler</a><br>
-Search for: <a href="http://scholar.google.com/scholar?q=Dynamic+Language+Optimizations"><span class="ext">&raquo;</span>&nbsp;Dynamic Language Optimizations</a><br>
-Search for: <a href="http://scholar.google.com/scholar?q=SSA+Form"><span class="ext">&raquo;</span>&nbsp;SSA Form</a><br>
-Search for: <a href="http://scholar.google.com/scholar?q=Linear+Scan+Register+Allocation"><span class="ext">&raquo;</span>&nbsp;Linear Scan Register Allocation</a><br>
-Here is a list of the <a href="http://article.gmane.org/gmane.comp.lang.lua.general/58908"><span class="ext">&raquo;</span>&nbsp;innovative features in LuaJIT</a>.<br>
+Search for: <a href="https://scholar.google.com/scholar?q=Trace+Compiler"><span class="ext">&raquo;</span>&nbsp;Trace Compiler</a><br>
+Search for: <a href="https://scholar.google.com/scholar?q=JIT+Compiler"><span class="ext">&raquo;</span>&nbsp;JIT Compiler</a><br>
+Search for: <a href="https://scholar.google.com/scholar?q=Dynamic+Language+Optimizations"><span class="ext">&raquo;</span>&nbsp;Dynamic Language Optimizations</a><br>
+Search for: <a href="https://scholar.google.com/scholar?q=SSA+Form"><span class="ext">&raquo;</span>&nbsp;SSA Form</a><br>
+Search for: <a href="https://scholar.google.com/scholar?q=Linear+Scan+Register+Allocation"><span class="ext">&raquo;</span>&nbsp;Linear Scan Register Allocation</a><br>
+Here is a list of the <a href="http://lua-users.org/lists/lua-l/2009-11/msg00089.html"><span class="ext">&raquo;</span>&nbsp;innovative features in LuaJIT</a>.<br>
 And, you know, reading the source is of course the only way to enlightenment. :-)
 And, you know, reading the source is of course the only way to enlightenment. :-)
 </dd>
 </dd>
 </dl>
 </dl>
 
 
-<dl>
+<dl id="arg">
 <dt>Q: Why do I get this error: "attempt to index global 'arg' (a nil value)"?<br>
 <dt>Q: Why do I get this error: "attempt to index global 'arg' (a nil value)"?<br>
 Q: My vararg functions fail after switching to LuaJIT!</dt>
 Q: My vararg functions fail after switching to LuaJIT!</dt>
 <dd>LuaJIT is compatible to the Lua 5.1 language standard. It doesn't
 <dd>LuaJIT is compatible to the Lua 5.1 language standard. It doesn't
 support the implicit <tt>arg</tt> parameter for old-style vararg
 support the implicit <tt>arg</tt> parameter for old-style vararg
 functions from Lua 5.0.<br>Please convert your code to the
 functions from Lua 5.0.<br>Please convert your code to the
-<a href="http://www.lua.org/manual/5.1/manual.html#2.5.9"><span class="ext">&raquo;</span>&nbsp;Lua 5.1
+<a href="https://www.lua.org/manual/5.1/manual.html#2.5.9"><span class="ext">&raquo;</span>&nbsp;Lua 5.1
 vararg syntax</a>.</dd>
 vararg syntax</a>.</dd>
 </dl>
 </dl>
 
 
-<dl>
+<dl id="x87">
 <dt>Q: Why do I get this error: "bad FPU precision"?<br>
 <dt>Q: Why do I get this error: "bad FPU precision"?<br>
 <dt>Q: I get weird behavior after initializing Direct3D.<br>
 <dt>Q: I get weird behavior after initializing Direct3D.<br>
 <dt>Q: Some FPU operations crash after I load a Delphi DLL.<br>
 <dt>Q: Some FPU operations crash after I load a Delphi DLL.<br>
@@ -130,7 +125,7 @@ Please check the Delphi docs for the Set8087CW method.
 
 
 </dl>
 </dl>
 
 
-<dl>
+<dl id="ctrlc">
 <dt>Q: Sometimes Ctrl-C fails to stop my Lua program. Why?</dt>
 <dt>Q: Sometimes Ctrl-C fails to stop my Lua program. Why?</dt>
 <dd>The interrupt signal handler sets a Lua debug hook. But this is
 <dd>The interrupt signal handler sets a Lua debug hook. But this is
 currently ignored by compiled code (this will eventually be fixed). If
 currently ignored by compiled code (this will eventually be fixed). If
@@ -141,7 +136,31 @@ twice to get stop your program. That's similar to when it's stuck
 running inside a C function under the Lua interpreter.</dd>
 running inside a C function under the Lua interpreter.</dd>
 </dl>
 </dl>
 
 
-<dl>
+<dl id="sandbox">
+<dt>Q: Can Lua code be safely sandboxed?</dt>
+<dd>
+Maybe for an extremly restricted subset of Lua and if you relentlessly
+scrutinize every single interface function you offer to the untrusted code.<br>
+
+Although Lua provides some sandboxing functionality (<tt>setfenv()</tt>, hooks),
+it's very hard to get this right even for the Lua core libraries. Of course,
+you'll need to inspect any extension library, too. And there are libraries
+that are inherently unsafe, e.g. the <a href="ext_ffi.html">FFI library</a>.<br>
+
+Relatedly, <b>loading untrusted bytecode is not safe!</b> It's trivial
+to crash the Lua or LuaJIT VM with maliciously crafted bytecode. This is
+well known and there's no bytecode verification on purpose, so please
+don't report a bug about it. Check the <tt>mode</tt> parameter for the
+<tt>load*()</tt> functions to disable loading of bytecode.<br>
+
+In general, the only promising approach is to sandbox Lua code at the
+process level and not the VM level.<br>
+
+More reading material at the <a href="http://lua-users.org/wiki/SandBoxes"><span class="ext">&raquo;</span>&nbsp;Lua Wiki</a> and <a href="https://en.wikipedia.org/wiki/Sandbox_(computer_security)"><span class="ext">&raquo;</span>&nbsp;Wikipedia</a>.
+</dd>
+</dl>
+
+<dl id="patches">
 <dt>Q: Why doesn't my favorite power-patch for Lua apply against LuaJIT?</dt>
 <dt>Q: Why doesn't my favorite power-patch for Lua apply against LuaJIT?</dt>
 <dd>Because it's a completely redesigned VM and has very little code
 <dd>Because it's a completely redesigned VM and has very little code
 in common with Lua anymore. Also, if the patch introduces changes to
 in common with Lua anymore. Also, if the patch introduces changes to
@@ -152,7 +171,7 @@ can use source transformations or use wrapper or proxy functions.
 The compiler will happily optimize away such indirections.</dd>
 The compiler will happily optimize away such indirections.</dd>
 </dl>
 </dl>
 
 
-<dl>
+<dl id="arch">
 <dt>Q: Lua runs everywhere. Why doesn't LuaJIT support my CPU?</dt>
 <dt>Q: Lua runs everywhere. Why doesn't LuaJIT support my CPU?</dt>
 <dd>Because it's a compiler &mdash; it needs to generate native
 <dd>Because it's a compiler &mdash; it needs to generate native
 machine code. This means the code generator must be ported to each
 machine code. This means the code generator must be ported to each
@@ -163,7 +182,7 @@ architectures. Other architectures will follow based on sufficient user
 demand and/or sponsoring.</dd>
 demand and/or sponsoring.</dd>
 </dl>
 </dl>
 
 
-<dl>
+<dl id="when">
 <dt>Q: When will feature X be added? When will the next version be released?</dt>
 <dt>Q: When will feature X be added? When will the next version be released?</dt>
 <dd>When it's ready.<br>
 <dd>When it's ready.<br>
 C'mon, it's open source &mdash; I'm doing it on my own time and you're
 C'mon, it's open source &mdash; I'm doing it on my own time and you're
@@ -175,7 +194,7 @@ the development of certain features, if they are important to you.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 9 - 14
libs/LuaJIT/doc/install.html

@@ -3,7 +3,7 @@
 <head>
 <head>
 <title>Installation</title>
 <title>Installation</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -38,7 +38,7 @@ td.compatno {
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1>Installation</h1>
 <h1>Installation</h1>
@@ -47,7 +47,7 @@ td.compatno {
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a class="current" href="install.html">Installation</a>
 <a class="current" href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -73,17 +73,12 @@ td.compatno {
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
@@ -250,7 +245,7 @@ Obviously the prefixes given during build and installation need to be the same.
 <p>
 <p>
 Either install one of the open source SDKs
 Either install one of the open source SDKs
 (<a href="http://mingw.org/"><span class="ext">&raquo;</span>&nbsp;MinGW</a> or
 (<a href="http://mingw.org/"><span class="ext">&raquo;</span>&nbsp;MinGW</a> or
-<a href="http://www.cygwin.com/"><span class="ext">&raquo;</span>&nbsp;Cygwin</a>), which come with a modified
+<a href="https://www.cygwin.com/"><span class="ext">&raquo;</span>&nbsp;Cygwin</a>), which come with a modified
 GCC plus the required development headers.
 GCC plus the required development headers.
 Or install Microsoft's Visual Studio (MSVC).
 Or install Microsoft's Visual Studio (MSVC).
 </p>
 </p>
@@ -393,7 +388,7 @@ make CROSS=mips-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
 make CROSS=mipsel-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
 make CROSS=mipsel-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
 </pre>
 </pre>
 <p>
 <p>
-You can cross-compile for <b id="android">Android</b> using the <a href="http://developer.android.com/ndk/"><span class="ext">&raquo;</span>&nbsp;Android NDK</a>.
+You can cross-compile for <b id="android">Android</b> using the <a href="https://developer.android.com/ndk/"><span class="ext">&raquo;</span>&nbsp;Android NDK</a>.
 Please adapt the environment variables to match the install locations and the
 Please adapt the environment variables to match the install locations and the
 desired target platform. E.g. Android&nbsp;4.1 corresponds to ABI level&nbsp;16.
 desired target platform. E.g. Android&nbsp;4.1 corresponds to ABI level&nbsp;16.
 </p>
 </p>
@@ -417,7 +412,7 @@ make HOST_CC="gcc -m32" CROSS=$NDKCROSS \
      TARGET_LD=$NDKCC
      TARGET_LD=$NDKCC
 </pre>
 </pre>
 <p>
 <p>
-You can cross-compile for <b id="ios">iOS 3.0+</b> (iPhone/iPad) using the <a href="http://developer.apple.com/ios/"><span class="ext">&raquo;</span>&nbsp;iOS SDK</a>:
+You can cross-compile for <b id="ios">iOS 3.0+</b> (iPhone/iPad) using the <a href="https://developer.apple.com/ios/"><span class="ext">&raquo;</span>&nbsp;iOS SDK</a>:
 </p>
 </p>
 <p style="font-size: 8pt;">
 <p style="font-size: 8pt;">
 Note: <b>the JIT compiler is disabled for iOS</b>, because regular iOS Apps
 Note: <b>the JIT compiler is disabled for iOS</b>, because regular iOS Apps
@@ -552,7 +547,7 @@ Make sure the <tt>jit</tt> library is loaded or the JIT compiler
 will not be activated.</li>
 will not be activated.</li>
 <li>The <tt>bit.*</tt> module for bitwise operations
 <li>The <tt>bit.*</tt> module for bitwise operations
 is already built-in. There's no need to statically link
 is already built-in. There's no need to statically link
-<a href="http://bitop.luajit.org/"><span class="ext">&raquo;</span>&nbsp;Lua BitOp</a> to your application.</li>
+<a href="https://bitop.luajit.org/"><span class="ext">&raquo;</span>&nbsp;Lua BitOp</a> to your application.</li>
 </ul>
 </ul>
 
 
 <h2 id="distro">Hints for Distribution Maintainers</h2>
 <h2 id="distro">Hints for Distribution Maintainers</h2>
@@ -619,7 +614,7 @@ to me (the upstream) and not you (the package maintainer), anyway.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 9 - 14
libs/LuaJIT/doc/luajit.html

@@ -3,7 +3,7 @@
 <head>
 <head>
 <title>LuaJIT</title>
 <title>LuaJIT</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -95,7 +95,7 @@ table.feature small {
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1>LuaJIT</h1>
 <h1>LuaJIT</h1>
@@ -104,7 +104,7 @@ table.feature small {
 <ul><li>
 <ul><li>
 <a class="current" href="luajit.html">LuaJIT</a>
 <a class="current" href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -130,29 +130,24 @@ table.feature small {
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
 <p>
 <p>
 LuaJIT is a <b>Just-In-Time Compiler</b> (JIT) for the
 LuaJIT is a <b>Just-In-Time Compiler</b> (JIT) for the
-<a href="http://www.lua.org/"><span class="ext">&raquo;</span>&nbsp;Lua</a> programming language.
+<a href="https://www.lua.org/"><span class="ext">&raquo;</span>&nbsp;Lua</a> programming language.
 Lua is a powerful, dynamic and light-weight programming language.
 Lua is a powerful, dynamic and light-weight programming language.
 It may be embedded or used as a general-purpose, stand-alone language.
 It may be embedded or used as a general-purpose, stand-alone language.
 </p>
 </p>
 <p>
 <p>
-LuaJIT is Copyright &copy; 2005-2018 Mike Pall, released under the
-<a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">&raquo;</span>&nbsp;MIT open source license</a>.
+LuaJIT is Copyright &copy; 2005-2020 Mike Pall, released under the
+<a href="https://www.opensource.org/licenses/mit-license.php"><span class="ext">&raquo;</span>&nbsp;MIT open source license</a>.
 </p>
 </p>
 <p>
 <p>
 </p>
 </p>
@@ -193,7 +188,7 @@ LuaJIT has been successfully used as a <b>scripting middleware</b> in
 games, appliances, network and graphics apps, numerical simulations,
 games, appliances, network and graphics apps, numerical simulations,
 trading platforms and many other specialty applications. It scales from
 trading platforms and many other specialty applications. It scales from
 embedded devices, smartphones, desktops up to server farms. It combines
 embedded devices, smartphones, desktops up to server farms. It combines
-high flexibility with <a href="http://luajit.org/performance.html"><span class="ext">&raquo;</span>&nbsp;high performance</a>
+high flexibility with high performance
 and an unmatched <b>low memory footprint</b>.
 and an unmatched <b>low memory footprint</b>.
 </p>
 </p>
 <p>
 <p>
@@ -225,7 +220,7 @@ Please select a sub-topic in the navigation bar to learn more about LuaJIT.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 6 - 11
libs/LuaJIT/doc/running.html

@@ -3,7 +3,7 @@
 <head>
 <head>
 <title>Running LuaJIT</title>
 <title>Running LuaJIT</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -32,7 +32,7 @@ td.param_default {
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1>Running LuaJIT</h1>
 <h1>Running LuaJIT</h1>
@@ -41,7 +41,7 @@ td.param_default {
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -67,17 +67,12 @@ td.param_default {
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a href="status.html">Status</a>
 <a href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
@@ -94,7 +89,7 @@ The <tt>luajit</tt> stand-alone executable is just a slightly modified
 version of the regular <tt>lua</tt> stand-alone executable.
 version of the regular <tt>lua</tt> stand-alone executable.
 It supports the same basic options, too. <tt>luajit&nbsp;-h</tt>
 It supports the same basic options, too. <tt>luajit&nbsp;-h</tt>
 prints a short list of the available options. Please have a look at the
 prints a short list of the available options. Please have a look at the
-<a href="http://www.lua.org/manual/5.1/manual.html#6"><span class="ext">&raquo;</span>&nbsp;Lua manual</a>
+<a href="https://www.lua.org/manual/5.1/manual.html#6"><span class="ext">&raquo;</span>&nbsp;Lua manual</a>
 for details.
 for details.
 </p>
 </p>
 <p>
 <p>
@@ -298,7 +293,7 @@ Here are the parameters and their default settings:
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 5 - 21
libs/LuaJIT/doc/status.html

@@ -3,7 +3,7 @@
 <head>
 <head>
 <title>Status</title>
 <title>Status</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2018">
+<meta name="Copyright" content="Copyright (C) 2005-2020">
 <meta name="Language" content="en">
 <meta name="Language" content="en">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
@@ -13,7 +13,7 @@ ul li { padding-bottom: 0.3em; }
 </head>
 </head>
 <body>
 <body>
 <div id="site">
 <div id="site">
-<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
 </div>
 </div>
 <div id="head">
 <div id="head">
 <h1>Status</h1>
 <h1>Status</h1>
@@ -22,7 +22,7 @@ ul li { padding-bottom: 0.3em; }
 <ul><li>
 <ul><li>
 <a href="luajit.html">LuaJIT</a>
 <a href="luajit.html">LuaJIT</a>
 <ul><li>
 <ul><li>
-<a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
 <a href="install.html">Installation</a>
 <a href="install.html">Installation</a>
 </li><li>
 </li><li>
@@ -48,17 +48,12 @@ ul li { padding-bottom: 0.3em; }
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
 <a class="current" href="status.html">Status</a>
 <a class="current" href="status.html">Status</a>
-<ul><li>
-<a href="changes.html">Changes</a>
-</li></ul>
 </li><li>
 </li><li>
 <a href="faq.html">FAQ</a>
 <a href="faq.html">FAQ</a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
-</li><li>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 <a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
 </li><li>
 </li><li>
-<a href="http://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
 </li></ul>
 </li></ul>
 </div>
 </div>
 <div id="main">
 <div id="main">
@@ -96,23 +91,12 @@ handled correctly. The error may fall through an on-trace
 <tt>lua_atpanic</tt> on x64. This issue will be fixed with the new
 <tt>lua_atpanic</tt> on x64. This issue will be fixed with the new
 garbage collector.
 garbage collector.
 </li>
 </li>
-<li>
-LuaJIT on 64 bit systems provides a <b>limited range</b> of 47 bits for the
-<b>legacy <tt>lightuserdata</tt></b> data type.
-This is only relevant on x64 systems which use the negative part of the
-virtual address space in user mode, e.g. Solaris/x64, and on ARM64 systems
-configured with a 48 bit or 52 bit VA.
-Avoid using <tt>lightuserdata</tt> to hold pointers that may point outside
-of that range, e.g. variables on the stack. In general, avoid this data
-type for new code and replace it with (much more performant) FFI bindings.
-FFI cdata pointers can address the full 64 bit range.
-</li>
 </ul>
 </ul>
 <br class="flush">
 <br class="flush">
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2018
+Copyright &copy; 2005-2020
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 1 - 1
libs/LuaJIT/dynasm/dasm_arm.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** DynASM ARM encoding engine.
 ** DynASM ARM encoding engine.
-** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+** Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 ** Released under the MIT license. See dynasm.lua for full copyright notice.
 ** Released under the MIT license. See dynasm.lua for full copyright notice.
 */
 */
 
 

+ 1 - 1
libs/LuaJIT/dynasm/dasm_arm.lua

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM ARM module.
 -- DynASM ARM module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- See dynasm.lua for full copyright notice.
 -- See dynasm.lua for full copyright notice.
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 

+ 1 - 1
libs/LuaJIT/dynasm/dasm_arm64.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** DynASM ARM64 encoding engine.
 ** DynASM ARM64 encoding engine.
-** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+** Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 ** Released under the MIT license. See dynasm.lua for full copyright notice.
 ** Released under the MIT license. See dynasm.lua for full copyright notice.
 */
 */
 
 

+ 1 - 1
libs/LuaJIT/dynasm/dasm_arm64.lua

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM ARM64 module.
 -- DynASM ARM64 module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- See dynasm.lua for full copyright notice.
 -- See dynasm.lua for full copyright notice.
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 

+ 8 - 7
libs/LuaJIT/dynasm/dasm_mips.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** DynASM MIPS encoding engine.
 ** DynASM MIPS encoding engine.
-** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+** Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 ** Released under the MIT license. See dynasm.lua for full copyright notice.
 ** Released under the MIT license. See dynasm.lua for full copyright notice.
 */
 */
 
 
@@ -355,14 +355,15 @@ int dasm_encode(Dst_DECL, void *buffer)
 	  CK(n >= 0, UNDEF_PC);
 	  CK(n >= 0, UNDEF_PC);
 	  n = *DASM_POS2PTR(D, n);
 	  n = *DASM_POS2PTR(D, n);
 	  if (ins & 2048)
 	  if (ins & 2048)
-	    n = n - (int)((char *)cp - base);
-	  else
 	    n = (n + (int)(size_t)base) & 0x0fffffff;
 	    n = (n + (int)(size_t)base) & 0x0fffffff;
-	patchrel:
+	  else
+	    n = n - (int)((char *)cp - base);
+	patchrel: {
+	  unsigned int e = 16 + ((ins >> 12) & 15);
 	  CK((n & 3) == 0 &&
 	  CK((n & 3) == 0 &&
-	     ((n + ((ins & 2048) ? 0x00020000 : 0)) >>
-	       ((ins & 2048) ? 18 : 28)) == 0, RANGE_REL);
-	  cp[-1] |= ((n>>2) & ((ins & 2048) ? 0x0000ffff: 0x03ffffff));
+	     ((n + ((ins & 2048) ? 0 : (1<<(e+1)))) >> (e+2)) == 0, RANGE_REL);
+	  cp[-1] |= ((n>>2) & ((1<<e)-1));
+	  }
 	  break;
 	  break;
 	case DASM_LABEL_LG:
 	case DASM_LABEL_LG:
 	  ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
 	  ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);

+ 401 - 228
libs/LuaJIT/dynasm/dasm_mips.lua

@@ -1,11 +1,12 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM MIPS32/MIPS64 module.
 -- DynASM MIPS32/MIPS64 module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- See dynasm.lua for full copyright notice.
 -- See dynasm.lua for full copyright notice.
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
 local mips64 = mips64
 local mips64 = mips64
+local mipsr6 = _map_def.MIPSR6
 
 
 -- Module information:
 -- Module information:
 local _info = {
 local _info = {
@@ -13,7 +14,7 @@ local _info = {
   description =	"DynASM MIPS32/MIPS64 module",
   description =	"DynASM MIPS32/MIPS64 module",
   version =	"1.4.0",
   version =	"1.4.0",
   vernum =	 10400,
   vernum =	 10400,
-  release =	"2016-05-24",
+  release =	"2020-01-20",
   author =	"Mike Pall",
   author =	"Mike Pall",
   license =	"MIT",
   license =	"MIT",
 }
 }
@@ -238,7 +239,6 @@ local map_op = {
   bne_3 =	"14000000STB",
   bne_3 =	"14000000STB",
   blez_2 =	"18000000SB",
   blez_2 =	"18000000SB",
   bgtz_2 =	"1c000000SB",
   bgtz_2 =	"1c000000SB",
-  addi_3 =	"20000000TSI",
   li_2 =	"24000000TI",
   li_2 =	"24000000TI",
   addiu_3 =	"24000000TSI",
   addiu_3 =	"24000000TSI",
   slti_3 =	"28000000TSI",
   slti_3 =	"28000000TSI",
@@ -248,40 +248,22 @@ local map_op = {
   ori_3 =	"34000000TSU",
   ori_3 =	"34000000TSU",
   xori_3 =	"38000000TSU",
   xori_3 =	"38000000TSU",
   lui_2 =	"3c000000TU",
   lui_2 =	"3c000000TU",
-  beqzl_2 =	"50000000SB",
-  beql_3 =	"50000000STB",
-  bnezl_2 =	"54000000SB",
-  bnel_3 =	"54000000STB",
-  blezl_2 =	"58000000SB",
-  bgtzl_2 =	"5c000000SB",
-  daddi_3 =	mips64 and "60000000TSI",
   daddiu_3 =	mips64 and "64000000TSI",
   daddiu_3 =	mips64 and "64000000TSI",
   ldl_2 =	mips64 and "68000000TO",
   ldl_2 =	mips64 and "68000000TO",
   ldr_2 =	mips64 and "6c000000TO",
   ldr_2 =	mips64 and "6c000000TO",
   lb_2 =	"80000000TO",
   lb_2 =	"80000000TO",
   lh_2 =	"84000000TO",
   lh_2 =	"84000000TO",
-  lwl_2 =	"88000000TO",
   lw_2 =	"8c000000TO",
   lw_2 =	"8c000000TO",
   lbu_2 =	"90000000TO",
   lbu_2 =	"90000000TO",
   lhu_2 =	"94000000TO",
   lhu_2 =	"94000000TO",
-  lwr_2 =	"98000000TO",
   lwu_2 =	mips64 and "9c000000TO",
   lwu_2 =	mips64 and "9c000000TO",
   sb_2 =	"a0000000TO",
   sb_2 =	"a0000000TO",
   sh_2 =	"a4000000TO",
   sh_2 =	"a4000000TO",
-  swl_2 =	"a8000000TO",
   sw_2 =	"ac000000TO",
   sw_2 =	"ac000000TO",
-  sdl_2 =	mips64 and "b0000000TO",
-  sdr_2 =	mips64 and "b1000000TO",
-  swr_2 =	"b8000000TO",
-  cache_2 =	"bc000000NO",
-  ll_2 =	"c0000000TO",
   lwc1_2 =	"c4000000HO",
   lwc1_2 =	"c4000000HO",
-  pref_2 =	"cc000000NO",
   ldc1_2 =	"d4000000HO",
   ldc1_2 =	"d4000000HO",
   ld_2 =	mips64 and "dc000000TO",
   ld_2 =	mips64 and "dc000000TO",
-  sc_2 =	"e0000000TO",
   swc1_2 =	"e4000000HO",
   swc1_2 =	"e4000000HO",
-  scd_2 =	mips64 and "f0000000TO",
   sdc1_2 =	"f4000000HO",
   sdc1_2 =	"f4000000HO",
   sd_2 =	mips64 and "fc000000TO",
   sd_2 =	mips64 and "fc000000TO",
 
 
@@ -289,10 +271,6 @@ local map_op = {
   nop_0 =	"00000000",
   nop_0 =	"00000000",
   sll_3 =	"00000000DTA",
   sll_3 =	"00000000DTA",
   sextw_2 =	"00000000DT",
   sextw_2 =	"00000000DT",
-  movf_2 =	"00000001DS",
-  movf_3 =	"00000001DSC",
-  movt_2 =	"00010001DS",
-  movt_3 =	"00010001DSC",
   srl_3 =	"00000002DTA",
   srl_3 =	"00000002DTA",
   rotr_3 =	"00200002DTA",
   rotr_3 =	"00200002DTA",
   sra_3 =	"00000003DTA",
   sra_3 =	"00000003DTA",
@@ -301,31 +279,16 @@ local map_op = {
   rotrv_3 =	"00000046DTS",
   rotrv_3 =	"00000046DTS",
   drotrv_3 =	mips64 and "00000056DTS",
   drotrv_3 =	mips64 and "00000056DTS",
   srav_3 =	"00000007DTS",
   srav_3 =	"00000007DTS",
-  jr_1 =	"00000008S",
   jalr_1 =	"0000f809S",
   jalr_1 =	"0000f809S",
   jalr_2 =	"00000009DS",
   jalr_2 =	"00000009DS",
-  movz_3 =	"0000000aDST",
-  movn_3 =	"0000000bDST",
   syscall_0 =	"0000000c",
   syscall_0 =	"0000000c",
   syscall_1 =	"0000000cY",
   syscall_1 =	"0000000cY",
   break_0 =	"0000000d",
   break_0 =	"0000000d",
   break_1 =	"0000000dY",
   break_1 =	"0000000dY",
   sync_0 =	"0000000f",
   sync_0 =	"0000000f",
-  mfhi_1 =	"00000010D",
-  mthi_1 =	"00000011S",
-  mflo_1 =	"00000012D",
-  mtlo_1 =	"00000013S",
   dsllv_3 =	mips64 and "00000014DTS",
   dsllv_3 =	mips64 and "00000014DTS",
   dsrlv_3 =	mips64 and "00000016DTS",
   dsrlv_3 =	mips64 and "00000016DTS",
   dsrav_3 =	mips64 and "00000017DTS",
   dsrav_3 =	mips64 and "00000017DTS",
-  mult_2 =	"00000018ST",
-  multu_2 =	"00000019ST",
-  div_2 =	"0000001aST",
-  divu_2 =	"0000001bST",
-  dmult_2 =	mips64 and "0000001cST",
-  dmultu_2 =	mips64 and "0000001dST",
-  ddiv_2 =	mips64 and "0000001eST",
-  ddivu_2 =	mips64 and "0000001fST",
   add_3 =	"00000020DST",
   add_3 =	"00000020DST",
   move_2 =	mips64 and "00000025DS" or "00000021DS",
   move_2 =	mips64 and "00000025DS" or "00000021DS",
   addu_3 =	"00000021DST",
   addu_3 =	"00000021DST",
@@ -369,32 +332,9 @@ local map_op = {
   bgez_2 =	"04010000SB",
   bgez_2 =	"04010000SB",
   bltzl_2 =	"04020000SB",
   bltzl_2 =	"04020000SB",
   bgezl_2 =	"04030000SB",
   bgezl_2 =	"04030000SB",
-  tgei_2 =	"04080000SI",
-  tgeiu_2 =	"04090000SI",
-  tlti_2 =	"040a0000SI",
-  tltiu_2 =	"040b0000SI",
-  teqi_2 =	"040c0000SI",
-  tnei_2 =	"040e0000SI",
-  bltzal_2 =	"04100000SB",
   bal_1 =	"04110000B",
   bal_1 =	"04110000B",
-  bgezal_2 =	"04110000SB",
-  bltzall_2 =	"04120000SB",
-  bgezall_2 =	"04130000SB",
   synci_1 =	"041f0000O",
   synci_1 =	"041f0000O",
 
 
-  -- Opcode SPECIAL2.
-  madd_2 =	"70000000ST",
-  maddu_2 =	"70000001ST",
-  mul_3 =	"70000002DST",
-  msub_2 =	"70000004ST",
-  msubu_2 =	"70000005ST",
-  clz_2 =	"70000020DS=",
-  clo_2 =	"70000021DS=",
-  dclz_2 =	mips64 and "70000024DS=",
-  dclo_2 =	mips64 and "70000025DS=",
-  sdbbp_0 =	"7000003f",
-  sdbbp_1 =	"7000003fY",
-
   -- Opcode SPECIAL3.
   -- Opcode SPECIAL3.
   ext_4 =	"7c000000TSAM", -- Note: last arg is msbd = size-1
   ext_4 =	"7c000000TSAM", -- Note: last arg is msbd = size-1
   dextm_4 =	mips64 and "7c000001TSAM", -- Args: pos    | size-1-32
   dextm_4 =	mips64 and "7c000001TSAM", -- Args: pos    | size-1-32
@@ -445,15 +385,6 @@ local map_op = {
   ctc1_2 =	"44c00000TG",
   ctc1_2 =	"44c00000TG",
   mthc1_2 =	"44e00000TG",
   mthc1_2 =	"44e00000TG",
 
 
-  bc1f_1 =	"45000000B",
-  bc1f_2 =	"45000000CB",
-  bc1t_1 =	"45010000B",
-  bc1t_2 =	"45010000CB",
-  bc1fl_1 =	"45020000B",
-  bc1fl_2 =	"45020000CB",
-  bc1tl_1 =	"45030000B",
-  bc1tl_2 =	"45030000CB",
-
   ["add.s_3"] =		"46000000FGH",
   ["add.s_3"] =		"46000000FGH",
   ["sub.s_3"] =		"46000001FGH",
   ["sub.s_3"] =		"46000001FGH",
   ["mul.s_3"] =		"46000002FGH",
   ["mul.s_3"] =		"46000002FGH",
@@ -470,51 +401,11 @@ local map_op = {
   ["trunc.w.s_2"] =	"4600000dFG",
   ["trunc.w.s_2"] =	"4600000dFG",
   ["ceil.w.s_2"] =	"4600000eFG",
   ["ceil.w.s_2"] =	"4600000eFG",
   ["floor.w.s_2"] =	"4600000fFG",
   ["floor.w.s_2"] =	"4600000fFG",
-  ["movf.s_2"] =	"46000011FG",
-  ["movf.s_3"] =	"46000011FGC",
-  ["movt.s_2"] =	"46010011FG",
-  ["movt.s_3"] =	"46010011FGC",
-  ["movz.s_3"] =	"46000012FGT",
-  ["movn.s_3"] =	"46000013FGT",
   ["recip.s_2"] =	"46000015FG",
   ["recip.s_2"] =	"46000015FG",
   ["rsqrt.s_2"] =	"46000016FG",
   ["rsqrt.s_2"] =	"46000016FG",
   ["cvt.d.s_2"] =	"46000021FG",
   ["cvt.d.s_2"] =	"46000021FG",
   ["cvt.w.s_2"] =	"46000024FG",
   ["cvt.w.s_2"] =	"46000024FG",
   ["cvt.l.s_2"] =	"46000025FG",
   ["cvt.l.s_2"] =	"46000025FG",
-  ["cvt.ps.s_3"] =	"46000026FGH",
-  ["c.f.s_2"] =		"46000030GH",
-  ["c.f.s_3"] =		"46000030VGH",
-  ["c.un.s_2"] =	"46000031GH",
-  ["c.un.s_3"] =	"46000031VGH",
-  ["c.eq.s_2"] =	"46000032GH",
-  ["c.eq.s_3"] =	"46000032VGH",
-  ["c.ueq.s_2"] =	"46000033GH",
-  ["c.ueq.s_3"] =	"46000033VGH",
-  ["c.olt.s_2"] =	"46000034GH",
-  ["c.olt.s_3"] =	"46000034VGH",
-  ["c.ult.s_2"] =	"46000035GH",
-  ["c.ult.s_3"] =	"46000035VGH",
-  ["c.ole.s_2"] =	"46000036GH",
-  ["c.ole.s_3"] =	"46000036VGH",
-  ["c.ule.s_2"] =	"46000037GH",
-  ["c.ule.s_3"] =	"46000037VGH",
-  ["c.sf.s_2"] =	"46000038GH",
-  ["c.sf.s_3"] =	"46000038VGH",
-  ["c.ngle.s_2"] =	"46000039GH",
-  ["c.ngle.s_3"] =	"46000039VGH",
-  ["c.seq.s_2"] =	"4600003aGH",
-  ["c.seq.s_3"] =	"4600003aVGH",
-  ["c.ngl.s_2"] =	"4600003bGH",
-  ["c.ngl.s_3"] =	"4600003bVGH",
-  ["c.lt.s_2"] =	"4600003cGH",
-  ["c.lt.s_3"] =	"4600003cVGH",
-  ["c.nge.s_2"] =	"4600003dGH",
-  ["c.nge.s_3"] =	"4600003dVGH",
-  ["c.le.s_2"] =	"4600003eGH",
-  ["c.le.s_3"] =	"4600003eVGH",
-  ["c.ngt.s_2"] =	"4600003fGH",
-  ["c.ngt.s_3"] =	"4600003fVGH",
-
   ["add.d_3"] =		"46200000FGH",
   ["add.d_3"] =		"46200000FGH",
   ["sub.d_3"] =		"46200001FGH",
   ["sub.d_3"] =		"46200001FGH",
   ["mul.d_3"] =		"46200002FGH",
   ["mul.d_3"] =		"46200002FGH",
@@ -531,130 +422,410 @@ local map_op = {
   ["trunc.w.d_2"] =	"4620000dFG",
   ["trunc.w.d_2"] =	"4620000dFG",
   ["ceil.w.d_2"] =	"4620000eFG",
   ["ceil.w.d_2"] =	"4620000eFG",
   ["floor.w.d_2"] =	"4620000fFG",
   ["floor.w.d_2"] =	"4620000fFG",
-  ["movf.d_2"] =	"46200011FG",
-  ["movf.d_3"] =	"46200011FGC",
-  ["movt.d_2"] =	"46210011FG",
-  ["movt.d_3"] =	"46210011FGC",
-  ["movz.d_3"] =	"46200012FGT",
-  ["movn.d_3"] =	"46200013FGT",
   ["recip.d_2"] =	"46200015FG",
   ["recip.d_2"] =	"46200015FG",
   ["rsqrt.d_2"] =	"46200016FG",
   ["rsqrt.d_2"] =	"46200016FG",
   ["cvt.s.d_2"] =	"46200020FG",
   ["cvt.s.d_2"] =	"46200020FG",
   ["cvt.w.d_2"] =	"46200024FG",
   ["cvt.w.d_2"] =	"46200024FG",
   ["cvt.l.d_2"] =	"46200025FG",
   ["cvt.l.d_2"] =	"46200025FG",
-  ["c.f.d_2"] =		"46200030GH",
-  ["c.f.d_3"] =		"46200030VGH",
-  ["c.un.d_2"] =	"46200031GH",
-  ["c.un.d_3"] =	"46200031VGH",
-  ["c.eq.d_2"] =	"46200032GH",
-  ["c.eq.d_3"] =	"46200032VGH",
-  ["c.ueq.d_2"] =	"46200033GH",
-  ["c.ueq.d_3"] =	"46200033VGH",
-  ["c.olt.d_2"] =	"46200034GH",
-  ["c.olt.d_3"] =	"46200034VGH",
-  ["c.ult.d_2"] =	"46200035GH",
-  ["c.ult.d_3"] =	"46200035VGH",
-  ["c.ole.d_2"] =	"46200036GH",
-  ["c.ole.d_3"] =	"46200036VGH",
-  ["c.ule.d_2"] =	"46200037GH",
-  ["c.ule.d_3"] =	"46200037VGH",
-  ["c.sf.d_2"] =	"46200038GH",
-  ["c.sf.d_3"] =	"46200038VGH",
-  ["c.ngle.d_2"] =	"46200039GH",
-  ["c.ngle.d_3"] =	"46200039VGH",
-  ["c.seq.d_2"] =	"4620003aGH",
-  ["c.seq.d_3"] =	"4620003aVGH",
-  ["c.ngl.d_2"] =	"4620003bGH",
-  ["c.ngl.d_3"] =	"4620003bVGH",
-  ["c.lt.d_2"] =	"4620003cGH",
-  ["c.lt.d_3"] =	"4620003cVGH",
-  ["c.nge.d_2"] =	"4620003dGH",
-  ["c.nge.d_3"] =	"4620003dVGH",
-  ["c.le.d_2"] =	"4620003eGH",
-  ["c.le.d_3"] =	"4620003eVGH",
-  ["c.ngt.d_2"] =	"4620003fGH",
-  ["c.ngt.d_3"] =	"4620003fVGH",
-
-  ["add.ps_3"] =	"46c00000FGH",
-  ["sub.ps_3"] =	"46c00001FGH",
-  ["mul.ps_3"] =	"46c00002FGH",
-  ["abs.ps_2"] =	"46c00005FG",
-  ["mov.ps_2"] =	"46c00006FG",
-  ["neg.ps_2"] =	"46c00007FG",
-  ["movf.ps_2"] =	"46c00011FG",
-  ["movf.ps_3"] =	"46c00011FGC",
-  ["movt.ps_2"] =	"46c10011FG",
-  ["movt.ps_3"] =	"46c10011FGC",
-  ["movz.ps_3"] =	"46c00012FGT",
-  ["movn.ps_3"] =	"46c00013FGT",
-  ["cvt.s.pu_2"] =	"46c00020FG",
-  ["cvt.s.pl_2"] =	"46c00028FG",
-  ["pll.ps_3"] =	"46c0002cFGH",
-  ["plu.ps_3"] =	"46c0002dFGH",
-  ["pul.ps_3"] =	"46c0002eFGH",
-  ["puu.ps_3"] =	"46c0002fFGH",
-  ["c.f.ps_2"] =	"46c00030GH",
-  ["c.f.ps_3"] =	"46c00030VGH",
-  ["c.un.ps_2"] =	"46c00031GH",
-  ["c.un.ps_3"] =	"46c00031VGH",
-  ["c.eq.ps_2"] =	"46c00032GH",
-  ["c.eq.ps_3"] =	"46c00032VGH",
-  ["c.ueq.ps_2"] =	"46c00033GH",
-  ["c.ueq.ps_3"] =	"46c00033VGH",
-  ["c.olt.ps_2"] =	"46c00034GH",
-  ["c.olt.ps_3"] =	"46c00034VGH",
-  ["c.ult.ps_2"] =	"46c00035GH",
-  ["c.ult.ps_3"] =	"46c00035VGH",
-  ["c.ole.ps_2"] =	"46c00036GH",
-  ["c.ole.ps_3"] =	"46c00036VGH",
-  ["c.ule.ps_2"] =	"46c00037GH",
-  ["c.ule.ps_3"] =	"46c00037VGH",
-  ["c.sf.ps_2"] =	"46c00038GH",
-  ["c.sf.ps_3"] =	"46c00038VGH",
-  ["c.ngle.ps_2"] =	"46c00039GH",
-  ["c.ngle.ps_3"] =	"46c00039VGH",
-  ["c.seq.ps_2"] =	"46c0003aGH",
-  ["c.seq.ps_3"] =	"46c0003aVGH",
-  ["c.ngl.ps_2"] =	"46c0003bGH",
-  ["c.ngl.ps_3"] =	"46c0003bVGH",
-  ["c.lt.ps_2"] =	"46c0003cGH",
-  ["c.lt.ps_3"] =	"46c0003cVGH",
-  ["c.nge.ps_2"] =	"46c0003dGH",
-  ["c.nge.ps_3"] =	"46c0003dVGH",
-  ["c.le.ps_2"] =	"46c0003eGH",
-  ["c.le.ps_3"] =	"46c0003eVGH",
-  ["c.ngt.ps_2"] =	"46c0003fGH",
-  ["c.ngt.ps_3"] =	"46c0003fVGH",
-
   ["cvt.s.w_2"] =	"46800020FG",
   ["cvt.s.w_2"] =	"46800020FG",
   ["cvt.d.w_2"] =	"46800021FG",
   ["cvt.d.w_2"] =	"46800021FG",
-
   ["cvt.s.l_2"] =	"46a00020FG",
   ["cvt.s.l_2"] =	"46a00020FG",
   ["cvt.d.l_2"] =	"46a00021FG",
   ["cvt.d.l_2"] =	"46a00021FG",
-
-  -- Opcode COP1X.
-  lwxc1_2 =		"4c000000FX",
-  ldxc1_2 =		"4c000001FX",
-  luxc1_2 =		"4c000005FX",
-  swxc1_2 =		"4c000008FX",
-  sdxc1_2 =		"4c000009FX",
-  suxc1_2 =		"4c00000dFX",
-  prefx_2 =		"4c00000fMX",
-  ["alnv.ps_4"] =	"4c00001eFGHS",
-  ["madd.s_4"] =	"4c000020FRGH",
-  ["madd.d_4"] =	"4c000021FRGH",
-  ["madd.ps_4"] =	"4c000026FRGH",
-  ["msub.s_4"] =	"4c000028FRGH",
-  ["msub.d_4"] =	"4c000029FRGH",
-  ["msub.ps_4"] =	"4c00002eFRGH",
-  ["nmadd.s_4"] =	"4c000030FRGH",
-  ["nmadd.d_4"] =	"4c000031FRGH",
-  ["nmadd.ps_4"] =	"4c000036FRGH",
-  ["nmsub.s_4"] =	"4c000038FRGH",
-  ["nmsub.d_4"] =	"4c000039FRGH",
-  ["nmsub.ps_4"] =	"4c00003eFRGH",
 }
 }
 
 
+if mipsr6 then -- Instructions added with MIPSR6.
+
+  for k,v in pairs({
+
+    -- Add immediate to upper bits.
+    aui_3 =	"3c000000TSI",
+    daui_3 =	mips64 and "74000000TSI",
+    dahi_2 =	mips64 and "04060000SI",
+    dati_2 =	mips64 and "041e0000SI",
+
+    -- TODO: addiupc, auipc, aluipc, lwpc, lwupc, ldpc.
+
+    -- Compact branches.
+    blezalc_2 =	"18000000TB",	-- rt != 0.
+    bgezalc_2 =	"18000000T=SB",	-- rt != 0.
+    bgtzalc_2 =	"1c000000TB",	-- rt != 0.
+    bltzalc_2 =	"1c000000T=SB",	-- rt != 0.
+
+    blezc_2 =	"58000000TB",	-- rt != 0.
+    bgezc_2 =	"58000000T=SB",	-- rt != 0.
+    bgec_3 =	"58000000STB",	-- rs != rt.
+    blec_3 =	"58000000TSB",	-- rt != rs.
+
+    bgtzc_2 =	"5c000000TB",	-- rt != 0.
+    bltzc_2 =	"5c000000T=SB",	-- rt != 0.
+    bltc_3 =	"5c000000STB",	-- rs != rt.
+    bgtc_3 =	"5c000000TSB",	-- rt != rs.
+
+    bgeuc_3 =	"18000000STB",	-- rs != rt.
+    bleuc_3 =	"18000000TSB",	-- rt != rs.
+    bltuc_3 =	"1c000000STB",	-- rs != rt.
+    bgtuc_3 =	"1c000000TSB",	-- rt != rs.
+
+    beqzalc_2 =	"20000000TB",	-- rt != 0.
+    bnezalc_2 =	"60000000TB",	-- rt != 0.
+    beqc_3 =	"20000000STB",	-- rs < rt.
+    bnec_3 =	"60000000STB",	-- rs < rt.
+    bovc_3 =	"20000000STB",	-- rs >= rt.
+    bnvc_3 =	"60000000STB",	-- rs >= rt.
+
+    beqzc_2 =	"d8000000SK",	-- rs != 0.
+    bnezc_2 =	"f8000000SK",	-- rs != 0.
+    jic_2 =	"d8000000TI",
+    jialc_2 =	"f8000000TI",
+    bc_1 =	"c8000000L",
+    balc_1 =	"e8000000L",
+
+    -- Opcode SPECIAL.
+    jr_1 =	"00000009S",
+    sdbbp_0 =	"0000000e",
+    sdbbp_1 =	"0000000eY",
+    lsa_4 =	"00000005DSTA",
+    dlsa_4 =	mips64 and "00000015DSTA",
+    seleqz_3 =	"00000035DST",
+    selnez_3 =	"00000037DST",
+    clz_2 =	"00000050DS",
+    clo_2 =	"00000051DS",
+    dclz_2 =	mips64 and "00000052DS",
+    dclo_2 =	mips64 and "00000053DS",
+    mul_3 =	"00000098DST",
+    muh_3 =	"000000d8DST",
+    mulu_3 =	"00000099DST",
+    muhu_3 =	"000000d9DST",
+    div_3 =	"0000009aDST",
+    mod_3 =	"000000daDST",
+    divu_3 =	"0000009bDST",
+    modu_3 =	"000000dbDST",
+    dmul_3 =	mips64 and "0000009cDST",
+    dmuh_3 =	mips64 and "000000dcDST",
+    dmulu_3 =	mips64 and "0000009dDST",
+    dmuhu_3 =	mips64 and "000000ddDST",
+    ddiv_3 =	mips64 and "0000009eDST",
+    dmod_3 =	mips64 and "000000deDST",
+    ddivu_3 =	mips64 and "0000009fDST",
+    dmodu_3 =	mips64 and "000000dfDST",
+
+    -- Opcode SPECIAL3.
+    align_4 =		"7c000220DSTA",
+    dalign_4 =		mips64 and "7c000224DSTA",
+    bitswap_2 =		"7c000020DT",
+    dbitswap_2 =	mips64 and "7c000024DT",
+
+    -- Opcode COP1.
+    bc1eqz_2 =	"45200000HB",
+    bc1nez_2 =	"45a00000HB",
+
+    ["sel.s_3"] =	"46000010FGH",
+    ["seleqz.s_3"] =	"46000014FGH",
+    ["selnez.s_3"] =	"46000017FGH",
+    ["maddf.s_3"] =	"46000018FGH",
+    ["msubf.s_3"] =	"46000019FGH",
+    ["rint.s_2"] =	"4600001aFG",
+    ["class.s_2"] =	"4600001bFG",
+    ["min.s_3"] =	"4600001cFGH",
+    ["mina.s_3"] =	"4600001dFGH",
+    ["max.s_3"] =	"4600001eFGH",
+    ["maxa.s_3"] =	"4600001fFGH",
+    ["cmp.af.s_3"] =	"46800000FGH",
+    ["cmp.un.s_3"] =	"46800001FGH",
+    ["cmp.or.s_3"] =	"46800011FGH",
+    ["cmp.eq.s_3"] =	"46800002FGH",
+    ["cmp.une.s_3"] =	"46800012FGH",
+    ["cmp.ueq.s_3"] =	"46800003FGH",
+    ["cmp.ne.s_3"] =	"46800013FGH",
+    ["cmp.lt.s_3"] =	"46800004FGH",
+    ["cmp.ult.s_3"] =	"46800005FGH",
+    ["cmp.le.s_3"] =	"46800006FGH",
+    ["cmp.ule.s_3"] =	"46800007FGH",
+    ["cmp.saf.s_3"] =	"46800008FGH",
+    ["cmp.sun.s_3"] =	"46800009FGH",
+    ["cmp.sor.s_3"] =	"46800019FGH",
+    ["cmp.seq.s_3"] =	"4680000aFGH",
+    ["cmp.sune.s_3"] =	"4680001aFGH",
+    ["cmp.sueq.s_3"] =	"4680000bFGH",
+    ["cmp.sne.s_3"] =	"4680001bFGH",
+    ["cmp.slt.s_3"] =	"4680000cFGH",
+    ["cmp.sult.s_3"] =	"4680000dFGH",
+    ["cmp.sle.s_3"] =	"4680000eFGH",
+    ["cmp.sule.s_3"] =	"4680000fFGH",
+
+    ["sel.d_3"] =	"46200010FGH",
+    ["seleqz.d_3"] =	"46200014FGH",
+    ["selnez.d_3"] =	"46200017FGH",
+    ["maddf.d_3"] =	"46200018FGH",
+    ["msubf.d_3"] =	"46200019FGH",
+    ["rint.d_2"] =	"4620001aFG",
+    ["class.d_2"] =	"4620001bFG",
+    ["min.d_3"] =	"4620001cFGH",
+    ["mina.d_3"] =	"4620001dFGH",
+    ["max.d_3"] =	"4620001eFGH",
+    ["maxa.d_3"] =	"4620001fFGH",
+    ["cmp.af.d_3"] =	"46a00000FGH",
+    ["cmp.un.d_3"] =	"46a00001FGH",
+    ["cmp.or.d_3"] =	"46a00011FGH",
+    ["cmp.eq.d_3"] =	"46a00002FGH",
+    ["cmp.une.d_3"] =	"46a00012FGH",
+    ["cmp.ueq.d_3"] =	"46a00003FGH",
+    ["cmp.ne.d_3"] =	"46a00013FGH",
+    ["cmp.lt.d_3"] =	"46a00004FGH",
+    ["cmp.ult.d_3"] =	"46a00005FGH",
+    ["cmp.le.d_3"] =	"46a00006FGH",
+    ["cmp.ule.d_3"] =	"46a00007FGH",
+    ["cmp.saf.d_3"] =	"46a00008FGH",
+    ["cmp.sun.d_3"] =	"46a00009FGH",
+    ["cmp.sor.d_3"] =	"46a00019FGH",
+    ["cmp.seq.d_3"] =	"46a0000aFGH",
+    ["cmp.sune.d_3"] =	"46a0001aFGH",
+    ["cmp.sueq.d_3"] =	"46a0000bFGH",
+    ["cmp.sne.d_3"] =	"46a0001bFGH",
+    ["cmp.slt.d_3"] =	"46a0000cFGH",
+    ["cmp.sult.d_3"] =	"46a0000dFGH",
+    ["cmp.sle.d_3"] =	"46a0000eFGH",
+    ["cmp.sule.d_3"] =	"46a0000fFGH",
+
+  }) do map_op[k] = v end
+
+else -- Instructions removed by MIPSR6.
+
+  for k,v in pairs({
+    -- Traps, don't use.
+    addi_3 =	"20000000TSI",
+    daddi_3 =	mips64 and "60000000TSI",
+
+    -- Branch on likely, don't use.
+    beqzl_2 =	"50000000SB",
+    beql_3 =	"50000000STB",
+    bnezl_2 =	"54000000SB",
+    bnel_3 =	"54000000STB",
+    blezl_2 =	"58000000SB",
+    bgtzl_2 =	"5c000000SB",
+
+    lwl_2 =	"88000000TO",
+    lwr_2 =	"98000000TO",
+    swl_2 =	"a8000000TO",
+    sdl_2 =	mips64 and "b0000000TO",
+    sdr_2 =	mips64 and "b1000000TO",
+    swr_2 =	"b8000000TO",
+    cache_2 =	"bc000000NO",
+    ll_2 =	"c0000000TO",
+    pref_2 =	"cc000000NO",
+    sc_2 =	"e0000000TO",
+    scd_2 =	mips64 and "f0000000TO",
+
+    -- Opcode SPECIAL.
+    movf_2 =	"00000001DS",
+    movf_3 =	"00000001DSC",
+    movt_2 =	"00010001DS",
+    movt_3 =	"00010001DSC",
+    jr_1 =	"00000008S",
+    movz_3 =	"0000000aDST",
+    movn_3 =	"0000000bDST",
+    mfhi_1 =	"00000010D",
+    mthi_1 =	"00000011S",
+    mflo_1 =	"00000012D",
+    mtlo_1 =	"00000013S",
+    mult_2 =	"00000018ST",
+    multu_2 =	"00000019ST",
+    div_3 =	"0000001aST",
+    divu_3 =	"0000001bST",
+    ddiv_3 =	mips64 and "0000001eST",
+    ddivu_3 =	mips64 and "0000001fST",
+    dmult_2 =	mips64 and "0000001cST",
+    dmultu_2 =	mips64 and "0000001dST",
+
+    -- Opcode REGIMM.
+    tgei_2 =	"04080000SI",
+    tgeiu_2 =	"04090000SI",
+    tlti_2 =	"040a0000SI",
+    tltiu_2 =	"040b0000SI",
+    teqi_2 =	"040c0000SI",
+    tnei_2 =	"040e0000SI",
+    bltzal_2 =	"04100000SB",
+    bgezal_2 =	"04110000SB",
+    bltzall_2 =	"04120000SB",
+    bgezall_2 =	"04130000SB",
+
+    -- Opcode SPECIAL2.
+    madd_2 =	"70000000ST",
+    maddu_2 =	"70000001ST",
+    mul_3 =	"70000002DST",
+    msub_2 =	"70000004ST",
+    msubu_2 =	"70000005ST",
+    clz_2 =	"70000020D=TS",
+    clo_2 =	"70000021D=TS",
+    dclz_2 =	mips64 and "70000024D=TS",
+    dclo_2 =	mips64 and "70000025D=TS",
+    sdbbp_0 =	"7000003f",
+    sdbbp_1 =	"7000003fY",
+
+    -- Opcode COP1.
+    bc1f_1 =	"45000000B",
+    bc1f_2 =	"45000000CB",
+    bc1t_1 =	"45010000B",
+    bc1t_2 =	"45010000CB",
+    bc1fl_1 =	"45020000B",
+    bc1fl_2 =	"45020000CB",
+    bc1tl_1 =	"45030000B",
+    bc1tl_2 =	"45030000CB",
+
+    ["movf.s_2"] =	"46000011FG",
+    ["movf.s_3"] =	"46000011FGC",
+    ["movt.s_2"] =	"46010011FG",
+    ["movt.s_3"] =	"46010011FGC",
+    ["movz.s_3"] =	"46000012FGT",
+    ["movn.s_3"] =	"46000013FGT",
+    ["cvt.ps.s_3"] =	"46000026FGH",
+    ["c.f.s_2"] =	"46000030GH",
+    ["c.f.s_3"] =	"46000030VGH",
+    ["c.un.s_2"] =	"46000031GH",
+    ["c.un.s_3"] =	"46000031VGH",
+    ["c.eq.s_2"] =	"46000032GH",
+    ["c.eq.s_3"] =	"46000032VGH",
+    ["c.ueq.s_2"] =	"46000033GH",
+    ["c.ueq.s_3"] =	"46000033VGH",
+    ["c.olt.s_2"] =	"46000034GH",
+    ["c.olt.s_3"] =	"46000034VGH",
+    ["c.ult.s_2"] =	"46000035GH",
+    ["c.ult.s_3"] =	"46000035VGH",
+    ["c.ole.s_2"] =	"46000036GH",
+    ["c.ole.s_3"] =	"46000036VGH",
+    ["c.ule.s_2"] =	"46000037GH",
+    ["c.ule.s_3"] =	"46000037VGH",
+    ["c.sf.s_2"] =	"46000038GH",
+    ["c.sf.s_3"] =	"46000038VGH",
+    ["c.ngle.s_2"] =	"46000039GH",
+    ["c.ngle.s_3"] =	"46000039VGH",
+    ["c.seq.s_2"] =	"4600003aGH",
+    ["c.seq.s_3"] =	"4600003aVGH",
+    ["c.ngl.s_2"] =	"4600003bGH",
+    ["c.ngl.s_3"] =	"4600003bVGH",
+    ["c.lt.s_2"] =	"4600003cGH",
+    ["c.lt.s_3"] =	"4600003cVGH",
+    ["c.nge.s_2"] =	"4600003dGH",
+    ["c.nge.s_3"] =	"4600003dVGH",
+    ["c.le.s_2"] =	"4600003eGH",
+    ["c.le.s_3"] =	"4600003eVGH",
+    ["c.ngt.s_2"] =	"4600003fGH",
+    ["c.ngt.s_3"] =	"4600003fVGH",
+    ["movf.d_2"] =	"46200011FG",
+    ["movf.d_3"] =	"46200011FGC",
+    ["movt.d_2"] =	"46210011FG",
+    ["movt.d_3"] =	"46210011FGC",
+    ["movz.d_3"] =	"46200012FGT",
+    ["movn.d_3"] =	"46200013FGT",
+    ["c.f.d_2"] =	"46200030GH",
+    ["c.f.d_3"] =	"46200030VGH",
+    ["c.un.d_2"] =	"46200031GH",
+    ["c.un.d_3"] =	"46200031VGH",
+    ["c.eq.d_2"] =	"46200032GH",
+    ["c.eq.d_3"] =	"46200032VGH",
+    ["c.ueq.d_2"] =	"46200033GH",
+    ["c.ueq.d_3"] =	"46200033VGH",
+    ["c.olt.d_2"] =	"46200034GH",
+    ["c.olt.d_3"] =	"46200034VGH",
+    ["c.ult.d_2"] =	"46200035GH",
+    ["c.ult.d_3"] =	"46200035VGH",
+    ["c.ole.d_2"] =	"46200036GH",
+    ["c.ole.d_3"] =	"46200036VGH",
+    ["c.ule.d_2"] =	"46200037GH",
+    ["c.ule.d_3"] =	"46200037VGH",
+    ["c.sf.d_2"] =	"46200038GH",
+    ["c.sf.d_3"] =	"46200038VGH",
+    ["c.ngle.d_2"] =	"46200039GH",
+    ["c.ngle.d_3"] =	"46200039VGH",
+    ["c.seq.d_2"] =	"4620003aGH",
+    ["c.seq.d_3"] =	"4620003aVGH",
+    ["c.ngl.d_2"] =	"4620003bGH",
+    ["c.ngl.d_3"] =	"4620003bVGH",
+    ["c.lt.d_2"] =	"4620003cGH",
+    ["c.lt.d_3"] =	"4620003cVGH",
+    ["c.nge.d_2"] =	"4620003dGH",
+    ["c.nge.d_3"] =	"4620003dVGH",
+    ["c.le.d_2"] =	"4620003eGH",
+    ["c.le.d_3"] =	"4620003eVGH",
+    ["c.ngt.d_2"] =	"4620003fGH",
+    ["c.ngt.d_3"] =	"4620003fVGH",
+    ["add.ps_3"] =	"46c00000FGH",
+    ["sub.ps_3"] =	"46c00001FGH",
+    ["mul.ps_3"] =	"46c00002FGH",
+    ["abs.ps_2"] =	"46c00005FG",
+    ["mov.ps_2"] =	"46c00006FG",
+    ["neg.ps_2"] =	"46c00007FG",
+    ["movf.ps_2"] =	"46c00011FG",
+    ["movf.ps_3"] =	"46c00011FGC",
+    ["movt.ps_2"] =	"46c10011FG",
+    ["movt.ps_3"] =	"46c10011FGC",
+    ["movz.ps_3"] =	"46c00012FGT",
+    ["movn.ps_3"] =	"46c00013FGT",
+    ["cvt.s.pu_2"] =	"46c00020FG",
+    ["cvt.s.pl_2"] =	"46c00028FG",
+    ["pll.ps_3"] =	"46c0002cFGH",
+    ["plu.ps_3"] =	"46c0002dFGH",
+    ["pul.ps_3"] =	"46c0002eFGH",
+    ["puu.ps_3"] =	"46c0002fFGH",
+    ["c.f.ps_2"] =	"46c00030GH",
+    ["c.f.ps_3"] =	"46c00030VGH",
+    ["c.un.ps_2"] =	"46c00031GH",
+    ["c.un.ps_3"] =	"46c00031VGH",
+    ["c.eq.ps_2"] =	"46c00032GH",
+    ["c.eq.ps_3"] =	"46c00032VGH",
+    ["c.ueq.ps_2"] =	"46c00033GH",
+    ["c.ueq.ps_3"] =	"46c00033VGH",
+    ["c.olt.ps_2"] =	"46c00034GH",
+    ["c.olt.ps_3"] =	"46c00034VGH",
+    ["c.ult.ps_2"] =	"46c00035GH",
+    ["c.ult.ps_3"] =	"46c00035VGH",
+    ["c.ole.ps_2"] =	"46c00036GH",
+    ["c.ole.ps_3"] =	"46c00036VGH",
+    ["c.ule.ps_2"] =	"46c00037GH",
+    ["c.ule.ps_3"] =	"46c00037VGH",
+    ["c.sf.ps_2"] =	"46c00038GH",
+    ["c.sf.ps_3"] =	"46c00038VGH",
+    ["c.ngle.ps_2"] =	"46c00039GH",
+    ["c.ngle.ps_3"] =	"46c00039VGH",
+    ["c.seq.ps_2"] =	"46c0003aGH",
+    ["c.seq.ps_3"] =	"46c0003aVGH",
+    ["c.ngl.ps_2"] =	"46c0003bGH",
+    ["c.ngl.ps_3"] =	"46c0003bVGH",
+    ["c.lt.ps_2"] =	"46c0003cGH",
+    ["c.lt.ps_3"] =	"46c0003cVGH",
+    ["c.nge.ps_2"] =	"46c0003dGH",
+    ["c.nge.ps_3"] =	"46c0003dVGH",
+    ["c.le.ps_2"] =	"46c0003eGH",
+    ["c.le.ps_3"] =	"46c0003eVGH",
+    ["c.ngt.ps_2"] =	"46c0003fGH",
+    ["c.ngt.ps_3"] =	"46c0003fVGH",
+
+    -- Opcode COP1X.
+    lwxc1_2 =	"4c000000FX",
+    ldxc1_2 =	"4c000001FX",
+    luxc1_2 =	"4c000005FX",
+    swxc1_2 =	"4c000008FX",
+    sdxc1_2 =	"4c000009FX",
+    suxc1_2 =	"4c00000dFX",
+    prefx_2 =	"4c00000fMX",
+    ["alnv.ps_4"] =	"4c00001eFGHS",
+    ["madd.s_4"] =	"4c000020FRGH",
+    ["madd.d_4"] =	"4c000021FRGH",
+    ["madd.ps_4"] =	"4c000026FRGH",
+    ["msub.s_4"] =	"4c000028FRGH",
+    ["msub.d_4"] =	"4c000029FRGH",
+    ["msub.ps_4"] =	"4c00002eFRGH",
+    ["nmadd.s_4"] =	"4c000030FRGH",
+    ["nmadd.d_4"] =	"4c000031FRGH",
+    ["nmadd.ps_4"] =	"4c000036FRGH",
+    ["nmsub.s_4"] =	"4c000038FRGH",
+    ["nmsub.d_4"] =	"4c000039FRGH",
+    ["nmsub.ps_4"] =	"4c00003eFRGH",
+
+  }) do map_op[k] = v end
+
+end
+
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
 local function parse_gpr(expr)
 local function parse_gpr(expr)
@@ -808,9 +979,11 @@ map_op[".template__"] = function(params, template, nparams)
       op = op + parse_disp(params[n]); n = n + 1
       op = op + parse_disp(params[n]); n = n + 1
     elseif p == "X" then
     elseif p == "X" then
       op = op + parse_index(params[n]); n = n + 1
       op = op + parse_index(params[n]); n = n + 1
-    elseif p == "B" or p == "J" then
+    elseif p == "B" or p == "J" or p == "K" or p == "L" then
       local mode, m, s = parse_label(params[n], false)
       local mode, m, s = parse_label(params[n], false)
-      if p == "B" then m = m + 2048 end
+      if p == "J" then m = m + 0xa800
+      elseif p == "K" then m = m + 0x5000
+      elseif p == "L" then m = m + 0xa000 end
       waction("REL_"..mode, m, s, 1)
       waction("REL_"..mode, m, s, 1)
       n = n + 1
       n = n + 1
     elseif p == "A" then
     elseif p == "A" then
@@ -833,7 +1006,7 @@ map_op[".template__"] = function(params, template, nparams)
     elseif p == "Z" then
     elseif p == "Z" then
       op = op + parse_imm(params[n], 10, 6, 0, false); n = n + 1
       op = op + parse_imm(params[n], 10, 6, 0, false); n = n + 1
     elseif p == "=" then
     elseif p == "=" then
-      op = op + shl(band(op, 0xf800), 5) -- Copy D to T for clz, clo.
+      n = n - 1 -- Re-use previous parameter for next template char.
     else
     else
       assert(false)
       assert(false)
     end
     end

+ 1 - 1
libs/LuaJIT/dynasm/dasm_mips64.lua

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM MIPS64 module.
 -- DynASM MIPS64 module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- See dynasm.lua for full copyright notice.
 -- See dynasm.lua for full copyright notice.
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- This module just sets 64 bit mode for the combined MIPS/MIPS64 module.
 -- This module just sets 64 bit mode for the combined MIPS/MIPS64 module.

+ 1 - 1
libs/LuaJIT/dynasm/dasm_ppc.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** DynASM PPC/PPC64 encoding engine.
 ** DynASM PPC/PPC64 encoding engine.
-** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+** Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 ** Released under the MIT license. See dynasm.lua for full copyright notice.
 ** Released under the MIT license. See dynasm.lua for full copyright notice.
 */
 */
 
 

+ 1 - 1
libs/LuaJIT/dynasm/dasm_ppc.lua

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM PPC/PPC64 module.
 -- DynASM PPC/PPC64 module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- See dynasm.lua for full copyright notice.
 -- See dynasm.lua for full copyright notice.
 --
 --
 -- Support for various extensions contributed by Caio Souza Oliveira.
 -- Support for various extensions contributed by Caio Souza Oliveira.

+ 1 - 1
libs/LuaJIT/dynasm/dasm_proto.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** DynASM encoding engine prototypes.
 ** DynASM encoding engine prototypes.
-** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+** Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 ** Released under the MIT license. See dynasm.lua for full copyright notice.
 ** Released under the MIT license. See dynasm.lua for full copyright notice.
 */
 */
 
 

+ 1 - 1
libs/LuaJIT/dynasm/dasm_x64.lua

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM x64 module.
 -- DynASM x64 module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- See dynasm.lua for full copyright notice.
 -- See dynasm.lua for full copyright notice.
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- This module just sets 64 bit mode for the combined x86/x64 module.
 -- This module just sets 64 bit mode for the combined x86/x64 module.

+ 8 - 5
libs/LuaJIT/dynasm/dasm_x86.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** DynASM x86 encoding engine.
 ** DynASM x86 encoding engine.
-** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+** Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 ** Released under the MIT license. See dynasm.lua for full copyright notice.
 ** Released under the MIT license. See dynasm.lua for full copyright notice.
 */
 */
 
 
@@ -305,11 +305,13 @@ int dasm_link(Dst_DECL, size_t *szp)
 
 
     while (pos != lastpos) {
     while (pos != lastpos) {
       dasm_ActList p = D->actionlist + b[pos++];
       dasm_ActList p = D->actionlist + b[pos++];
+      int op = 0;
       while (1) {
       while (1) {
-	int op, action = *p++;
+	int action = *p++;
 	switch (action) {
 	switch (action) {
-	case DASM_REL_LG: p++; op = p[-3]; goto rel_pc;
-	case DASM_REL_PC: op = p[-2]; rel_pc: {
+	case DASM_REL_LG: p++;
+	  /* fallthrough */
+	case DASM_REL_PC: {
 	  int shrink = op == 0xe9 ? 3 : ((op&0xf0) == 0x80 ? 4 : 0);
 	  int shrink = op == 0xe9 ? 3 : ((op&0xf0) == 0x80 ? 4 : 0);
 	  if (shrink) {  /* Shrinkable branch opcode? */
 	  if (shrink) {  /* Shrinkable branch opcode? */
 	    int lofs, lpos = b[pos];
 	    int lofs, lpos = b[pos];
@@ -341,9 +343,10 @@ int dasm_link(Dst_DECL, size_t *szp)
 	case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */
 	case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */
 	case DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */
 	case DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */
 	case DASM_EXTERN: p += 2; break;
 	case DASM_EXTERN: p += 2; break;
-	case DASM_ESC: p++; break;
+	case DASM_ESC: op = *p++; break;
 	case DASM_MARK: break;
 	case DASM_MARK: break;
 	case DASM_SECTION: case DASM_STOP: goto stop;
 	case DASM_SECTION: case DASM_STOP: goto stop;
+	default: op = action; break;
 	}
 	}
       }
       }
       stop: (void)0;
       stop: (void)0;

+ 2 - 2
libs/LuaJIT/dynasm/dasm_x86.lua

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM x86/x64 module.
 -- DynASM x86/x64 module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- See dynasm.lua for full copyright notice.
 -- See dynasm.lua for full copyright notice.
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
@@ -1852,7 +1852,7 @@ end
 
 
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
-local map_vexarg = { u = false, v = 1, V = 2 }
+local map_vexarg = { u = false, v = 1, V = 2, w = 3 }
 
 
 -- Process pattern string.
 -- Process pattern string.
 local function dopattern(pat, args, sz, op, needrex)
 local function dopattern(pat, args, sz, op, needrex)

+ 5 - 4
libs/LuaJIT/dynasm/dynasm.lua

@@ -2,7 +2,7 @@
 -- DynASM. A dynamic assembler for code generation engines.
 -- DynASM. A dynamic assembler for code generation engines.
 -- Originally designed and implemented for LuaJIT.
 -- Originally designed and implemented for LuaJIT.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- See below for full copyright notice.
 -- See below for full copyright notice.
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
@@ -14,10 +14,10 @@ local _info = {
   vernum =	 10400,
   vernum =	 10400,
   release =	"2015-10-18",
   release =	"2015-10-18",
   author =	"Mike Pall",
   author =	"Mike Pall",
-  url =		"http://luajit.org/dynasm.html",
+  url =		"https://luajit.org/dynasm.html",
   license =	"MIT",
   license =	"MIT",
   copyright =	[[
   copyright =	[[
-Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 
 
 Permission is hereby granted, free of charge, to any person obtaining
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 a copy of this software and associated documentation files (the
@@ -38,7 +38,7 @@ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
-[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
+[ MIT license: https://www.opensource.org/licenses/mit-license.php ]
 ]],
 ]],
 }
 }
 
 
@@ -630,6 +630,7 @@ end
 -- Load architecture-specific module.
 -- Load architecture-specific module.
 local function loadarch(arch)
 local function loadarch(arch)
   if not match(arch, "^[%w_]+$") then return "bad arch name" end
   if not match(arch, "^[%w_]+$") then return "bad arch name" end
+  _G._map_def = map_def
   local ok, m_arch = pcall(require, "dasm_"..arch)
   local ok, m_arch = pcall(require, "dasm_"..arch)
   if not ok then return "cannot load module: "..m_arch end
   if not ok then return "cannot load module: "..m_arch end
   g_arch = m_arch
   g_arch = m_arch

+ 4 - 4
libs/LuaJIT/etc/luajit.1

@@ -6,7 +6,7 @@ luajit \- Just-In-Time Compiler for the Lua Language
 .B luajit
 .B luajit
 [\fIoptions\fR]... [\fIscript\fR [\fIargs\fR]...]
 [\fIoptions\fR]... [\fIscript\fR [\fIargs\fR]...]
 .SH "WEB SITE"
 .SH "WEB SITE"
-.IR http://luajit.org
+.IR https://luajit.org
 .SH DESCRIPTION
 .SH DESCRIPTION
 .PP
 .PP
 This is the command-line program to run Lua programs with \fBLuaJIT\fR.
 This is the command-line program to run Lua programs with \fBLuaJIT\fR.
@@ -74,15 +74,15 @@ 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.
 Runs some nested loops and shows the resulting traces.
 .SH COPYRIGHT
 .SH COPYRIGHT
 .PP
 .PP
-\fBLuaJIT\fR is Copyright \(co 2005-2017 Mike Pall.
+\fBLuaJIT\fR is Copyright \(co 2005-2020 Mike Pall.
 .br
 .br
 \fBLuaJIT\fR is open source software, released under the MIT license.
 \fBLuaJIT\fR is open source software, released under the MIT license.
 .SH SEE ALSO
 .SH SEE ALSO
 .PP
 .PP
 More details in the provided HTML docs or at:
 More details in the provided HTML docs or at:
-.IR http://luajit.org
+.IR https://luajit.org
 .br
 .br
 More about the Lua language can be found at:
 More about the Lua language can be found at:
-.IR http://lua.org/docs.html
+.IR https://lua.org/docs.html
 .PP
 .PP
 lua(1)
 lua(1)

+ 1 - 1
libs/LuaJIT/etc/luajit.pc

@@ -17,7 +17,7 @@ INSTALL_CMOD=${prefix}/${multilib}/lua/${abiver}
 
 
 Name: LuaJIT
 Name: LuaJIT
 Description: Just-in-time compiler for Lua
 Description: Just-in-time compiler for Lua
-URL: http://luajit.org
+URL: https://luajit.org
 Version: ${version}
 Version: ${version}
 Requires:
 Requires:
 Libs: -L${libdir} -l${libname}
 Libs: -L${libdir} -l${libname}

+ 11 - 14
libs/LuaJIT/src/Makefile

@@ -7,7 +7,7 @@
 # Also works with MinGW and Cygwin on Windows.
 # Also works with MinGW and Cygwin on Windows.
 # Please check msvcbuild.bat for building with MSVC on Windows.
 # Please check msvcbuild.bat for building with MSVC on Windows.
 #
 #
-# Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+# Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 ##############################################################################
 ##############################################################################
 
 
 MAJVER=  2
 MAJVER=  2
@@ -132,7 +132,6 @@ XCFLAGS=
 #
 #
 # This define is required to run LuaJIT under Valgrind. The Valgrind
 # This define is required to run LuaJIT under Valgrind. The Valgrind
 # header files must be installed. You should enable debug information, too.
 # header files must be installed. You should enable debug information, too.
-# Use --suppressions=lj.supp to avoid some false positives.
 #XCFLAGS+= -DLUAJIT_USE_VALGRIND
 #XCFLAGS+= -DLUAJIT_USE_VALGRIND
 #
 #
 # This is the client for the GDB JIT API. GDB 7.0 or higher is required
 # This is the client for the GDB JIT API. GDB 7.0 or higher is required
@@ -212,7 +211,7 @@ TARGET_CC= $(STATIC_CC)
 TARGET_STCC= $(STATIC_CC)
 TARGET_STCC= $(STATIC_CC)
 TARGET_DYNCC= $(DYNAMIC_CC)
 TARGET_DYNCC= $(DYNAMIC_CC)
 TARGET_LD= $(CROSS)$(CC)
 TARGET_LD= $(CROSS)$(CC)
-TARGET_AR= $(CROSS)ar rcus
+TARGET_AR= $(CROSS)ar rcus 2>/dev/null
 TARGET_STRIP= $(CROSS)strip
 TARGET_STRIP= $(CROSS)strip
 
 
 TARGET_LIBPATH= $(or $(PREFIX),/usr/local)/$(or $(MULTILIB),lib)
 TARGET_LIBPATH= $(or $(PREFIX),/usr/local)/$(or $(MULTILIB),lib)
@@ -311,9 +310,7 @@ ifeq (Windows,$(TARGET_SYS))
   TARGET_STRIP+= --strip-unneeded
   TARGET_STRIP+= --strip-unneeded
   TARGET_XSHLDFLAGS= -shared -Wl,--out-implib,$(TARGET_DLLDOTANAME)
   TARGET_XSHLDFLAGS= -shared -Wl,--out-implib,$(TARGET_DLLDOTANAME)
   TARGET_DYNXLDOPTS=
   TARGET_DYNXLDOPTS=
-  HOST_RM= del
 else
 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))
 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
   TARGET_XCFLAGS+= -fno-stack-protector
 endif
 endif
@@ -365,7 +362,7 @@ ifneq ($(HOST_SYS),$(TARGET_SYS))
     HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX
     HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX
   else
   else
   ifeq (iOS,$(TARGET_SYS))
   ifeq (iOS,$(TARGET_SYS))
-    HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX
+    HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX -DTARGET_OS_IPHONE=1
   else
   else
     HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OTHER
     HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OTHER
   endif
   endif
@@ -445,6 +442,9 @@ ifeq (arm,$(TARGET_LJARCH))
     DASM_AFLAGS+= -D IOS
     DASM_AFLAGS+= -D IOS
   endif
   endif
 else
 else
+ifneq (,$(findstring LJ_TARGET_MIPSR6 ,$(TARGET_TESTARCH)))
+  DASM_AFLAGS+= -D MIPSR6
+endif
 ifeq (ppc,$(TARGET_LJARCH))
 ifeq (ppc,$(TARGET_LJARCH))
   ifneq (,$(findstring LJ_ARCH_SQRT 1,$(TARGET_TESTARCH)))
   ifneq (,$(findstring LJ_ARCH_SQRT 1,$(TARGET_TESTARCH)))
     DASM_AFLAGS+= -D SQRT
     DASM_AFLAGS+= -D SQRT
@@ -458,9 +458,6 @@ ifeq (ppc,$(TARGET_LJARCH))
   ifeq (PS3,$(TARGET_SYS))
   ifeq (PS3,$(TARGET_SYS))
     DASM_AFLAGS+= -D PPE -D TOC
     DASM_AFLAGS+= -D PPE -D TOC
   endif
   endif
-  ifneq (,$(findstring LJ_ARCH_PPC64 ,$(TARGET_TESTARCH)))
-    DASM_ARCH= ppc64
-  endif
 endif
 endif
 endif
 endif
 endif
 endif
@@ -485,10 +482,10 @@ LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \
 	 lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o
 	 lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o
 LJLIB_C= $(LJLIB_O:.o=.c)
 LJLIB_C= $(LJLIB_O:.o=.c)
 
 
-LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o lj_buf.o \
+LJCORE_O= lj_assert.o lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o lj_buf.o \
 	  lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o lj_debug.o \
 	  lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o lj_debug.o \
-	  lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o lj_strscan.o \
-	  lj_strfmt.o lj_strfmt_num.o lj_api.o lj_profile.o \
+	  lj_prng.o lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o \
+	  lj_strscan.o lj_strfmt.o lj_strfmt_num.o lj_api.o lj_profile.o \
 	  lj_lex.o lj_parse.o lj_bcread.o lj_bcwrite.o lj_load.o \
 	  lj_lex.o lj_parse.o lj_bcread.o lj_bcwrite.o lj_load.o \
 	  lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \
 	  lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \
 	  lj_opt_dce.o lj_opt_loop.o lj_opt_split.o lj_opt_sink.o \
 	  lj_opt_dce.o lj_opt_loop.o lj_opt_split.o lj_opt_sink.o \
@@ -563,6 +560,7 @@ ifeq (Windows,$(HOST_SYS))
     MINILUA_X= host\minilua
     MINILUA_X= host\minilua
     BUILDVM_X= host\buildvm
     BUILDVM_X= host\buildvm
     ALL_RM:= $(subst /,\,$(ALL_RM))
     ALL_RM:= $(subst /,\,$(ALL_RM))
+    HOST_RM= del
   endif
   endif
 endif
 endif
 
 
@@ -603,7 +601,6 @@ E= @echo
 default all:	$(TARGET_T)
 default all:	$(TARGET_T)
 
 
 amalg:
 amalg:
-	@grep "^[+|]" ljamalg.c
 	$(MAKE) all "LJCORE_O=ljamalg.o"
 	$(MAKE) all "LJCORE_O=ljamalg.o"
 
 
 clean:
 clean:
@@ -637,7 +634,7 @@ $(MINILUA_T): $(MINILUA_O)
 	$(E) "HOSTLINK  $@"
 	$(E) "HOSTLINK  $@"
 	$(Q)$(HOST_CC) $(HOST_ALDFLAGS) -o $@ $(MINILUA_O) $(MINILUA_LIBS) $(HOST_ALIBS)
 	$(Q)$(HOST_CC) $(HOST_ALDFLAGS) -o $@ $(MINILUA_O) $(MINILUA_LIBS) $(HOST_ALIBS)
 
 
-host/buildvm_arch.h: $(DASM_DASC) $(DASM_DEP) $(DASM_DIR)/*.lua
+host/buildvm_arch.h: $(DASM_DASC) $(DASM_DEP) $(DASM_DIR)/*.lua lj_arch.h lua.h luaconf.h
 	$(E) "DYNASM    $@"
 	$(E) "DYNASM    $@"
 	$(Q)$(DASM) $(DASM_FLAGS) -o $@ $(DASM_DASC)
 	$(Q)$(DASM) $(DASM_FLAGS) -o $@ $(DASM_DASC)
 
 

+ 36 - 31
libs/LuaJIT/src/Makefile.dep

@@ -1,6 +1,6 @@
 lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
 lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
  lj_arch.h lj_err.h lj_errmsg.h lj_state.h lj_trace.h lj_jit.h lj_ir.h \
  lj_arch.h lj_err.h lj_errmsg.h lj_state.h lj_trace.h lj_jit.h lj_ir.h \
- lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h lj_alloc.h
+ lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h
 lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
 lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
  lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \
  lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \
  lj_tab.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cconv.h \
  lj_tab.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cconv.h \
@@ -28,7 +28,7 @@ lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
  lj_target.h lj_target_*.h lj_trace.h lj_dispatch.h lj_traceerr.h \
  lj_target.h lj_target_*.h lj_trace.h lj_dispatch.h lj_traceerr.h \
  lj_vm.h lj_vmevent.h lj_lib.h luajit.h lj_libdef.h
  lj_vm.h lj_vmevent.h lj_lib.h luajit.h lj_libdef.h
 lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
 lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
- lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_libdef.h
+ lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_prng.h lj_libdef.h
 lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
 lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
  lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_lib.h \
  lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_lib.h \
  lj_libdef.h
  lj_libdef.h
@@ -41,7 +41,8 @@ lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
 lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
 lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
  lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h \
  lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h \
  lj_tab.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
  lj_tab.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
-lj_alloc.o: lj_alloc.c lj_def.h lua.h luaconf.h lj_arch.h lj_alloc.h
+lj_alloc.o: lj_alloc.c lj_def.h lua.h luaconf.h lj_arch.h lj_alloc.h \
+ lj_prng.h
 lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
 lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
  lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
  lj_meta.h lj_state.h lj_bc.h lj_frame.h lj_trace.h lj_jit.h lj_ir.h \
  lj_meta.h lj_state.h lj_bc.h lj_frame.h lj_trace.h lj_jit.h lj_ir.h \
@@ -51,6 +52,7 @@ lj_asm.o: lj_asm.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_ircall.h lj_iropt.h lj_mcode.h lj_trace.h lj_dispatch.h lj_traceerr.h \
  lj_ircall.h lj_iropt.h lj_mcode.h lj_trace.h lj_dispatch.h lj_traceerr.h \
  lj_snap.h lj_asm.h lj_vm.h lj_target.h lj_target_*.h lj_emit_*.h \
  lj_snap.h lj_asm.h lj_vm.h lj_target.h lj_target_*.h lj_emit_*.h \
  lj_asm_*.h
  lj_asm_*.h
+lj_assert.o: lj_assert.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h
 lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \
 lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \
  lj_bcdef.h
  lj_bcdef.h
 lj_bcread.o: lj_bcread.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_bcread.o: lj_bcread.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
@@ -125,7 +127,7 @@ lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
 lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_buf.h lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h \
  lj_buf.h lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h \
  lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h \
  lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h \
- lj_carith.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h
+ lj_carith.h lj_vm.h lj_strscan.h lj_strfmt.h lj_prng.h
 lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
 lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h \
  lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h \
  lualib.h lj_state.h lj_lex.h lj_parse.h lj_char.h lj_strscan.h \
  lualib.h lj_state.h lj_lex.h lj_parse.h lj_char.h lj_strscan.h \
@@ -139,7 +141,7 @@ lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
  lj_frame.h lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
  lj_frame.h lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
 lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h \
- lj_dispatch.h lj_bc.h lj_traceerr.h lj_vm.h
+ lj_dispatch.h lj_bc.h lj_traceerr.h lj_prng.h lj_vm.h
 lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
 lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_meta.h lj_frame.h \
  lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_meta.h lj_frame.h \
  lj_bc.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h
  lj_bc.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h
@@ -155,7 +157,7 @@ lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h \
  lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h \
  lj_vm.h
  lj_vm.h
 lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_tab.h lj_ir.h lj_jit.h lj_iropt.h lj_ircall.h
+ lj_tab.h lj_ir.h lj_jit.h lj_iropt.h lj_ircall.h lj_dispatch.h lj_bc.h
 lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
 lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
  lj_arch.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
  lj_arch.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
  lj_traceerr.h lj_vm.h lj_strscan.h
  lj_traceerr.h lj_vm.h lj_strscan.h
@@ -171,11 +173,12 @@ lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_profile.o: lj_profile.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_profile.o: lj_profile.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_buf.h lj_gc.h lj_str.h lj_frame.h lj_bc.h lj_debug.h lj_dispatch.h \
  lj_buf.h lj_gc.h lj_str.h lj_frame.h lj_bc.h lj_debug.h lj_dispatch.h \
  lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h luajit.h
  lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h luajit.h
+lj_prng.o: lj_prng.c lj_def.h lua.h luaconf.h lj_arch.h lj_prng.h
 lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
  lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
  lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_debug.h lj_ir.h lj_jit.h \
  lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_debug.h lj_ir.h lj_jit.h \
  lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h \
  lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h \
- lj_record.h lj_ffrecord.h lj_snap.h lj_vm.h
+ lj_record.h lj_ffrecord.h lj_snap.h lj_vm.h lj_prng.h
 lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
 lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_tab.h lj_state.h lj_frame.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h \
  lj_tab.h lj_state.h lj_frame.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h \
  lj_trace.h lj_dispatch.h lj_traceerr.h lj_snap.h lj_target.h \
  lj_trace.h lj_dispatch.h lj_traceerr.h lj_snap.h lj_target.h \
@@ -183,7 +186,8 @@ lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
 lj_state.o: lj_state.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_state.o: lj_state.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_func.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_func.h \
  lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_trace.h lj_jit.h \
  lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_trace.h lj_jit.h \
- lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_lex.h lj_alloc.h luajit.h
+ lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_prng.h lj_lex.h \
+ lj_alloc.h luajit.h
 lj_str.o: lj_str.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
 lj_str.o: lj_str.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_char.h
  lj_err.h lj_errmsg.h lj_str.h lj_char.h
 lj_strfmt.o: lj_strfmt.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_strfmt.o: lj_strfmt.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
@@ -198,7 +202,7 @@ lj_trace.o: lj_trace.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_frame.h lj_bc.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_frame.h lj_bc.h \
  lj_state.h lj_ir.h lj_jit.h lj_iropt.h lj_mcode.h lj_trace.h \
  lj_state.h lj_ir.h lj_jit.h lj_iropt.h lj_mcode.h lj_trace.h \
  lj_dispatch.h lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h \
  lj_dispatch.h lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h \
- lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h
+ lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h lj_prng.h
 lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_udata.h
  lj_gc.h lj_udata.h
 lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
@@ -206,28 +210,29 @@ lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_vm.h lj_vmevent.h
  lj_vm.h lj_vmevent.h
 lj_vmmath.o: lj_vmmath.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_vmmath.o: lj_vmmath.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_ir.h lj_vm.h
  lj_ir.h lj_vm.h
-ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \
- lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h \
- lj_func.h lj_udata.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h \
- lj_cdata.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h \
- lj_vm.h lj_err.c lj_debug.h lj_ff.h lj_ffdef.h lj_strfmt.h lj_char.c \
- lj_char.h lj_bc.c lj_bcdef.h lj_obj.c lj_buf.c lj_str.c lj_tab.c \
- lj_func.c lj_udata.c lj_meta.c lj_strscan.h lj_lib.h lj_debug.c \
- lj_state.c lj_lex.h lj_alloc.h luajit.h lj_dispatch.c lj_ccallback.h \
- lj_profile.h lj_vmevent.c lj_vmevent.h lj_vmmath.c lj_strscan.c \
- lj_strfmt.c lj_strfmt_num.c lj_api.c lj_profile.c lj_lex.c lualib.h \
- lj_parse.h lj_parse.c lj_bcread.c lj_bcdump.h lj_bcwrite.c lj_load.c \
- lj_ctype.c lj_cdata.c lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h \
- lj_ccallback.c lj_target.h lj_target_*.h lj_mcode.h lj_carith.c \
- lj_carith.h lj_clib.c lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_ir.c \
- lj_ircall.h lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h \
- lj_opt_narrow.c lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_opt_split.c \
- lj_opt_sink.c lj_mcode.c lj_snap.c lj_record.c lj_record.h lj_ffrecord.h \
- lj_crecord.c lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h \
- lj_emit_*.h lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c \
- lib_aux.c lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c \
- lib_io.c lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c \
- lib_ffi.c lib_init.c
+ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_assert.c lj_obj.h \
+ lj_def.h lj_arch.h lj_gc.c lj_gc.h lj_err.h lj_errmsg.h lj_buf.h \
+ lj_str.h lj_tab.h lj_func.h lj_udata.h lj_meta.h lj_state.h lj_frame.h \
+ lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
+ lj_traceerr.h lj_vm.h lj_err.c lj_debug.h lj_ff.h lj_ffdef.h lj_strfmt.h \
+ lj_char.c lj_char.h lj_bc.c lj_bcdef.h lj_obj.c lj_buf.c lj_str.c \
+ lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_strscan.h lj_lib.h lj_debug.c \
+ lj_prng.c lj_prng.h lj_state.c lj_lex.h lj_alloc.h luajit.h \
+ lj_dispatch.c lj_ccallback.h lj_profile.h lj_vmevent.c lj_vmevent.h \
+ lj_vmmath.c lj_strscan.c lj_strfmt.c lj_strfmt_num.c lj_api.c \
+ lj_profile.c lj_lex.c lualib.h lj_parse.h lj_parse.c lj_bcread.c \
+ lj_bcdump.h lj_bcwrite.c lj_load.c lj_ctype.c lj_cdata.c lj_cconv.h \
+ lj_cconv.c lj_ccall.c lj_ccall.h lj_ccallback.c lj_target.h \
+ lj_target_*.h lj_mcode.h lj_carith.c lj_carith.h lj_clib.c lj_clib.h \
+ lj_cparse.c lj_cparse.h lj_lib.c lj_ir.c lj_ircall.h lj_iropt.h \
+ lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c lj_opt_dce.c \
+ lj_opt_loop.c lj_snap.h lj_opt_split.c lj_opt_sink.c lj_mcode.c \
+ lj_snap.c lj_record.c lj_record.h lj_ffrecord.h lj_crecord.c \
+ lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h lj_emit_*.h \
+ lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c \
+ lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c \
+ lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c \
+ lib_init.c
 luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h
 luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h
 host/buildvm.o: host/buildvm.c host/buildvm.h lj_def.h lua.h luaconf.h \
 host/buildvm.o: host/buildvm.c host/buildvm.h lj_def.h lua.h luaconf.h \
  lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_gc.h lj_obj.h lj_bc.h lj_ir.h \
  lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_gc.h lj_obj.h lj_bc.h lj_ir.h \

+ 1 - 1
libs/LuaJIT/src/host/buildvm.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** LuaJIT VM builder.
 ** LuaJIT VM builder.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** This is a tool to build the hand-tuned assembler code required for
 ** This is a tool to build the hand-tuned assembler code required for
 ** LuaJIT's bytecode interpreter. It supports a variety of output formats
 ** LuaJIT's bytecode interpreter. It supports a variety of output formats

+ 1 - 1
libs/LuaJIT/src/host/buildvm.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** LuaJIT VM builder.
 ** LuaJIT VM builder.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _BUILDVM_H
 #ifndef _BUILDVM_H

+ 1 - 12
libs/LuaJIT/src/host/buildvm_asm.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** LuaJIT VM builder: Assembler source code emitter.
 ** LuaJIT VM builder: Assembler source code emitter.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #include "buildvm.h"
 #include "buildvm.h"
@@ -144,14 +144,6 @@ static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n,
     fprintf(ctx->fp, "\t%s %d, %d, " TOCPREFIX "%s\n",
     fprintf(ctx->fp, "\t%s %d, %d, " TOCPREFIX "%s\n",
 	    (ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym);
 	    (ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym);
   } else if ((ins >> 26) == 18) {
   } else if ((ins >> 26) == 18) {
-#if LJ_ARCH_PPC64
-    const char *suffix = strchr(sym, '@');
-    if (suffix && suffix[1] == 'h') {
-      fprintf(ctx->fp, "\taddis 11, 2, %s\n", sym);
-    } else if (suffix && suffix[1] == 'l') {
-      fprintf(ctx->fp, "\tld 12, %s\n", sym);
-    } else
-#endif
     fprintf(ctx->fp, "\t%s " TOCPREFIX "%s\n", (ins & 1) ? "bl" : "b", sym);
     fprintf(ctx->fp, "\t%s " TOCPREFIX "%s\n", (ins & 1) ? "bl" : "b", sym);
   } else {
   } else {
     fprintf(stderr,
     fprintf(stderr,
@@ -250,9 +242,6 @@ void emit_asm(BuildCtx *ctx)
   int i, rel;
   int i, rel;
 
 
   fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch);
   fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch);
-#if LJ_ARCH_PPC64
-  fprintf(ctx->fp, "\t.abiversion 2\n");
-#endif
   fprintf(ctx->fp, "\t.text\n");
   fprintf(ctx->fp, "\t.text\n");
   emit_asm_align(ctx, 4);
   emit_asm_align(ctx, 4);
 
 

+ 1 - 1
libs/LuaJIT/src/host/buildvm_fold.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** LuaJIT VM builder: IR folding hash table generator.
 ** LuaJIT VM builder: IR folding hash table generator.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #include "buildvm.h"
 #include "buildvm.h"

+ 1 - 1
libs/LuaJIT/src/host/buildvm_lib.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** LuaJIT VM builder: library definition compiler.
 ** LuaJIT VM builder: library definition compiler.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #include "buildvm.h"
 #include "buildvm.h"

+ 2 - 15
libs/LuaJIT/src/host/buildvm_peobj.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** LuaJIT VM builder: PE object emitter.
 ** LuaJIT VM builder: PE object emitter.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** Only used for building on Windows, since we cannot assume the presence
 ** Only used for building on Windows, since we cannot assume the presence
 ** of a suitable assembler. The host and target byte order must match.
 ** of a suitable assembler. The host and target byte order must match.
@@ -9,7 +9,7 @@
 #include "buildvm.h"
 #include "buildvm.h"
 #include "lj_bc.h"
 #include "lj_bc.h"
 
 
-#if LJ_TARGET_X86ORX64 || LJ_TARGET_PPC
+#if LJ_TARGET_X86ORX64
 
 
 /* Context for PE object emitter. */
 /* Context for PE object emitter. */
 static char *strtab;
 static char *strtab;
@@ -93,12 +93,6 @@ typedef struct PEsymaux {
 #define PEOBJ_RELOC_ADDR32NB	0x03
 #define PEOBJ_RELOC_ADDR32NB	0x03
 #define PEOBJ_RELOC_OFS		0
 #define PEOBJ_RELOC_OFS		0
 #define PEOBJ_TEXT_FLAGS	0x60500020  /* 60=r+x, 50=align16, 20=code. */
 #define PEOBJ_TEXT_FLAGS	0x60500020  /* 60=r+x, 50=align16, 20=code. */
-#elif LJ_TARGET_PPC
-#define PEOBJ_ARCH_TARGET	0x01f2
-#define PEOBJ_RELOC_REL32	0x06
-#define PEOBJ_RELOC_DIR32	0x02
-#define PEOBJ_RELOC_OFS		(-4)
-#define PEOBJ_TEXT_FLAGS	0x60400020  /* 60=r+x, 40=align8, 20=code. */
 #endif
 #endif
 
 
 /* Section numbers (0-based). */
 /* Section numbers (0-based). */
@@ -251,15 +245,8 @@ void emit_peobj(BuildCtx *ctx)
   /* Write .text section. */
   /* Write .text section. */
   host_endian.u = 1;
   host_endian.u = 1;
   if (host_endian.b != LJ_ENDIAN_SELECT(1, 0)) {
   if (host_endian.b != LJ_ENDIAN_SELECT(1, 0)) {
-#if LJ_TARGET_PPC
-    uint32_t *p = (uint32_t *)ctx->code;
-    int n = (int)(ctx->codesz >> 2);
-    for (i = 0; i < n; i++, p++)
-      *p = lj_bswap(*p);  /* Byteswap .text section. */
-#else
     fprintf(stderr, "Error: different byte order for host and target\n");
     fprintf(stderr, "Error: different byte order for host and target\n");
     exit(1);
     exit(1);
-#endif
   }
   }
   owrite(ctx, ctx->code, ctx->codesz);
   owrite(ctx, ctx->code, ctx->codesz);
   for (i = 0; i < ctx->nreloc; i++) {
   for (i = 0; i < ctx->nreloc; i++) {

+ 1 - 1
libs/LuaJIT/src/host/genlibbc.lua

@@ -2,7 +2,7 @@
 -- Lua script to dump the bytecode of the library functions written in Lua.
 -- Lua script to dump the bytecode of the library functions written in Lua.
 -- The resulting 'buildvm_libbc.h' is used for the build process of LuaJIT.
 -- The resulting 'buildvm_libbc.h' is used for the build process of LuaJIT.
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 
 

+ 1 - 1
libs/LuaJIT/src/host/genminilua.lua

@@ -2,7 +2,7 @@
 -- Lua script to generate a customized, minified version of Lua.
 -- Lua script to generate a customized, minified version of Lua.
 -- The resulting 'minilua' is used for the build process of LuaJIT.
 -- The resulting 'minilua' is used for the build process of LuaJIT.
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 
 

+ 1 - 1
libs/LuaJIT/src/jit/bc.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT bytecode listing module.
 -- LuaJIT bytecode listing module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 --
 --

+ 46 - 42
libs/LuaJIT/src/jit/bcsave.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT module to save/list bytecode.
 -- LuaJIT module to save/list bytecode.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 --
 --
@@ -17,6 +17,10 @@ local bit = require("bit")
 -- Symbol name prefix for LuaJIT bytecode.
 -- Symbol name prefix for LuaJIT bytecode.
 local LJBC_PREFIX = "luaJIT_BC_"
 local LJBC_PREFIX = "luaJIT_BC_"
 
 
+local type, assert = type, assert
+local format = string.format
+local tremove, tconcat = table.remove, table.concat
+
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
 local function usage()
 local function usage()
@@ -63,8 +67,18 @@ local map_type = {
 }
 }
 
 
 local map_arch = {
 local map_arch = {
-  x86 = true, x64 = true, arm = true, arm64 = true, arm64be = true,
-  ppc = true, mips = true, mipsel = true,
+  x86 =		{ e = "le", b = 32, m = 3, p = 0x14c, },
+  x64 =		{ e = "le", b = 64, m = 62, p = 0x8664, },
+  arm =		{ e = "le", b = 32, m = 40, p = 0x1c0, },
+  arm64 =	{ e = "le", b = 64, m = 183, p = 0xaa64, },
+  arm64be =	{ e = "be", b = 64, m = 183, },
+  ppc =		{ e = "be", b = 32, m = 20, },
+  mips =	{ e = "be", b = 32, m = 8, f = 0x50001006, },
+  mipsel =	{ e = "le", b = 32, m = 8, f = 0x50001006, },
+  mips64 =	{ e = "be", b = 64, m = 8, f = 0x80000007, },
+  mips64el =	{ e = "le", b = 64, m = 8, f = 0x80000007, },
+  mips64r6 =	{ e = "be", b = 64, m = 8, f = 0xa0000407, },
+  mips64r6el =	{ e = "le", b = 64, m = 8, f = 0xa0000407, },
 }
 }
 
 
 local map_os = {
 local map_os = {
@@ -73,33 +87,33 @@ local map_os = {
 }
 }
 
 
 local function checkarg(str, map, err)
 local function checkarg(str, map, err)
-  str = string.lower(str)
+  str = str:lower()
   local s = check(map[str], "unknown ", err)
   local s = check(map[str], "unknown ", err)
-  return s == true and str or s
+  return type(s) == "string" and s or str
 end
 end
 
 
 local function detecttype(str)
 local function detecttype(str)
-  local ext = string.match(string.lower(str), "%.(%a+)$")
+  local ext = str:lower():match("%.(%a+)$")
   return map_type[ext] or "raw"
   return map_type[ext] or "raw"
 end
 end
 
 
 local function checkmodname(str)
 local function checkmodname(str)
-  check(string.match(str, "^[%w_.%-]+$"), "bad module name")
-  return string.gsub(str, "[%.%-]", "_")
+  check(str:match("^[%w_.%-]+$"), "bad module name")
+  return str:gsub("[%.%-]", "_")
 end
 end
 
 
 local function detectmodname(str)
 local function detectmodname(str)
   if type(str) == "string" then
   if type(str) == "string" then
-    local tail = string.match(str, "[^/\\]+$")
+    local tail = str:match("[^/\\]+$")
     if tail then str = tail end
     if tail then str = tail end
-    local head = string.match(str, "^(.*)%.[^.]*$")
+    local head = str:match("^(.*)%.[^.]*$")
     if head then str = head end
     if head then str = head end
-    str = string.match(str, "^[%w_.%-]+")
+    str = str:match("^[%w_.%-]+")
   else
   else
     str = nil
     str = nil
   end
   end
   check(str, "cannot derive module name, use -n name")
   check(str, "cannot derive module name, use -n name")
-  return string.gsub(str, "[%.%-]", "_")
+  return str:gsub("[%.%-]", "_")
 end
 end
 
 
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
@@ -118,8 +132,8 @@ end
 local function bcsave_c(ctx, output, s)
 local function bcsave_c(ctx, output, s)
   local fp = savefile(output, "w")
   local fp = savefile(output, "w")
   if ctx.type == "c" then
   if ctx.type == "c" then
-    fp:write(string.format([[
-#ifdef _cplusplus
+    fp:write(format([[
+#ifdef __cplusplus
 extern "C"
 extern "C"
 #endif
 #endif
 #ifdef _WIN32
 #ifdef _WIN32
@@ -128,7 +142,7 @@ __declspec(dllexport)
 const unsigned char %s%s[] = {
 const unsigned char %s%s[] = {
 ]], LJBC_PREFIX, ctx.modname))
 ]], LJBC_PREFIX, ctx.modname))
   else
   else
-    fp:write(string.format([[
+    fp:write(format([[
 #define %s%s_SIZE %d
 #define %s%s_SIZE %d
 static const unsigned char %s%s[] = {
 static const unsigned char %s%s[] = {
 ]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname))
 ]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname))
@@ -138,13 +152,13 @@ static const unsigned char %s%s[] = {
     local b = tostring(string.byte(s, i))
     local b = tostring(string.byte(s, i))
     m = m + #b + 1
     m = m + #b + 1
     if m > 78 then
     if m > 78 then
-      fp:write(table.concat(t, ",", 1, n), ",\n")
+      fp:write(tconcat(t, ",", 1, n), ",\n")
       n, m = 0, #b + 1
       n, m = 0, #b + 1
     end
     end
     n = n + 1
     n = n + 1
     t[n] = b
     t[n] = b
   end
   end
-  bcsave_tail(fp, output, table.concat(t, ",", 1, n).."\n};\n")
+  bcsave_tail(fp, output, tconcat(t, ",", 1, n).."\n};\n")
 end
 end
 
 
 local function bcsave_elfobj(ctx, output, s, ffi)
 local function bcsave_elfobj(ctx, output, s, ffi)
@@ -199,12 +213,8 @@ typedef struct {
 } ELF64obj;
 } ELF64obj;
 ]]
 ]]
   local symname = LJBC_PREFIX..ctx.modname
   local symname = LJBC_PREFIX..ctx.modname
-  local is64, isbe = false, false
-  if ctx.arch == "x64" or ctx.arch == "arm64" or ctx.arch == "arm64be" then
-    is64 = true
-  elseif ctx.arch == "ppc" or ctx.arch == "mips" then
-    isbe = true
-  end
+  local ai = assert(map_arch[ctx.arch])
+  local is64, isbe = ai.b == 64, ai.e == "be"
 
 
   -- Handle different host/target endianess.
   -- Handle different host/target endianess.
   local function f32(x) return x end
   local function f32(x) return x end
@@ -237,10 +247,8 @@ typedef struct {
   hdr.eendian = isbe and 2 or 1
   hdr.eendian = isbe and 2 or 1
   hdr.eversion = 1
   hdr.eversion = 1
   hdr.type = f16(1)
   hdr.type = f16(1)
-  hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, arm64be=183, ppc=20, mips=8, mipsel=8 })[ctx.arch])
-  if ctx.arch == "mips" or ctx.arch == "mipsel" then
-    hdr.flags = f32(0x50001006)
-  end
+  hdr.machine = f16(ai.m)
+  hdr.flags = f32(ai.f or 0)
   hdr.version = f32(1)
   hdr.version = f32(1)
   hdr.shofs = fofs(ffi.offsetof(o, "sect"))
   hdr.shofs = fofs(ffi.offsetof(o, "sect"))
   hdr.ehsize = f16(ffi.sizeof(hdr))
   hdr.ehsize = f16(ffi.sizeof(hdr))
@@ -336,12 +344,8 @@ typedef struct {
 } PEobj;
 } PEobj;
 ]]
 ]]
   local symname = LJBC_PREFIX..ctx.modname
   local symname = LJBC_PREFIX..ctx.modname
-  local is64 = false
-  if ctx.arch == "x86" then
-    symname = "_"..symname
-  elseif ctx.arch == "x64" then
-    is64 = true
-  end
+  local ai = assert(map_arch[ctx.arch])
+  local is64 = ai.b == 64
   local symexport = "   /EXPORT:"..symname..",DATA "
   local symexport = "   /EXPORT:"..symname..",DATA "
 
 
   -- The file format is always little-endian. Swap if the host is big-endian.
   -- The file format is always little-endian. Swap if the host is big-endian.
@@ -355,7 +359,7 @@ typedef struct {
   -- Create PE object and fill in header.
   -- Create PE object and fill in header.
   local o = ffi.new("PEobj")
   local o = ffi.new("PEobj")
   local hdr = o.hdr
   local hdr = o.hdr
-  hdr.arch = f16(({ x86=0x14c, x64=0x8664, arm=0x1c0, ppc=0x1f2, mips=0x366, mipsel=0x366 })[ctx.arch])
+  hdr.arch = f16(assert(ai.p))
   hdr.nsects = f16(2)
   hdr.nsects = f16(2)
   hdr.symtabofs = f32(ffi.offsetof(o, "sym0"))
   hdr.symtabofs = f32(ffi.offsetof(o, "sym0"))
   hdr.nsyms = f32(6)
   hdr.nsyms = f32(6)
@@ -605,16 +609,16 @@ local function docmd(...)
   local n = 1
   local n = 1
   local list = false
   local list = false
   local ctx = {
   local ctx = {
-    strip = true, arch = jit.arch, os = string.lower(jit.os),
+    strip = true, arch = jit.arch, os = jit.os:lower(),
     type = false, modname = false,
     type = false, modname = false,
   }
   }
   while n <= #arg do
   while n <= #arg do
     local a = arg[n]
     local a = arg[n]
-    if type(a) == "string" and string.sub(a, 1, 1) == "-" and a ~= "-" then
-      table.remove(arg, n)
+    if type(a) == "string" and a:sub(1, 1) == "-" and a ~= "-" then
+      tremove(arg, n)
       if a == "--" then break end
       if a == "--" then break end
       for m=2,#a do
       for m=2,#a do
-	local opt = string.sub(a, m, m)
+	local opt = a:sub(m, m)
 	if opt == "l" then
 	if opt == "l" then
 	  list = true
 	  list = true
 	elseif opt == "s" then
 	elseif opt == "s" then
@@ -627,13 +631,13 @@ local function docmd(...)
 	    if n ~= 1 then usage() end
 	    if n ~= 1 then usage() end
 	    arg[1] = check(loadstring(arg[1]))
 	    arg[1] = check(loadstring(arg[1]))
 	  elseif opt == "n" then
 	  elseif opt == "n" then
-	    ctx.modname = checkmodname(table.remove(arg, n))
+	    ctx.modname = checkmodname(tremove(arg, n))
 	  elseif opt == "t" then
 	  elseif opt == "t" then
-	    ctx.type = checkarg(table.remove(arg, n), map_type, "file type")
+	    ctx.type = checkarg(tremove(arg, n), map_type, "file type")
 	  elseif opt == "a" then
 	  elseif opt == "a" then
-	    ctx.arch = checkarg(table.remove(arg, n), map_arch, "architecture")
+	    ctx.arch = checkarg(tremove(arg, n), map_arch, "architecture")
 	  elseif opt == "o" then
 	  elseif opt == "o" then
-	    ctx.os = checkarg(table.remove(arg, n), map_os, "OS name")
+	    ctx.os = checkarg(tremove(arg, n), map_os, "OS name")
 	  else
 	  else
 	    usage()
 	    usage()
 	  end
 	  end

+ 1 - 1
libs/LuaJIT/src/jit/dis_arm.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT ARM disassembler module.
 -- LuaJIT ARM disassembler module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- This is a helper module used by the LuaJIT machine code dumper module.
 -- This is a helper module used by the LuaJIT machine code dumper module.

+ 1 - 1
libs/LuaJIT/src/jit/dis_arm64.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT ARM64 disassembler module.
 -- LuaJIT ARM64 disassembler module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 --
 --
 -- Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.
 -- Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.

+ 1 - 1
libs/LuaJIT/src/jit/dis_arm64be.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT ARM64BE disassembler wrapper module.
 -- LuaJIT ARM64BE disassembler wrapper module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- ARM64 instructions are always little-endian. So just forward to the
 -- ARM64 instructions are always little-endian. So just forward to the

+ 273 - 22
libs/LuaJIT/src/jit/dis_mips.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT MIPS disassembler module.
 -- LuaJIT MIPS disassembler module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT/X license. See Copyright Notice in luajit.h
 -- 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.
 -- This is a helper module used by the LuaJIT machine code dumper module.
@@ -19,13 +19,34 @@ local band, bor, tohex = bit.band, bit.bor, bit.tohex
 local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
 local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
 
 
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
--- Primary and extended opcode maps
+-- Extended opcode maps common to all MIPS releases
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
-local map_movci = { shift = 16, mask = 1, [0] = "movfDSC", "movtDSC", }
 local map_srl = { shift = 21, mask = 1, [0] = "srlDTA", "rotrDTA", }
 local map_srl = { shift = 21, mask = 1, [0] = "srlDTA", "rotrDTA", }
 local map_srlv = { shift = 6, mask = 1, [0] = "srlvDTS", "rotrvDTS", }
 local map_srlv = { shift = 6, mask = 1, [0] = "srlvDTS", "rotrvDTS", }
 
 
+local map_cop0 = {
+  shift = 25, mask = 1,
+  [0] = {
+    shift = 21, mask = 15,
+    [0] = "mfc0TDW", [4] = "mtc0TDW",
+    [10] = "rdpgprDT",
+    [11] = { shift = 5, mask = 1, [0] = "diT0", "eiT0", },
+    [14] = "wrpgprDT",
+  }, {
+    shift = 0, mask = 63,
+    [1] = "tlbr", [2] = "tlbwi", [6] = "tlbwr", [8] = "tlbp",
+    [24] = "eret", [31] = "deret",
+    [32] = "wait",
+  },
+}
+
+------------------------------------------------------------------------------
+-- Primary and extended opcode maps for MIPS R1-R5
+------------------------------------------------------------------------------
+
+local map_movci = { shift = 16, mask = 1, [0] = "movfDSC", "movtDSC", }
+
 local map_special = {
 local map_special = {
   shift = 0, mask = 63,
   shift = 0, mask = 63,
   [0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" },
   [0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" },
@@ -87,22 +108,6 @@ local map_regimm = {
   false,	false,		false,		"synciSO",
   false,	false,		false,		"synciSO",
 }
 }
 
 
-local map_cop0 = {
-  shift = 25, mask = 1,
-  [0] = {
-    shift = 21, mask = 15,
-    [0] = "mfc0TDW", [4] = "mtc0TDW",
-    [10] = "rdpgprDT",
-    [11] = { shift = 5, mask = 1, [0] = "diT0", "eiT0", },
-    [14] = "wrpgprDT",
-  }, {
-    shift = 0, mask = 63,
-    [1] = "tlbr", [2] = "tlbwi", [6] = "tlbwr", [8] = "tlbp",
-    [24] = "eret", [31] = "deret",
-    [32] = "wait",
-  },
-}
-
 local map_cop1s = {
 local map_cop1s = {
   shift = 0, mask = 63,
   shift = 0, mask = 63,
   [0] = "add.sFGH",	"sub.sFGH",	"mul.sFGH",	"div.sFGH",
   [0] = "add.sFGH",	"sub.sFGH",	"mul.sFGH",	"div.sFGH",
@@ -233,6 +238,208 @@ local map_pri = {
   false,	"sdc1HSO",	"sdc2TSO",	"sdTSO",
   false,	"sdc1HSO",	"sdc2TSO",	"sdTSO",
 }
 }
 
 
+------------------------------------------------------------------------------
+-- Primary and extended opcode maps for MIPS R6
+------------------------------------------------------------------------------
+
+local map_mul_r6 =   { shift = 6, mask = 3, [2] = "mulDST",   [3] = "muhDST" }
+local map_mulu_r6 =  { shift = 6, mask = 3, [2] = "muluDST",  [3] = "muhuDST" }
+local map_div_r6 =   { shift = 6, mask = 3, [2] = "divDST",   [3] = "modDST" }
+local map_divu_r6 =  { shift = 6, mask = 3, [2] = "divuDST",  [3] = "moduDST" }
+local map_dmul_r6 =  { shift = 6, mask = 3, [2] = "dmulDST",  [3] = "dmuhDST" }
+local map_dmulu_r6 = { shift = 6, mask = 3, [2] = "dmuluDST", [3] = "dmuhuDST" }
+local map_ddiv_r6 =  { shift = 6, mask = 3, [2] = "ddivDST",  [3] = "dmodDST" }
+local map_ddivu_r6 = { shift = 6, mask = 3, [2] = "ddivuDST", [3] = "dmoduDST" }
+
+local map_special_r6 = {
+  shift = 0, mask = 63,
+  [0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" },
+  false,	map_srl,	"sraDTA",
+  "sllvDTS",	false,		map_srlv,	"sravDTS",
+  "jrS",	"jalrD1S",	false,		false,
+  "syscallY",	"breakY",	false,		"sync",
+  "clzDS",	"cloDS",	"dclzDS",	"dcloDS",
+  "dsllvDST",	"dlsaDSTA",	"dsrlvDST",	"dsravDST",
+  map_mul_r6,	map_mulu_r6,	map_div_r6,	map_divu_r6,
+  map_dmul_r6,	map_dmulu_r6,	map_ddiv_r6,	map_ddivu_r6,
+  "addDST",	"addu|moveDST0", "subDST",	"subu|neguDS0T",
+  "andDST",	"or|moveDST0",	"xorDST",	"nor|notDST0",
+  false,	false,		"sltDST",	"sltuDST",
+  "daddDST",	"dadduDST",	"dsubDST",	"dsubuDST",
+  "tgeSTZ",	"tgeuSTZ",	"tltSTZ",	"tltuSTZ",
+  "teqSTZ",	"seleqzDST",	"tneSTZ",	"selnezDST",
+  "dsllDTA",	false,		"dsrlDTA",	"dsraDTA",
+  "dsll32DTA",	false,		"dsrl32DTA",	"dsra32DTA",
+}
+
+local map_bshfl_r6 = {
+  shift = 9, mask = 3,
+  [1] = "alignDSTa",
+  _ = {
+    shift = 6, mask = 31,
+    [0] = "bitswapDT",
+    [2] = "wsbhDT",
+    [16] = "sebDT",
+    [24] = "sehDT",
+  }
+}
+
+local map_dbshfl_r6 = {
+  shift = 9, mask = 3,
+  [1] = "dalignDSTa",
+  _ = {
+    shift = 6, mask = 31,
+    [0] = "dbitswapDT",
+    [2] = "dsbhDT",
+    [5] = "dshdDT",
+  }
+}
+
+local map_special3_r6 = {
+  shift = 0, mask = 63,
+  [0]  = "extTSAK", [1]  = "dextmTSAP", [3]  = "dextTSAK",
+  [4]  = "insTSAL", [6]  = "dinsuTSEQ", [7]  = "dinsTSAL",
+  [32] = map_bshfl_r6, [36] = map_dbshfl_r6,  [59] = "rdhwrTD",
+}
+
+local map_regimm_r6 = {
+  shift = 16, mask = 31,
+  [0] = "bltzSB", [1] = "bgezSB",
+  [6] = "dahiSI", [30] = "datiSI",
+  [23] = "sigrieI", [31] = "synciSO",
+}
+
+local map_pcrel_r6 = {
+  shift = 19, mask = 3,
+  [0] = "addiupcS2", "lwpcS2", "lwupcS2", {
+    shift = 18, mask = 1,
+    [0] = "ldpcS3", { shift = 16, mask = 3, [2] = "auipcSI", [3] = "aluipcSI" }
+  }
+}
+
+local map_cop1s_r6 = {
+  shift = 0, mask = 63,
+  [0] = "add.sFGH",	"sub.sFGH",	"mul.sFGH",	"div.sFGH",
+  "sqrt.sFG",		"abs.sFG",	"mov.sFG",	"neg.sFG",
+  "round.l.sFG",	"trunc.l.sFG",	"ceil.l.sFG",	"floor.l.sFG",
+  "round.w.sFG",	"trunc.w.sFG",	"ceil.w.sFG",	"floor.w.sFG",
+  "sel.sFGH",		false,		false,		false,
+  "seleqz.sFGH",	"recip.sFG",	"rsqrt.sFG",	"selnez.sFGH",
+  "maddf.sFGH",		"msubf.sFGH",	"rint.sFG",	"class.sFG",
+  "min.sFGH",		"mina.sFGH",	"max.sFGH",	"maxa.sFGH",
+  false,		"cvt.d.sFG",	false,		false,
+  "cvt.w.sFG",		"cvt.l.sFG",
+}
+
+local map_cop1d_r6 = {
+  shift = 0, mask = 63,
+  [0] = "add.dFGH",	"sub.dFGH",	"mul.dFGH",	"div.dFGH",
+  "sqrt.dFG",		"abs.dFG",	"mov.dFG",	"neg.dFG",
+  "round.l.dFG",	"trunc.l.dFG",	"ceil.l.dFG",	"floor.l.dFG",
+  "round.w.dFG",	"trunc.w.dFG",	"ceil.w.dFG",	"floor.w.dFG",
+  "sel.dFGH",		false,		false,		false,
+  "seleqz.dFGH",	"recip.dFG",	"rsqrt.dFG",	"selnez.dFGH",
+  "maddf.dFGH",		"msubf.dFGH",	"rint.dFG",	"class.dFG",
+  "min.dFGH",		"mina.dFGH",	"max.dFGH",	"maxa.dFGH",
+  "cvt.s.dFG",		false,		false,		false,
+  "cvt.w.dFG",		"cvt.l.dFG",
+}
+
+local map_cop1w_r6 = {
+  shift = 0, mask = 63,
+  [0] = "cmp.af.sFGH",	"cmp.un.sFGH",	"cmp.eq.sFGH",	"cmp.ueq.sFGH",
+  "cmp.lt.sFGH",	"cmp.ult.sFGH",	"cmp.le.sFGH",	"cmp.ule.sFGH",
+  "cmp.saf.sFGH",	"cmp.sun.sFGH",	"cmp.seq.sFGH",	"cmp.sueq.sFGH",
+  "cmp.slt.sFGH",	"cmp.sult.sFGH",	"cmp.sle.sFGH",	"cmp.sule.sFGH",
+  false,		"cmp.or.sFGH",	"cmp.une.sFGH",	"cmp.ne.sFGH",
+  false,		false,		false,		false,
+  false,		"cmp.sor.sFGH",	"cmp.sune.sFGH",	"cmp.sne.sFGH",
+  false,		false,		false,		false,
+  "cvt.s.wFG", "cvt.d.wFG",
+}
+
+local map_cop1l_r6 = {
+  shift = 0, mask = 63,
+  [0] = "cmp.af.dFGH",	"cmp.un.dFGH",	"cmp.eq.dFGH",	"cmp.ueq.dFGH",
+  "cmp.lt.dFGH",	"cmp.ult.dFGH",	"cmp.le.dFGH",	"cmp.ule.dFGH",
+  "cmp.saf.dFGH",	"cmp.sun.dFGH",	"cmp.seq.dFGH",	"cmp.sueq.dFGH",
+  "cmp.slt.dFGH",	"cmp.sult.dFGH",	"cmp.sle.dFGH",	"cmp.sule.dFGH",
+  false,		"cmp.or.dFGH",	"cmp.une.dFGH",	"cmp.ne.dFGH",
+  false,		false,		false,		false,
+  false,		"cmp.sor.dFGH",	"cmp.sune.dFGH",	"cmp.sne.dFGH",
+  false,		false,		false,		false,
+  "cvt.s.lFG", "cvt.d.lFG",
+}
+
+local map_cop1_r6 = {
+  shift = 21, mask = 31,
+  [0] = "mfc1TG", "dmfc1TG",	"cfc1TG",	"mfhc1TG",
+  "mtc1TG",	"dmtc1TG",	"ctc1TG",	"mthc1TG",
+  false,	"bc1eqzHB",	false,		false,
+  false,	"bc1nezHB",	false,		false,
+  map_cop1s_r6,	map_cop1d_r6,	false,		false,
+  map_cop1w_r6,	map_cop1l_r6,
+}
+
+local function maprs_popTS(rs, rt)
+  if rt == 0 then return 0 elseif rs == 0 then return 1
+  elseif rs == rt then return 2 else return 3 end
+end
+
+local map_pop06_r6 = {
+  maprs = maprs_popTS, [0] = "blezSB", "blezalcTB", "bgezalcTB", "bgeucSTB"
+}
+local map_pop07_r6 = {
+  maprs = maprs_popTS, [0] = "bgtzSB", "bgtzalcTB", "bltzalcTB", "bltucSTB"
+}
+local map_pop26_r6 = {
+  maprs = maprs_popTS, "blezcTB", "bgezcTB", "bgecSTB"
+}
+local map_pop27_r6 = {
+  maprs = maprs_popTS, "bgtzcTB", "bltzcTB", "bltcSTB"
+}
+
+local function maprs_popS(rs, rt)
+  if rs == 0 then return 0 else return 1 end
+end
+
+local map_pop66_r6 = {
+  maprs = maprs_popS, [0] = "jicTI", "beqzcSb"
+}
+local map_pop76_r6 = {
+  maprs = maprs_popS, [0] = "jialcTI", "bnezcSb"
+}
+
+local function maprs_popST(rs, rt)
+  if rs >= rt then return 0 elseif rs == 0 then return 1 else return 2 end
+end
+
+local map_pop10_r6 = {
+  maprs = maprs_popST, [0] = "bovcSTB", "beqzalcTB", "beqcSTB"
+}
+local map_pop30_r6 = {
+  maprs = maprs_popST, [0] = "bnvcSTB", "bnezalcTB", "bnecSTB"
+}
+
+local map_pri_r6 = {
+  [0] = map_special_r6,	map_regimm_r6,	"jJ",	"jalJ",
+  "beq|beqz|bST00B",	"bne|bnezST0B",		map_pop06_r6,	map_pop07_r6,
+  map_pop10_r6,	"addiu|liTS0I",	"sltiTSI",	"sltiuTSI",
+  "andiTSU",	"ori|liTS0U",	"xoriTSU",	"aui|luiTS0U",
+  map_cop0,	map_cop1_r6,	false,		false,
+  false,	false,		map_pop26_r6,	map_pop27_r6,
+  map_pop30_r6,	"daddiuTSI",	false,		false,
+  false,	"dauiTSI",	false,		map_special3_r6,
+  "lbTSO",	"lhTSO",	false,		"lwTSO",
+  "lbuTSO",	"lhuTSO",	false,		false,
+  "sbTSO",	"shTSO",	false,		"swTSO",
+  false,	false,		false,		false,
+  false,	"lwc1HSO",	"bc#",		false,
+  false,	"ldc1HSO",	map_pop66_r6,	"ldTSO",
+  false,	"swc1HSO",	"balc#",	map_pcrel_r6,
+  false,	"sdc1HSO",	map_pop76_r6,	"sdTSO",
+}
+
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
 local map_gpr = {
 local map_gpr = {
@@ -287,10 +494,14 @@ local function disass_ins(ctx)
   ctx.op = op
   ctx.op = op
   ctx.rel = nil
   ctx.rel = nil
 
 
-  local opat = map_pri[rshift(op, 26)]
+  local opat = ctx.map_pri[rshift(op, 26)]
   while type(opat) ~= "string" do
   while type(opat) ~= "string" do
     if not opat then return unknown(ctx) end
     if not opat then return unknown(ctx) end
-    opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._
+    if opat.maprs then
+      opat = opat[opat.maprs(band(rshift(op,21),31), band(rshift(op,16),31))]
+    else
+      opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._
+    end
   end
   end
   local name, pat = match(opat, "^([a-z0-9_.]*)(.*)")
   local name, pat = match(opat, "^([a-z0-9_.]*)(.*)")
   local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)")
   local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)")
@@ -314,6 +525,8 @@ local function disass_ins(ctx)
       x = "f"..band(rshift(op, 21), 31)
       x = "f"..band(rshift(op, 21), 31)
     elseif p == "A" then
     elseif p == "A" then
       x = band(rshift(op, 6), 31)
       x = band(rshift(op, 6), 31)
+    elseif p == "a" then
+      x = band(rshift(op, 6), 7)
     elseif p == "E" then
     elseif p == "E" then
       x = band(rshift(op, 6), 31) + 32
       x = band(rshift(op, 6), 31) + 32
     elseif p == "M" then
     elseif p == "M" then
@@ -333,6 +546,10 @@ local function disass_ins(ctx)
       x = band(rshift(op, 11), 31) - last + 33
       x = band(rshift(op, 11), 31) - last + 33
     elseif p == "I" then
     elseif p == "I" then
       x = arshift(lshift(op, 16), 16)
       x = arshift(lshift(op, 16), 16)
+    elseif p == "2" then
+      x = arshift(lshift(op, 13), 11)
+    elseif p == "3" then
+      x = arshift(lshift(op, 14), 11)
     elseif p == "U" then
     elseif p == "U" then
       x = band(op, 0xffff)
       x = band(op, 0xffff)
     elseif p == "O" then
     elseif p == "O" then
@@ -342,7 +559,15 @@ local function disass_ins(ctx)
       local index = map_gpr[band(rshift(op, 16), 31)]
       local index = map_gpr[band(rshift(op, 16), 31)]
       operands[#operands] = format("%s(%s)", index, last)
       operands[#operands] = format("%s(%s)", index, last)
     elseif p == "B" then
     elseif p == "B" then
-      x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 16)*4 + 4
+      x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 14) + 4
+      ctx.rel = x
+      x = format("0x%08x", x)
+    elseif p == "b" then
+      x = ctx.addr + ctx.pos + arshift(lshift(op, 11), 9) + 4
+      ctx.rel = x
+      x = format("0x%08x", x)
+    elseif p == "#" then
+      x = ctx.addr + ctx.pos + arshift(lshift(op, 6), 4) + 4
       ctx.rel = x
       ctx.rel = x
       x = format("0x%08x", x)
       x = format("0x%08x", x)
     elseif p == "J" then
     elseif p == "J" then
@@ -408,6 +633,7 @@ local function create(code, addr, out)
   ctx.disass = disass_block
   ctx.disass = disass_block
   ctx.hexdump = 8
   ctx.hexdump = 8
   ctx.get = get_be
   ctx.get = get_be
+  ctx.map_pri = map_pri
   return ctx
   return ctx
 end
 end
 
 
@@ -417,6 +643,19 @@ local function create_el(code, addr, out)
   return ctx
   return ctx
 end
 end
 
 
+local function create_r6(code, addr, out)
+  local ctx = create(code, addr, out)
+  ctx.map_pri = map_pri_r6
+  return ctx
+end
+
+local function create_r6_el(code, addr, out)
+  local ctx = create(code, addr, out)
+  ctx.get = get_le
+  ctx.map_pri = map_pri_r6
+  return ctx
+end
+
 -- Simple API: disassemble code (a string) at address and output via out.
 -- Simple API: disassemble code (a string) at address and output via out.
 local function disass(code, addr, out)
 local function disass(code, addr, out)
   create(code, addr, out):disass()
   create(code, addr, out):disass()
@@ -426,6 +665,14 @@ local function disass_el(code, addr, out)
   create_el(code, addr, out):disass()
   create_el(code, addr, out):disass()
 end
 end
 
 
+local function disass_r6(code, addr, out)
+  create_r6(code, addr, out):disass()
+end
+
+local function disass_r6_el(code, addr, out)
+  create_r6_el(code, addr, out):disass()
+end
+
 -- Return register name for RID.
 -- Return register name for RID.
 local function regname(r)
 local function regname(r)
   if r < 32 then return map_gpr[r] end
   if r < 32 then return map_gpr[r] end
@@ -436,8 +683,12 @@ end
 return {
 return {
   create = create,
   create = create,
   create_el = create_el,
   create_el = create_el,
+  create_r6 = create_r6,
+  create_r6_el = create_r6_el,
   disass = disass,
   disass = disass,
   disass_el = disass_el,
   disass_el = disass_el,
+  disass_r6 = disass_r6,
+  disass_r6_el = disass_r6_el,
   regname = regname
   regname = regname
 }
 }
 
 

+ 1 - 1
libs/LuaJIT/src/jit/dis_mips64.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT MIPS64 disassembler wrapper module.
 -- LuaJIT MIPS64 disassembler wrapper module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- This module just exports the big-endian functions from the
 -- This module just exports the big-endian functions from the

+ 1 - 1
libs/LuaJIT/src/jit/dis_mips64el.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT MIPS64EL disassembler wrapper module.
 -- LuaJIT MIPS64EL disassembler wrapper module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- This module just exports the little-endian functions from the
 -- This module just exports the little-endian functions from the

+ 17 - 0
libs/LuaJIT/src/jit/dis_mips64r6.lua

@@ -0,0 +1,17 @@
+----------------------------------------------------------------------------
+-- LuaJIT MIPS64R6 disassembler wrapper module.
+--
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Released under the MIT license. See Copyright Notice in luajit.h
+----------------------------------------------------------------------------
+-- This module just exports the r6 big-endian functions from the
+-- MIPS disassembler module. All the interesting stuff is there.
+------------------------------------------------------------------------------
+
+local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
+return {
+  create = dis_mips.create_r6,
+  disass = dis_mips.disass_r6,
+  regname = dis_mips.regname
+}
+

+ 17 - 0
libs/LuaJIT/src/jit/dis_mips64r6el.lua

@@ -0,0 +1,17 @@
+----------------------------------------------------------------------------
+-- LuaJIT MIPS64R6EL disassembler wrapper module.
+--
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Released under the MIT license. See Copyright Notice in luajit.h
+----------------------------------------------------------------------------
+-- This module just exports the r6 little-endian functions from the
+-- MIPS disassembler module. All the interesting stuff is there.
+------------------------------------------------------------------------------
+
+local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
+return {
+  create = dis_mips.create_r6_el,
+  disass = dis_mips.disass_r6_el,
+  regname = dis_mips.regname
+}
+

+ 1 - 1
libs/LuaJIT/src/jit/dis_mipsel.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT MIPSEL disassembler wrapper module.
 -- LuaJIT MIPSEL disassembler wrapper module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- This module just exports the little-endian functions from the
 -- This module just exports the little-endian functions from the

+ 1 - 1
libs/LuaJIT/src/jit/dis_ppc.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT PPC disassembler module.
 -- LuaJIT PPC disassembler module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT/X license. See Copyright Notice in luajit.h
 -- 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.
 -- This is a helper module used by the LuaJIT machine code dumper module.

+ 1 - 1
libs/LuaJIT/src/jit/dis_x64.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT x64 disassembler wrapper module.
 -- LuaJIT x64 disassembler wrapper module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- This module just exports the 64 bit functions from the combined
 -- This module just exports the 64 bit functions from the combined

+ 1 - 1
libs/LuaJIT/src/jit/dis_x86.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT x86/x64 disassembler module.
 -- LuaJIT x86/x64 disassembler module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- This is a helper module used by the LuaJIT machine code dumper module.
 -- This is a helper module used by the LuaJIT machine code dumper module.

+ 5 - 3
libs/LuaJIT/src/jit/dump.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT compiler dump module.
 -- LuaJIT compiler dump module.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 --
 --
@@ -315,7 +315,9 @@ local function formatk(tr, idx, sn)
   local tn = type(k)
   local tn = type(k)
   local s
   local s
   if tn == "number" then
   if tn == "number" then
-    if band(sn or 0, 0x30000) ~= 0 then
+    if t < 12 then
+      s = k == 0 and "NULL" or format("[0x%08x]", k)
+    elseif band(sn or 0, 0x30000) ~= 0 then
       s = band(sn, 0x20000) ~= 0 and "contpc" or "ftsz"
       s = band(sn, 0x20000) ~= 0 and "contpc" or "ftsz"
     elseif k == 2^52+2^51 then
     elseif k == 2^52+2^51 then
       s = "bias"
       s = "bias"
@@ -612,7 +614,7 @@ local function dump_texit(tr, ex, ngpr, nfpr, ...)
   out:write("---- TRACE ", tr, " exit ", ex, "\n")
   out:write("---- TRACE ", tr, " exit ", ex, "\n")
   if dumpmode.X then
   if dumpmode.X then
     local regs = {...}
     local regs = {...}
-    if jit.arch == "x64" then
+    if jit.arch:sub(-2) == "64" then
       for i=1,ngpr do
       for i=1,ngpr do
 	out:write(format(" %016x", regs[i]))
 	out:write(format(" %016x", regs[i]))
 	if i % 4 == 0 then out:write("\n") end
 	if i % 4 == 0 then out:write("\n") end

+ 1 - 1
libs/LuaJIT/src/jit/p.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT profiler.
 -- LuaJIT profiler.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 --
 --

+ 1 - 1
libs/LuaJIT/src/jit/v.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- Verbose mode of the LuaJIT compiler.
 -- Verbose mode of the LuaJIT compiler.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 --
 --

+ 1 - 1
libs/LuaJIT/src/jit/zone.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT profiler zones.
 -- LuaJIT profiler zones.
 --
 --
--- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
 -- Released under the MIT license. See Copyright Notice in luajit.h
 -- Released under the MIT license. See Copyright Notice in luajit.h
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 --
 --

+ 3 - 7
libs/LuaJIT/src/lib_aux.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Auxiliary library for the Lua/C API.
 ** Auxiliary library for the Lua/C API.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** Major parts taken verbatim or adapted from the Lua interpreter.
 ** Major parts taken verbatim or adapted from the Lua interpreter.
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
@@ -345,17 +345,13 @@ LUALIB_API lua_State *luaL_newstate(void)
 
 
 #else
 #else
 
 
-#include "lj_alloc.h"
-
 LUALIB_API lua_State *luaL_newstate(void)
 LUALIB_API lua_State *luaL_newstate(void)
 {
 {
   lua_State *L;
   lua_State *L;
-  void *ud = lj_alloc_create();
-  if (ud == NULL) return NULL;
 #if LJ_64 && !LJ_GC64
 #if LJ_64 && !LJ_GC64
-  L = lj_state_newstate(lj_alloc_f, ud);
+  L = lj_state_newstate(LJ_ALLOCF_INTERNAL, NULL);
 #else
 #else
-  L = lua_newstate(lj_alloc_f, ud);
+  L = lua_newstate(LJ_ALLOCF_INTERNAL, NULL);
 #endif
 #endif
   if (L) G(L)->panic = panic;
   if (L) G(L)->panic = panic;
   return L;
   return L;

+ 8 - 6
libs/LuaJIT/src/lib_base.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Base and coroutine library.
 ** Base and coroutine library.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
 ** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
@@ -224,9 +224,11 @@ LJLIB_CF(unpack)
   int32_t n, i = lj_lib_optint(L, 2, 1);
   int32_t n, i = lj_lib_optint(L, 2, 1);
   int32_t e = (L->base+3-1 < L->top && !tvisnil(L->base+3-1)) ?
   int32_t e = (L->base+3-1 < L->top && !tvisnil(L->base+3-1)) ?
 	      lj_lib_checkint(L, 3) : (int32_t)lj_tab_len(t);
 	      lj_lib_checkint(L, 3) : (int32_t)lj_tab_len(t);
+  uint32_t nu;
   if (i > e) return 0;
   if (i > e) return 0;
-  n = e - i + 1;
-  if (n <= 0 || !lua_checkstack(L, n))
+  nu = (uint32_t)e - (uint32_t)i;
+  n = (int32_t)(nu+1);
+  if (nu >= LUAI_MAXCSTACK || !lua_checkstack(L, n))
     lj_err_caller(L, LJ_ERR_UNPACK);
     lj_err_caller(L, LJ_ERR_UNPACK);
   do {
   do {
     cTValue *tv = lj_tab_getint(t, i);
     cTValue *tv = lj_tab_getint(t, i);
@@ -299,7 +301,7 @@ LJLIB_ASM(tonumber)		LJLIB_REC(.)
 	while (lj_char_isspace((unsigned char)(*ep))) ep++;
 	while (lj_char_isspace((unsigned char)(*ep))) ep++;
 	if (*ep == '\0') {
 	if (*ep == '\0') {
 	  if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u+neg)) {
 	  if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u+neg)) {
-	    if (neg) ul = -ul;
+	    if (neg) ul = (unsigned long)-(long)ul;
 	    setintV(L->base-1-LJ_FR2, (int32_t)ul);
 	    setintV(L->base-1-LJ_FR2, (int32_t)ul);
 	  } else {
 	  } else {
 	    lua_Number n = (lua_Number)ul;
 	    lua_Number n = (lua_Number)ul;
@@ -502,8 +504,8 @@ LJLIB_CF(print)
     lua_gettable(L, LUA_GLOBALSINDEX);
     lua_gettable(L, LUA_GLOBALSINDEX);
     tv = L->top-1;
     tv = L->top-1;
   }
   }
-  shortcut = (tvisfunc(tv) && funcV(tv)->c.ffid == FF_tostring)
-              && !gcrefu(basemt_it(G(L), LJ_TNUMX));
+  shortcut = (tvisfunc(tv) && funcV(tv)->c.ffid == FF_tostring) &&
+	     !gcrefu(basemt_it(G(L), LJ_TNUMX));
   for (i = 0; i < nargs; i++) {
   for (i = 0; i < nargs; i++) {
     cTValue *o = &L->base[i];
     cTValue *o = &L->base[i];
     const char *str;
     const char *str;

+ 1 - 1
libs/LuaJIT/src/lib_bit.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Bit manipulation library.
 ** Bit manipulation library.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lib_bit_c
 #define lib_bit_c

+ 9 - 8
libs/LuaJIT/src/lib_debug.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Debug library.
 ** Debug library.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
@@ -231,8 +231,8 @@ LJLIB_CF(debug_upvalueid)
   int32_t n = lj_lib_checkint(L, 2) - 1;
   int32_t n = lj_lib_checkint(L, 2) - 1;
   if ((uint32_t)n >= fn->l.nupvalues)
   if ((uint32_t)n >= fn->l.nupvalues)
     lj_err_arg(L, 2, LJ_ERR_IDXRNG);
     lj_err_arg(L, 2, LJ_ERR_IDXRNG);
-  setlightudV(L->top-1, isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) :
-					(void *)&fn->c.upvalue[n]);
+  lua_pushlightuserdata(L, isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) :
+					   (void *)&fn->c.upvalue[n]);
   return 1;
   return 1;
 }
 }
 
 
@@ -283,13 +283,13 @@ LJLIB_CF(debug_setuservalue)
 
 
 /* ------------------------------------------------------------------------ */
 /* ------------------------------------------------------------------------ */
 
 
-#define KEY_HOOK	((void *)0x3004)
+#define KEY_HOOK	(U64x(80000000,00000000)|'h')
 
 
 static void hookf(lua_State *L, lua_Debug *ar)
 static void hookf(lua_State *L, lua_Debug *ar)
 {
 {
   static const char *const hooknames[] =
   static const char *const hooknames[] =
     {"call", "return", "line", "count", "tail return"};
     {"call", "return", "line", "count", "tail return"};
-  lua_pushlightuserdata(L, KEY_HOOK);
+  (L->top++)->u64 = KEY_HOOK;
   lua_rawget(L, LUA_REGISTRYINDEX);
   lua_rawget(L, LUA_REGISTRYINDEX);
   if (lua_isfunction(L, -1)) {
   if (lua_isfunction(L, -1)) {
     lua_pushstring(L, hooknames[(int)ar->event]);
     lua_pushstring(L, hooknames[(int)ar->event]);
@@ -334,7 +334,7 @@ LJLIB_CF(debug_sethook)
     count = luaL_optint(L, arg+3, 0);
     count = luaL_optint(L, arg+3, 0);
     func = hookf; mask = makemask(smask, count);
     func = hookf; mask = makemask(smask, count);
   }
   }
-  lua_pushlightuserdata(L, KEY_HOOK);
+  (L->top++)->u64 = KEY_HOOK;
   lua_pushvalue(L, arg+1);
   lua_pushvalue(L, arg+1);
   lua_rawset(L, LUA_REGISTRYINDEX);
   lua_rawset(L, LUA_REGISTRYINDEX);
   lua_sethook(L, func, mask, count);
   lua_sethook(L, func, mask, count);
@@ -349,7 +349,7 @@ LJLIB_CF(debug_gethook)
   if (hook != NULL && hook != hookf) {  /* external hook? */
   if (hook != NULL && hook != hookf) {  /* external hook? */
     lua_pushliteral(L, "external hook");
     lua_pushliteral(L, "external hook");
   } else {
   } else {
-    lua_pushlightuserdata(L, KEY_HOOK);
+    (L->top++)->u64 = KEY_HOOK;
     lua_rawget(L, LUA_REGISTRYINDEX);   /* get hook */
     lua_rawget(L, LUA_REGISTRYINDEX);   /* get hook */
   }
   }
   lua_pushstring(L, unmakemask(mask, buff));
   lua_pushstring(L, unmakemask(mask, buff));
@@ -369,7 +369,8 @@ LJLIB_CF(debug_debug)
       return 0;
       return 0;
     if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
     if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
 	lua_pcall(L, 0, 0, 0)) {
 	lua_pcall(L, 0, 0, 0)) {
-      fputs(lua_tostring(L, -1), stderr);
+      const char *s = lua_tostring(L, -1);
+      fputs(s ? s : "(error object is not a string)", stderr);
       fputs("\n", stderr);
       fputs("\n", stderr);
     }
     }
     lua_settop(L, 0);  /* remove eventual returns */
     lua_settop(L, 0);  /* remove eventual returns */

+ 2 - 2
libs/LuaJIT/src/lib_ffi.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** FFI library.
 ** FFI library.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lib_ffi_c
 #define lib_ffi_c
@@ -194,7 +194,7 @@ LJLIB_CF(ffi_meta___eq)		LJLIB_REC(cdata_arith MM_eq)
 
 
 LJLIB_CF(ffi_meta___len)	LJLIB_REC(cdata_arith MM_len)
 LJLIB_CF(ffi_meta___len)	LJLIB_REC(cdata_arith MM_len)
 {
 {
-  return lj_carith_len(L);
+  return ffi_arith(L);
 }
 }
 
 
 LJLIB_CF(ffi_meta___lt)		LJLIB_REC(cdata_arith MM_lt)
 LJLIB_CF(ffi_meta___lt)		LJLIB_REC(cdata_arith MM_lt)

+ 1 - 1
libs/LuaJIT/src/lib_init.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Library initialization.
 ** Library initialization.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** Major parts taken verbatim from the Lua interpreter.
 ** Major parts taken verbatim from the Lua interpreter.
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h

+ 11 - 5
libs/LuaJIT/src/lib_io.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** I/O library.
 ** I/O library.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
 ** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
@@ -101,9 +101,6 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
     stat = pclose(iof->fp);
     stat = pclose(iof->fp);
 #elif LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP
 #elif LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP
     stat = _pclose(iof->fp);
     stat = _pclose(iof->fp);
-#else
-    lua_assert(0);
-    return 0;
 #endif
 #endif
 #if LJ_52
 #if LJ_52
     iof->fp = NULL;
     iof->fp = NULL;
@@ -112,7 +109,8 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
     ok = (stat != -1);
     ok = (stat != -1);
 #endif
 #endif
   } else {
   } else {
-    lua_assert((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF);
+    lj_assertL((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF,
+	       "close of unknown FILE* type");
     setnilV(L->top++);
     setnilV(L->top++);
     lua_pushliteral(L, "cannot close standard file");
     lua_pushliteral(L, "cannot close standard file");
     return 2;
     return 2;
@@ -306,6 +304,14 @@ LJLIB_CF(io_method_flush)		LJLIB_REC(io_flush 0)
   return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL);
   return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL);
 }
 }
 
 
+#if LJ_32 && defined(__ANDROID__) && __ANDROID_API__ < 24
+/* The Android NDK is such an unmatched marvel of engineering. */
+extern int fseeko32(FILE *, long int, int) __asm__("fseeko");
+extern long int ftello32(FILE *) __asm__("ftello");
+#define fseeko(fp, pos, whence)	(fseeko32((fp), (pos), (whence)))
+#define ftello(fp)		(ftello32((fp)))
+#endif
+
 LJLIB_CF(io_method_seek)
 LJLIB_CF(io_method_seek)
 {
 {
   FILE *fp = io_tofile(L)->fp;
   FILE *fp = io_tofile(L)->fp;

+ 40 - 52
libs/LuaJIT/src/lib_jit.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** JIT library.
 ** JIT library.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lib_jit_c
 #define lib_jit_c
@@ -104,8 +104,8 @@ LJLIB_CF(jit_status)
   jit_State *J = L2J(L);
   jit_State *J = L2J(L);
   L->top = L->base;
   L->top = L->base;
   setboolV(L->top++, (J->flags & JIT_F_ON) ? 1 : 0);
   setboolV(L->top++, (J->flags & JIT_F_ON) ? 1 : 0);
-  flagbits_to_strings(L, J->flags, JIT_F_CPU_FIRST, JIT_F_CPUSTRING);
-  flagbits_to_strings(L, J->flags, JIT_F_OPT_FIRST, JIT_F_OPTSTRING);
+  flagbits_to_strings(L, J->flags, JIT_F_CPU, JIT_F_CPUSTRING);
+  flagbits_to_strings(L, J->flags, JIT_F_OPT, JIT_F_OPTSTRING);
   return (int)(L->top - L->base);
   return (int)(L->top - L->base);
 #else
 #else
   setboolV(L->top++, 0);
   setboolV(L->top++, 0);
@@ -113,6 +113,13 @@ LJLIB_CF(jit_status)
 #endif
 #endif
 }
 }
 
 
+LJLIB_CF(jit_security)
+{
+  int idx = lj_lib_checkopt(L, 1, -1, LJ_SECURITY_MODESTRING);
+  setintV(L->top++, ((LJ_SECURITY_MODE >> (2*idx)) & 3));
+  return 1;
+}
+
 LJLIB_CF(jit_attach)
 LJLIB_CF(jit_attach)
 {
 {
 #ifdef LUAJIT_DISABLE_VMEVENT
 #ifdef LUAJIT_DISABLE_VMEVENT
@@ -227,7 +234,7 @@ LJLIB_CF(jit_util_funcbc)
   if (pc < pt->sizebc) {
   if (pc < pt->sizebc) {
     BCIns ins = proto_bc(pt)[pc];
     BCIns ins = proto_bc(pt)[pc];
     BCOp op = bc_op(ins);
     BCOp op = bc_op(ins);
-    lua_assert(op < BC__MAX);
+    lj_assertL(op < BC__MAX, "bad bytecode op %d", op);
     setintV(L->top, ins);
     setintV(L->top, ins);
     setintV(L->top+1, lj_bc_mode[op]);
     setintV(L->top+1, lj_bc_mode[op]);
     L->top += 2;
     L->top += 2;
@@ -471,7 +478,7 @@ static int jitopt_flag(jit_State *J, const char *str)
     str += str[2] == '-' ? 3 : 2;
     str += str[2] == '-' ? 3 : 2;
     set = 0;
     set = 0;
   }
   }
-  for (opt = JIT_F_OPT_FIRST; ; opt <<= 1) {
+  for (opt = JIT_F_OPT; ; opt <<= 1) {
     size_t len = *(const uint8_t *)lst;
     size_t len = *(const uint8_t *)lst;
     if (len == 0)
     if (len == 0)
       break;
       break;
@@ -491,7 +498,7 @@ static int jitopt_param(jit_State *J, const char *str)
   int i;
   int i;
   for (i = 0; i < JIT_P__MAX; i++) {
   for (i = 0; i < JIT_P__MAX; i++) {
     size_t len = *(const uint8_t *)lst;
     size_t len = *(const uint8_t *)lst;
-    lua_assert(len != 0);
+    lj_assertJ(len != 0, "bad JIT_P_STRING");
     if (strncmp(str, lst+1, len) == 0 && str[len] == '=') {
     if (strncmp(str, lst+1, len) == 0 && str[len] == '=') {
       int32_t n = 0;
       int32_t n = 0;
       const char *p = &str[len+1];
       const char *p = &str[len+1];
@@ -540,15 +547,15 @@ LJLIB_CF(jit_opt_start)
 
 
 /* Not loaded by default, use: local profile = require("jit.profile") */
 /* Not loaded by default, use: local profile = require("jit.profile") */
 
 
-static const char KEY_PROFILE_THREAD = 't';
-static const char KEY_PROFILE_FUNC = 'f';
+#define KEY_PROFILE_THREAD	(U64x(80000000,00000000)|'t')
+#define KEY_PROFILE_FUNC	(U64x(80000000,00000000)|'f')
 
 
 static void jit_profile_callback(lua_State *L2, lua_State *L, int samples,
 static void jit_profile_callback(lua_State *L2, lua_State *L, int samples,
 				 int vmstate)
 				 int vmstate)
 {
 {
   TValue key;
   TValue key;
   cTValue *tv;
   cTValue *tv;
-  setlightudV(&key, (void *)&KEY_PROFILE_FUNC);
+  key.u64 = KEY_PROFILE_FUNC;
   tv = lj_tab_get(L, tabV(registry(L)), &key);
   tv = lj_tab_get(L, tabV(registry(L)), &key);
   if (tvisfunc(tv)) {
   if (tvisfunc(tv)) {
     char vmst = (char)vmstate;
     char vmst = (char)vmstate;
@@ -575,9 +582,9 @@ LJLIB_CF(jit_profile_start)
   lua_State *L2 = lua_newthread(L);  /* Thread that runs profiler callback. */
   lua_State *L2 = lua_newthread(L);  /* Thread that runs profiler callback. */
   TValue key;
   TValue key;
   /* Anchor thread and function in registry. */
   /* Anchor thread and function in registry. */
-  setlightudV(&key, (void *)&KEY_PROFILE_THREAD);
+  key.u64 = KEY_PROFILE_THREAD;
   setthreadV(L, lj_tab_set(L, registry, &key), L2);
   setthreadV(L, lj_tab_set(L, registry, &key), L2);
-  setlightudV(&key, (void *)&KEY_PROFILE_FUNC);
+  key.u64 = KEY_PROFILE_FUNC;
   setfuncV(L, lj_tab_set(L, registry, &key), func);
   setfuncV(L, lj_tab_set(L, registry, &key), func);
   lj_gc_anybarriert(L, registry);
   lj_gc_anybarriert(L, registry);
   luaJIT_profile_start(L, mode ? strdata(mode) : "",
   luaJIT_profile_start(L, mode ? strdata(mode) : "",
@@ -592,9 +599,9 @@ LJLIB_CF(jit_profile_stop)
   TValue key;
   TValue key;
   luaJIT_profile_stop(L);
   luaJIT_profile_stop(L);
   registry = tabV(registry(L));
   registry = tabV(registry(L));
-  setlightudV(&key, (void *)&KEY_PROFILE_THREAD);
+  key.u64 = KEY_PROFILE_THREAD;
   setnilV(lj_tab_set(L, registry, &key));
   setnilV(lj_tab_set(L, registry, &key));
-  setlightudV(&key, (void *)&KEY_PROFILE_FUNC);
+  key.u64 = KEY_PROFILE_FUNC;
   setnilV(lj_tab_set(L, registry, &key));
   setnilV(lj_tab_set(L, registry, &key));
   lj_gc_anybarriert(L, registry);
   lj_gc_anybarriert(L, registry);
   return 0;
   return 0;
@@ -640,59 +647,41 @@ JIT_PARAMDEF(JIT_PARAMINIT)
 #undef JIT_PARAMINIT
 #undef JIT_PARAMINIT
   0
   0
 };
 };
-#endif
 
 
 #if LJ_TARGET_ARM && LJ_TARGET_LINUX
 #if LJ_TARGET_ARM && LJ_TARGET_LINUX
 #include <sys/utsname.h>
 #include <sys/utsname.h>
 #endif
 #endif
 
 
-/* Arch-dependent CPU detection. */
-static uint32_t jit_cpudetect(lua_State *L)
+/* Arch-dependent CPU feature detection. */
+static uint32_t jit_cpudetect(void)
 {
 {
   uint32_t flags = 0;
   uint32_t flags = 0;
 #if LJ_TARGET_X86ORX64
 #if LJ_TARGET_X86ORX64
+
   uint32_t vendor[4];
   uint32_t vendor[4];
   uint32_t features[4];
   uint32_t features[4];
   if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
   if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
-#if !LJ_HASJIT
-#define JIT_F_SSE2	2
-#endif
-    flags |= ((features[3] >> 26)&1) * JIT_F_SSE2;
-#if LJ_HASJIT
     flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
     flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
     flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
     flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
-    if (vendor[2] == 0x6c65746e) {  /* Intel. */
-      if ((features[0] & 0x0fff0ff0) == 0x000106c0)  /* Atom. */
-	flags |= JIT_F_LEA_AGU;
-    } else if (vendor[2] == 0x444d4163) {  /* AMD. */
-      uint32_t fam = (features[0] & 0x0ff00f00);
-      if (fam >= 0x00000f00)  /* K8, K10. */
-	flags |= JIT_F_PREFER_IMUL;
-    }
     if (vendor[0] >= 7) {
     if (vendor[0] >= 7) {
       uint32_t xfeatures[4];
       uint32_t xfeatures[4];
       lj_vm_cpuid(7, xfeatures);
       lj_vm_cpuid(7, xfeatures);
       flags |= ((xfeatures[1] >> 8)&1) * JIT_F_BMI2;
       flags |= ((xfeatures[1] >> 8)&1) * JIT_F_BMI2;
     }
     }
-#endif
   }
   }
-  /* Check for required instruction set support on x86 (unnecessary on x64). */
-#if LJ_TARGET_X86
-  if (!(flags & JIT_F_SSE2))
-    luaL_error(L, "CPU with SSE2 required");
-#endif
+  /* Don't bother checking for SSE2 -- the VM will crash before getting here. */
+
 #elif LJ_TARGET_ARM
 #elif LJ_TARGET_ARM
-#if LJ_HASJIT
+
   int ver = LJ_ARCH_VERSION;  /* Compile-time ARM CPU detection. */
   int ver = LJ_ARCH_VERSION;  /* Compile-time ARM CPU detection. */
 #if LJ_TARGET_LINUX
 #if LJ_TARGET_LINUX
   if (ver < 70) {  /* Runtime ARM CPU detection. */
   if (ver < 70) {  /* Runtime ARM CPU detection. */
     struct utsname ut;
     struct utsname ut;
     uname(&ut);
     uname(&ut);
     if (strncmp(ut.machine, "armv", 4) == 0) {
     if (strncmp(ut.machine, "armv", 4) == 0) {
-      if (ut.machine[4] >= '7')
-	ver = 70;
-      else if (ut.machine[4] == '6')
-	ver = 60;
+      if (ut.machine[4] >= '8') ver = 80;
+      else if (ut.machine[4] == '7') ver = 70;
+      else if (ut.machine[4] == '6') ver = 60;
     }
     }
   }
   }
 #endif
 #endif
@@ -700,20 +689,22 @@ static uint32_t jit_cpudetect(lua_State *L)
 	   ver >= 61 ? JIT_F_ARMV6T2_ :
 	   ver >= 61 ? JIT_F_ARMV6T2_ :
 	   ver >= 60 ? JIT_F_ARMV6_ : 0;
 	   ver >= 60 ? JIT_F_ARMV6_ : 0;
   flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2;
   flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2;
-#endif
+
 #elif LJ_TARGET_ARM64
 #elif LJ_TARGET_ARM64
+
   /* No optional CPU features to detect (for now). */
   /* No optional CPU features to detect (for now). */
+
 #elif LJ_TARGET_PPC
 #elif LJ_TARGET_PPC
-#if LJ_HASJIT
+
 #if LJ_ARCH_SQRT
 #if LJ_ARCH_SQRT
   flags |= JIT_F_SQRT;
   flags |= JIT_F_SQRT;
 #endif
 #endif
 #if LJ_ARCH_ROUND
 #if LJ_ARCH_ROUND
   flags |= JIT_F_ROUND;
   flags |= JIT_F_ROUND;
 #endif
 #endif
-#endif
+
 #elif LJ_TARGET_MIPS
 #elif LJ_TARGET_MIPS
-#if LJ_HASJIT
+
   /* Compile-time MIPS CPU detection. */
   /* Compile-time MIPS CPU detection. */
 #if LJ_ARCH_VERSION >= 20
 #if LJ_ARCH_VERSION >= 20
   flags |= JIT_F_MIPSXXR2;
   flags |= JIT_F_MIPSXXR2;
@@ -731,31 +722,28 @@ static uint32_t jit_cpudetect(lua_State *L)
     if (x) flags |= JIT_F_MIPSXXR2;  /* Either 0x80000000 (R2) or 0 (R1). */
     if (x) flags |= JIT_F_MIPSXXR2;  /* Either 0x80000000 (R2) or 0 (R1). */
   }
   }
 #endif
 #endif
-#endif
+
 #else
 #else
 #error "Missing CPU detection for this architecture"
 #error "Missing CPU detection for this architecture"
 #endif
 #endif
-  UNUSED(L);
   return flags;
   return flags;
 }
 }
 
 
 /* Initialize JIT compiler. */
 /* Initialize JIT compiler. */
 static void jit_init(lua_State *L)
 static void jit_init(lua_State *L)
 {
 {
-  uint32_t flags = jit_cpudetect(L);
-#if LJ_HASJIT
   jit_State *J = L2J(L);
   jit_State *J = L2J(L);
-  J->flags = flags | JIT_F_ON | JIT_F_OPT_DEFAULT;
+  J->flags = jit_cpudetect() | JIT_F_ON | JIT_F_OPT_DEFAULT;
   memcpy(J->param, jit_param_default, sizeof(J->param));
   memcpy(J->param, jit_param_default, sizeof(J->param));
   lj_dispatch_update(G(L));
   lj_dispatch_update(G(L));
-#else
-  UNUSED(flags);
-#endif
 }
 }
+#endif
 
 
 LUALIB_API int luaopen_jit(lua_State *L)
 LUALIB_API int luaopen_jit(lua_State *L)
 {
 {
+#if LJ_HASJIT
   jit_init(L);
   jit_init(L);
+#endif
   lua_pushliteral(L, LJ_OS_NAME);
   lua_pushliteral(L, LJ_OS_NAME);
   lua_pushliteral(L, LJ_ARCH_NAME);
   lua_pushliteral(L, LJ_ARCH_NAME);
   lua_pushinteger(L, LUAJIT_VERSION_NUM);
   lua_pushinteger(L, LUAJIT_VERSION_NUM);

+ 27 - 52
libs/LuaJIT/src/lib_math.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Math library.
 ** Math library.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #include <math.h>
 #include <math.h>
@@ -15,6 +15,7 @@
 #include "lj_obj.h"
 #include "lj_obj.h"
 #include "lj_lib.h"
 #include "lj_lib.h"
 #include "lj_vm.h"
 #include "lj_vm.h"
+#include "lj_prng.h"
 
 
 /* ------------------------------------------------------------------------ */
 /* ------------------------------------------------------------------------ */
 
 
@@ -33,19 +34,19 @@ LJLIB_ASM(math_sqrt)		LJLIB_REC(math_unary IRFPM_SQRT)
   lj_lib_checknum(L, 1);
   lj_lib_checknum(L, 1);
   return FFH_RETRY;
   return FFH_RETRY;
 }
 }
-LJLIB_ASM_(math_log10)		LJLIB_REC(math_unary IRFPM_LOG10)
-LJLIB_ASM_(math_exp)		LJLIB_REC(math_unary IRFPM_EXP)
-LJLIB_ASM_(math_sin)		LJLIB_REC(math_unary IRFPM_SIN)
-LJLIB_ASM_(math_cos)		LJLIB_REC(math_unary IRFPM_COS)
-LJLIB_ASM_(math_tan)		LJLIB_REC(math_unary IRFPM_TAN)
-LJLIB_ASM_(math_asin)		LJLIB_REC(math_atrig FF_math_asin)
-LJLIB_ASM_(math_acos)		LJLIB_REC(math_atrig FF_math_acos)
-LJLIB_ASM_(math_atan)		LJLIB_REC(math_atrig FF_math_atan)
-LJLIB_ASM_(math_sinh)		LJLIB_REC(math_htrig IRCALL_sinh)
-LJLIB_ASM_(math_cosh)		LJLIB_REC(math_htrig IRCALL_cosh)
-LJLIB_ASM_(math_tanh)		LJLIB_REC(math_htrig IRCALL_tanh)
+LJLIB_ASM_(math_log10)		LJLIB_REC(math_call IRCALL_log10)
+LJLIB_ASM_(math_exp)		LJLIB_REC(math_call IRCALL_exp)
+LJLIB_ASM_(math_sin)		LJLIB_REC(math_call IRCALL_sin)
+LJLIB_ASM_(math_cos)		LJLIB_REC(math_call IRCALL_cos)
+LJLIB_ASM_(math_tan)		LJLIB_REC(math_call IRCALL_tan)
+LJLIB_ASM_(math_asin)		LJLIB_REC(math_call IRCALL_asin)
+LJLIB_ASM_(math_acos)		LJLIB_REC(math_call IRCALL_acos)
+LJLIB_ASM_(math_atan)		LJLIB_REC(math_call IRCALL_atan)
+LJLIB_ASM_(math_sinh)		LJLIB_REC(math_call IRCALL_sinh)
+LJLIB_ASM_(math_cosh)		LJLIB_REC(math_call IRCALL_cosh)
+LJLIB_ASM_(math_tanh)		LJLIB_REC(math_call IRCALL_tanh)
 LJLIB_ASM_(math_frexp)
 LJLIB_ASM_(math_frexp)
-LJLIB_ASM_(math_modf)		LJLIB_REC(.)
+LJLIB_ASM_(math_modf)
 
 
 LJLIB_ASM(math_log)		LJLIB_REC(math_log)
 LJLIB_ASM(math_log)		LJLIB_REC(math_log)
 {
 {
@@ -105,34 +106,11 @@ LJLIB_PUSH(1e310) LJLIB_SET(huge)
 ** Full-period ME-CF generator with L=64, J=4, k=223, N1=49.
 ** Full-period ME-CF generator with L=64, J=4, k=223, N1=49.
 */
 */
 
 
-/* PRNG state. */
-struct RandomState {
-  uint64_t gen[4];	/* State of the 4 LFSR generators. */
-  int valid;		/* State is valid. */
-};
-
 /* Union needed for bit-pattern conversion between uint64_t and double. */
 /* Union needed for bit-pattern conversion between uint64_t and double. */
 typedef union { uint64_t u64; double d; } U64double;
 typedef union { uint64_t u64; double d; } U64double;
 
 
-/* Update generator i and compute a running xor of all states. */
-#define TW223_GEN(i, k, q, s) \
-  z = rs->gen[i]; \
-  z = (((z<<q)^z) >> (k-s)) ^ ((z&((uint64_t)(int64_t)-1 << (64-k)))<<s); \
-  r ^= z; rs->gen[i] = z;
-
-/* PRNG step function. Returns a double in the range 1.0 <= d < 2.0. */
-LJ_NOINLINE uint64_t LJ_FASTCALL lj_math_random_step(RandomState *rs)
-{
-  uint64_t z, r = 0;
-  TW223_GEN(0, 63, 31, 18)
-  TW223_GEN(1, 58, 19, 28)
-  TW223_GEN(2, 55, 24,  7)
-  TW223_GEN(3, 47, 21,  8)
-  return (r & U64x(000fffff,ffffffff)) | U64x(3ff00000,00000000);
-}
-
-/* PRNG initialization function. */
-static void random_init(RandomState *rs, double d)
+/* PRNG seeding function. */
+static void random_seed(PRNGState *rs, double d)
 {
 {
   uint32_t r = 0x11090601;  /* 64-k[i] as four 8 bit constants. */
   uint32_t r = 0x11090601;  /* 64-k[i] as four 8 bit constants. */
   int i;
   int i;
@@ -141,24 +119,22 @@ static void random_init(RandomState *rs, double d)
     uint32_t m = 1u << (r&255);
     uint32_t m = 1u << (r&255);
     r >>= 8;
     r >>= 8;
     u.d = d = d * 3.14159265358979323846 + 2.7182818284590452354;
     u.d = d = d * 3.14159265358979323846 + 2.7182818284590452354;
-    if (u.u64 < m) u.u64 += m;  /* Ensure k[i] MSB of gen[i] are non-zero. */
-    rs->gen[i] = u.u64;
+    if (u.u64 < m) u.u64 += m;  /* Ensure k[i] MSB of u[i] are non-zero. */
+    rs->u[i] = u.u64;
   }
   }
-  rs->valid = 1;
   for (i = 0; i < 10; i++)
   for (i = 0; i < 10; i++)
-    lj_math_random_step(rs);
+    (void)lj_prng_u64(rs);
 }
 }
 
 
 /* PRNG extract function. */
 /* PRNG extract function. */
-LJLIB_PUSH(top-2)  /* Upvalue holds userdata with RandomState. */
+LJLIB_PUSH(top-2)  /* Upvalue holds userdata with PRNGState. */
 LJLIB_CF(math_random)		LJLIB_REC(.)
 LJLIB_CF(math_random)		LJLIB_REC(.)
 {
 {
   int n = (int)(L->top - L->base);
   int n = (int)(L->top - L->base);
-  RandomState *rs = (RandomState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
+  PRNGState *rs = (PRNGState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
   U64double u;
   U64double u;
   double d;
   double d;
-  if (LJ_UNLIKELY(!rs->valid)) random_init(rs, 0.0);
-  u.u64 = lj_math_random_step(rs);
+  u.u64 = lj_prng_u64d(rs);
   d = u.d - 1.0;
   d = u.d - 1.0;
   if (n > 0) {
   if (n > 0) {
 #if LJ_DUALNUM
 #if LJ_DUALNUM
@@ -203,11 +179,11 @@ LJLIB_CF(math_random)		LJLIB_REC(.)
 }
 }
 
 
 /* PRNG seed function. */
 /* PRNG seed function. */
-LJLIB_PUSH(top-2)  /* Upvalue holds userdata with RandomState. */
+LJLIB_PUSH(top-2)  /* Upvalue holds userdata with PRNGState. */
 LJLIB_CF(math_randomseed)
 LJLIB_CF(math_randomseed)
 {
 {
-  RandomState *rs = (RandomState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
-  random_init(rs, lj_lib_checknum(L, 1));
+  PRNGState *rs = (PRNGState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
+  random_seed(rs, lj_lib_checknum(L, 1));
   return 0;
   return 0;
 }
 }
 
 
@@ -217,9 +193,8 @@ LJLIB_CF(math_randomseed)
 
 
 LUALIB_API int luaopen_math(lua_State *L)
 LUALIB_API int luaopen_math(lua_State *L)
 {
 {
-  RandomState *rs;
-  rs = (RandomState *)lua_newuserdata(L, sizeof(RandomState));
-  rs->valid = 0;  /* Use lazy initialization to save some time on startup. */
+  PRNGState *rs = (PRNGState *)lua_newuserdata(L, sizeof(PRNGState));
+  lj_prng_seed_fixed(rs);
   LJ_LIB_REG(L, LUA_MATHLIBNAME, math);
   LJ_LIB_REG(L, LUA_MATHLIBNAME, math);
   return 1;
   return 1;
 }
 }

+ 1 - 1
libs/LuaJIT/src/lib_os.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** OS library.
 ** OS library.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h

+ 13 - 8
libs/LuaJIT/src/lib_package.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Package library.
 ** Package library.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Copyright (C) 1994-2012 Lua.org, PUC-Rio. See Copyright Notice in lua.h
 ** Copyright (C) 1994-2012 Lua.org, PUC-Rio. See Copyright Notice in lua.h
@@ -237,7 +237,12 @@ static const char *mksymname(lua_State *L, const char *modname,
 
 
 static int ll_loadfunc(lua_State *L, const char *path, const char *name, int r)
 static int ll_loadfunc(lua_State *L, const char *path, const char *name, int r)
 {
 {
-  void **reg = ll_register(L, path);
+  void **reg;
+  if (strlen(path) >= 4096) {
+    lua_pushliteral(L, "path too long");
+    return PACKAGE_ERR_LIB;
+  }
+  reg = ll_register(L, path);
   if (*reg == NULL) *reg = ll_load(L, path, (*name == '*'));
   if (*reg == NULL) *reg = ll_load(L, path, (*name == '*'));
   if (*reg == NULL) {
   if (*reg == NULL) {
     return PACKAGE_ERR_LIB;  /* Unable to load library. */
     return PACKAGE_ERR_LIB;  /* Unable to load library. */
@@ -255,7 +260,7 @@ static int ll_loadfunc(lua_State *L, const char *path, const char *name, int r)
       const char *bcdata = ll_bcsym(*reg, mksymname(L, name, SYMPREFIX_BC));
       const char *bcdata = ll_bcsym(*reg, mksymname(L, name, SYMPREFIX_BC));
       lua_pop(L, 1);
       lua_pop(L, 1);
       if (bcdata) {
       if (bcdata) {
-	if (luaL_loadbuffer(L, bcdata, LJ_MAX_BUF, name) != 0)
+	if (luaL_loadbuffer(L, bcdata, ~(size_t)0, name) != 0)
 	  return PACKAGE_ERR_LOAD;
 	  return PACKAGE_ERR_LOAD;
 	return 0;
 	return 0;
       }
       }
@@ -412,7 +417,7 @@ static int lj_cf_package_loader_preload(lua_State *L)
   if (lua_isnil(L, -1)) {  /* Not found? */
   if (lua_isnil(L, -1)) {  /* Not found? */
     const char *bcname = mksymname(L, name, SYMPREFIX_BC);
     const char *bcname = mksymname(L, name, SYMPREFIX_BC);
     const char *bcdata = ll_bcsym(NULL, bcname);
     const char *bcdata = ll_bcsym(NULL, bcname);
-    if (bcdata == NULL || luaL_loadbuffer(L, bcdata, LJ_MAX_BUF, name) != 0)
+    if (bcdata == NULL || luaL_loadbuffer(L, bcdata, ~(size_t)0, name) != 0)
       lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
       lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
   }
   }
   return 1;
   return 1;
@@ -420,7 +425,7 @@ static int lj_cf_package_loader_preload(lua_State *L)
 
 
 /* ------------------------------------------------------------------------ */
 /* ------------------------------------------------------------------------ */
 
 
-#define sentinel	((void *)0x4004)
+#define KEY_SENTINEL	(U64x(80000000,00000000)|'s')
 
 
 static int lj_cf_package_require(lua_State *L)
 static int lj_cf_package_require(lua_State *L)
 {
 {
@@ -430,7 +435,7 @@ static int lj_cf_package_require(lua_State *L)
   lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
   lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
   lua_getfield(L, 2, name);
   lua_getfield(L, 2, name);
   if (lua_toboolean(L, -1)) {  /* is it there? */
   if (lua_toboolean(L, -1)) {  /* is it there? */
-    if (lua_touserdata(L, -1) == sentinel)  /* check loops */
+    if ((L->top-1)->u64 == KEY_SENTINEL)  /* check loops */
       luaL_error(L, "loop or previous error loading module " LUA_QS, name);
       luaL_error(L, "loop or previous error loading module " LUA_QS, name);
     return 1;  /* package is already loaded */
     return 1;  /* package is already loaded */
   }
   }
@@ -453,14 +458,14 @@ static int lj_cf_package_require(lua_State *L)
     else
     else
       lua_pop(L, 1);
       lua_pop(L, 1);
   }
   }
-  lua_pushlightuserdata(L, sentinel);
+  (L->top++)->u64 = KEY_SENTINEL;
   lua_setfield(L, 2, name);  /* _LOADED[name] = sentinel */
   lua_setfield(L, 2, name);  /* _LOADED[name] = sentinel */
   lua_pushstring(L, name);  /* pass name as argument to module */
   lua_pushstring(L, name);  /* pass name as argument to module */
   lua_call(L, 1, 1);  /* run loaded module */
   lua_call(L, 1, 1);  /* run loaded module */
   if (!lua_isnil(L, -1))  /* non-nil return? */
   if (!lua_isnil(L, -1))  /* non-nil return? */
     lua_setfield(L, 2, name);  /* _LOADED[name] = returned value */
     lua_setfield(L, 2, name);  /* _LOADED[name] = returned value */
   lua_getfield(L, 2, name);
   lua_getfield(L, 2, name);
-  if (lua_touserdata(L, -1) == sentinel) {   /* module did not set a value? */
+  if ((L->top-1)->u64 == KEY_SENTINEL) {   /* module did not set a value? */
     lua_pushboolean(L, 1);  /* use true as result */
     lua_pushboolean(L, 1);  /* use true as result */
     lua_pushvalue(L, -1);  /* extra copy to be returned */
     lua_pushvalue(L, -1);  /* extra copy to be returned */
     lua_setfield(L, 2, name);  /* _LOADED[name] = true */
     lua_setfield(L, 2, name);  /* _LOADED[name] = true */

+ 5 - 5
libs/LuaJIT/src/lib_string.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** String library.
 ** String library.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
@@ -136,7 +136,7 @@ LJLIB_CF(string_dump)
 /* ------------------------------------------------------------------------ */
 /* ------------------------------------------------------------------------ */
 
 
 /* macro to `unsign' a character */
 /* macro to `unsign' a character */
-#define uchar(c)        ((unsigned char)(c))
+#define uchar(c)	((unsigned char)(c))
 
 
 #define CAP_UNFINISHED	(-1)
 #define CAP_UNFINISHED	(-1)
 #define CAP_POSITION	(-2)
 #define CAP_POSITION	(-2)
@@ -645,7 +645,7 @@ static GCstr *string_fmt_tostring(lua_State *L, int arg, int retry)
 {
 {
   TValue *o = L->base+arg-1;
   TValue *o = L->base+arg-1;
   cTValue *mo;
   cTValue *mo;
-  lua_assert(o < L->top);  /* Caller already checks for existence. */
+  lj_assertL(o < L->top, "bad usage");  /* Caller already checks for existence. */
   if (LJ_LIKELY(tvisstr(o)))
   if (LJ_LIKELY(tvisstr(o)))
     return strV(o);
     return strV(o);
   if (retry != 2 && !tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
   if (retry != 2 && !tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
@@ -714,10 +714,10 @@ again:
 	lj_strfmt_putfchar(sb, sf, lj_lib_checkint(L, arg));
 	lj_strfmt_putfchar(sb, sf, lj_lib_checkint(L, arg));
 	break;
 	break;
       case STRFMT_PTR:  /* No formatting. */
       case STRFMT_PTR:  /* No formatting. */
-	lj_strfmt_putptr(sb, lj_obj_ptr(L->base+arg-1));
+	lj_strfmt_putptr(sb, lj_obj_ptr(G(L), L->base+arg-1));
 	break;
 	break;
       default:
       default:
-	lua_assert(0);
+	lj_assertL(0, "bad string format type");
 	break;
 	break;
       }
       }
     }
     }

+ 1 - 1
libs/LuaJIT/src/lib_table.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Table library.
 ** Table library.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h

+ 0 - 41
libs/LuaJIT/src/lj.supp

@@ -1,41 +0,0 @@
-# Valgrind suppression file for LuaJIT 2.0.
-{
-   Optimized string compare
-   Memcheck:Addr4
-   fun:lj_str_cmp
-}
-{
-   Optimized string compare
-   Memcheck:Addr1
-   fun:lj_str_cmp
-}
-{
-   Optimized string compare
-   Memcheck:Addr4
-   fun:lj_str_new
-}
-{
-   Optimized string compare
-   Memcheck:Addr1
-   fun:lj_str_new
-}
-{
-   Optimized string compare
-   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
-}

+ 47 - 52
libs/LuaJIT/src/lj_alloc.c

@@ -6,7 +6,7 @@
 **
 **
 **   This is a version (aka dlmalloc) of malloc/free/realloc written by
 **   This is a version (aka dlmalloc) of malloc/free/realloc written by
 **   Doug Lea and released to the public domain, as explained at
 **   Doug Lea and released to the public domain, as explained at
-**   http://creativecommons.org/licenses/publicdomain.
+**   https://creativecommons.org/licenses/publicdomain.
 **
 **
 **   * Version pre-2.8.4 Wed Mar 29 19:46:29 2006    (dl at gee)
 **   * Version pre-2.8.4 Wed Mar 29 19:46:29 2006    (dl at gee)
 **
 **
@@ -16,8 +16,8 @@
 ** If you want to use dlmalloc in another project, you should get
 ** If you want to use dlmalloc in another project, you should get
 ** the original from: ftp://gee.cs.oswego.edu/pub/misc/
 ** the original from: ftp://gee.cs.oswego.edu/pub/misc/
 ** For thread-safe derivatives, take a look at:
 ** For thread-safe derivatives, take a look at:
-** - ptmalloc: http://www.malloc.de/
-** - nedmalloc: http://www.nedprod.com/programs/portable/nedmalloc/
+** - ptmalloc: https://www.malloc.de/
+** - nedmalloc: https://www.nedprod.com/programs/portable/nedmalloc/
 */
 */
 
 
 #define lj_alloc_c
 #define lj_alloc_c
@@ -31,6 +31,7 @@
 #include "lj_def.h"
 #include "lj_def.h"
 #include "lj_arch.h"
 #include "lj_arch.h"
 #include "lj_alloc.h"
 #include "lj_alloc.h"
+#include "lj_prng.h"
 
 
 #ifndef LUAJIT_USE_SYSMALLOC
 #ifndef LUAJIT_USE_SYSMALLOC
 
 
@@ -123,7 +124,7 @@
 
 
 #if LJ_ALLOC_NTAVM
 #if LJ_ALLOC_NTAVM
 /* Undocumented, but hey, that's what we all love so much about Windows. */
 /* Undocumented, but hey, that's what we all love so much about Windows. */
-typedef long (*PNTAVM)(HANDLE handle, void **addr, ULONG zbits,
+typedef long (*PNTAVM)(HANDLE handle, void **addr, ULONG_PTR zbits,
 		       size_t *size, ULONG alloctype, ULONG prot);
 		       size_t *size, ULONG alloctype, ULONG prot);
 static PNTAVM ntavm;
 static PNTAVM ntavm;
 
 
@@ -140,7 +141,7 @@ static void init_mmap(void)
 #define INIT_MMAP()	init_mmap()
 #define INIT_MMAP()	init_mmap()
 
 
 /* Win64 32 bit MMAP via NtAllocateVirtualMemory. */
 /* Win64 32 bit MMAP via NtAllocateVirtualMemory. */
-static void *CALL_MMAP(size_t size)
+static void *mmap_plain(size_t size)
 {
 {
   DWORD olderr = GetLastError();
   DWORD olderr = GetLastError();
   void *ptr = NULL;
   void *ptr = NULL;
@@ -151,7 +152,7 @@ static void *CALL_MMAP(size_t size)
 }
 }
 
 
 /* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
 /* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
-static void *DIRECT_MMAP(size_t size)
+static void *direct_mmap(size_t size)
 {
 {
   DWORD olderr = GetLastError();
   DWORD olderr = GetLastError();
   void *ptr = NULL;
   void *ptr = NULL;
@@ -164,7 +165,7 @@ static void *DIRECT_MMAP(size_t size)
 #else
 #else
 
 
 /* Win32 MMAP via VirtualAlloc */
 /* Win32 MMAP via VirtualAlloc */
-static void *CALL_MMAP(size_t size)
+static void *mmap_plain(size_t size)
 {
 {
   DWORD olderr = GetLastError();
   DWORD olderr = GetLastError();
   void *ptr = LJ_WIN_VALLOC(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
   void *ptr = LJ_WIN_VALLOC(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
@@ -173,7 +174,7 @@ static void *CALL_MMAP(size_t size)
 }
 }
 
 
 /* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
 /* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
-static void *DIRECT_MMAP(size_t size)
+static void *direct_mmap(size_t size)
 {
 {
   DWORD olderr = GetLastError();
   DWORD olderr = GetLastError();
   void *ptr = LJ_WIN_VALLOC(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
   void *ptr = LJ_WIN_VALLOC(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
@@ -184,6 +185,9 @@ static void *DIRECT_MMAP(size_t size)
 
 
 #endif
 #endif
 
 
+#define CALL_MMAP(prng, size)	mmap_plain(size)
+#define DIRECT_MMAP(prng, size)	direct_mmap(size)
+
 /* This function supports releasing coalesed segments */
 /* This function supports releasing coalesed segments */
 static int CALL_MUNMAP(void *ptr, size_t size)
 static int CALL_MUNMAP(void *ptr, size_t size)
 {
 {
@@ -226,30 +230,10 @@ static int CALL_MUNMAP(void *ptr, size_t size)
 
 
 #define LJ_ALLOC_MMAP_PROBE_LOWER	((uintptr_t)0x4000)
 #define LJ_ALLOC_MMAP_PROBE_LOWER	((uintptr_t)0x4000)
 
 
-/* No point in a giant ifdef mess. Just try to open /dev/urandom.
-** It doesn't really matter if this fails, since we get some ASLR bits from
-** every unsuitable allocation, too. And we prefer linear allocation, anyway.
-*/
-#include <fcntl.h>
-#include <unistd.h>
-
-static uintptr_t mmap_probe_seed(void)
-{
-  uintptr_t val;
-  int fd = open("/dev/urandom", O_RDONLY);
-  if (fd != -1) {
-    int ok = ((size_t)read(fd, &val, sizeof(val)) == sizeof(val));
-    (void)close(fd);
-    if (ok) return val;
-  }
-  return 1;  /* Punt. */
-}
-
-static void *mmap_probe(size_t size)
+static void *mmap_probe(PRNGState *rs, size_t size)
 {
 {
   /* Hint for next allocation. Doesn't need to be thread-safe. */
   /* Hint for next allocation. Doesn't need to be thread-safe. */
   static uintptr_t hint_addr = 0;
   static uintptr_t hint_addr = 0;
-  static uintptr_t hint_prng = 0;
   int olderr = errno;
   int olderr = errno;
   int retry;
   int retry;
   for (retry = 0; retry < LJ_ALLOC_MMAP_PROBE_MAX; retry++) {
   for (retry = 0; retry < LJ_ALLOC_MMAP_PROBE_MAX; retry++) {
@@ -281,15 +265,8 @@ static void *mmap_probe(size_t size)
       }
       }
     }
     }
     /* Finally, try pseudo-random probing. */
     /* Finally, try pseudo-random probing. */
-    if (LJ_UNLIKELY(hint_prng == 0)) {
-      hint_prng = mmap_probe_seed();
-    }
-    /* The unsuitable address we got has some ASLR PRNG bits. */
-    hint_addr ^= addr & ~((uintptr_t)(LJ_PAGESIZE-1));
-    do {  /* The PRNG itself is very weak, but see above. */
-      hint_prng = hint_prng * 1103515245 + 12345;
-      hint_addr ^= hint_prng * (uintptr_t)LJ_PAGESIZE;
-      hint_addr &= (((uintptr_t)1 << LJ_ALLOC_MBITS)-1);
+    do {
+      hint_addr = lj_prng_u64(rs) & (((uintptr_t)1<<LJ_ALLOC_MBITS)-LJ_PAGESIZE);
     } while (hint_addr < LJ_ALLOC_MMAP_PROBE_LOWER);
     } while (hint_addr < LJ_ALLOC_MMAP_PROBE_LOWER);
   }
   }
   errno = olderr;
   errno = olderr;
@@ -300,18 +277,22 @@ static void *mmap_probe(size_t size)
 
 
 #if LJ_ALLOC_MMAP32
 #if LJ_ALLOC_MMAP32
 
 
-#if defined(__sun__)
+#if LJ_TARGET_SOLARIS
 #define LJ_ALLOC_MMAP32_START	((uintptr_t)0x1000)
 #define LJ_ALLOC_MMAP32_START	((uintptr_t)0x1000)
 #else
 #else
 #define LJ_ALLOC_MMAP32_START	((uintptr_t)0)
 #define LJ_ALLOC_MMAP32_START	((uintptr_t)0)
 #endif
 #endif
 
 
+#if LJ_ALLOC_MMAP_PROBE
+static void *mmap_map32(PRNGState *rs, size_t size)
+#else
 static void *mmap_map32(size_t size)
 static void *mmap_map32(size_t size)
+#endif
 {
 {
 #if LJ_ALLOC_MMAP_PROBE
 #if LJ_ALLOC_MMAP_PROBE
   static int fallback = 0;
   static int fallback = 0;
   if (fallback)
   if (fallback)
-    return mmap_probe(size);
+    return mmap_probe(rs, size);
 #endif
 #endif
   {
   {
     int olderr = errno;
     int olderr = errno;
@@ -321,7 +302,7 @@ static void *mmap_map32(size_t size)
 #if LJ_ALLOC_MMAP_PROBE
 #if LJ_ALLOC_MMAP_PROBE
     if (ptr == MFAIL) {
     if (ptr == MFAIL) {
       fallback = 1;
       fallback = 1;
-      return mmap_probe(size);
+      return mmap_probe(rs, size);
     }
     }
 #endif
 #endif
     return ptr;
     return ptr;
@@ -331,17 +312,22 @@ static void *mmap_map32(size_t size)
 #endif
 #endif
 
 
 #if LJ_ALLOC_MMAP32
 #if LJ_ALLOC_MMAP32
-#define CALL_MMAP(size)		mmap_map32(size)
+#if LJ_ALLOC_MMAP_PROBE
+#define CALL_MMAP(prng, size)	mmap_map32(prng, size)
+#else
+#define CALL_MMAP(prng, size)	mmap_map32(size)
+#endif
 #elif LJ_ALLOC_MMAP_PROBE
 #elif LJ_ALLOC_MMAP_PROBE
-#define CALL_MMAP(size)		mmap_probe(size)
+#define CALL_MMAP(prng, size)	mmap_probe(prng, size)
 #else
 #else
-static void *CALL_MMAP(size_t size)
+static void *mmap_plain(size_t size)
 {
 {
   int olderr = errno;
   int olderr = errno;
   void *ptr = mmap(NULL, size, MMAP_PROT, MMAP_FLAGS, -1, 0);
   void *ptr = mmap(NULL, size, MMAP_PROT, MMAP_FLAGS, -1, 0);
   errno = olderr;
   errno = olderr;
   return ptr;
   return ptr;
 }
 }
+#define CALL_MMAP(prng, size)	mmap_plain(size)
 #endif
 #endif
 
 
 #if LJ_64 && !LJ_GC64 && ((defined(__FreeBSD__) && __FreeBSD__ < 10) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4
 #if LJ_64 && !LJ_GC64 && ((defined(__FreeBSD__) && __FreeBSD__ < 10) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4
@@ -394,7 +380,7 @@ static void *CALL_MREMAP_(void *ptr, size_t osz, size_t nsz, int flags)
 #endif
 #endif
 
 
 #ifndef DIRECT_MMAP
 #ifndef DIRECT_MMAP
-#define DIRECT_MMAP(s)		CALL_MMAP(s)
+#define DIRECT_MMAP(prng, s)	CALL_MMAP(prng, s)
 #endif
 #endif
 
 
 #ifndef CALL_MREMAP
 #ifndef CALL_MREMAP
@@ -553,6 +539,7 @@ struct malloc_state {
   mchunkptr  smallbins[(NSMALLBINS+1)*2];
   mchunkptr  smallbins[(NSMALLBINS+1)*2];
   tbinptr    treebins[NTREEBINS];
   tbinptr    treebins[NTREEBINS];
   msegment   seg;
   msegment   seg;
+  PRNGState  *prng;
 };
 };
 
 
 typedef struct malloc_state *mstate;
 typedef struct malloc_state *mstate;
@@ -610,7 +597,7 @@ static int has_segment_link(mstate m, msegmentptr ss)
   noncontiguous segments are added.
   noncontiguous segments are added.
 */
 */
 #define TOP_FOOT_SIZE\
 #define TOP_FOOT_SIZE\
-  (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)
+  (align_offset(TWO_SIZE_T_SIZES)+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)
 
 
 /* ---------------------------- Indexing Bins ---------------------------- */
 /* ---------------------------- Indexing Bins ---------------------------- */
 
 
@@ -835,11 +822,11 @@ static int has_segment_link(mstate m, msegmentptr ss)
 
 
 /* -----------------------  Direct-mmapping chunks ----------------------- */
 /* -----------------------  Direct-mmapping chunks ----------------------- */
 
 
-static void *direct_alloc(size_t nb)
+static void *direct_alloc(mstate m, size_t nb)
 {
 {
   size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
   size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
   if (LJ_LIKELY(mmsize > nb)) {     /* Check for wrap around 0 */
   if (LJ_LIKELY(mmsize > nb)) {     /* Check for wrap around 0 */
-    char *mm = (char *)(DIRECT_MMAP(mmsize));
+    char *mm = (char *)(DIRECT_MMAP(m->prng, mmsize));
     if (mm != CMFAIL) {
     if (mm != CMFAIL) {
       size_t offset = align_offset(chunk2mem(mm));
       size_t offset = align_offset(chunk2mem(mm));
       size_t psize = mmsize - offset - DIRECT_FOOT_PAD;
       size_t psize = mmsize - offset - DIRECT_FOOT_PAD;
@@ -851,6 +838,7 @@ static void *direct_alloc(size_t nb)
       return chunk2mem(p);
       return chunk2mem(p);
     }
     }
   }
   }
+  UNUSED(m);
   return NULL;
   return NULL;
 }
 }
 
 
@@ -999,7 +987,7 @@ static void *alloc_sys(mstate m, size_t nb)
 
 
   /* Directly map large chunks */
   /* Directly map large chunks */
   if (LJ_UNLIKELY(nb >= DEFAULT_MMAP_THRESHOLD)) {
   if (LJ_UNLIKELY(nb >= DEFAULT_MMAP_THRESHOLD)) {
-    void *mem = direct_alloc(nb);
+    void *mem = direct_alloc(m, nb);
     if (mem != 0)
     if (mem != 0)
       return mem;
       return mem;
   }
   }
@@ -1008,7 +996,7 @@ static void *alloc_sys(mstate m, size_t nb)
     size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE;
     size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE;
     size_t rsize = granularity_align(req);
     size_t rsize = granularity_align(req);
     if (LJ_LIKELY(rsize > nb)) { /* Fail if wraps around zero */
     if (LJ_LIKELY(rsize > nb)) { /* Fail if wraps around zero */
-      char *mp = (char *)(CALL_MMAP(rsize));
+      char *mp = (char *)(CALL_MMAP(m->prng, rsize));
       if (mp != CMFAIL) {
       if (mp != CMFAIL) {
 	tbase = mp;
 	tbase = mp;
 	tsize = rsize;
 	tsize = rsize;
@@ -1235,12 +1223,13 @@ static void *tmalloc_small(mstate m, size_t nb)
 
 
 /* ----------------------------------------------------------------------- */
 /* ----------------------------------------------------------------------- */
 
 
-void *lj_alloc_create(void)
+void *lj_alloc_create(PRNGState *rs)
 {
 {
   size_t tsize = DEFAULT_GRANULARITY;
   size_t tsize = DEFAULT_GRANULARITY;
   char *tbase;
   char *tbase;
   INIT_MMAP();
   INIT_MMAP();
-  tbase = (char *)(CALL_MMAP(tsize));
+  UNUSED(rs);
+  tbase = (char *)(CALL_MMAP(rs, tsize));
   if (tbase != CMFAIL) {
   if (tbase != CMFAIL) {
     size_t msize = pad_request(sizeof(struct malloc_state));
     size_t msize = pad_request(sizeof(struct malloc_state));
     mchunkptr mn;
     mchunkptr mn;
@@ -1259,6 +1248,12 @@ void *lj_alloc_create(void)
   return NULL;
   return NULL;
 }
 }
 
 
+void lj_alloc_setprng(void *msp, PRNGState *rs)
+{
+  mstate ms = (mstate)msp;
+  ms->prng = rs;
+}
+
 void lj_alloc_destroy(void *msp)
 void lj_alloc_destroy(void *msp)
 {
 {
   mstate ms = (mstate)msp;
   mstate ms = (mstate)msp;

+ 2 - 1
libs/LuaJIT/src/lj_alloc.h

@@ -9,7 +9,8 @@
 #include "lj_def.h"
 #include "lj_def.h"
 
 
 #ifndef LUAJIT_USE_SYSMALLOC
 #ifndef LUAJIT_USE_SYSMALLOC
-LJ_FUNC void *lj_alloc_create(void);
+LJ_FUNC void *lj_alloc_create(PRNGState *rs);
+LJ_FUNC void lj_alloc_setprng(void *msp, PRNGState *rs);
 LJ_FUNC void lj_alloc_destroy(void *msp);
 LJ_FUNC void lj_alloc_destroy(void *msp);
 LJ_FUNC void *lj_alloc_f(void *msp, void *ptr, size_t osize, size_t nsize);
 LJ_FUNC void *lj_alloc_f(void *msp, void *ptr, size_t osize, size_t nsize);
 #endif
 #endif

+ 119 - 74
libs/LuaJIT/src/lj_api.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Public Lua/C API.
 ** Public Lua/C API.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Major portions taken verbatim or adapted from the Lua interpreter.
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
@@ -28,8 +28,8 @@
 
 
 /* -- Common helper functions --------------------------------------------- */
 /* -- Common helper functions --------------------------------------------- */
 
 
-#define api_checknelems(L, n)		api_check(L, (n) <= (L->top - L->base))
-#define api_checkvalidindex(L, i)	api_check(L, (i) != niltv(L))
+#define lj_checkapi_slot(idx) \
+  lj_checkapi((idx) <= (L->top - L->base), "stack slot %d out of range", (idx))
 
 
 static TValue *index2adr(lua_State *L, int idx)
 static TValue *index2adr(lua_State *L, int idx)
 {
 {
@@ -37,7 +37,8 @@ static TValue *index2adr(lua_State *L, int idx)
     TValue *o = L->base + (idx - 1);
     TValue *o = L->base + (idx - 1);
     return o < L->top ? o : niltv(L);
     return o < L->top ? o : niltv(L);
   } else if (idx > LUA_REGISTRYINDEX) {
   } else if (idx > LUA_REGISTRYINDEX) {
-    api_check(L, idx != 0 && -idx <= L->top - L->base);
+    lj_checkapi(idx != 0 && -idx <= L->top - L->base,
+		"bad stack slot %d", idx);
     return L->top + idx;
     return L->top + idx;
   } else if (idx == LUA_GLOBALSINDEX) {
   } else if (idx == LUA_GLOBALSINDEX) {
     TValue *o = &G(L)->tmptv;
     TValue *o = &G(L)->tmptv;
@@ -47,7 +48,8 @@ static TValue *index2adr(lua_State *L, int idx)
     return registry(L);
     return registry(L);
   } else {
   } else {
     GCfunc *fn = curr_func(L);
     GCfunc *fn = curr_func(L);
-    api_check(L, fn->c.gct == ~LJ_TFUNC && !isluafunc(fn));
+    lj_checkapi(fn->c.gct == ~LJ_TFUNC && !isluafunc(fn),
+		"calling frame is not a C function");
     if (idx == LUA_ENVIRONINDEX) {
     if (idx == LUA_ENVIRONINDEX) {
       TValue *o = &G(L)->tmptv;
       TValue *o = &G(L)->tmptv;
       settabV(L, o, tabref(fn->c.env));
       settabV(L, o, tabref(fn->c.env));
@@ -59,13 +61,27 @@ static TValue *index2adr(lua_State *L, int idx)
   }
   }
 }
 }
 
 
-static TValue *stkindex2adr(lua_State *L, int idx)
+static LJ_AINLINE TValue *index2adr_check(lua_State *L, int idx)
+{
+  TValue *o = index2adr(L, idx);
+  lj_checkapi(o != niltv(L), "invalid stack slot %d", idx);
+  return o;
+}
+
+static TValue *index2adr_stack(lua_State *L, int idx)
 {
 {
   if (idx > 0) {
   if (idx > 0) {
     TValue *o = L->base + (idx - 1);
     TValue *o = L->base + (idx - 1);
+    if (o < L->top) {
+      return o;
+    } else {
+      lj_checkapi(0, "invalid stack slot %d", idx);
+      return niltv(L);
+    }
     return o < L->top ? o : niltv(L);
     return o < L->top ? o : niltv(L);
   } else {
   } else {
-    api_check(L, idx != 0 && -idx <= L->top - L->base);
+    lj_checkapi(idx != 0 && -idx <= L->top - L->base,
+		"invalid stack slot %d", idx);
     return L->top + idx;
     return L->top + idx;
   }
   }
 }
 }
@@ -99,17 +115,17 @@ LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
     lj_err_callerv(L, LJ_ERR_STKOVM, msg);
     lj_err_callerv(L, LJ_ERR_STKOVM, msg);
 }
 }
 
 
-LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
+LUA_API void lua_xmove(lua_State *L, lua_State *to, int n)
 {
 {
   TValue *f, *t;
   TValue *f, *t;
-  if (from == to) return;
-  api_checknelems(from, n);
-  api_check(from, G(from) == G(to));
+  if (L == to) return;
+  lj_checkapi_slot(n);
+  lj_checkapi(G(L) == G(to), "move across global states");
   lj_state_checkstack(to, (MSize)n);
   lj_state_checkstack(to, (MSize)n);
-  f = from->top;
+  f = L->top;
   t = to->top = to->top + n;
   t = to->top = to->top + n;
   while (--n >= 0) copyTV(to, --t, --f);
   while (--n >= 0) copyTV(to, --t, --f);
-  from->top = f;
+  L->top = f;
 }
 }
 
 
 LUA_API const lua_Number *lua_version(lua_State *L)
 LUA_API const lua_Number *lua_version(lua_State *L)
@@ -129,7 +145,7 @@ LUA_API int lua_gettop(lua_State *L)
 LUA_API void lua_settop(lua_State *L, int idx)
 LUA_API void lua_settop(lua_State *L, int idx)
 {
 {
   if (idx >= 0) {
   if (idx >= 0) {
-    api_check(L, idx <= tvref(L->maxstack) - L->base);
+    lj_checkapi(idx <= tvref(L->maxstack) - L->base, "bad stack slot %d", idx);
     if (L->base + idx > L->top) {
     if (L->base + idx > L->top) {
       if (L->base + idx >= tvref(L->maxstack))
       if (L->base + idx >= tvref(L->maxstack))
 	lj_state_growstack(L, (MSize)idx - (MSize)(L->top - L->base));
 	lj_state_growstack(L, (MSize)idx - (MSize)(L->top - L->base));
@@ -138,23 +154,21 @@ LUA_API void lua_settop(lua_State *L, int idx)
       L->top = L->base + idx;
       L->top = L->base + idx;
     }
     }
   } else {
   } else {
-    api_check(L, -(idx+1) <= (L->top - L->base));
+    lj_checkapi(-(idx+1) <= (L->top - L->base), "bad stack slot %d", idx);
     L->top += idx+1;  /* Shrinks top (idx < 0). */
     L->top += idx+1;  /* Shrinks top (idx < 0). */
   }
   }
 }
 }
 
 
 LUA_API void lua_remove(lua_State *L, int idx)
 LUA_API void lua_remove(lua_State *L, int idx)
 {
 {
-  TValue *p = stkindex2adr(L, idx);
-  api_checkvalidindex(L, p);
+  TValue *p = index2adr_stack(L, idx);
   while (++p < L->top) copyTV(L, p-1, p);
   while (++p < L->top) copyTV(L, p-1, p);
   L->top--;
   L->top--;
 }
 }
 
 
 LUA_API void lua_insert(lua_State *L, int idx)
 LUA_API void lua_insert(lua_State *L, int idx)
 {
 {
-  TValue *q, *p = stkindex2adr(L, idx);
-  api_checkvalidindex(L, p);
+  TValue *q, *p = index2adr_stack(L, idx);
   for (q = L->top; q > p; q--) copyTV(L, q, q-1);
   for (q = L->top; q > p; q--) copyTV(L, q, q-1);
   copyTV(L, p, L->top);
   copyTV(L, p, L->top);
 }
 }
@@ -162,19 +176,18 @@ LUA_API void lua_insert(lua_State *L, int idx)
 static void copy_slot(lua_State *L, TValue *f, int idx)
 static void copy_slot(lua_State *L, TValue *f, int idx)
 {
 {
   if (idx == LUA_GLOBALSINDEX) {
   if (idx == LUA_GLOBALSINDEX) {
-    api_check(L, tvistab(f));
+    lj_checkapi(tvistab(f), "stack slot %d is not a table", idx);
     /* NOBARRIER: A thread (i.e. L) is never black. */
     /* NOBARRIER: A thread (i.e. L) is never black. */
     setgcref(L->env, obj2gco(tabV(f)));
     setgcref(L->env, obj2gco(tabV(f)));
   } else if (idx == LUA_ENVIRONINDEX) {
   } else if (idx == LUA_ENVIRONINDEX) {
     GCfunc *fn = curr_func(L);
     GCfunc *fn = curr_func(L);
     if (fn->c.gct != ~LJ_TFUNC)
     if (fn->c.gct != ~LJ_TFUNC)
       lj_err_msg(L, LJ_ERR_NOENV);
       lj_err_msg(L, LJ_ERR_NOENV);
-    api_check(L, tvistab(f));
+    lj_checkapi(tvistab(f), "stack slot %d is not a table", idx);
     setgcref(fn->c.env, obj2gco(tabV(f)));
     setgcref(fn->c.env, obj2gco(tabV(f)));
     lj_gc_barrier(L, fn, f);
     lj_gc_barrier(L, fn, f);
   } else {
   } else {
-    TValue *o = index2adr(L, idx);
-    api_checkvalidindex(L, o);
+    TValue *o = index2adr_check(L, idx);
     copyTV(L, o, f);
     copyTV(L, o, f);
     if (idx < LUA_GLOBALSINDEX)  /* Need a barrier for upvalues. */
     if (idx < LUA_GLOBALSINDEX)  /* Need a barrier for upvalues. */
       lj_gc_barrier(L, curr_func(L), f);
       lj_gc_barrier(L, curr_func(L), f);
@@ -183,7 +196,7 @@ static void copy_slot(lua_State *L, TValue *f, int idx)
 
 
 LUA_API void lua_replace(lua_State *L, int idx)
 LUA_API void lua_replace(lua_State *L, int idx)
 {
 {
-  api_checknelems(L, 1);
+  lj_checkapi_slot(1);
   copy_slot(L, L->top - 1, idx);
   copy_slot(L, L->top - 1, idx);
   L->top--;
   L->top--;
 }
 }
@@ -219,7 +232,7 @@ LUA_API int lua_type(lua_State *L, int idx)
 #else
 #else
     int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u);
     int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u);
 #endif
 #endif
-    lua_assert(tt != LUA_TNIL || tvisnil(o));
+    lj_assertL(tt != LUA_TNIL || tvisnil(o), "bad tag conversion");
     return tt;
     return tt;
   }
   }
 }
 }
@@ -595,7 +608,7 @@ LUA_API void *lua_touserdata(lua_State *L, int idx)
   if (tvisudata(o))
   if (tvisudata(o))
     return uddata(udataV(o));
     return uddata(udataV(o));
   else if (tvislightud(o))
   else if (tvislightud(o))
-    return lightudV(o);
+    return lightudV(G(L), o);
   else
   else
     return NULL;
     return NULL;
 }
 }
@@ -608,7 +621,7 @@ LUA_API lua_State *lua_tothread(lua_State *L, int idx)
 
 
 LUA_API const void *lua_topointer(lua_State *L, int idx)
 LUA_API const void *lua_topointer(lua_State *L, int idx)
 {
 {
-  return lj_obj_ptr(index2adr(L, idx));
+  return lj_obj_ptr(G(L), index2adr(L, idx));
 }
 }
 
 
 /* -- Stack setters (object creation) ------------------------------------- */
 /* -- Stack setters (object creation) ------------------------------------- */
@@ -677,14 +690,14 @@ LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction f, int n)
 {
 {
   GCfunc *fn;
   GCfunc *fn;
   lj_gc_check(L);
   lj_gc_check(L);
-  api_checknelems(L, n);
+  lj_checkapi_slot(n);
   fn = lj_func_newC(L, (MSize)n, getcurrenv(L));
   fn = lj_func_newC(L, (MSize)n, getcurrenv(L));
   fn->c.f = f;
   fn->c.f = f;
   L->top -= n;
   L->top -= n;
   while (n--)
   while (n--)
     copyTV(L, &fn->c.upvalue[n], L->top+n);
     copyTV(L, &fn->c.upvalue[n], L->top+n);
   setfuncV(L, L->top, fn);
   setfuncV(L, L->top, fn);
-  lua_assert(iswhite(obj2gco(fn)));
+  lj_assertL(iswhite(obj2gco(fn)), "new GC object is not white");
   incr_top(L);
   incr_top(L);
 }
 }
 
 
@@ -694,9 +707,38 @@ LUA_API void lua_pushboolean(lua_State *L, int b)
   incr_top(L);
   incr_top(L);
 }
 }
 
 
+#if LJ_64
+static void *lightud_intern(lua_State *L, void *p)
+{
+  global_State *g = G(L);
+  uint64_t u = (uint64_t)p;
+  uint32_t up = lightudup(u);
+  uint32_t *segmap = mref(g->gc.lightudseg, uint32_t);
+  MSize segnum = g->gc.lightudnum;
+  if (segmap) {
+    MSize seg;
+    for (seg = 0; seg <= segnum; seg++)
+      if (segmap[seg] == up)  /* Fast path. */
+	return (void *)(((uint64_t)seg << LJ_LIGHTUD_BITS_LO) | lightudlo(u));
+    segnum++;
+  }
+  if (!((segnum-1) & segnum) && segnum != 1) {
+    if (segnum >= (1 << LJ_LIGHTUD_BITS_SEG)) lj_err_msg(L, LJ_ERR_BADLU);
+    lj_mem_reallocvec(L, segmap, segnum, segnum ? 2*segnum : 2u, uint32_t);
+    setmref(g->gc.lightudseg, segmap);
+  }
+  g->gc.lightudnum = segnum;
+  segmap[segnum] = up;
+  return (void *)(((uint64_t)segnum << LJ_LIGHTUD_BITS_LO) | lightudlo(u));
+}
+#endif
+
 LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
 LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
 {
 {
-  setlightudV(L->top, checklightudptr(L, p));
+#if LJ_64
+  p = lightud_intern(L, p);
+#endif
+  setrawlightudV(L->top, p);
   incr_top(L);
   incr_top(L);
 }
 }
 
 
@@ -754,7 +796,7 @@ LUA_API void *lua_newuserdata(lua_State *L, size_t size)
 
 
 LUA_API void lua_concat(lua_State *L, int n)
 LUA_API void lua_concat(lua_State *L, int n)
 {
 {
-  api_checknelems(L, n);
+  lj_checkapi_slot(n);
   if (n >= 2) {
   if (n >= 2) {
     n--;
     n--;
     do {
     do {
@@ -780,9 +822,8 @@ LUA_API void lua_concat(lua_State *L, int n)
 
 
 LUA_API void lua_gettable(lua_State *L, int idx)
 LUA_API void lua_gettable(lua_State *L, int idx)
 {
 {
-  cTValue *v, *t = index2adr(L, idx);
-  api_checkvalidindex(L, t);
-  v = lj_meta_tget(L, t, L->top-1);
+  cTValue *t = index2adr_check(L, idx);
+  cTValue *v = lj_meta_tget(L, t, L->top-1);
   if (v == NULL) {
   if (v == NULL) {
     L->top += 2;
     L->top += 2;
     lj_vm_call(L, L->top-2, 1+1);
     lj_vm_call(L, L->top-2, 1+1);
@@ -794,9 +835,8 @@ LUA_API void lua_gettable(lua_State *L, int idx)
 
 
 LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
 LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
 {
 {
-  cTValue *v, *t = index2adr(L, idx);
+  cTValue *v, *t = index2adr_check(L, idx);
   TValue key;
   TValue key;
-  api_checkvalidindex(L, t);
   setstrV(L, &key, lj_str_newz(L, k));
   setstrV(L, &key, lj_str_newz(L, k));
   v = lj_meta_tget(L, t, &key);
   v = lj_meta_tget(L, t, &key);
   if (v == NULL) {
   if (v == NULL) {
@@ -812,14 +852,14 @@ LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
 LUA_API void lua_rawget(lua_State *L, int idx)
 LUA_API void lua_rawget(lua_State *L, int idx)
 {
 {
   cTValue *t = index2adr(L, idx);
   cTValue *t = index2adr(L, idx);
-  api_check(L, tvistab(t));
+  lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
   copyTV(L, L->top-1, lj_tab_get(L, tabV(t), L->top-1));
   copyTV(L, L->top-1, lj_tab_get(L, tabV(t), L->top-1));
 }
 }
 
 
 LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
 LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
 {
 {
   cTValue *v, *t = index2adr(L, idx);
   cTValue *v, *t = index2adr(L, idx);
-  api_check(L, tvistab(t));
+  lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
   v = lj_tab_getint(tabV(t), n);
   v = lj_tab_getint(tabV(t), n);
   if (v) {
   if (v) {
     copyTV(L, L->top, v);
     copyTV(L, L->top, v);
@@ -861,8 +901,7 @@ LUALIB_API int luaL_getmetafield(lua_State *L, int idx, const char *field)
 
 
 LUA_API void lua_getfenv(lua_State *L, int idx)
 LUA_API void lua_getfenv(lua_State *L, int idx)
 {
 {
-  cTValue *o = index2adr(L, idx);
-  api_checkvalidindex(L, o);
+  cTValue *o = index2adr_check(L, idx);
   if (tvisfunc(o)) {
   if (tvisfunc(o)) {
     settabV(L, L->top, tabref(funcV(o)->c.env));
     settabV(L, L->top, tabref(funcV(o)->c.env));
   } else if (tvisudata(o)) {
   } else if (tvisudata(o)) {
@@ -879,7 +918,7 @@ LUA_API int lua_next(lua_State *L, int idx)
 {
 {
   cTValue *t = index2adr(L, idx);
   cTValue *t = index2adr(L, idx);
   int more;
   int more;
-  api_check(L, tvistab(t));
+  lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
   more = lj_tab_next(L, tabV(t), L->top-1);
   more = lj_tab_next(L, tabV(t), L->top-1);
   if (more) {
   if (more) {
     incr_top(L);  /* Return new key and value slot. */
     incr_top(L);  /* Return new key and value slot. */
@@ -892,7 +931,8 @@ LUA_API int lua_next(lua_State *L, int idx)
 LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n)
 LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n)
 {
 {
   TValue *val;
   TValue *val;
-  const char *name = lj_debug_uvnamev(index2adr(L, idx), (uint32_t)(n-1), &val);
+  GCobj *o;
+  const char *name = lj_debug_uvnamev(index2adr(L, idx), (uint32_t)(n-1), &val, &o);
   if (name) {
   if (name) {
     copyTV(L, L->top, val);
     copyTV(L, L->top, val);
     incr_top(L);
     incr_top(L);
@@ -904,7 +944,7 @@ LUA_API void *lua_upvalueid(lua_State *L, int idx, int n)
 {
 {
   GCfunc *fn = funcV(index2adr(L, idx));
   GCfunc *fn = funcV(index2adr(L, idx));
   n--;
   n--;
-  api_check(L, (uint32_t)n < fn->l.nupvalues);
+  lj_checkapi((uint32_t)n < fn->l.nupvalues, "bad upvalue %d", n);
   return isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) :
   return isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) :
 			 (void *)&fn->c.upvalue[n];
 			 (void *)&fn->c.upvalue[n];
 }
 }
@@ -914,8 +954,10 @@ LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2)
   GCfunc *fn1 = funcV(index2adr(L, idx1));
   GCfunc *fn1 = funcV(index2adr(L, idx1));
   GCfunc *fn2 = funcV(index2adr(L, idx2));
   GCfunc *fn2 = funcV(index2adr(L, idx2));
   n1--; n2--;
   n1--; n2--;
-  api_check(L, isluafunc(fn1) && (uint32_t)n1 < fn1->l.nupvalues);
-  api_check(L, isluafunc(fn2) && (uint32_t)n2 < fn2->l.nupvalues);
+  lj_checkapi(isluafunc(fn1), "stack slot %d is not a Lua function", idx1);
+  lj_checkapi(isluafunc(fn2), "stack slot %d is not a Lua function", idx2);
+  lj_checkapi((uint32_t)n1 < fn1->l.nupvalues, "bad upvalue %d", n1+1);
+  lj_checkapi((uint32_t)n2 < fn2->l.nupvalues, "bad upvalue %d", n2+1);
   setgcrefr(fn1->l.uvptr[n1], fn2->l.uvptr[n2]);
   setgcrefr(fn1->l.uvptr[n1], fn2->l.uvptr[n2]);
   lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1]));
   lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1]));
 }
 }
@@ -944,9 +986,8 @@ LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
 LUA_API void lua_settable(lua_State *L, int idx)
 LUA_API void lua_settable(lua_State *L, int idx)
 {
 {
   TValue *o;
   TValue *o;
-  cTValue *t = index2adr(L, idx);
-  api_checknelems(L, 2);
-  api_checkvalidindex(L, t);
+  cTValue *t = index2adr_check(L, idx);
+  lj_checkapi_slot(2);
   o = lj_meta_tset(L, t, L->top-2);
   o = lj_meta_tset(L, t, L->top-2);
   if (o) {
   if (o) {
     /* NOBARRIER: lj_meta_tset ensures the table is not black. */
     /* NOBARRIER: lj_meta_tset ensures the table is not black. */
@@ -965,9 +1006,8 @@ LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
 {
 {
   TValue *o;
   TValue *o;
   TValue key;
   TValue key;
-  cTValue *t = index2adr(L, idx);
-  api_checknelems(L, 1);
-  api_checkvalidindex(L, t);
+  cTValue *t = index2adr_check(L, idx);
+  lj_checkapi_slot(1);
   setstrV(L, &key, lj_str_newz(L, k));
   setstrV(L, &key, lj_str_newz(L, k));
   o = lj_meta_tset(L, t, &key);
   o = lj_meta_tset(L, t, &key);
   if (o) {
   if (o) {
@@ -986,7 +1026,7 @@ LUA_API void lua_rawset(lua_State *L, int idx)
 {
 {
   GCtab *t = tabV(index2adr(L, idx));
   GCtab *t = tabV(index2adr(L, idx));
   TValue *dst, *key;
   TValue *dst, *key;
-  api_checknelems(L, 2);
+  lj_checkapi_slot(2);
   key = L->top-2;
   key = L->top-2;
   dst = lj_tab_set(L, t, key);
   dst = lj_tab_set(L, t, key);
   copyTV(L, dst, key+1);
   copyTV(L, dst, key+1);
@@ -998,7 +1038,7 @@ LUA_API void lua_rawseti(lua_State *L, int idx, int n)
 {
 {
   GCtab *t = tabV(index2adr(L, idx));
   GCtab *t = tabV(index2adr(L, idx));
   TValue *dst, *src;
   TValue *dst, *src;
-  api_checknelems(L, 1);
+  lj_checkapi_slot(1);
   dst = lj_tab_setint(L, t, n);
   dst = lj_tab_setint(L, t, n);
   src = L->top-1;
   src = L->top-1;
   copyTV(L, dst, src);
   copyTV(L, dst, src);
@@ -1010,13 +1050,12 @@ LUA_API int lua_setmetatable(lua_State *L, int idx)
 {
 {
   global_State *g;
   global_State *g;
   GCtab *mt;
   GCtab *mt;
-  cTValue *o = index2adr(L, idx);
-  api_checknelems(L, 1);
-  api_checkvalidindex(L, o);
+  cTValue *o = index2adr_check(L, idx);
+  lj_checkapi_slot(1);
   if (tvisnil(L->top-1)) {
   if (tvisnil(L->top-1)) {
     mt = NULL;
     mt = NULL;
   } else {
   } else {
-    api_check(L, tvistab(L->top-1));
+    lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
     mt = tabV(L->top-1);
     mt = tabV(L->top-1);
   }
   }
   g = G(L);
   g = G(L);
@@ -1053,11 +1092,10 @@ LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
 
 
 LUA_API int lua_setfenv(lua_State *L, int idx)
 LUA_API int lua_setfenv(lua_State *L, int idx)
 {
 {
-  cTValue *o = index2adr(L, idx);
+  cTValue *o = index2adr_check(L, idx);
   GCtab *t;
   GCtab *t;
-  api_checknelems(L, 1);
-  api_checkvalidindex(L, o);
-  api_check(L, tvistab(L->top-1));
+  lj_checkapi_slot(1);
+  lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
   t = tabV(L->top-1);
   t = tabV(L->top-1);
   if (tvisfunc(o)) {
   if (tvisfunc(o)) {
     setgcref(funcV(o)->c.env, obj2gco(t));
     setgcref(funcV(o)->c.env, obj2gco(t));
@@ -1078,13 +1116,14 @@ LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
 {
 {
   cTValue *f = index2adr(L, idx);
   cTValue *f = index2adr(L, idx);
   TValue *val;
   TValue *val;
+  GCobj *o;
   const char *name;
   const char *name;
-  api_checknelems(L, 1);
-  name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val);
+  lj_checkapi_slot(1);
+  name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val, &o);
   if (name) {
   if (name) {
     L->top--;
     L->top--;
     copyTV(L, val, L->top);
     copyTV(L, val, L->top);
-    lj_gc_barrier(L, funcV(f), L->top);
+    lj_gc_barrier(L, o, L->top);
   }
   }
   return name;
   return name;
 }
 }
@@ -1106,8 +1145,9 @@ static TValue *api_call_base(lua_State *L, int nargs)
 
 
 LUA_API void lua_call(lua_State *L, int nargs, int nresults)
 LUA_API void lua_call(lua_State *L, int nargs, int nresults)
 {
 {
-  api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
-  api_checknelems(L, nargs+1);
+  lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
+	      "thread called in wrong state %d", L->status);
+  lj_checkapi_slot(nargs+1);
   lj_vm_call(L, api_call_base(L, nargs), nresults+1);
   lj_vm_call(L, api_call_base(L, nargs), nresults+1);
 }
 }
 
 
@@ -1117,13 +1157,13 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
   uint8_t oldh = hook_save(g);
   uint8_t oldh = hook_save(g);
   ptrdiff_t ef;
   ptrdiff_t ef;
   int status;
   int status;
-  api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
-  api_checknelems(L, nargs+1);
+  lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
+	      "thread called in wrong state %d", L->status);
+  lj_checkapi_slot(nargs+1);
   if (errfunc == 0) {
   if (errfunc == 0) {
     ef = 0;
     ef = 0;
   } else {
   } else {
-    cTValue *o = stkindex2adr(L, errfunc);
-    api_checkvalidindex(L, o);
+    cTValue *o = index2adr_stack(L, errfunc);
     ef = savestack(L, o);
     ef = savestack(L, o);
   }
   }
   status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
   status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
@@ -1138,7 +1178,10 @@ static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
   fn->c.f = func;
   fn->c.f = func;
   setfuncV(L, top++, fn);
   setfuncV(L, top++, fn);
   if (LJ_FR2) setnilV(top++);
   if (LJ_FR2) setnilV(top++);
-  setlightudV(top++, checklightudptr(L, ud));
+#if LJ_64
+  ud = lightud_intern(L, ud);
+#endif
+  setrawlightudV(top++, ud);
   cframe_nres(L->cframe) = 1+0;  /* Zero results. */
   cframe_nres(L->cframe) = 1+0;  /* Zero results. */
   L->top = top;
   L->top = top;
   return top-1;  /* Now call the newly allocated C function. */
   return top-1;  /* Now call the newly allocated C function. */
@@ -1149,7 +1192,8 @@ LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
   global_State *g = G(L);
   global_State *g = G(L);
   uint8_t oldh = hook_save(g);
   uint8_t oldh = hook_save(g);
   int status;
   int status;
-  api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
+  lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
+	      "thread called in wrong state %d", L->status);
   status = lj_vm_cpcall(L, func, ud, cpcall);
   status = lj_vm_cpcall(L, func, ud, cpcall);
   if (status) hook_restore(g, oldh);
   if (status) hook_restore(g, oldh);
   return status;
   return status;
@@ -1198,11 +1242,12 @@ LUA_API int lua_yield(lua_State *L, int nresults)
       setcont(top, lj_cont_hook);
       setcont(top, lj_cont_hook);
       if (LJ_FR2) top++;
       if (LJ_FR2) top++;
       setframe_pc(top, cframe_pc(cf)-1);
       setframe_pc(top, cframe_pc(cf)-1);
-      if (LJ_FR2) top++;
+      top++;
       setframe_gc(top, obj2gco(L), LJ_TTHREAD);
       setframe_gc(top, obj2gco(L), LJ_TTHREAD);
+      if (LJ_FR2) top++;
       setframe_ftsz(top, ((char *)(top+1)-(char *)L->base)+FRAME_CONT);
       setframe_ftsz(top, ((char *)(top+1)-(char *)L->base)+FRAME_CONT);
       L->top = L->base = top+1;
       L->top = L->base = top+1;
-#if LJ_TARGET_X64
+#if ((defined(__GNUC__) || defined(__clang__)) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) && !LJ_NO_UNWIND) || LJ_TARGET_WINDOWS
       lj_err_throw(L, LUA_YIELD);
       lj_err_throw(L, LUA_YIELD);
 #else
 #else
       L->cframe = NULL;
       L->cframe = NULL;

+ 106 - 21
libs/LuaJIT/src/lj_arch.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** Target architecture selection.
 ** Target architecture selection.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _LJ_ARCH_H
 #ifndef _LJ_ARCH_H
@@ -8,6 +8,8 @@
 
 
 #include "lua.h"
 #include "lua.h"
 
 
+/* -- Target definitions -------------------------------------------------- */
+
 /* Target endianess. */
 /* Target endianess. */
 #define LUAJIT_LE	0
 #define LUAJIT_LE	0
 #define LUAJIT_BE	1
 #define LUAJIT_BE	1
@@ -38,6 +40,14 @@
 #define LUAJIT_OS_BSD		4
 #define LUAJIT_OS_BSD		4
 #define LUAJIT_OS_POSIX		5
 #define LUAJIT_OS_POSIX		5
 
 
+/* Number mode. */
+#define LJ_NUMMODE_SINGLE	0	/* Single-number mode only. */
+#define LJ_NUMMODE_SINGLE_DUAL	1	/* Default to single-number mode. */
+#define LJ_NUMMODE_DUAL		2	/* Dual-number mode only. */
+#define LJ_NUMMODE_DUAL_SINGLE	3	/* Default to dual-number mode. */
+
+/* -- Target detection ---------------------------------------------------- */
+
 /* Select native target if no target defined. */
 /* Select native target if no target defined. */
 #ifndef LUAJIT_TARGET
 #ifndef LUAJIT_TARGET
 
 
@@ -69,12 +79,16 @@
 #elif defined(__linux__)
 #elif defined(__linux__)
 #define LUAJIT_OS	LUAJIT_OS_LINUX
 #define LUAJIT_OS	LUAJIT_OS_LINUX
 #elif defined(__MACH__) && defined(__APPLE__)
 #elif defined(__MACH__) && defined(__APPLE__)
+#include "TargetConditionals.h"
 #define LUAJIT_OS	LUAJIT_OS_OSX
 #define LUAJIT_OS	LUAJIT_OS_OSX
 #elif (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
 #elif (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
        defined(__NetBSD__) || defined(__OpenBSD__) || \
        defined(__NetBSD__) || defined(__OpenBSD__) || \
        defined(__DragonFly__)) && !defined(__ORBIS__)
        defined(__DragonFly__)) && !defined(__ORBIS__)
 #define LUAJIT_OS	LUAJIT_OS_BSD
 #define LUAJIT_OS	LUAJIT_OS_BSD
-#elif (defined(__sun__) && defined(__svr4__)) || defined(__HAIKU__)
+#elif (defined(__sun__) && defined(__svr4__))
+#define LJ_TARGET_SOLARIS	1
+#define LUAJIT_OS	LUAJIT_OS_POSIX
+#elif defined(__HAIKU__)
 #define LUAJIT_OS	LUAJIT_OS_POSIX
 #define LUAJIT_OS	LUAJIT_OS_POSIX
 #elif defined(__CYGWIN__)
 #elif defined(__CYGWIN__)
 #define LJ_TARGET_CYGWIN	1
 #define LJ_TARGET_CYGWIN	1
@@ -103,10 +117,16 @@
 #define LJ_TARGET_WINDOWS	(LUAJIT_OS == LUAJIT_OS_WINDOWS)
 #define LJ_TARGET_WINDOWS	(LUAJIT_OS == LUAJIT_OS_WINDOWS)
 #define LJ_TARGET_LINUX		(LUAJIT_OS == LUAJIT_OS_LINUX)
 #define LJ_TARGET_LINUX		(LUAJIT_OS == LUAJIT_OS_LINUX)
 #define LJ_TARGET_OSX		(LUAJIT_OS == LUAJIT_OS_OSX)
 #define LJ_TARGET_OSX		(LUAJIT_OS == LUAJIT_OS_OSX)
-#define LJ_TARGET_IOS		(LJ_TARGET_OSX && (LUAJIT_TARGET == LUAJIT_ARCH_ARM || LUAJIT_TARGET == LUAJIT_ARCH_ARM64))
+#define LJ_TARGET_BSD		(LUAJIT_OS == LUAJIT_OS_BSD)
 #define LJ_TARGET_POSIX		(LUAJIT_OS > LUAJIT_OS_WINDOWS)
 #define LJ_TARGET_POSIX		(LUAJIT_OS > LUAJIT_OS_WINDOWS)
 #define LJ_TARGET_DLOPEN	LJ_TARGET_POSIX
 #define LJ_TARGET_DLOPEN	LJ_TARGET_POSIX
 
 
+#if TARGET_OS_IPHONE
+#define LJ_TARGET_IOS		1
+#else
+#define LJ_TARGET_IOS		0
+#endif
+
 #ifdef __CELLOS_LV2__
 #ifdef __CELLOS_LV2__
 #define LJ_TARGET_PS3		1
 #define LJ_TARGET_PS3		1
 #define LJ_TARGET_CONSOLE	1
 #define LJ_TARGET_CONSOLE	1
@@ -142,10 +162,7 @@
 #endif
 #endif
 #endif
 #endif
 
 
-#define LJ_NUMMODE_SINGLE	0	/* Single-number mode only. */
-#define LJ_NUMMODE_SINGLE_DUAL	1	/* Default to single-number mode. */
-#define LJ_NUMMODE_DUAL		2	/* Dual-number mode only. */
-#define LJ_NUMMODE_DUAL_SINGLE	3	/* Default to dual-number mode. */
+/* -- Arch-specific settings ---------------------------------------------- */
 
 
 /* Set target architecture properties. */
 /* Set target architecture properties. */
 #if LUAJIT_TARGET == LUAJIT_ARCH_X86
 #if LUAJIT_TARGET == LUAJIT_ARCH_X86
@@ -208,13 +225,13 @@
 #define LJ_TARGET_UNIFYROT	2	/* Want only IR_BROR. */
 #define LJ_TARGET_UNIFYROT	2	/* Want only IR_BROR. */
 #define LJ_ARCH_NUMMODE		LJ_NUMMODE_DUAL
 #define LJ_ARCH_NUMMODE		LJ_NUMMODE_DUAL
 
 
-#if __ARM_ARCH_8__ || __ARM_ARCH_8A__
+#if __ARM_ARCH == 8 || __ARM_ARCH_8__ || __ARM_ARCH_8A__
 #define LJ_ARCH_VERSION		80
 #define LJ_ARCH_VERSION		80
-#elif __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH_7S__ || __ARM_ARCH_7VE__
+#elif __ARM_ARCH == 7 || __ARM_ARCH_7__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH_7S__ || __ARM_ARCH_7VE__
 #define LJ_ARCH_VERSION		70
 #define LJ_ARCH_VERSION		70
 #elif __ARM_ARCH_6T2__
 #elif __ARM_ARCH_6T2__
 #define LJ_ARCH_VERSION		61
 #define LJ_ARCH_VERSION		61
-#elif __ARM_ARCH_6__ || __ARM_ARCH_6J__ || __ARM_ARCH_6K__ || __ARM_ARCH_6Z__ || __ARM_ARCH_6ZK__
+#elif __ARM_ARCH == 6 || __ARM_ARCH_6__ || __ARM_ARCH_6J__ || __ARM_ARCH_6K__ || __ARM_ARCH_6Z__ || __ARM_ARCH_6ZK__
 #define LJ_ARCH_VERSION		60
 #define LJ_ARCH_VERSION		60
 #else
 #else
 #define LJ_ARCH_VERSION		50
 #define LJ_ARCH_VERSION		50
@@ -296,9 +313,7 @@
 #define LJ_ARCH_PPC32ON64	1
 #define LJ_ARCH_PPC32ON64	1
 #define LJ_ARCH_NOFFI		1
 #define LJ_ARCH_NOFFI		1
 #elif LJ_ARCH_BITS == 64
 #elif LJ_ARCH_BITS == 64
-#define LJ_ARCH_PPC64		1
-#define LJ_TARGET_GC64		1
-#define LJ_ARCH_NOJIT		1	/* NYI */
+#error "No support for PPC64"
 #endif
 #endif
 
 
 #if _ARCH_PWR7
 #if _ARCH_PWR7
@@ -330,18 +345,38 @@
 #elif LUAJIT_TARGET == LUAJIT_ARCH_MIPS32 || LUAJIT_TARGET == LUAJIT_ARCH_MIPS64
 #elif LUAJIT_TARGET == LUAJIT_ARCH_MIPS32 || LUAJIT_TARGET == LUAJIT_ARCH_MIPS64
 
 
 #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL)
 #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL)
+#if __mips_isa_rev >= 6
+#define LJ_TARGET_MIPSR6	1
+#define LJ_TARGET_UNALIGNED	1
+#endif
 #if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32
 #if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32
+#if LJ_TARGET_MIPSR6
+#define LJ_ARCH_NAME		"mips32r6el"
+#else
 #define LJ_ARCH_NAME		"mipsel"
 #define LJ_ARCH_NAME		"mipsel"
+#endif
+#else
+#if LJ_TARGET_MIPSR6
+#define LJ_ARCH_NAME		"mips64r6el"
 #else
 #else
 #define LJ_ARCH_NAME		"mips64el"
 #define LJ_ARCH_NAME		"mips64el"
 #endif
 #endif
+#endif
 #define LJ_ARCH_ENDIAN		LUAJIT_LE
 #define LJ_ARCH_ENDIAN		LUAJIT_LE
 #else
 #else
 #if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32
 #if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32
+#if LJ_TARGET_MIPSR6
+#define LJ_ARCH_NAME		"mips32r6"
+#else
 #define LJ_ARCH_NAME		"mips"
 #define LJ_ARCH_NAME		"mips"
+#endif
+#else
+#if LJ_TARGET_MIPSR6
+#define LJ_ARCH_NAME		"mips64r6"
 #else
 #else
 #define LJ_ARCH_NAME		"mips64"
 #define LJ_ARCH_NAME		"mips64"
 #endif
 #endif
+#endif
 #define LJ_ARCH_ENDIAN		LUAJIT_BE
 #define LJ_ARCH_ENDIAN		LUAJIT_BE
 #endif
 #endif
 
 
@@ -377,7 +412,9 @@
 #define LJ_TARGET_UNIFYROT	2	/* Want only IR_BROR. */
 #define LJ_TARGET_UNIFYROT	2	/* Want only IR_BROR. */
 #define LJ_ARCH_NUMMODE		LJ_NUMMODE_DUAL
 #define LJ_ARCH_NUMMODE		LJ_NUMMODE_DUAL
 
 
-#if _MIPS_ARCH_MIPS32R2 || _MIPS_ARCH_MIPS64R2
+#if LJ_TARGET_MIPSR6
+#define LJ_ARCH_VERSION		60
+#elif _MIPS_ARCH_MIPS32R2 || _MIPS_ARCH_MIPS64R2
 #define LJ_ARCH_VERSION		20
 #define LJ_ARCH_VERSION		20
 #else
 #else
 #define LJ_ARCH_VERSION		10
 #define LJ_ARCH_VERSION		10
@@ -387,9 +424,7 @@
 #error "No target architecture defined"
 #error "No target architecture defined"
 #endif
 #endif
 
 
-#ifndef LJ_PAGESIZE
-#define LJ_PAGESIZE		4096
-#endif
+/* -- Checks for requirements --------------------------------------------- */
 
 
 /* Check for minimum required compiler versions. */
 /* Check for minimum required compiler versions. */
 #if defined(__GNUC__)
 #if defined(__GNUC__)
@@ -443,7 +478,7 @@
 #error "No support for ILP32 model on ARM64"
 #error "No support for ILP32 model on ARM64"
 #endif
 #endif
 #elif LJ_TARGET_PPC
 #elif LJ_TARGET_PPC
-#if !LJ_ARCH_PPC64 && (defined(_LITTLE_ENDIAN) && (!defined(_BYTE_ORDER) || (_BYTE_ORDER == _LITTLE_ENDIAN)))
+#if defined(_LITTLE_ENDIAN) && (!defined(_BYTE_ORDER) || (_BYTE_ORDER == _LITTLE_ENDIAN))
 #error "No support for little-endian PPC32"
 #error "No support for little-endian PPC32"
 #endif
 #endif
 #if defined(__NO_FPRS__) && !defined(_SOFT_FLOAT)
 #if defined(__NO_FPRS__) && !defined(_SOFT_FLOAT)
@@ -453,13 +488,20 @@
 #if !((defined(_MIPS_SIM_ABI32) && _MIPS_SIM == _MIPS_SIM_ABI32) || (defined(_ABIO32) && _MIPS_SIM == _ABIO32))
 #if !((defined(_MIPS_SIM_ABI32) && _MIPS_SIM == _MIPS_SIM_ABI32) || (defined(_ABIO32) && _MIPS_SIM == _ABIO32))
 #error "Only o32 ABI supported for MIPS32"
 #error "Only o32 ABI supported for MIPS32"
 #endif
 #endif
+#if LJ_TARGET_MIPSR6
+/* Not that useful, since most available r6 CPUs are 64 bit. */
+#error "No support for MIPS32R6"
+#endif
 #elif LJ_TARGET_MIPS64
 #elif LJ_TARGET_MIPS64
 #if !((defined(_MIPS_SIM_ABI64) && _MIPS_SIM == _MIPS_SIM_ABI64) || (defined(_ABI64) && _MIPS_SIM == _ABI64))
 #if !((defined(_MIPS_SIM_ABI64) && _MIPS_SIM == _MIPS_SIM_ABI64) || (defined(_ABI64) && _MIPS_SIM == _ABI64))
+/* MIPS32ON64 aka n32 ABI support might be desirable, but difficult. */
 #error "Only n64 ABI supported for MIPS64"
 #error "Only n64 ABI supported for MIPS64"
 #endif
 #endif
 #endif
 #endif
 #endif
 #endif
 
 
+/* -- Derived defines ----------------------------------------------------- */
+
 /* Enable or disable the dual-number mode for the VM. */
 /* Enable or disable the dual-number mode for the VM. */
 #if (LJ_ARCH_NUMMODE == LJ_NUMMODE_SINGLE && LUAJIT_NUMMODE == 2) || \
 #if (LJ_ARCH_NUMMODE == LJ_NUMMODE_SINGLE && LUAJIT_NUMMODE == 2) || \
     (LJ_ARCH_NUMMODE == LJ_NUMMODE_DUAL && LUAJIT_NUMMODE == 1)
     (LJ_ARCH_NUMMODE == LJ_NUMMODE_DUAL && LUAJIT_NUMMODE == 1)
@@ -557,13 +599,14 @@
 #define LJ_TARGET_UNALIGNED	0
 #define LJ_TARGET_UNALIGNED	0
 #endif
 #endif
 
 
+#ifndef LJ_PAGESIZE
+#define LJ_PAGESIZE		4096
+#endif
+
 /* Various workarounds for embedded operating systems or weak C runtimes. */
 /* Various workarounds for embedded operating systems or weak C runtimes. */
 #if defined(__ANDROID__) || defined(__symbian__) || LJ_TARGET_XBOX360 || LJ_TARGET_WINDOWS
 #if defined(__ANDROID__) || defined(__symbian__) || LJ_TARGET_XBOX360 || LJ_TARGET_WINDOWS
 #define LUAJIT_NO_LOG2
 #define LUAJIT_NO_LOG2
 #endif
 #endif
-#if defined(__symbian__) || LJ_TARGET_WINDOWS
-#define LUAJIT_NO_EXP2
-#endif
 #if LJ_TARGET_CONSOLE || (LJ_TARGET_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0)
 #if LJ_TARGET_CONSOLE || (LJ_TARGET_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0)
 #define LJ_NO_SYSTEM		1
 #define LJ_NO_SYSTEM		1
 #endif
 #endif
@@ -596,4 +639,46 @@ extern void *LJ_WIN_LOADLIBA(const char *path);
 #define LJ_52			0
 #define LJ_52			0
 #endif
 #endif
 
 
+/* -- VM security --------------------------------------------------------- */
+
+/* Don't make any changes here. Instead build with:
+**   make "XCFLAGS=-DLUAJIT_SECURITY_flag=value"
+**
+** Important note to distro maintainers: DO NOT change the defaults for a
+** regular distro build -- neither upwards, nor downwards!
+** These build-time configurable security flags are intended for embedders
+** who may have specific needs wrt. security vs. performance.
+*/
+
+/* Security defaults. */
+#ifndef LUAJIT_SECURITY_PRNG
+/* PRNG init: 0 = fixed/insecure, 1 = secure from OS. */
+#define LUAJIT_SECURITY_PRNG	1
+#endif
+
+#ifndef LUAJIT_SECURITY_STRHASH
+/* String hash: 0 = sparse only, 1 = sparse + dense. */
+#define LUAJIT_SECURITY_STRHASH	1
+#endif
+
+#ifndef LUAJIT_SECURITY_STRID
+/* String IDs: 0 = linear, 1 = reseed < 255, 2 = reseed < 15, 3 = random. */
+#define LUAJIT_SECURITY_STRID	1
+#endif
+
+#ifndef LUAJIT_SECURITY_MCODE
+/* Machine code page protection: 0 = insecure RWX, 1 = secure RW^X. */
+#define LUAJIT_SECURITY_MCODE	1
+#endif
+
+#define LJ_SECURITY_MODE \
+  ( 0u \
+  | ((LUAJIT_SECURITY_PRNG & 3) << 0) \
+  | ((LUAJIT_SECURITY_STRHASH & 3) << 2) \
+  | ((LUAJIT_SECURITY_STRID & 3) << 4) \
+  | ((LUAJIT_SECURITY_MCODE & 3) << 6) \
+  )
+#define LJ_SECURITY_MODESTRING \
+  "\004prng\007strhash\005strid\005mcode"
+
 #endif
 #endif

+ 159 - 90
libs/LuaJIT/src/lj_asm.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** IR assembler (SSA IR -> machine code).
 ** IR assembler (SSA IR -> machine code).
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lj_asm_c
 #define lj_asm_c
@@ -96,6 +96,12 @@ typedef struct ASMState {
   uint16_t parentmap[LJ_MAX_JSLOTS];  /* Parent instruction to RegSP map. */
   uint16_t parentmap[LJ_MAX_JSLOTS];  /* Parent instruction to RegSP map. */
 } ASMState;
 } ASMState;
 
 
+#ifdef LUA_USE_ASSERT
+#define lj_assertA(c, ...)	lj_assertG_(J2G(as->J), (c), __VA_ARGS__)
+#else
+#define lj_assertA(c, ...)	((void)as)
+#endif
+
 #define IR(ref)			(&as->ir[(ref)])
 #define IR(ref)			(&as->ir[(ref)])
 
 
 #define ASMREF_TMP1		REF_TRUE	/* Temp. register. */
 #define ASMREF_TMP1		REF_TRUE	/* Temp. register. */
@@ -127,9 +133,8 @@ static LJ_AINLINE void checkmclim(ASMState *as)
 #ifdef LUA_USE_ASSERT
 #ifdef LUA_USE_ASSERT
   if (as->mcp + MCLIM_REDZONE < as->mcp_prev) {
   if (as->mcp + MCLIM_REDZONE < as->mcp_prev) {
     IRIns *ir = IR(as->curins+1);
     IRIns *ir = IR(as->curins+1);
-    fprintf(stderr, "RED ZONE OVERFLOW: %p IR %04d  %02d %04d %04d\n", as->mcp,
-	    as->curins+1-REF_BIAS, ir->o, ir->op1-REF_BIAS, ir->op2-REF_BIAS);
-    lua_assert(0);
+    lj_assertA(0, "red zone overflow: %p IR %04d  %02d %04d %04d\n", as->mcp,
+      as->curins+1-REF_BIAS, ir->o, ir->op1-REF_BIAS, ir->op2-REF_BIAS);
   }
   }
 #endif
 #endif
   if (LJ_UNLIKELY(as->mcp < as->mclim)) asm_mclimit(as);
   if (LJ_UNLIKELY(as->mcp < as->mclim)) asm_mclimit(as);
@@ -243,7 +248,7 @@ static void ra_dprintf(ASMState *as, const char *fmt, ...)
 	  *p++ = *q >= 'A' && *q <= 'Z' ? *q + 0x20 : *q;
 	  *p++ = *q >= 'A' && *q <= 'Z' ? *q + 0x20 : *q;
       } else {
       } else {
 	*p++ = '?';
 	*p++ = '?';
-	lua_assert(0);
+	lj_assertA(0, "bad register %d for debug format \"%s\"", r, fmt);
       }
       }
     } else if (e[1] == 'f' || e[1] == 'i') {
     } else if (e[1] == 'f' || e[1] == 'i') {
       IRRef ref;
       IRRef ref;
@@ -261,7 +266,7 @@ static void ra_dprintf(ASMState *as, const char *fmt, ...)
     } else if (e[1] == 'x') {
     } else if (e[1] == 'x') {
       p += sprintf(p, "%08x", va_arg(argp, int32_t));
       p += sprintf(p, "%08x", va_arg(argp, int32_t));
     } else {
     } else {
-      lua_assert(0);
+      lj_assertA(0, "bad debug format code");
     }
     }
     fmt = e+2;
     fmt = e+2;
   }
   }
@@ -320,7 +325,7 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
   Reg r;
   Reg r;
   if (ra_iskref(ref)) {
   if (ra_iskref(ref)) {
     r = ra_krefreg(ref);
     r = ra_krefreg(ref);
-    lua_assert(!rset_test(as->freeset, r));
+    lj_assertA(!rset_test(as->freeset, r), "rematk of free reg %d", r);
     ra_free(as, r);
     ra_free(as, r);
     ra_modified(as, r);
     ra_modified(as, r);
 #if LJ_64
 #if LJ_64
@@ -332,7 +337,9 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
   }
   }
   ir = IR(ref);
   ir = IR(ref);
   r = ir->r;
   r = ir->r;
-  lua_assert(ra_hasreg(r) && !ra_hasspill(ir->s));
+  lj_assertA(ra_hasreg(r), "rematk of K%03d has no reg", REF_BIAS - ref);
+  lj_assertA(!ra_hasspill(ir->s),
+	     "rematk of K%03d has spill slot [%x]", REF_BIAS - ref, ir->s);
   ra_free(as, r);
   ra_free(as, r);
   ra_modified(as, r);
   ra_modified(as, r);
   ir->r = RID_INIT;  /* Do not keep any hint. */
   ir->r = RID_INIT;  /* Do not keep any hint. */
@@ -346,7 +353,8 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
     ra_sethint(ir->r, RID_BASE);  /* Restore BASE register hint. */
     ra_sethint(ir->r, RID_BASE);  /* Restore BASE register hint. */
     emit_getgl(as, r, jit_base);
     emit_getgl(as, r, jit_base);
   } else if (emit_canremat(ASMREF_L) && ir->o == IR_KPRI) {
   } else if (emit_canremat(ASMREF_L) && ir->o == IR_KPRI) {
-    lua_assert(irt_isnil(ir->t));  /* REF_NIL stores ASMREF_L register. */
+    /* REF_NIL stores ASMREF_L register. */
+    lj_assertA(irt_isnil(ir->t), "rematk of bad ASMREF_L");
     emit_getgl(as, r, cur_L);
     emit_getgl(as, r, cur_L);
 #if LJ_64
 #if LJ_64
   } else if (ir->o == IR_KINT64) {
   } else if (ir->o == IR_KINT64) {
@@ -359,8 +367,9 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
 #endif
 #endif
 #endif
 #endif
   } else {
   } else {
-    lua_assert(ir->o == IR_KINT || ir->o == IR_KGC ||
-	       ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL);
+    lj_assertA(ir->o == IR_KINT || ir->o == IR_KGC ||
+	       ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL,
+	       "rematk of bad IR op %d", ir->o);
     emit_loadi(as, r, ir->i);
     emit_loadi(as, r, ir->i);
   }
   }
   return r;
   return r;
@@ -370,7 +379,8 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
 static int32_t ra_spill(ASMState *as, IRIns *ir)
 static int32_t ra_spill(ASMState *as, IRIns *ir)
 {
 {
   int32_t slot = ir->s;
   int32_t slot = ir->s;
-  lua_assert(ir >= as->ir + REF_TRUE);
+  lj_assertA(ir >= as->ir + REF_TRUE,
+	     "spill of K%03d", REF_BIAS - (int)(ir - as->ir));
   if (!ra_hasspill(slot)) {
   if (!ra_hasspill(slot)) {
     if (irt_is64(ir->t)) {
     if (irt_is64(ir->t)) {
       slot = as->evenspill;
       slot = as->evenspill;
@@ -395,7 +405,9 @@ static Reg ra_releasetmp(ASMState *as, IRRef ref)
 {
 {
   IRIns *ir = IR(ref);
   IRIns *ir = IR(ref);
   Reg r = ir->r;
   Reg r = ir->r;
-  lua_assert(ra_hasreg(r) && !ra_hasspill(ir->s));
+  lj_assertA(ra_hasreg(r), "release of TMP%d has no reg", ref-ASMREF_TMP1+1);
+  lj_assertA(!ra_hasspill(ir->s),
+	     "release of TMP%d has spill slot [%x]", ref-ASMREF_TMP1+1, ir->s);
   ra_free(as, r);
   ra_free(as, r);
   ra_modified(as, r);
   ra_modified(as, r);
   ir->r = RID_INIT;
   ir->r = RID_INIT;
@@ -411,7 +423,7 @@ static Reg ra_restore(ASMState *as, IRRef ref)
     IRIns *ir = IR(ref);
     IRIns *ir = IR(ref);
     int32_t ofs = ra_spill(as, ir);  /* Force a spill slot. */
     int32_t ofs = ra_spill(as, ir);  /* Force a spill slot. */
     Reg r = ir->r;
     Reg r = ir->r;
-    lua_assert(ra_hasreg(r));
+    lj_assertA(ra_hasreg(r), "restore of IR %04d has no reg", ref - REF_BIAS);
     ra_sethint(ir->r, r);  /* Keep hint. */
     ra_sethint(ir->r, r);  /* Keep hint. */
     ra_free(as, r);
     ra_free(as, r);
     if (!rset_test(as->weakset, r)) {  /* Only restore non-weak references. */
     if (!rset_test(as->weakset, r)) {  /* Only restore non-weak references. */
@@ -440,14 +452,15 @@ static Reg ra_evict(ASMState *as, RegSet allow)
 {
 {
   IRRef ref;
   IRRef ref;
   RegCost cost = ~(RegCost)0;
   RegCost cost = ~(RegCost)0;
-  lua_assert(allow != RSET_EMPTY);
+  lj_assertA(allow != RSET_EMPTY, "evict from empty set");
   if (RID_NUM_FPR == 0 || allow < RID2RSET(RID_MAX_GPR)) {
   if (RID_NUM_FPR == 0 || allow < RID2RSET(RID_MAX_GPR)) {
     GPRDEF(MINCOST)
     GPRDEF(MINCOST)
   } else {
   } else {
     FPRDEF(MINCOST)
     FPRDEF(MINCOST)
   }
   }
   ref = regcost_ref(cost);
   ref = regcost_ref(cost);
-  lua_assert(ra_iskref(ref) || (ref >= as->T->nk && ref < as->T->nins));
+  lj_assertA(ra_iskref(ref) || (ref >= as->T->nk && ref < as->T->nins),
+	     "evict of out-of-range IR %04d", ref - REF_BIAS);
   /* Preferably pick any weak ref instead of a non-weak, non-const ref. */
   /* Preferably pick any weak ref instead of a non-weak, non-const ref. */
   if (!irref_isk(ref) && (as->weakset & allow)) {
   if (!irref_isk(ref) && (as->weakset & allow)) {
     IRIns *ir = IR(ref);
     IRIns *ir = IR(ref);
@@ -605,7 +618,8 @@ static Reg ra_allocref(ASMState *as, IRRef ref, RegSet allow)
   IRIns *ir = IR(ref);
   IRIns *ir = IR(ref);
   RegSet pick = as->freeset & allow;
   RegSet pick = as->freeset & allow;
   Reg r;
   Reg r;
-  lua_assert(ra_noreg(ir->r));
+  lj_assertA(ra_noreg(ir->r),
+	     "IR %04d already has reg %d", ref - REF_BIAS, ir->r);
   if (pick) {
   if (pick) {
     /* First check register hint from propagation or PHI. */
     /* First check register hint from propagation or PHI. */
     if (ra_hashint(ir->r)) {
     if (ra_hashint(ir->r)) {
@@ -669,8 +683,10 @@ static void ra_rename(ASMState *as, Reg down, Reg up)
   IRIns *ir = IR(ref);
   IRIns *ir = IR(ref);
   ir->r = (uint8_t)up;
   ir->r = (uint8_t)up;
   as->cost[down] = 0;
   as->cost[down] = 0;
-  lua_assert((down < RID_MAX_GPR) == (up < RID_MAX_GPR));
-  lua_assert(!rset_test(as->freeset, down) && rset_test(as->freeset, up));
+  lj_assertA((down < RID_MAX_GPR) == (up < RID_MAX_GPR),
+	     "rename between GPR/FPR %d and %d", down, up);
+  lj_assertA(!rset_test(as->freeset, down), "rename from free reg %d", down);
+  lj_assertA(rset_test(as->freeset, up), "rename to non-free reg %d", up);
   ra_free(as, down);  /* 'down' is free ... */
   ra_free(as, down);  /* 'down' is free ... */
   ra_modified(as, down);
   ra_modified(as, down);
   rset_clear(as->freeset, up);  /* ... and 'up' is now allocated. */
   rset_clear(as->freeset, up);  /* ... and 'up' is now allocated. */
@@ -711,7 +727,7 @@ static void ra_destreg(ASMState *as, IRIns *ir, Reg r)
 {
 {
   Reg dest = ra_dest(as, ir, RID2RSET(r));
   Reg dest = ra_dest(as, ir, RID2RSET(r));
   if (dest != r) {
   if (dest != r) {
-    lua_assert(rset_test(as->freeset, r));
+    lj_assertA(rset_test(as->freeset, r), "dest reg %d is not free", r);
     ra_modified(as, r);
     ra_modified(as, r);
     emit_movrr(as, ir, dest, r);
     emit_movrr(as, ir, dest, r);
   }
   }
@@ -744,8 +760,9 @@ static void ra_left(ASMState *as, Reg dest, IRRef lref)
 #endif
 #endif
 #endif
 #endif
       } else if (ir->o != IR_KPRI) {
       } else if (ir->o != IR_KPRI) {
-	lua_assert(ir->o == IR_KINT || ir->o == IR_KGC ||
-		   ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL);
+	lj_assertA(ir->o == IR_KINT || ir->o == IR_KGC ||
+		   ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL,
+		   "K%03d has bad IR op %d", REF_BIAS - lref, ir->o);
 	emit_loadi(as, dest, ir->i);
 	emit_loadi(as, dest, ir->i);
 	return;
 	return;
       }
       }
@@ -887,11 +904,14 @@ static void asm_snap_alloc1(ASMState *as, IRRef ref)
 #endif
 #endif
       {  /* Allocate stored values for TNEW, TDUP and CNEW. */
       {  /* Allocate stored values for TNEW, TDUP and CNEW. */
 	IRIns *irs;
 	IRIns *irs;
-	lua_assert(ir->o == IR_TNEW || ir->o == IR_TDUP || ir->o == IR_CNEW);
+	lj_assertA(ir->o == IR_TNEW || ir->o == IR_TDUP || ir->o == IR_CNEW,
+		   "sink of IR %04d has bad op %d", ref - REF_BIAS, ir->o);
 	for (irs = IR(as->snapref-1); irs > ir; irs--)
 	for (irs = IR(as->snapref-1); irs > ir; irs--)
 	  if (irs->r == RID_SINK && asm_sunk_store(as, ir, irs)) {
 	  if (irs->r == RID_SINK && asm_sunk_store(as, ir, irs)) {
-	    lua_assert(irs->o == IR_ASTORE || irs->o == IR_HSTORE ||
-		       irs->o == IR_FSTORE || irs->o == IR_XSTORE);
+	    lj_assertA(irs->o == IR_ASTORE || irs->o == IR_HSTORE ||
+		       irs->o == IR_FSTORE || irs->o == IR_XSTORE,
+		       "sunk store IR %04d has bad op %d",
+		       (int)(irs - as->ir) - REF_BIAS, irs->o);
 	    asm_snap_alloc1(as, irs->op2);
 	    asm_snap_alloc1(as, irs->op2);
 	    if (LJ_32 && (irs+1)->o == IR_HIOP)
 	    if (LJ_32 && (irs+1)->o == IR_HIOP)
 	      asm_snap_alloc1(as, (irs+1)->op2);
 	      asm_snap_alloc1(as, (irs+1)->op2);
@@ -938,7 +958,9 @@ static void asm_snap_alloc(ASMState *as)
     if (!irref_isk(ref)) {
     if (!irref_isk(ref)) {
       asm_snap_alloc1(as, ref);
       asm_snap_alloc1(as, ref);
       if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) {
       if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) {
-	lua_assert(irt_type(IR(ref+1)->t) == IRT_SOFTFP);
+	lj_assertA(irt_type(IR(ref+1)->t) == IRT_SOFTFP,
+		   "snap %d[%d] points to bad SOFTFP IR %04d",
+		   as->snapno, n, ref - REF_BIAS);
 	asm_snap_alloc1(as, ref+1);
 	asm_snap_alloc1(as, ref+1);
       }
       }
     }
     }
@@ -1002,19 +1024,20 @@ static int32_t asm_stack_adjust(ASMState *as)
 }
 }
 
 
 /* Must match with hash*() in lj_tab.c. */
 /* Must match with hash*() in lj_tab.c. */
-static uint32_t ir_khash(IRIns *ir)
+static uint32_t ir_khash(ASMState *as, IRIns *ir)
 {
 {
   uint32_t lo, hi;
   uint32_t lo, hi;
+  UNUSED(as);
   if (irt_isstr(ir->t)) {
   if (irt_isstr(ir->t)) {
-    return ir_kstr(ir)->hash;
+    return ir_kstr(ir)->sid;
   } else if (irt_isnum(ir->t)) {
   } else if (irt_isnum(ir->t)) {
     lo = ir_knum(ir)->u32.lo;
     lo = ir_knum(ir)->u32.lo;
     hi = ir_knum(ir)->u32.hi << 1;
     hi = ir_knum(ir)->u32.hi << 1;
   } else if (irt_ispri(ir->t)) {
   } else if (irt_ispri(ir->t)) {
-    lua_assert(!irt_isnil(ir->t));
+    lj_assertA(!irt_isnil(ir->t), "hash of nil key");
     return irt_type(ir->t)-IRT_FALSE;
     return irt_type(ir->t)-IRT_FALSE;
   } else {
   } else {
-    lua_assert(irt_isgcv(ir->t));
+    lj_assertA(irt_isgcv(ir->t), "hash of bad IR type %d", irt_type(ir->t));
     lo = u32ptr(ir_kgc(ir));
     lo = u32ptr(ir_kgc(ir));
 #if LJ_GC64
 #if LJ_GC64
     hi = (uint32_t)(u64ptr(ir_kgc(ir)) >> 32) | (irt_toitype(ir->t) << 15);
     hi = (uint32_t)(u64ptr(ir_kgc(ir)) >> 32) | (irt_toitype(ir->t) << 15);
@@ -1122,7 +1145,8 @@ static void asm_bufput(ASMState *as, IRIns *ir)
   args[0] = ir->op1;  /* SBuf * */
   args[0] = ir->op1;  /* SBuf * */
   args[1] = ir->op2;  /* GCstr * */
   args[1] = ir->op2;  /* GCstr * */
   irs = IR(ir->op2);
   irs = IR(ir->op2);
-  lua_assert(irt_isstr(irs->t));
+  lj_assertA(irt_isstr(irs->t),
+	     "BUFPUT of non-string IR %04d", ir->op2 - REF_BIAS);
   if (irs->o == IR_KGC) {
   if (irs->o == IR_KGC) {
     GCstr *s = ir_kstr(irs);
     GCstr *s = ir_kstr(irs);
     if (s->len == 1) {  /* Optimize put of single-char string constant. */
     if (s->len == 1) {  /* Optimize put of single-char string constant. */
@@ -1136,7 +1160,8 @@ static void asm_bufput(ASMState *as, IRIns *ir)
 	args[1] = ASMREF_TMP1;  /* TValue * */
 	args[1] = ASMREF_TMP1;  /* TValue * */
 	ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putnum];
 	ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putnum];
       } else {
       } else {
-	lua_assert(irt_isinteger(IR(irs->op1)->t));
+	lj_assertA(irt_isinteger(IR(irs->op1)->t),
+		   "TOSTR of non-numeric IR %04d", irs->op1);
 	args[1] = irs->op1;  /* int */
 	args[1] = irs->op1;  /* int */
 	if (irs->op2 == IRTOSTR_INT)
 	if (irs->op2 == IRTOSTR_INT)
 	  ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putint];
 	  ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putint];
@@ -1201,7 +1226,8 @@ static void asm_conv64(ASMState *as, IRIns *ir)
   IRType dt = (((ir-1)->op2 & IRCONV_DSTMASK) >> IRCONV_DSH);
   IRType dt = (((ir-1)->op2 & IRCONV_DSTMASK) >> IRCONV_DSH);
   IRCallID id;
   IRCallID id;
   IRRef args[2];
   IRRef args[2];
-  lua_assert((ir-1)->o == IR_CONV && ir->o == IR_HIOP);
+  lj_assertA((ir-1)->o == IR_CONV && ir->o == IR_HIOP,
+	     "not a CONV/HIOP pair at IR %04d", (int)(ir - as->ir) - REF_BIAS);
   args[LJ_BE] = (ir-1)->op1;
   args[LJ_BE] = (ir-1)->op1;
   args[LJ_LE] = ir->op1;
   args[LJ_LE] = ir->op1;
   if (st == IRT_NUM || st == IRT_FLOAT) {
   if (st == IRT_NUM || st == IRT_FLOAT) {
@@ -1256,15 +1282,16 @@ static void asm_collectargs(ASMState *as, IRIns *ir,
 			    const CCallInfo *ci, IRRef *args)
 			    const CCallInfo *ci, IRRef *args)
 {
 {
   uint32_t n = CCI_XNARGS(ci);
   uint32_t n = CCI_XNARGS(ci);
-  lua_assert(n <= CCI_NARGS_MAX*2);  /* Account for split args. */
+  /* Account for split args. */
+  lj_assertA(n <= CCI_NARGS_MAX*2, "too many args %d to collect", n);
   if ((ci->flags & CCI_L)) { *args++ = ASMREF_L; n--; }
   if ((ci->flags & CCI_L)) { *args++ = ASMREF_L; n--; }
   while (n-- > 1) {
   while (n-- > 1) {
     ir = IR(ir->op1);
     ir = IR(ir->op1);
-    lua_assert(ir->o == IR_CARG);
+    lj_assertA(ir->o == IR_CARG, "malformed CALL arg tree");
     args[n] = ir->op2 == REF_NIL ? 0 : ir->op2;
     args[n] = ir->op2 == REF_NIL ? 0 : ir->op2;
   }
   }
   args[0] = ir->op1 == REF_NIL ? 0 : ir->op1;
   args[0] = ir->op1 == REF_NIL ? 0 : ir->op1;
-  lua_assert(IR(ir->op1)->o != IR_CARG);
+  lj_assertA(IR(ir->op1)->o != IR_CARG, "malformed CALL arg tree");
 }
 }
 
 
 /* Reconstruct CCallInfo flags for CALLX*. */
 /* Reconstruct CCallInfo flags for CALLX*. */
@@ -1308,32 +1335,6 @@ static void asm_call(ASMState *as, IRIns *ir)
   asm_gencall(as, ci, args);
   asm_gencall(as, ci, args);
 }
 }
 
 
-#if !LJ_SOFTFP32
-static void asm_fppow(ASMState *as, IRIns *ir, IRRef lref, IRRef rref)
-{
-  const CCallInfo *ci = &lj_ir_callinfo[IRCALL_pow];
-  IRRef args[2];
-  args[0] = lref;
-  args[1] = rref;
-  asm_setupresult(as, ir, ci);
-  asm_gencall(as, ci, args);
-}
-
-static int asm_fpjoin_pow(ASMState *as, IRIns *ir)
-{
-  IRIns *irp = IR(ir->op1);
-  if (irp == ir-1 && irp->o == IR_MUL && !ra_used(irp)) {
-    IRIns *irpp = IR(irp->op1);
-    if (irpp == ir-2 && irpp->o == IR_FPMATH &&
-	irpp->op2 == IRFPM_LOG2 && !ra_used(irpp)) {
-      asm_fppow(as, ir, irpp->op1, irp->op2);
-      return 1;
-    }
-  }
-  return 0;
-}
-#endif
-
 /* -- PHI and loop handling ----------------------------------------------- */
 /* -- PHI and loop handling ----------------------------------------------- */
 
 
 /* Break a PHI cycle by renaming to a free register (evict if needed). */
 /* Break a PHI cycle by renaming to a free register (evict if needed). */
@@ -1604,6 +1605,68 @@ static void asm_loop(ASMState *as)
 #error "Missing assembler for target CPU"
 #error "Missing assembler for target CPU"
 #endif
 #endif
 
 
+/* -- Common instruction helpers ------------------------------------------ */
+
+#if !LJ_SOFTFP32
+#if !LJ_TARGET_X86ORX64
+#define asm_ldexp(as, ir)	asm_callid(as, ir, IRCALL_ldexp)
+#define asm_fppowi(as, ir)	asm_callid(as, ir, IRCALL_lj_vm_powi)
+#endif
+
+static void asm_pow(ASMState *as, IRIns *ir)
+{
+#if LJ_64 && LJ_HASFFI
+  if (!irt_isnum(ir->t))
+    asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 :
+					  IRCALL_lj_carith_powu64);
+  else
+#endif
+  if (irt_isnum(IR(ir->op2)->t))
+    asm_callid(as, ir, IRCALL_pow);
+  else
+    asm_fppowi(as, ir);
+}
+
+static void asm_div(ASMState *as, IRIns *ir)
+{
+#if LJ_64 && LJ_HASFFI
+  if (!irt_isnum(ir->t))
+    asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_divi64 :
+					  IRCALL_lj_carith_divu64);
+  else
+#endif
+    asm_fpdiv(as, ir);
+}
+#endif
+
+static void asm_mod(ASMState *as, IRIns *ir)
+{
+#if LJ_64 && LJ_HASFFI
+  if (!irt_isint(ir->t))
+    asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_modi64 :
+					  IRCALL_lj_carith_modu64);
+  else
+#endif
+    asm_callid(as, ir, IRCALL_lj_vm_modi);
+}
+
+static void asm_fuseequal(ASMState *as, IRIns *ir)
+{
+  /* Fuse HREF + EQ/NE. */
+  if ((ir-1)->o == IR_HREF && ir->op1 == as->curins-1) {
+    as->curins--;
+    asm_href(as, ir-1, (IROp)ir->o);
+  } else {
+    asm_equal(as, ir);
+  }
+}
+
+static void asm_alen(ASMState *as, IRIns *ir)
+{
+  asm_callid(as, ir, ir->op2 == REF_NIL ? IRCALL_lj_tab_len :
+					  IRCALL_lj_tab_len_hint);
+}
+
 /* -- Instruction dispatch ------------------------------------------------ */
 /* -- Instruction dispatch ------------------------------------------------ */
 
 
 /* Assemble a single instruction. */
 /* Assemble a single instruction. */
@@ -1612,7 +1675,10 @@ static void asm_ir(ASMState *as, IRIns *ir)
   switch ((IROp)ir->o) {
   switch ((IROp)ir->o) {
   /* Miscellaneous ops. */
   /* Miscellaneous ops. */
   case IR_LOOP: asm_loop(as); break;
   case IR_LOOP: asm_loop(as); break;
-  case IR_NOP: case IR_XBAR: lua_assert(!ra_used(ir)); break;
+  case IR_NOP: case IR_XBAR:
+    lj_assertA(!ra_used(ir),
+	       "IR %04d not unused", (int)(ir - as->ir) - REF_BIAS);
+    break;
   case IR_USE:
   case IR_USE:
     ra_alloc1(as, ir->op1, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); break;
     ra_alloc1(as, ir->op1, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); break;
   case IR_PHI: asm_phi(as, ir); break;
   case IR_PHI: asm_phi(as, ir); break;
@@ -1626,14 +1692,7 @@ static void asm_ir(ASMState *as, IRIns *ir)
   case IR_ABC:
   case IR_ABC:
     asm_comp(as, ir);
     asm_comp(as, ir);
     break;
     break;
-  case IR_EQ: case IR_NE:
-    if ((ir-1)->o == IR_HREF && ir->op1 == as->curins-1) {
-      as->curins--;
-      asm_href(as, ir-1, (IROp)ir->o);
-    } else {
-      asm_equal(as, ir);
-    }
-    break;
+  case IR_EQ: case IR_NE: asm_fuseequal(as, ir); break;
 
 
   case IR_RETF: asm_retf(as, ir); break;
   case IR_RETF: asm_retf(as, ir); break;
 
 
@@ -1657,14 +1716,15 @@ static void asm_ir(ASMState *as, IRIns *ir)
   case IR_NEG: asm_neg(as, ir); break;
   case IR_NEG: asm_neg(as, ir); break;
 #if LJ_SOFTFP32
 #if LJ_SOFTFP32
   case IR_DIV: case IR_POW: case IR_ABS:
   case IR_DIV: case IR_POW: case IR_ABS:
-  case IR_ATAN2: case IR_LDEXP: case IR_FPMATH: case IR_TOBIT:
-    lua_assert(0);  /* Unused for LJ_SOFTFP32. */
+  case IR_LDEXP: case IR_FPMATH: case IR_TOBIT:
+    /* Unused for LJ_SOFTFP32. */
+    lj_assertA(0, "IR %04d with unused op %d",
+		  (int)(ir - as->ir) - REF_BIAS, ir->o);
     break;
     break;
 #else
 #else
   case IR_DIV: asm_div(as, ir); break;
   case IR_DIV: asm_div(as, ir); break;
   case IR_POW: asm_pow(as, ir); break;
   case IR_POW: asm_pow(as, ir); break;
   case IR_ABS: asm_abs(as, ir); break;
   case IR_ABS: asm_abs(as, ir); break;
-  case IR_ATAN2: asm_atan2(as, ir); break;
   case IR_LDEXP: asm_ldexp(as, ir); break;
   case IR_LDEXP: asm_ldexp(as, ir); break;
   case IR_FPMATH: asm_fpmath(as, ir); break;
   case IR_FPMATH: asm_fpmath(as, ir); break;
   case IR_TOBIT: asm_tobit(as, ir); break;
   case IR_TOBIT: asm_tobit(as, ir); break;
@@ -1694,6 +1754,7 @@ static void asm_ir(ASMState *as, IRIns *ir)
   case IR_FLOAD: asm_fload(as, ir); break;
   case IR_FLOAD: asm_fload(as, ir); break;
   case IR_XLOAD: asm_xload(as, ir); break;
   case IR_XLOAD: asm_xload(as, ir); break;
   case IR_SLOAD: asm_sload(as, ir); break;
   case IR_SLOAD: asm_sload(as, ir); break;
+  case IR_ALEN: asm_alen(as, ir); break;
 
 
   case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break;
   case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break;
   case IR_FSTORE: asm_fstore(as, ir); break;
   case IR_FSTORE: asm_fstore(as, ir); break;
@@ -1703,7 +1764,14 @@ static void asm_ir(ASMState *as, IRIns *ir)
   case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break;
   case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break;
   case IR_TNEW: asm_tnew(as, ir); break;
   case IR_TNEW: asm_tnew(as, ir); break;
   case IR_TDUP: asm_tdup(as, ir); break;
   case IR_TDUP: asm_tdup(as, ir); break;
-  case IR_CNEW: case IR_CNEWI: asm_cnew(as, ir); break;
+  case IR_CNEW: case IR_CNEWI:
+#if LJ_HASFFI
+    asm_cnew(as, ir);
+#else
+    lj_assertA(0, "IR %04d with unused op %d",
+		  (int)(ir - as->ir) - REF_BIAS, ir->o);
+#endif
+    break;
 
 
   /* Buffer operations. */
   /* Buffer operations. */
   case IR_BUFHDR: asm_bufhdr(as, ir); break;
   case IR_BUFHDR: asm_bufhdr(as, ir); break;
@@ -1779,8 +1847,10 @@ static void asm_head_side(ASMState *as)
   for (i = as->stopins; i > REF_BASE; i--) {
   for (i = as->stopins; i > REF_BASE; i--) {
     IRIns *ir = IR(i);
     IRIns *ir = IR(i);
     RegSP rs;
     RegSP rs;
-    lua_assert((ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_PARENT)) ||
-	       (LJ_SOFTFP && ir->o == IR_HIOP) || ir->o == IR_PVAL);
+    lj_assertA((ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_PARENT)) ||
+	       (LJ_SOFTFP && ir->o == IR_HIOP) || ir->o == IR_PVAL,
+	       "IR %04d has bad parent op %d",
+	       (int)(ir - as->ir) - REF_BIAS, ir->o);
     rs = as->parentmap[i - REF_FIRST];
     rs = as->parentmap[i - REF_FIRST];
     if (ra_hasreg(ir->r)) {
     if (ra_hasreg(ir->r)) {
       rset_clear(allow, ir->r);
       rset_clear(allow, ir->r);
@@ -2039,7 +2109,7 @@ static void asm_setup_regsp(ASMState *as)
   ir = IR(REF_FIRST);
   ir = IR(REF_FIRST);
   if (as->parent) {
   if (as->parent) {
     uint16_t *p;
     uint16_t *p;
-    lastir = lj_snap_regspmap(as->parent, as->J->exitno, ir);
+    lastir = lj_snap_regspmap(as->J, as->parent, as->J->exitno, ir);
     if (lastir - ir > LJ_MAX_JSLOTS)
     if (lastir - ir > LJ_MAX_JSLOTS)
       lj_trace_err(as->J, LJ_TRERR_NYICOAL);
       lj_trace_err(as->J, LJ_TRERR_NYICOAL);
     as->stopins = (IRRef)((lastir-1) - as->ir);
     as->stopins = (IRRef)((lastir-1) - as->ir);
@@ -2112,8 +2182,8 @@ static void asm_setup_regsp(ASMState *as)
 	  ir->prev = REGSP_HINT(RID_FPRET);
 	  ir->prev = REGSP_HINT(RID_FPRET);
 	  continue;
 	  continue;
 	}
 	}
-	/* fallthrough */
 #endif
 #endif
+      /* fallthrough */
       case IR_CALLN: case IR_CALLXS:
       case IR_CALLN: case IR_CALLXS:
 #if LJ_SOFTFP
 #if LJ_SOFTFP
       case IR_MIN: case IR_MAX:
       case IR_MIN: case IR_MAX:
@@ -2158,11 +2228,6 @@ static void asm_setup_regsp(ASMState *as)
 	as->modset = RSET_SCRATCH;
 	as->modset = RSET_SCRATCH;
       break;
       break;
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
-    case IR_ATAN2:
-#if LJ_TARGET_X86
-      if (as->evenspill < 4)  /* Leave room to call atan2(). */
-	as->evenspill = 4;
-#endif
 #if !LJ_TARGET_X86ORX64
 #if !LJ_TARGET_X86ORX64
     case IR_LDEXP:
     case IR_LDEXP:
 #endif
 #endif
@@ -2173,6 +2238,10 @@ static void asm_setup_regsp(ASMState *as)
 	if (inloop)
 	if (inloop)
 	  as->modset |= RSET_SCRATCH;
 	  as->modset |= RSET_SCRATCH;
 #if LJ_TARGET_X86
 #if LJ_TARGET_X86
+	if (irt_isnum(IR(ir->op2)->t)) {
+	  if (as->evenspill < 4)  /* Leave room to call pow(). */
+	    as->evenspill = 4;
+	}
 	break;
 	break;
 #else
 #else
 	ir->prev = REGSP_HINT(RID_FPRET);
 	ir->prev = REGSP_HINT(RID_FPRET);
@@ -2198,9 +2267,6 @@ static void asm_setup_regsp(ASMState *as)
 	  continue;
 	  continue;
 	}
 	}
 	break;
 	break;
-      } else if (ir->op2 == IRFPM_EXP2 && !LJ_64) {
-	if (as->evenspill < 4)  /* Leave room to call pow(). */
-	  as->evenspill = 4;
       }
       }
 #endif
 #endif
       if (inloop)
       if (inloop)
@@ -2276,7 +2342,7 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
   /* Ensure an initialized instruction beyond the last one for HIOP checks. */
   /* Ensure an initialized instruction beyond the last one for HIOP checks. */
   /* This also allows one RENAME to be added without reallocating curfinal. */
   /* This also allows one RENAME to be added without reallocating curfinal. */
   as->orignins = lj_ir_nextins(J);
   as->orignins = lj_ir_nextins(J);
-  J->cur.ir[as->orignins].o = IR_NOP;
+  lj_ir_nop(&J->cur.ir[as->orignins]);
 
 
   /* Setup initial state. Copy some fields to reduce indirections. */
   /* Setup initial state. Copy some fields to reduce indirections. */
   as->J = J;
   as->J = J;
@@ -2347,7 +2413,10 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
     /* Assemble a trace in linear backwards order. */
     /* Assemble a trace in linear backwards order. */
     for (as->curins--; as->curins > as->stopins; as->curins--) {
     for (as->curins--; as->curins > as->stopins; as->curins--) {
       IRIns *ir = IR(as->curins);
       IRIns *ir = IR(as->curins);
-      lua_assert(!(LJ_32 && irt_isint64(ir->t)));  /* Handled by SPLIT. */
+      /* 64 bit types handled by SPLIT for 32 bit archs. */
+      lj_assertA(!(LJ_32 && irt_isint64(ir->t)),
+		 "IR %04d has unsplit 64 bit type",
+		 (int)(ir - as->ir) - REF_BIAS);
       if (!ra_used(ir) && !ir_sideeff(ir) && (as->flags & JIT_F_OPT_DCE))
       if (!ra_used(ir) && !ir_sideeff(ir) && (as->flags & JIT_F_OPT_DCE))
 	continue;  /* Dead-code elimination can be soooo easy. */
 	continue;  /* Dead-code elimination can be soooo easy. */
       if (irt_isguard(ir->t))
       if (irt_isguard(ir->t))
@@ -2377,7 +2446,7 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
     asm_phi_fixup(as);
     asm_phi_fixup(as);
 
 
     if (J->curfinal->nins >= T->nins) {  /* IR didn't grow? */
     if (J->curfinal->nins >= T->nins) {  /* IR didn't grow? */
-      lua_assert(J->curfinal->nk == T->nk);
+      lj_assertA(J->curfinal->nk == T->nk, "unexpected IR constant growth");
       memcpy(J->curfinal->ir + as->orignins, T->ir + as->orignins,
       memcpy(J->curfinal->ir + as->orignins, T->ir + as->orignins,
 	     (T->nins - as->orignins) * sizeof(IRIns));  /* Copy RENAMEs. */
 	     (T->nins - as->orignins) * sizeof(IRIns));  /* Copy RENAMEs. */
       T->nins = J->curfinal->nins;
       T->nins = J->curfinal->nins;

+ 1 - 1
libs/LuaJIT/src/lj_asm.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** IR assembler (SSA IR -> machine code).
 ** IR assembler (SSA IR -> machine code).
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _LJ_ASM_H
 #ifndef _LJ_ASM_H

+ 91 - 73
libs/LuaJIT/src/lj_asm_arm.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** ARM IR assembler (SSA IR -> machine code).
 ** ARM IR assembler (SSA IR -> machine code).
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 /* -- Register allocator extensions --------------------------------------- */
 /* -- Register allocator extensions --------------------------------------- */
@@ -41,7 +41,7 @@ static Reg ra_scratchpair(ASMState *as, RegSet allow)
       }
       }
     }
     }
   }
   }
-  lua_assert(rset_test(RSET_GPREVEN, r));
+  lj_assertA(rset_test(RSET_GPREVEN, r), "odd reg %d", r);
   ra_modified(as, r);
   ra_modified(as, r);
   ra_modified(as, r+1);
   ra_modified(as, r+1);
   RA_DBGX((as, "scratchpair    $r $r", r, r+1));
   RA_DBGX((as, "scratchpair    $r $r", r, r+1));
@@ -269,7 +269,7 @@ static void asm_fusexref(ASMState *as, ARMIns ai, Reg rd, IRRef ref,
 	return;
 	return;
       }
       }
     } else if (ir->o == IR_STRREF && !(!LJ_SOFTFP && (ai & 0x08000000))) {
     } else if (ir->o == IR_STRREF && !(!LJ_SOFTFP && (ai & 0x08000000))) {
-      lua_assert(ofs == 0);
+      lj_assertA(ofs == 0, "bad usage");
       ofs = (int32_t)sizeof(GCstr);
       ofs = (int32_t)sizeof(GCstr);
       if (irref_isk(ir->op2)) {
       if (irref_isk(ir->op2)) {
 	ofs += IR(ir->op2)->i;
 	ofs += IR(ir->op2)->i;
@@ -389,9 +389,11 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
       as->freeset |= (of & RSET_RANGE(REGARG_FIRSTGPR, REGARG_LASTGPR+1));
       as->freeset |= (of & RSET_RANGE(REGARG_FIRSTGPR, REGARG_LASTGPR+1));
       if (irt_isnum(ir->t)) gpr = (gpr+1) & ~1u;
       if (irt_isnum(ir->t)) gpr = (gpr+1) & ~1u;
       if (gpr <= REGARG_LASTGPR) {
       if (gpr <= REGARG_LASTGPR) {
-	lua_assert(rset_test(as->freeset, gpr));  /* Must have been evicted. */
+	lj_assertA(rset_test(as->freeset, gpr),
+		   "reg %d not free", gpr);  /* Must have been evicted. */
 	if (irt_isnum(ir->t)) {
 	if (irt_isnum(ir->t)) {
-	  lua_assert(rset_test(as->freeset, gpr+1));  /* Ditto. */
+	  lj_assertA(rset_test(as->freeset, gpr+1),
+		     "reg %d not free", gpr+1);  /* Ditto. */
 	  emit_dnm(as, ARMI_VMOV_RR_D, gpr, gpr+1, (src & 15));
 	  emit_dnm(as, ARMI_VMOV_RR_D, gpr, gpr+1, (src & 15));
 	  gpr += 2;
 	  gpr += 2;
 	} else {
 	} else {
@@ -408,7 +410,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
 #endif
 #endif
     {
     {
       if (gpr <= REGARG_LASTGPR) {
       if (gpr <= REGARG_LASTGPR) {
-	lua_assert(rset_test(as->freeset, gpr));  /* Must have been evicted. */
+	lj_assertA(rset_test(as->freeset, gpr),
+		   "reg %d not free", gpr);  /* Must have been evicted. */
 	if (ref) ra_leftov(as, gpr, ref);
 	if (ref) ra_leftov(as, gpr, ref);
 	gpr++;
 	gpr++;
       } else {
       } else {
@@ -433,7 +436,7 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
     rset_clear(drop, (ir+1)->r);  /* Dest reg handled below. */
     rset_clear(drop, (ir+1)->r);  /* Dest reg handled below. */
   ra_evictset(as, drop);  /* Evictions must be performed first. */
   ra_evictset(as, drop);  /* Evictions must be performed first. */
   if (ra_used(ir)) {
   if (ra_used(ir)) {
-    lua_assert(!irt_ispri(ir->t));
+    lj_assertA(!irt_ispri(ir->t), "PRI dest");
     if (!LJ_SOFTFP && irt_isfp(ir->t)) {
     if (!LJ_SOFTFP && irt_isfp(ir->t)) {
       if (LJ_ABI_SOFTFP || (ci->flags & (CCI_CASTU64|CCI_VARARG))) {
       if (LJ_ABI_SOFTFP || (ci->flags & (CCI_CASTU64|CCI_VARARG))) {
 	Reg dest = (ra_dest(as, ir, RSET_FPR) & 15);
 	Reg dest = (ra_dest(as, ir, RSET_FPR) & 15);
@@ -530,13 +533,17 @@ static void asm_conv(ASMState *as, IRIns *ir)
 #endif
 #endif
   IRRef lref = ir->op1;
   IRRef lref = ir->op1;
   /* 64 bit integer conversions are handled by SPLIT. */
   /* 64 bit integer conversions are handled by SPLIT. */
-  lua_assert(!irt_isint64(ir->t) && !(st == IRT_I64 || st == IRT_U64));
+  lj_assertA(!irt_isint64(ir->t) && !(st == IRT_I64 || st == IRT_U64),
+	     "IR %04d has unsplit 64 bit type",
+	     (int)(ir - as->ir) - REF_BIAS);
 #if LJ_SOFTFP
 #if LJ_SOFTFP
   /* FP conversions are handled by SPLIT. */
   /* FP conversions are handled by SPLIT. */
-  lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT));
+  lj_assertA(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT),
+	     "IR %04d has FP type",
+	     (int)(ir - as->ir) - REF_BIAS);
   /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */
   /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */
 #else
 #else
-  lua_assert(irt_type(ir->t) != st);
+  lj_assertA(irt_type(ir->t) != st, "inconsistent types for CONV");
   if (irt_isfp(ir->t)) {
   if (irt_isfp(ir->t)) {
     Reg dest = ra_dest(as, ir, RSET_FPR);
     Reg dest = ra_dest(as, ir, RSET_FPR);
     if (stfp) {  /* FP to FP conversion. */
     if (stfp) {  /* FP to FP conversion. */
@@ -553,7 +560,8 @@ static void asm_conv(ASMState *as, IRIns *ir)
   } else if (stfp) {  /* FP to integer conversion. */
   } else if (stfp) {  /* FP to integer conversion. */
     if (irt_isguard(ir->t)) {
     if (irt_isguard(ir->t)) {
       /* Checked conversions are only supported from number to int. */
       /* Checked conversions are only supported from number to int. */
-      lua_assert(irt_isint(ir->t) && st == IRT_NUM);
+      lj_assertA(irt_isint(ir->t) && st == IRT_NUM,
+		 "bad type for checked CONV");
       asm_tointg(as, ir, ra_alloc1(as, lref, RSET_FPR));
       asm_tointg(as, ir, ra_alloc1(as, lref, RSET_FPR));
     } else {
     } else {
       Reg left = ra_alloc1(as, lref, RSET_FPR);
       Reg left = ra_alloc1(as, lref, RSET_FPR);
@@ -572,7 +580,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
     Reg dest = ra_dest(as, ir, RSET_GPR);
     Reg dest = ra_dest(as, ir, RSET_GPR);
     if (st >= IRT_I8 && st <= IRT_U16) {  /* Extend to 32 bit integer. */
     if (st >= IRT_I8 && st <= IRT_U16) {  /* Extend to 32 bit integer. */
       Reg left = ra_alloc1(as, lref, RSET_GPR);
       Reg left = ra_alloc1(as, lref, RSET_GPR);
-      lua_assert(irt_isint(ir->t) || irt_isu32(ir->t));
+      lj_assertA(irt_isint(ir->t) || irt_isu32(ir->t), "bad type for CONV EXT");
       if ((as->flags & JIT_F_ARMV6)) {
       if ((as->flags & JIT_F_ARMV6)) {
 	ARMIns ai = st == IRT_I8 ? ARMI_SXTB :
 	ARMIns ai = st == IRT_I8 ? ARMI_SXTB :
 		    st == IRT_U8 ? ARMI_UXTB :
 		    st == IRT_U8 ? ARMI_UXTB :
@@ -667,7 +675,7 @@ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
       ra_allockreg(as, i32ptr(ir_knum(ir)), dest);
       ra_allockreg(as, i32ptr(ir_knum(ir)), dest);
     } else {
     } else {
 #if LJ_SOFTFP
 #if LJ_SOFTFP
-      lua_assert(0);
+      lj_assertA(0, "unsplit FP op");
 #else
 #else
       /* Otherwise force a spill and use the spill slot. */
       /* Otherwise force a spill and use the spill slot. */
       emit_opk(as, ARMI_ADD, dest, RID_SP, ra_spill(as, ir), RSET_GPR);
       emit_opk(as, ARMI_ADD, dest, RID_SP, ra_spill(as, ir), RSET_GPR);
@@ -811,16 +819,16 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
   *l_loop = ARMF_CC(ARMI_B, CC_NE) | ((as->mcp-l_loop-2) & 0x00ffffffu);
   *l_loop = ARMF_CC(ARMI_B, CC_NE) | ((as->mcp-l_loop-2) & 0x00ffffffu);
 
 
   /* Load main position relative to tab->node into dest. */
   /* Load main position relative to tab->node into dest. */
-  khash = irref_isk(refkey) ? ir_khash(irkey) : 1;
+  khash = irref_isk(refkey) ? ir_khash(as, irkey) : 1;
   if (khash == 0) {
   if (khash == 0) {
     emit_lso(as, ARMI_LDR, dest, tab, (int32_t)offsetof(GCtab, node));
     emit_lso(as, ARMI_LDR, dest, tab, (int32_t)offsetof(GCtab, node));
   } else {
   } else {
     emit_dnm(as, ARMI_ADD|ARMF_SH(ARMSH_LSL, 3), dest, dest, tmp);
     emit_dnm(as, ARMI_ADD|ARMF_SH(ARMSH_LSL, 3), dest, dest, tmp);
     emit_dnm(as, ARMI_ADD|ARMF_SH(ARMSH_LSL, 1), tmp, tmp, tmp);
     emit_dnm(as, ARMI_ADD|ARMF_SH(ARMSH_LSL, 1), tmp, tmp, tmp);
-    if (irt_isstr(kt)) {  /* Fetch of str->hash is cheaper than ra_allock. */
+    if (irt_isstr(kt)) {  /* Fetch of str->sid is cheaper than ra_allock. */
       emit_dnm(as, ARMI_AND, tmp, tmp+1, RID_TMP);
       emit_dnm(as, ARMI_AND, tmp, tmp+1, RID_TMP);
       emit_lso(as, ARMI_LDR, dest, tab, (int32_t)offsetof(GCtab, node));
       emit_lso(as, ARMI_LDR, dest, tab, (int32_t)offsetof(GCtab, node));
-      emit_lso(as, ARMI_LDR, tmp+1, key, (int32_t)offsetof(GCstr, hash));
+      emit_lso(as, ARMI_LDR, tmp+1, key, (int32_t)offsetof(GCstr, sid));
       emit_lso(as, ARMI_LDR, RID_TMP, tab, (int32_t)offsetof(GCtab, hmask));
       emit_lso(as, ARMI_LDR, RID_TMP, tab, (int32_t)offsetof(GCtab, hmask));
     } else if (irref_isk(refkey)) {
     } else if (irref_isk(refkey)) {
       emit_opk(as, ARMI_AND, tmp, RID_TMP, (int32_t)khash,
       emit_opk(as, ARMI_AND, tmp, RID_TMP, (int32_t)khash,
@@ -867,7 +875,7 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
   Reg node = ra_alloc1(as, ir->op1, RSET_GPR);
   Reg node = ra_alloc1(as, ir->op1, RSET_GPR);
   Reg key = RID_NONE, type = RID_TMP, idx = node;
   Reg key = RID_NONE, type = RID_TMP, idx = node;
   RegSet allow = rset_exclude(RSET_GPR, node);
   RegSet allow = rset_exclude(RSET_GPR, node);
-  lua_assert(ofs % sizeof(Node) == 0);
+  lj_assertA(ofs % sizeof(Node) == 0, "unaligned HREFK slot");
   if (ofs > 4095) {
   if (ofs > 4095) {
     idx = dest;
     idx = dest;
     rset_clear(allow, dest);
     rset_clear(allow, dest);
@@ -934,7 +942,7 @@ static void asm_uref(ASMState *as, IRIns *ir)
 static void asm_fref(ASMState *as, IRIns *ir)
 static void asm_fref(ASMState *as, IRIns *ir)
 {
 {
   UNUSED(as); UNUSED(ir);
   UNUSED(as); UNUSED(ir);
-  lua_assert(!ra_used(ir));
+  lj_assertA(!ra_used(ir), "unfused FREF");
 }
 }
 
 
 static void asm_strref(ASMState *as, IRIns *ir)
 static void asm_strref(ASMState *as, IRIns *ir)
@@ -971,25 +979,27 @@ static void asm_strref(ASMState *as, IRIns *ir)
 
 
 /* -- Loads and stores ---------------------------------------------------- */
 /* -- Loads and stores ---------------------------------------------------- */
 
 
-static ARMIns asm_fxloadins(IRIns *ir)
+static ARMIns asm_fxloadins(ASMState *as, IRIns *ir)
 {
 {
+  UNUSED(as);
   switch (irt_type(ir->t)) {
   switch (irt_type(ir->t)) {
   case IRT_I8: return ARMI_LDRSB;
   case IRT_I8: return ARMI_LDRSB;
   case IRT_U8: return ARMI_LDRB;
   case IRT_U8: return ARMI_LDRB;
   case IRT_I16: return ARMI_LDRSH;
   case IRT_I16: return ARMI_LDRSH;
   case IRT_U16: return ARMI_LDRH;
   case IRT_U16: return ARMI_LDRH;
-  case IRT_NUM: lua_assert(!LJ_SOFTFP); return ARMI_VLDR_D;
+  case IRT_NUM: lj_assertA(!LJ_SOFTFP, "unsplit FP op"); return ARMI_VLDR_D;
   case IRT_FLOAT: if (!LJ_SOFTFP) return ARMI_VLDR_S;  /* fallthrough */
   case IRT_FLOAT: if (!LJ_SOFTFP) return ARMI_VLDR_S;  /* fallthrough */
   default: return ARMI_LDR;
   default: return ARMI_LDR;
   }
   }
 }
 }
 
 
-static ARMIns asm_fxstoreins(IRIns *ir)
+static ARMIns asm_fxstoreins(ASMState *as, IRIns *ir)
 {
 {
+  UNUSED(as);
   switch (irt_type(ir->t)) {
   switch (irt_type(ir->t)) {
   case IRT_I8: case IRT_U8: return ARMI_STRB;
   case IRT_I8: case IRT_U8: return ARMI_STRB;
   case IRT_I16: case IRT_U16: return ARMI_STRH;
   case IRT_I16: case IRT_U16: return ARMI_STRH;
-  case IRT_NUM: lua_assert(!LJ_SOFTFP); return ARMI_VSTR_D;
+  case IRT_NUM: lj_assertA(!LJ_SOFTFP, "unsplit FP op"); return ARMI_VSTR_D;
   case IRT_FLOAT: if (!LJ_SOFTFP) return ARMI_VSTR_S;  /* fallthrough */
   case IRT_FLOAT: if (!LJ_SOFTFP) return ARMI_VSTR_S;  /* fallthrough */
   default: return ARMI_STR;
   default: return ARMI_STR;
   }
   }
@@ -997,13 +1007,15 @@ static ARMIns asm_fxstoreins(IRIns *ir)
 
 
 static void asm_fload(ASMState *as, IRIns *ir)
 static void asm_fload(ASMState *as, IRIns *ir)
 {
 {
-  if (ir->op1 == REF_NIL) {
-    lua_assert(!ra_used(ir));  /* We can end up here if DCE is turned off. */
+  Reg dest = ra_dest(as, ir, RSET_GPR);
+  ARMIns ai = asm_fxloadins(as, ir);
+  Reg idx;
+  int32_t ofs;
+  if (ir->op1 == REF_NIL) {  /* FLOAD from GG_State with offset. */
+    idx = ra_allock(as, (int32_t)(ir->op2<<2) + (int32_t)J2GG(as->J), RSET_GPR);
+    ofs = 0;
   } else {
   } else {
-    Reg dest = ra_dest(as, ir, RSET_GPR);
-    Reg idx = ra_alloc1(as, ir->op1, RSET_GPR);
-    ARMIns ai = asm_fxloadins(ir);
-    int32_t ofs;
+    idx = ra_alloc1(as, ir->op1, RSET_GPR);
     if (ir->op2 == IRFL_TAB_ARRAY) {
     if (ir->op2 == IRFL_TAB_ARRAY) {
       ofs = asm_fuseabase(as, ir->op1);
       ofs = asm_fuseabase(as, ir->op1);
       if (ofs) {  /* Turn the t->array load into an add for colocated arrays. */
       if (ofs) {  /* Turn the t->array load into an add for colocated arrays. */
@@ -1012,11 +1024,11 @@ static void asm_fload(ASMState *as, IRIns *ir)
       }
       }
     }
     }
     ofs = field_ofs[ir->op2];
     ofs = field_ofs[ir->op2];
-    if ((ai & 0x04000000))
-      emit_lso(as, ai, dest, idx, ofs);
-    else
-      emit_lsox(as, ai, dest, idx, ofs);
   }
   }
+  if ((ai & 0x04000000))
+    emit_lso(as, ai, dest, idx, ofs);
+  else
+    emit_lsox(as, ai, dest, idx, ofs);
 }
 }
 
 
 static void asm_fstore(ASMState *as, IRIns *ir)
 static void asm_fstore(ASMState *as, IRIns *ir)
@@ -1026,7 +1038,7 @@ static void asm_fstore(ASMState *as, IRIns *ir)
     IRIns *irf = IR(ir->op1);
     IRIns *irf = IR(ir->op1);
     Reg idx = ra_alloc1(as, irf->op1, rset_exclude(RSET_GPR, src));
     Reg idx = ra_alloc1(as, irf->op1, rset_exclude(RSET_GPR, src));
     int32_t ofs = field_ofs[irf->op2];
     int32_t ofs = field_ofs[irf->op2];
-    ARMIns ai = asm_fxstoreins(ir);
+    ARMIns ai = asm_fxstoreins(as, ir);
     if ((ai & 0x04000000))
     if ((ai & 0x04000000))
       emit_lso(as, ai, src, idx, ofs);
       emit_lso(as, ai, src, idx, ofs);
     else
     else
@@ -1038,8 +1050,8 @@ static void asm_xload(ASMState *as, IRIns *ir)
 {
 {
   Reg dest = ra_dest(as, ir,
   Reg dest = ra_dest(as, ir,
 		     (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
 		     (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
-  lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));
-  asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0);
+  lj_assertA(!(ir->op2 & IRXLOAD_UNALIGNED), "unaligned XLOAD");
+  asm_fusexref(as, asm_fxloadins(as, ir), dest, ir->op1, RSET_GPR, 0);
 }
 }
 
 
 static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
 static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
@@ -1047,7 +1059,7 @@ static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
   if (ir->r != RID_SINK) {
   if (ir->r != RID_SINK) {
     Reg src = ra_alloc1(as, ir->op2,
     Reg src = ra_alloc1(as, ir->op2,
 			(!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
 			(!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
-    asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1,
+    asm_fusexref(as, asm_fxstoreins(as, ir), src, ir->op1,
 		 rset_exclude(RSET_GPR, src), ofs);
 		 rset_exclude(RSET_GPR, src), ofs);
   }
   }
 }
 }
@@ -1066,8 +1078,9 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
     rset_clear(allow, type);
     rset_clear(allow, type);
   }
   }
   if (ra_used(ir)) {
   if (ra_used(ir)) {
-    lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||
-	       irt_isint(ir->t) || irt_isaddr(ir->t));
+    lj_assertA((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||
+	       irt_isint(ir->t) || irt_isaddr(ir->t),
+	       "bad load type %d", irt_type(ir->t));
     dest = ra_dest(as, ir, (!LJ_SOFTFP && t == IRT_NUM) ? RSET_FPR : allow);
     dest = ra_dest(as, ir, (!LJ_SOFTFP && t == IRT_NUM) ? RSET_FPR : allow);
     rset_clear(allow, dest);
     rset_clear(allow, dest);
   }
   }
@@ -1133,10 +1146,13 @@ static void asm_sload(ASMState *as, IRIns *ir)
   IRType t = hiop ? IRT_NUM : irt_type(ir->t);
   IRType t = hiop ? IRT_NUM : irt_type(ir->t);
   Reg dest = RID_NONE, type = RID_NONE, base;
   Reg dest = RID_NONE, type = RID_NONE, base;
   RegSet allow = RSET_GPR;
   RegSet allow = RSET_GPR;
-  lua_assert(!(ir->op2 & IRSLOAD_PARENT));  /* Handled by asm_head_side(). */
-  lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK));
+  lj_assertA(!(ir->op2 & IRSLOAD_PARENT),
+	     "bad parent SLOAD");  /* Handled by asm_head_side(). */
+  lj_assertA(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK),
+	     "inconsistent SLOAD variant");
 #if LJ_SOFTFP
 #if LJ_SOFTFP
-  lua_assert(!(ir->op2 & IRSLOAD_CONVERT));  /* Handled by LJ_SOFTFP SPLIT. */
+  lj_assertA(!(ir->op2 & IRSLOAD_CONVERT),
+	     "unsplit SLOAD convert");  /* Handled by LJ_SOFTFP SPLIT. */
   if (hiop && ra_used(ir+1)) {
   if (hiop && ra_used(ir+1)) {
     type = ra_dest(as, ir+1, allow);
     type = ra_dest(as, ir+1, allow);
     rset_clear(allow, type);
     rset_clear(allow, type);
@@ -1152,8 +1168,9 @@ static void asm_sload(ASMState *as, IRIns *ir)
     Reg tmp = RID_NONE;
     Reg tmp = RID_NONE;
     if ((ir->op2 & IRSLOAD_CONVERT))
     if ((ir->op2 & IRSLOAD_CONVERT))
       tmp = ra_scratch(as, t == IRT_INT ? RSET_FPR : RSET_GPR);
       tmp = ra_scratch(as, t == IRT_INT ? RSET_FPR : RSET_GPR);
-    lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||
-	       irt_isint(ir->t) || irt_isaddr(ir->t));
+    lj_assertA((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||
+	       irt_isint(ir->t) || irt_isaddr(ir->t),
+	       "bad SLOAD type %d", irt_type(ir->t));
     dest = ra_dest(as, ir, (!LJ_SOFTFP && t == IRT_NUM) ? RSET_FPR : allow);
     dest = ra_dest(as, ir, (!LJ_SOFTFP && t == IRT_NUM) ? RSET_FPR : allow);
     rset_clear(allow, dest);
     rset_clear(allow, dest);
     base = ra_alloc1(as, REF_BASE, allow);
     base = ra_alloc1(as, REF_BASE, allow);
@@ -1218,7 +1235,8 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   IRRef args[4];
   IRRef args[4];
   RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
   RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
   RegSet drop = RSET_SCRATCH;
   RegSet drop = RSET_SCRATCH;
-  lua_assert(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL));
+  lj_assertA(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL),
+	     "bad CNEW/CNEWI operands");
 
 
   as->gcsteps++;
   as->gcsteps++;
   if (ra_hasreg(ir->r))
   if (ra_hasreg(ir->r))
@@ -1230,10 +1248,10 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   /* Initialize immutable cdata object. */
   /* Initialize immutable cdata object. */
   if (ir->o == IR_CNEWI) {
   if (ir->o == IR_CNEWI) {
     int32_t ofs = sizeof(GCcdata);
     int32_t ofs = sizeof(GCcdata);
-    lua_assert(sz == 4 || sz == 8);
+    lj_assertA(sz == 4 || sz == 8, "bad CNEWI size %d", sz);
     if (sz == 8) {
     if (sz == 8) {
       ofs += 4; ir++;
       ofs += 4; ir++;
-      lua_assert(ir->o == IR_HIOP);
+      lj_assertA(ir->o == IR_HIOP, "expected HIOP for CNEWI");
     }
     }
     for (;;) {
     for (;;) {
       Reg r = ra_alloc1(as, ir->op2, allow);
       Reg r = ra_alloc1(as, ir->op2, allow);
@@ -1268,8 +1286,6 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
   ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
 	       ra_releasetmp(as, ASMREF_TMP1));
 	       ra_releasetmp(as, ASMREF_TMP1));
 }
 }
-#else
-#define asm_cnew(as, ir)	((void)0)
 #endif
 #endif
 
 
 /* -- Write barriers ------------------------------------------------------ */
 /* -- Write barriers ------------------------------------------------------ */
@@ -1301,7 +1317,7 @@ static void asm_obar(ASMState *as, IRIns *ir)
   MCLabel l_end;
   MCLabel l_end;
   Reg obj, val, tmp;
   Reg obj, val, tmp;
   /* No need for other object barriers (yet). */
   /* No need for other object barriers (yet). */
-  lua_assert(IR(ir->op1)->o == IR_UREFC);
+  lj_assertA(IR(ir->op1)->o == IR_UREFC, "bad OBAR type");
   ra_evictset(as, RSET_SCRATCH);
   ra_evictset(as, RSET_SCRATCH);
   l_end = emit_label(as);
   l_end = emit_label(as);
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[0] = ASMREF_TMP1;  /* global_State *g */
@@ -1364,8 +1380,6 @@ static void asm_callround(ASMState *as, IRIns *ir, int id)
 
 
 static void asm_fpmath(ASMState *as, IRIns *ir)
 static void asm_fpmath(ASMState *as, IRIns *ir)
 {
 {
-  if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir))
-    return;
   if (ir->op2 <= IRFPM_TRUNC)
   if (ir->op2 <= IRFPM_TRUNC)
     asm_callround(as, ir, ir->op2);
     asm_callround(as, ir, ir->op2);
   else if (ir->op2 == IRFPM_SQRT)
   else if (ir->op2 == IRFPM_SQRT)
@@ -1507,15 +1521,10 @@ static void asm_mul(ASMState *as, IRIns *ir)
 #define asm_mulov(as, ir)	asm_mul(as, ir)
 #define asm_mulov(as, ir)	asm_mul(as, ir)
 
 
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
-#define asm_div(as, ir)		asm_fparith(as, ir, ARMI_VDIV_D)
-#define asm_pow(as, ir)		asm_callid(as, ir, IRCALL_lj_vm_powi)
+#define asm_fpdiv(as, ir)	asm_fparith(as, ir, ARMI_VDIV_D)
 #define asm_abs(as, ir)		asm_fpunary(as, ir, ARMI_VABS_D)
 #define asm_abs(as, ir)		asm_fpunary(as, ir, ARMI_VABS_D)
-#define asm_atan2(as, ir)	asm_callid(as, ir, IRCALL_atan2)
-#define asm_ldexp(as, ir)	asm_callid(as, ir, IRCALL_ldexp)
 #endif
 #endif
 
 
-#define asm_mod(as, ir)		asm_callid(as, ir, IRCALL_lj_vm_modi)
-
 static void asm_neg(ASMState *as, IRIns *ir)
 static void asm_neg(ASMState *as, IRIns *ir)
 {
 {
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
@@ -1584,7 +1593,7 @@ static void asm_bitshift(ASMState *as, IRIns *ir, ARMShift sh)
 #define asm_bshr(as, ir)	asm_bitshift(as, ir, ARMSH_LSR)
 #define asm_bshr(as, ir)	asm_bitshift(as, ir, ARMSH_LSR)
 #define asm_bsar(as, ir)	asm_bitshift(as, ir, ARMSH_ASR)
 #define asm_bsar(as, ir)	asm_bitshift(as, ir, ARMSH_ASR)
 #define asm_bror(as, ir)	asm_bitshift(as, ir, ARMSH_ROR)
 #define asm_bror(as, ir)	asm_bitshift(as, ir, ARMSH_ROR)
-#define asm_brol(as, ir)	lua_assert(0)
+#define asm_brol(as, ir)	lj_assertA(0, "unexpected BROL")
 
 
 static void asm_intmin_max(ASMState *as, IRIns *ir, int cc)
 static void asm_intmin_max(ASMState *as, IRIns *ir, int cc)
 {
 {
@@ -1659,8 +1668,8 @@ static void asm_min_max(ASMState *as, IRIns *ir, int cc, int fcc)
     asm_intmin_max(as, ir, cc);
     asm_intmin_max(as, ir, cc);
 }
 }
 
 
-#define asm_min(as, ir)		asm_min_max(as, ir, CC_GT, CC_HI)
-#define asm_max(as, ir)		asm_min_max(as, ir, CC_LT, CC_LO)
+#define asm_min(as, ir)		asm_min_max(as, ir, CC_GT, CC_PL)
+#define asm_max(as, ir)		asm_min_max(as, ir, CC_LT, CC_LE)
 
 
 /* -- Comparisons --------------------------------------------------------- */
 /* -- Comparisons --------------------------------------------------------- */
 
 
@@ -1735,7 +1744,8 @@ static void asm_intcomp(ASMState *as, IRIns *ir)
   Reg left;
   Reg left;
   uint32_t m;
   uint32_t m;
   int cmpprev0 = 0;
   int cmpprev0 = 0;
-  lua_assert(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t));
+  lj_assertA(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t),
+	     "bad comparison data type %d", irt_type(ir->t));
   if (asm_swapops(as, lref, rref)) {
   if (asm_swapops(as, lref, rref)) {
     Reg tmp = lref; lref = rref; rref = tmp;
     Reg tmp = lref; lref = rref; rref = tmp;
     if (cc >= CC_GE) cc ^= 7;  /* LT <-> GT, LE <-> GE */
     if (cc >= CC_GE) cc ^= 7;  /* LT <-> GT, LE <-> GE */
@@ -1852,7 +1862,7 @@ static void asm_hiop(ASMState *as, IRIns *ir)
   } else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) {
   } else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) {
     as->curins--;  /* Always skip the loword min/max. */
     as->curins--;  /* Always skip the loword min/max. */
     if (uselo || usehi)
     if (uselo || usehi)
-      asm_sfpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_HI : CC_LO);
+      asm_sfpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_PL : CC_LE);
     return;
     return;
 #elif LJ_HASFFI
 #elif LJ_HASFFI
   } else if ((ir-1)->o == IR_CONV) {
   } else if ((ir-1)->o == IR_CONV) {
@@ -1904,10 +1914,11 @@ static void asm_hiop(ASMState *as, IRIns *ir)
   case IR_CNEWI:
   case IR_CNEWI:
     /* Nothing to do here. Handled by lo op itself. */
     /* Nothing to do here. Handled by lo op itself. */
     break;
     break;
-  default: lua_assert(0); break;
+  default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
   }
   }
 #else
 #else
-  UNUSED(as); UNUSED(ir); lua_assert(0);
+  /* Unused without SOFTFP or FFI. */
+  UNUSED(as); UNUSED(ir); lj_assertA(0, "unexpected HIOP");
 #endif
 #endif
 }
 }
 
 
@@ -1932,7 +1943,7 @@ static void asm_stack_check(ASMState *as, BCReg topslot,
   if (irp) {
   if (irp) {
     if (!ra_hasspill(irp->s)) {
     if (!ra_hasspill(irp->s)) {
       pbase = irp->r;
       pbase = irp->r;
-      lua_assert(ra_hasreg(pbase));
+      lj_assertA(ra_hasreg(pbase), "base reg lost");
     } else if (allow) {
     } else if (allow) {
       pbase = rset_pickbot(allow);
       pbase = rset_pickbot(allow);
     } else {
     } else {
@@ -1944,7 +1955,7 @@ static void asm_stack_check(ASMState *as, BCReg topslot,
   }
   }
   emit_branch(as, ARMF_CC(ARMI_BL, CC_LS), exitstub_addr(as->J, exitno));
   emit_branch(as, ARMF_CC(ARMI_BL, CC_LS), exitstub_addr(as->J, exitno));
   k = emit_isk12(0, (int32_t)(8*topslot));
   k = emit_isk12(0, (int32_t)(8*topslot));
-  lua_assert(k);
+  lj_assertA(k, "slot offset %d does not fit in K12", 8*topslot);
   emit_n(as, ARMI_CMP^k, RID_TMP);
   emit_n(as, ARMI_CMP^k, RID_TMP);
   emit_dnm(as, ARMI_SUB, RID_TMP, RID_TMP, pbase);
   emit_dnm(as, ARMI_SUB, RID_TMP, RID_TMP, pbase);
   emit_lso(as, ARMI_LDR, RID_TMP, RID_TMP,
   emit_lso(as, ARMI_LDR, RID_TMP, RID_TMP,
@@ -1981,7 +1992,8 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
 #if LJ_SOFTFP
 #if LJ_SOFTFP
       RegSet odd = rset_exclude(RSET_GPRODD, RID_BASE);
       RegSet odd = rset_exclude(RSET_GPRODD, RID_BASE);
       Reg tmp;
       Reg tmp;
-      lua_assert(irref_isk(ref));  /* LJ_SOFTFP: must be a number constant. */
+      /* LJ_SOFTFP: must be a number constant. */
+      lj_assertA(irref_isk(ref), "unsplit FP op");
       tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.lo,
       tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.lo,
 		      rset_exclude(RSET_GPREVEN, RID_BASE));
 		      rset_exclude(RSET_GPREVEN, RID_BASE));
       emit_lso(as, ARMI_STR, tmp, RID_BASE, ofs);
       emit_lso(as, ARMI_STR, tmp, RID_BASE, ofs);
@@ -1995,7 +2007,8 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
     } else {
     } else {
       RegSet odd = rset_exclude(RSET_GPRODD, RID_BASE);
       RegSet odd = rset_exclude(RSET_GPRODD, RID_BASE);
       Reg type;
       Reg type;
-      lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t));
+      lj_assertA(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t),
+		 "restore of IR type %d", irt_type(ir->t));
       if (!irt_ispri(ir->t)) {
       if (!irt_ispri(ir->t)) {
 	Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPREVEN, RID_BASE));
 	Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPREVEN, RID_BASE));
 	emit_lso(as, ARMI_STR, src, RID_BASE, ofs);
 	emit_lso(as, ARMI_STR, src, RID_BASE, ofs);
@@ -2015,11 +2028,14 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
     }
     }
     checkmclim(as);
     checkmclim(as);
   }
   }
-  lua_assert(map + nent == flinks);
+  lj_assertA(map + nent == flinks, "inconsistent frames in snapshot");
 }
 }
 
 
 /* -- GC handling --------------------------------------------------------- */
 /* -- GC handling --------------------------------------------------------- */
 
 
+/* Marker to prevent patching the GC check exit. */
+#define ARM_NOPATCH_GC_CHECK	(ARMI_BIC|ARMI_K12)
+
 /* Check GC threshold and do one or more GC steps. */
 /* Check GC threshold and do one or more GC steps. */
 static void asm_gc_check(ASMState *as)
 static void asm_gc_check(ASMState *as)
 {
 {
@@ -2031,6 +2047,7 @@ static void asm_gc_check(ASMState *as)
   l_end = emit_label(as);
   l_end = emit_label(as);
   /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
   /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
   asm_guardcc(as, CC_NE);  /* Assumes asm_snap_prep() already done. */
   asm_guardcc(as, CC_NE);  /* Assumes asm_snap_prep() already done. */
+  *--as->mcp = ARM_NOPATCH_GC_CHECK;
   emit_n(as, ARMI_CMP|ARMI_K12|0, RID_RET);
   emit_n(as, ARMI_CMP|ARMI_K12|0, RID_RET);
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[1] = ASMREF_TMP2;  /* MSize steps     */
   args[1] = ASMREF_TMP2;  /* MSize steps     */
@@ -2101,7 +2118,7 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
     rset_clear(allow, ra_dest(as, ir, allow));
     rset_clear(allow, ra_dest(as, ir, allow));
   } else {
   } else {
     Reg r = irp->r;
     Reg r = irp->r;
-    lua_assert(ra_hasreg(r));
+    lj_assertA(ra_hasreg(r), "base reg lost");
     rset_clear(allow, r);
     rset_clear(allow, r);
     if (r != ir->r && !rset_test(as->freeset, r))
     if (r != ir->r && !rset_test(as->freeset, r))
       ra_restore(as, regcost_ref(as->cost[r]));
       ra_restore(as, regcost_ref(as->cost[r]));
@@ -2123,7 +2140,7 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk)
   } else {
   } else {
     /* Patch stack adjustment. */
     /* Patch stack adjustment. */
     uint32_t k = emit_isk12(ARMI_ADD, spadj);
     uint32_t k = emit_isk12(ARMI_ADD, spadj);
-    lua_assert(k);
+    lj_assertA(k, "stack adjustment %d does not fit in K12", spadj);
     p[-2] = (ARMI_ADD^k) | ARMF_D(RID_SP) | ARMF_N(RID_SP);
     p[-2] = (ARMI_ADD^k) | ARMF_D(RID_SP) | ARMF_N(RID_SP);
   }
   }
   /* Patch exit branch. */
   /* Patch exit branch. */
@@ -2199,13 +2216,14 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
     /* Look for bl_cc exitstub, replace with b_cc target. */
     /* Look for bl_cc exitstub, replace with b_cc target. */
     uint32_t ins = *p;
     uint32_t ins = *p;
     if ((ins & 0x0f000000u) == 0x0b000000u && ins < 0xf0000000u &&
     if ((ins & 0x0f000000u) == 0x0b000000u && ins < 0xf0000000u &&
-	((ins ^ (px-p)) & 0x00ffffffu) == 0) {
+	((ins ^ (px-p)) & 0x00ffffffu) == 0 &&
+	p[-1] != ARM_NOPATCH_GC_CHECK) {
       *p = (ins & 0xfe000000u) | (((target-p)-2) & 0x00ffffffu);
       *p = (ins & 0xfe000000u) | (((target-p)-2) & 0x00ffffffu);
       cend = p+1;
       cend = p+1;
       if (!cstart) cstart = p;
       if (!cstart) cstart = p;
     }
     }
   }
   }
-  lua_assert(cstart != NULL);
+  lj_assertJ(cstart != NULL, "exit stub %d not found", exitno);
   lj_mcode_sync(cstart, cend);
   lj_mcode_sync(cstart, cend);
   lj_mcode_patch(J, mcarea, 1);
   lj_mcode_patch(J, mcarea, 1);
 }
 }

+ 74 - 90
libs/LuaJIT/src/lj_asm_arm64.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** ARM64 IR assembler (SSA IR -> machine code).
 ** ARM64 IR assembler (SSA IR -> machine code).
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 **
 **
 ** Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.
 ** Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.
 ** Sponsored by Cisco Systems, Inc.
 ** Sponsored by Cisco Systems, Inc.
@@ -213,7 +213,7 @@ static uint32_t asm_fuseopm(ASMState *as, A64Ins ai, IRRef ref, RegSet allow)
     return A64F_M(ir->r);
     return A64F_M(ir->r);
   } else if (irref_isk(ref)) {
   } else if (irref_isk(ref)) {
     uint32_t m;
     uint32_t m;
-    int64_t k = get_k64val(ir);
+    int64_t k = get_k64val(as, ref);
     if ((ai & 0x1f000000) == 0x0a000000)
     if ((ai & 0x1f000000) == 0x0a000000)
       m = emit_isk13(k, irt_is64(ir->t));
       m = emit_isk13(k, irt_is64(ir->t));
     else
     else
@@ -354,9 +354,9 @@ static int asm_fusemadd(ASMState *as, IRIns *ir, A64Ins ai, A64Ins air)
 static int asm_fuseandshift(ASMState *as, IRIns *ir)
 static int asm_fuseandshift(ASMState *as, IRIns *ir)
 {
 {
   IRIns *irl = IR(ir->op1);
   IRIns *irl = IR(ir->op1);
-  lua_assert(ir->o == IR_BAND);
+  lj_assertA(ir->o == IR_BAND, "bad usage");
   if (canfuse(as, irl) && irref_isk(ir->op2)) {
   if (canfuse(as, irl) && irref_isk(ir->op2)) {
-    uint64_t mask = get_k64val(IR(ir->op2));
+    uint64_t mask = get_k64val(as, ir->op2);
     if (irref_isk(irl->op2) && (irl->o == IR_BSHR || irl->o == IR_BSHL)) {
     if (irref_isk(irl->op2) && (irl->o == IR_BSHR || irl->o == IR_BSHL)) {
       int32_t shmask = irt_is64(irl->t) ? 63 : 31;
       int32_t shmask = irt_is64(irl->t) ? 63 : 31;
       int32_t shift = (IR(irl->op2)->i & shmask);
       int32_t shift = (IR(irl->op2)->i & shmask);
@@ -384,7 +384,7 @@ static int asm_fuseandshift(ASMState *as, IRIns *ir)
 static int asm_fuseorshift(ASMState *as, IRIns *ir)
 static int asm_fuseorshift(ASMState *as, IRIns *ir)
 {
 {
   IRIns *irl = IR(ir->op1), *irr = IR(ir->op2);
   IRIns *irl = IR(ir->op1), *irr = IR(ir->op2);
-  lua_assert(ir->o == IR_BOR);
+  lj_assertA(ir->o == IR_BOR, "bad usage");
   if (canfuse(as, irl) && canfuse(as, irr) &&
   if (canfuse(as, irl) && canfuse(as, irr) &&
       ((irl->o == IR_BSHR && irr->o == IR_BSHL) ||
       ((irl->o == IR_BSHR && irr->o == IR_BSHL) ||
        (irl->o == IR_BSHL && irr->o == IR_BSHR))) {
        (irl->o == IR_BSHL && irr->o == IR_BSHR))) {
@@ -428,7 +428,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
     if (ref) {
     if (ref) {
       if (irt_isfp(ir->t)) {
       if (irt_isfp(ir->t)) {
 	if (fpr <= REGARG_LASTFPR) {
 	if (fpr <= REGARG_LASTFPR) {
-	  lua_assert(rset_test(as->freeset, fpr)); /* Must have been evicted. */
+	  lj_assertA(rset_test(as->freeset, fpr),
+		     "reg %d not free", fpr);  /* Must have been evicted. */
 	  ra_leftov(as, fpr, ref);
 	  ra_leftov(as, fpr, ref);
 	  fpr++;
 	  fpr++;
 	} else {
 	} else {
@@ -438,7 +439,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
 	}
 	}
       } else {
       } else {
 	if (gpr <= REGARG_LASTGPR) {
 	if (gpr <= REGARG_LASTGPR) {
-	  lua_assert(rset_test(as->freeset, gpr)); /* Must have been evicted. */
+	  lj_assertA(rset_test(as->freeset, gpr),
+		     "reg %d not free", gpr);  /* Must have been evicted. */
 	  ra_leftov(as, gpr, ref);
 	  ra_leftov(as, gpr, ref);
 	  gpr++;
 	  gpr++;
 	} else {
 	} else {
@@ -459,7 +461,7 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
     rset_clear(drop, ir->r); /* Dest reg handled below. */
     rset_clear(drop, ir->r); /* Dest reg handled below. */
   ra_evictset(as, drop); /* Evictions must be performed first. */
   ra_evictset(as, drop); /* Evictions must be performed first. */
   if (ra_used(ir)) {
   if (ra_used(ir)) {
-    lua_assert(!irt_ispri(ir->t));
+    lj_assertA(!irt_ispri(ir->t), "PRI dest");
     if (irt_isfp(ir->t)) {
     if (irt_isfp(ir->t)) {
       if (ci->flags & CCI_CASTU64) {
       if (ci->flags & CCI_CASTU64) {
 	Reg dest = ra_dest(as, ir, RSET_FPR) & 31;
 	Reg dest = ra_dest(as, ir, RSET_FPR) & 31;
@@ -546,7 +548,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
   int st64 = (st == IRT_I64 || st == IRT_U64 || st == IRT_P64);
   int st64 = (st == IRT_I64 || st == IRT_U64 || st == IRT_P64);
   int stfp = (st == IRT_NUM || st == IRT_FLOAT);
   int stfp = (st == IRT_NUM || st == IRT_FLOAT);
   IRRef lref = ir->op1;
   IRRef lref = ir->op1;
-  lua_assert(irt_type(ir->t) != st);
+  lj_assertA(irt_type(ir->t) != st, "inconsistent types for CONV");
   if (irt_isfp(ir->t)) {
   if (irt_isfp(ir->t)) {
     Reg dest = ra_dest(as, ir, RSET_FPR);
     Reg dest = ra_dest(as, ir, RSET_FPR);
     if (stfp) {  /* FP to FP conversion. */
     if (stfp) {  /* FP to FP conversion. */
@@ -566,7 +568,8 @@ static void asm_conv(ASMState *as, IRIns *ir)
   } else if (stfp) {  /* FP to integer conversion. */
   } else if (stfp) {  /* FP to integer conversion. */
     if (irt_isguard(ir->t)) {
     if (irt_isguard(ir->t)) {
       /* Checked conversions are only supported from number to int. */
       /* Checked conversions are only supported from number to int. */
-      lua_assert(irt_isint(ir->t) && st == IRT_NUM);
+      lj_assertA(irt_isint(ir->t) && st == IRT_NUM,
+		 "bad type for checked CONV");
       asm_tointg(as, ir, ra_alloc1(as, lref, RSET_FPR));
       asm_tointg(as, ir, ra_alloc1(as, lref, RSET_FPR));
     } else {
     } else {
       Reg left = ra_alloc1(as, lref, RSET_FPR);
       Reg left = ra_alloc1(as, lref, RSET_FPR);
@@ -586,7 +589,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
     A64Ins ai = st == IRT_I8 ? A64I_SXTBw :
     A64Ins ai = st == IRT_I8 ? A64I_SXTBw :
 		st == IRT_U8 ? A64I_UXTBw :
 		st == IRT_U8 ? A64I_UXTBw :
 		st == IRT_I16 ? A64I_SXTHw : A64I_UXTHw;
 		st == IRT_I16 ? A64I_SXTHw : A64I_UXTHw;
-    lua_assert(irt_isint(ir->t) || irt_isu32(ir->t));
+    lj_assertA(irt_isint(ir->t) || irt_isu32(ir->t), "bad type for CONV EXT");
     emit_dn(as, ai, dest, left);
     emit_dn(as, ai, dest, left);
   } else {
   } else {
     Reg dest = ra_dest(as, ir, RSET_GPR);
     Reg dest = ra_dest(as, ir, RSET_GPR);
@@ -650,7 +653,8 @@ static void asm_tvstore64(ASMState *as, Reg base, int32_t ofs, IRRef ref)
 {
 {
   RegSet allow = rset_exclude(RSET_GPR, base);
   RegSet allow = rset_exclude(RSET_GPR, base);
   IRIns *ir = IR(ref);
   IRIns *ir = IR(ref);
-  lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t));
+  lj_assertA(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t),
+	     "store of IR type %d", irt_type(ir->t));
   if (irref_isk(ref)) {
   if (irref_isk(ref)) {
     TValue k;
     TValue k;
     lj_ir_kvalue(as->J->L, &k, ir);
     lj_ir_kvalue(as->J->L, &k, ir);
@@ -770,7 +774,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
     }
     }
     rset_clear(allow, scr);
     rset_clear(allow, scr);
   } else {
   } else {
-    lua_assert(irt_ispri(kt) && !irt_isnil(kt));
+    lj_assertA(irt_ispri(kt) && !irt_isnil(kt), "bad HREF key type");
     type = ra_allock(as, ~((int64_t)~irt_toitype(ir->t) << 47), allow);
     type = ra_allock(as, ~((int64_t)~irt_toitype(ir->t) << 47), allow);
     scr = ra_scratch(as, rset_clear(allow, type));
     scr = ra_scratch(as, rset_clear(allow, type));
     rset_clear(allow, scr);
     rset_clear(allow, scr);
@@ -831,7 +835,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
     rset_clear(allow, type);
     rset_clear(allow, type);
   }
   }
   /* Load main position relative to tab->node into dest. */
   /* Load main position relative to tab->node into dest. */
-  khash = isk ? ir_khash(irkey) : 1;
+  khash = isk ? ir_khash(as, irkey) : 1;
   if (khash == 0) {
   if (khash == 0) {
     emit_lso(as, A64I_LDRx, dest, tab, offsetof(GCtab, node));
     emit_lso(as, A64I_LDRx, dest, tab, offsetof(GCtab, node));
   } else {
   } else {
@@ -843,9 +847,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
       emit_dnm(as, A64I_ANDw, dest, dest, tmphash);
       emit_dnm(as, A64I_ANDw, dest, dest, tmphash);
       emit_lso(as, A64I_LDRw, dest, tab, offsetof(GCtab, hmask));
       emit_lso(as, A64I_LDRw, dest, tab, offsetof(GCtab, hmask));
     } else if (irt_isstr(kt)) {
     } else if (irt_isstr(kt)) {
-      /* Fetch of str->hash is cheaper than ra_allock. */
+      /* Fetch of str->sid is cheaper than ra_allock. */
       emit_dnm(as, A64I_ANDw, dest, dest, tmp);
       emit_dnm(as, A64I_ANDw, dest, dest, tmp);
-      emit_lso(as, A64I_LDRw, tmp, key, offsetof(GCstr, hash));
+      emit_lso(as, A64I_LDRw, tmp, key, offsetof(GCstr, sid));
       emit_lso(as, A64I_LDRw, dest, tab, offsetof(GCtab, hmask));
       emit_lso(as, A64I_LDRw, dest, tab, offsetof(GCtab, hmask));
     } else {  /* Must match with hash*() in lj_tab.c. */
     } else {  /* Must match with hash*() in lj_tab.c. */
       emit_dnm(as, A64I_ANDw, dest, dest, tmp);
       emit_dnm(as, A64I_ANDw, dest, dest, tmp);
@@ -886,7 +890,7 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
   Reg key, idx = node;
   Reg key, idx = node;
   RegSet allow = rset_exclude(RSET_GPR, node);
   RegSet allow = rset_exclude(RSET_GPR, node);
   uint64_t k;
   uint64_t k;
-  lua_assert(ofs % sizeof(Node) == 0);
+  lj_assertA(ofs % sizeof(Node) == 0, "unaligned HREFK slot");
   if (bigofs) {
   if (bigofs) {
     idx = dest;
     idx = dest;
     rset_clear(allow, dest);
     rset_clear(allow, dest);
@@ -936,7 +940,7 @@ static void asm_uref(ASMState *as, IRIns *ir)
 static void asm_fref(ASMState *as, IRIns *ir)
 static void asm_fref(ASMState *as, IRIns *ir)
 {
 {
   UNUSED(as); UNUSED(ir);
   UNUSED(as); UNUSED(ir);
-  lua_assert(!ra_used(ir));
+  lj_assertA(!ra_used(ir), "unfused FREF");
 }
 }
 
 
 static void asm_strref(ASMState *as, IRIns *ir)
 static void asm_strref(ASMState *as, IRIns *ir)
@@ -988,7 +992,7 @@ static void asm_fload(ASMState *as, IRIns *ir)
   Reg idx;
   Reg idx;
   A64Ins ai = asm_fxloadins(ir);
   A64Ins ai = asm_fxloadins(ir);
   int32_t ofs;
   int32_t ofs;
-  if (ir->op1 == REF_NIL) {
+  if (ir->op1 == REF_NIL) {  /* FLOAD from GG_State with offset. */
     idx = RID_GL;
     idx = RID_GL;
     ofs = (ir->op2 << 2) - GG_OFS(g);
     ofs = (ir->op2 << 2) - GG_OFS(g);
   } else {
   } else {
@@ -1019,7 +1023,7 @@ static void asm_fstore(ASMState *as, IRIns *ir)
 static void asm_xload(ASMState *as, IRIns *ir)
 static void asm_xload(ASMState *as, IRIns *ir)
 {
 {
   Reg dest = ra_dest(as, ir, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);
   Reg dest = ra_dest(as, ir, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);
-  lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));
+  lj_assertA(!(ir->op2 & IRXLOAD_UNALIGNED), "unaligned XLOAD");
   asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR);
   asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR);
 }
 }
 
 
@@ -1037,8 +1041,9 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
   Reg idx, tmp, type;
   Reg idx, tmp, type;
   int32_t ofs = 0;
   int32_t ofs = 0;
   RegSet gpr = RSET_GPR, allow = irt_isnum(ir->t) ? RSET_FPR : RSET_GPR;
   RegSet gpr = RSET_GPR, allow = irt_isnum(ir->t) ? RSET_FPR : RSET_GPR;
-  lua_assert(irt_isnum(ir->t) || irt_ispri(ir->t) || irt_isaddr(ir->t) ||
-	     irt_isint(ir->t));
+  lj_assertA(irt_isnum(ir->t) || irt_ispri(ir->t) || irt_isaddr(ir->t) ||
+	     irt_isint(ir->t),
+	     "bad load type %d", irt_type(ir->t));
   if (ra_used(ir)) {
   if (ra_used(ir)) {
     Reg dest = ra_dest(as, ir, allow);
     Reg dest = ra_dest(as, ir, allow);
     tmp = irt_isnum(ir->t) ? ra_scratch(as, rset_clear(gpr, dest)) : dest;
     tmp = irt_isnum(ir->t) ? ra_scratch(as, rset_clear(gpr, dest)) : dest;
@@ -1057,7 +1062,8 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
   /* Always do the type check, even if the load result is unused. */
   /* Always do the type check, even if the load result is unused. */
   asm_guardcc(as, irt_isnum(ir->t) ? CC_LS : CC_NE);
   asm_guardcc(as, irt_isnum(ir->t) ? CC_LS : CC_NE);
   if (irt_type(ir->t) >= IRT_NUM) {
   if (irt_type(ir->t) >= IRT_NUM) {
-    lua_assert(irt_isinteger(ir->t) || irt_isnum(ir->t));
+    lj_assertA(irt_isinteger(ir->t) || irt_isnum(ir->t),
+	       "bad load type %d", irt_type(ir->t));
     emit_nm(as, A64I_CMPx | A64F_SH(A64SH_LSR, 32),
     emit_nm(as, A64I_CMPx | A64F_SH(A64SH_LSR, 32),
 	    ra_allock(as, LJ_TISNUM << 15, rset_exclude(gpr, idx)), tmp);
 	    ra_allock(as, LJ_TISNUM << 15, rset_exclude(gpr, idx)), tmp);
   } else if (irt_isaddr(ir->t)) {
   } else if (irt_isaddr(ir->t)) {
@@ -1067,7 +1073,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
     emit_n(as, (A64I_CMNx^A64I_K12) | A64F_U12(1), tmp);
     emit_n(as, (A64I_CMNx^A64I_K12) | A64F_U12(1), tmp);
   } else {
   } else {
     emit_nm(as, A64I_CMPx | A64F_SH(A64SH_LSR, 32),
     emit_nm(as, A64I_CMPx | A64F_SH(A64SH_LSR, 32),
-	    ra_allock(as, (irt_toitype(ir->t) << 15) | 0x7fff, allow), tmp);
+	    ra_allock(as, (irt_toitype(ir->t) << 15) | 0x7fff, gpr), tmp);
   }
   }
   if (ofs & FUSE_REG)
   if (ofs & FUSE_REG)
     emit_dnm(as, (A64I_LDRx^A64I_LS_R)|A64I_LS_UXTWx|A64I_LS_SH, tmp, idx, (ofs & 31));
     emit_dnm(as, (A64I_LDRx^A64I_LS_R)|A64I_LS_UXTWx|A64I_LS_SH, tmp, idx, (ofs & 31));
@@ -1122,8 +1128,10 @@ static void asm_sload(ASMState *as, IRIns *ir)
   IRType1 t = ir->t;
   IRType1 t = ir->t;
   Reg dest = RID_NONE, base;
   Reg dest = RID_NONE, base;
   RegSet allow = RSET_GPR;
   RegSet allow = RSET_GPR;
-  lua_assert(!(ir->op2 & IRSLOAD_PARENT));  /* Handled by asm_head_side(). */
-  lua_assert(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK));
+  lj_assertA(!(ir->op2 & IRSLOAD_PARENT),
+	     "bad parent SLOAD");  /* Handled by asm_head_side(). */
+  lj_assertA(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK),
+	     "inconsistent SLOAD variant");
   if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {
   if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {
     dest = ra_scratch(as, RSET_FPR);
     dest = ra_scratch(as, RSET_FPR);
     asm_tointg(as, ir, dest);
     asm_tointg(as, ir, dest);
@@ -1132,7 +1140,8 @@ static void asm_sload(ASMState *as, IRIns *ir)
     Reg tmp = RID_NONE;
     Reg tmp = RID_NONE;
     if ((ir->op2 & IRSLOAD_CONVERT))
     if ((ir->op2 & IRSLOAD_CONVERT))
       tmp = ra_scratch(as, irt_isint(t) ? RSET_FPR : RSET_GPR);
       tmp = ra_scratch(as, irt_isint(t) ? RSET_FPR : RSET_GPR);
-    lua_assert((irt_isnum(t)) || irt_isint(t) || irt_isaddr(t));
+    lj_assertA((irt_isnum(t)) || irt_isint(t) || irt_isaddr(t),
+	       "bad SLOAD type %d", irt_type(t));
     dest = ra_dest(as, ir, irt_isnum(t) ? RSET_FPR : allow);
     dest = ra_dest(as, ir, irt_isnum(t) ? RSET_FPR : allow);
     base = ra_alloc1(as, REF_BASE, rset_clear(allow, dest));
     base = ra_alloc1(as, REF_BASE, rset_clear(allow, dest));
     if (irt_isaddr(t)) {
     if (irt_isaddr(t)) {
@@ -1172,7 +1181,8 @@ dotypecheck:
     /* Need type check, even if the load result is unused. */
     /* Need type check, even if the load result is unused. */
     asm_guardcc(as, irt_isnum(t) ? CC_LS : CC_NE);
     asm_guardcc(as, irt_isnum(t) ? CC_LS : CC_NE);
     if (irt_type(t) >= IRT_NUM) {
     if (irt_type(t) >= IRT_NUM) {
-      lua_assert(irt_isinteger(t) || irt_isnum(t));
+      lj_assertA(irt_isinteger(t) || irt_isnum(t),
+		 "bad SLOAD type %d", irt_type(t));
       emit_nm(as, A64I_CMPx | A64F_SH(A64SH_LSR, 32),
       emit_nm(as, A64I_CMPx | A64F_SH(A64SH_LSR, 32),
 	      ra_allock(as, LJ_TISNUM << 15, allow), tmp);
 	      ra_allock(as, LJ_TISNUM << 15, allow), tmp);
     } else if (irt_isnil(t)) {
     } else if (irt_isnil(t)) {
@@ -1207,7 +1217,8 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
   IRRef args[4];
   IRRef args[4];
   RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
   RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
-  lua_assert(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL));
+  lj_assertA(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL),
+	     "bad CNEW/CNEWI operands");
 
 
   as->gcsteps++;
   as->gcsteps++;
   asm_setupresult(as, ir, ci);  /* GCcdata * */
   asm_setupresult(as, ir, ci);  /* GCcdata * */
@@ -1215,7 +1226,7 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   if (ir->o == IR_CNEWI) {
   if (ir->o == IR_CNEWI) {
     int32_t ofs = sizeof(GCcdata);
     int32_t ofs = sizeof(GCcdata);
     Reg r = ra_alloc1(as, ir->op2, allow);
     Reg r = ra_alloc1(as, ir->op2, allow);
-    lua_assert(sz == 4 || sz == 8);
+    lj_assertA(sz == 4 || sz == 8, "bad CNEWI size %d", sz);
     emit_lso(as, sz == 8 ? A64I_STRx : A64I_STRw, r, RID_RET, ofs);
     emit_lso(as, sz == 8 ? A64I_STRx : A64I_STRw, r, RID_RET, ofs);
   } else if (ir->op2 != REF_NIL) {  /* Create VLA/VLS/aligned cdata. */
   } else if (ir->op2 != REF_NIL) {  /* Create VLA/VLS/aligned cdata. */
     ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv];
     ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv];
@@ -1242,8 +1253,6 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
   ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
 	       ra_releasetmp(as, ASMREF_TMP1));
 	       ra_releasetmp(as, ASMREF_TMP1));
 }
 }
-#else
-#define asm_cnew(as, ir)	((void)0)
 #endif
 #endif
 
 
 /* -- Write barriers ------------------------------------------------------ */
 /* -- Write barriers ------------------------------------------------------ */
@@ -1276,7 +1285,7 @@ static void asm_obar(ASMState *as, IRIns *ir)
   RegSet allow = RSET_GPR;
   RegSet allow = RSET_GPR;
   Reg obj, val, tmp;
   Reg obj, val, tmp;
   /* No need for other object barriers (yet). */
   /* No need for other object barriers (yet). */
-  lua_assert(IR(ir->op1)->o == IR_UREFC);
+  lj_assertA(IR(ir->op1)->o == IR_UREFC, "bad OBAR type");
   ra_evictset(as, RSET_SCRATCH);
   ra_evictset(as, RSET_SCRATCH);
   l_end = emit_label(as);
   l_end = emit_label(as);
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[0] = ASMREF_TMP1;  /* global_State *g */
@@ -1320,8 +1329,6 @@ static void asm_fpmath(ASMState *as, IRIns *ir)
   } else if (fpm <= IRFPM_TRUNC) {
   } else if (fpm <= IRFPM_TRUNC) {
     asm_fpunary(as, ir, fpm == IRFPM_FLOOR ? A64I_FRINTMd :
     asm_fpunary(as, ir, fpm == IRFPM_FLOOR ? A64I_FRINTMd :
 			fpm == IRFPM_CEIL ? A64I_FRINTPd : A64I_FRINTZd);
 			fpm == IRFPM_CEIL ? A64I_FRINTPd : A64I_FRINTZd);
-  } else if (fpm == IRFPM_EXP2 && asm_fpjoin_pow(as, ir)) {
-    return;
   } else {
   } else {
     asm_callid(as, ir, IRCALL_lj_vm_floor + fpm);
     asm_callid(as, ir, IRCALL_lj_vm_floor + fpm);
   }
   }
@@ -1428,46 +1435,12 @@ static void asm_mul(ASMState *as, IRIns *ir)
   asm_intmul(as, ir);
   asm_intmul(as, ir);
 }
 }
 
 
-static void asm_div(ASMState *as, IRIns *ir)
-{
-#if LJ_HASFFI
-  if (!irt_isnum(ir->t))
-    asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_divi64 :
-					  IRCALL_lj_carith_divu64);
-  else
-#endif
-    asm_fparith(as, ir, A64I_FDIVd);
-}
-
-static void asm_pow(ASMState *as, IRIns *ir)
-{
-#if LJ_HASFFI
-  if (!irt_isnum(ir->t))
-    asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 :
-					  IRCALL_lj_carith_powu64);
-  else
-#endif
-    asm_callid(as, ir, IRCALL_lj_vm_powi);
-}
-
 #define asm_addov(as, ir)	asm_add(as, ir)
 #define asm_addov(as, ir)	asm_add(as, ir)
 #define asm_subov(as, ir)	asm_sub(as, ir)
 #define asm_subov(as, ir)	asm_sub(as, ir)
 #define asm_mulov(as, ir)	asm_mul(as, ir)
 #define asm_mulov(as, ir)	asm_mul(as, ir)
 
 
+#define asm_fpdiv(as, ir)	asm_fparith(as, ir, A64I_FDIVd)
 #define asm_abs(as, ir)		asm_fpunary(as, ir, A64I_FABS)
 #define asm_abs(as, ir)		asm_fpunary(as, ir, A64I_FABS)
-#define asm_atan2(as, ir)	asm_callid(as, ir, IRCALL_atan2)
-#define asm_ldexp(as, ir)	asm_callid(as, ir, IRCALL_ldexp)
-
-static void asm_mod(ASMState *as, IRIns *ir)
-{
-#if LJ_HASFFI
-  if (!irt_isint(ir->t))
-    asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_modi64 :
-					  IRCALL_lj_carith_modu64);
-  else
-#endif
-    asm_callid(as, ir, IRCALL_lj_vm_modi);
-}
 
 
 static void asm_neg(ASMState *as, IRIns *ir)
 static void asm_neg(ASMState *as, IRIns *ir)
 {
 {
@@ -1582,7 +1555,7 @@ static void asm_bitshift(ASMState *as, IRIns *ir, A64Ins ai, A64Shift sh)
 #define asm_bshr(as, ir)	asm_bitshift(as, ir, A64I_UBFMw, A64SH_LSR)
 #define asm_bshr(as, ir)	asm_bitshift(as, ir, A64I_UBFMw, A64SH_LSR)
 #define asm_bsar(as, ir)	asm_bitshift(as, ir, A64I_SBFMw, A64SH_ASR)
 #define asm_bsar(as, ir)	asm_bitshift(as, ir, A64I_SBFMw, A64SH_ASR)
 #define asm_bror(as, ir)	asm_bitshift(as, ir, A64I_EXTRw, A64SH_ROR)
 #define asm_bror(as, ir)	asm_bitshift(as, ir, A64I_EXTRw, A64SH_ROR)
-#define asm_brol(as, ir)	lua_assert(0)
+#define asm_brol(as, ir)	lj_assertA(0, "unexpected BROL")
 
 
 static void asm_intmin_max(ASMState *as, IRIns *ir, A64CC cc)
 static void asm_intmin_max(ASMState *as, IRIns *ir, A64CC cc)
 {
 {
@@ -1598,7 +1571,7 @@ static void asm_fpmin_max(ASMState *as, IRIns *ir, A64CC fcc)
   Reg dest = (ra_dest(as, ir, RSET_FPR) & 31);
   Reg dest = (ra_dest(as, ir, RSET_FPR) & 31);
   Reg right, left = ra_alloc2(as, ir, RSET_FPR);
   Reg right, left = ra_alloc2(as, ir, RSET_FPR);
   right = ((left >> 8) & 31); left &= 31;
   right = ((left >> 8) & 31); left &= 31;
-  emit_dnm(as, A64I_FCSELd | A64F_CC(fcc), dest, left, right);
+  emit_dnm(as, A64I_FCSELd | A64F_CC(fcc), dest, right, left);
   emit_nm(as, A64I_FCMPd, left, right);
   emit_nm(as, A64I_FCMPd, left, right);
 }
 }
 
 
@@ -1610,8 +1583,8 @@ static void asm_min_max(ASMState *as, IRIns *ir, A64CC cc, A64CC fcc)
     asm_intmin_max(as, ir, cc);
     asm_intmin_max(as, ir, cc);
 }
 }
 
 
-#define asm_max(as, ir)		asm_min_max(as, ir, CC_GT, CC_HI)
-#define asm_min(as, ir)		asm_min_max(as, ir, CC_LT, CC_LO)
+#define asm_min(as, ir)		asm_min_max(as, ir, CC_LT, CC_PL)
+#define asm_max(as, ir)		asm_min_max(as, ir, CC_GT, CC_LE)
 
 
 /* -- Comparisons --------------------------------------------------------- */
 /* -- Comparisons --------------------------------------------------------- */
 
 
@@ -1663,15 +1636,16 @@ static void asm_intcomp(ASMState *as, IRIns *ir)
   Reg left;
   Reg left;
   uint32_t m;
   uint32_t m;
   int cmpprev0 = 0;
   int cmpprev0 = 0;
-  lua_assert(irt_is64(ir->t) || irt_isint(ir->t) ||
-	     irt_isu32(ir->t) || irt_isaddr(ir->t) || irt_isu8(ir->t));
+  lj_assertA(irt_is64(ir->t) || irt_isint(ir->t) ||
+	     irt_isu32(ir->t) || irt_isaddr(ir->t) || irt_isu8(ir->t),
+	     "bad comparison data type %d", irt_type(ir->t));
   if (asm_swapops(as, lref, rref)) {
   if (asm_swapops(as, lref, rref)) {
     IRRef tmp = lref; lref = rref; rref = tmp;
     IRRef tmp = lref; lref = rref; rref = tmp;
     if (cc >= CC_GE) cc ^= 7;  /* LT <-> GT, LE <-> GE */
     if (cc >= CC_GE) cc ^= 7;  /* LT <-> GT, LE <-> GE */
     else if (cc > CC_NE) cc ^= 11;  /* LO <-> HI, LS <-> HS */
     else if (cc > CC_NE) cc ^= 11;  /* LO <-> HI, LS <-> HS */
   }
   }
   oldcc = cc;
   oldcc = cc;
-  if (irref_isk(rref) && get_k64val(IR(rref)) == 0) {
+  if (irref_isk(rref) && get_k64val(as, rref) == 0) {
     IRIns *irl = IR(lref);
     IRIns *irl = IR(lref);
     if (cc == CC_GE) cc = CC_PL;
     if (cc == CC_GE) cc = CC_PL;
     else if (cc == CC_LT) cc = CC_MI;
     else if (cc == CC_LT) cc = CC_MI;
@@ -1686,7 +1660,7 @@ static void asm_intcomp(ASMState *as, IRIns *ir)
 	Reg tmp = blref; blref = brref; brref = tmp;
 	Reg tmp = blref; blref = brref; brref = tmp;
       }
       }
       if (irref_isk(brref)) {
       if (irref_isk(brref)) {
-	uint64_t k = get_k64val(IR(brref));
+	uint64_t k = get_k64val(as, brref);
 	if (k && !(k & (k-1)) && (cc == CC_EQ || cc == CC_NE)) {
 	if (k && !(k & (k-1)) && (cc == CC_EQ || cc == CC_NE)) {
 	  asm_guardtnb(as, cc == CC_EQ ? A64I_TBZ : A64I_TBNZ,
 	  asm_guardtnb(as, cc == CC_EQ ? A64I_TBZ : A64I_TBNZ,
 		       ra_alloc1(as, blref, RSET_GPR), emit_ctz64(k));
 		       ra_alloc1(as, blref, RSET_GPR), emit_ctz64(k));
@@ -1735,7 +1709,8 @@ static void asm_comp(ASMState *as, IRIns *ir)
 /* Hiword op of a split 64 bit op. Previous op must be the loword op. */
 /* Hiword op of a split 64 bit op. Previous op must be the loword op. */
 static void asm_hiop(ASMState *as, IRIns *ir)
 static void asm_hiop(ASMState *as, IRIns *ir)
 {
 {
-  UNUSED(as); UNUSED(ir); lua_assert(0);  /* Unused on 64 bit. */
+  UNUSED(as); UNUSED(ir);
+  lj_assertA(0, "unexpected HIOP");  /* Unused on 64 bit. */
 }
 }
 
 
 /* -- Profiling ----------------------------------------------------------- */
 /* -- Profiling ----------------------------------------------------------- */
@@ -1743,7 +1718,7 @@ static void asm_hiop(ASMState *as, IRIns *ir)
 static void asm_prof(ASMState *as, IRIns *ir)
 static void asm_prof(ASMState *as, IRIns *ir)
 {
 {
   uint32_t k = emit_isk13(HOOK_PROFILE, 0);
   uint32_t k = emit_isk13(HOOK_PROFILE, 0);
-  lua_assert(k != 0);
+  lj_assertA(k != 0, "HOOK_PROFILE does not fit in K13");
   UNUSED(ir);
   UNUSED(ir);
   asm_guardcc(as, CC_NE);
   asm_guardcc(as, CC_NE);
   emit_n(as, A64I_TSTw^k, RID_TMP);
   emit_n(as, A64I_TSTw^k, RID_TMP);
@@ -1761,7 +1736,7 @@ static void asm_stack_check(ASMState *as, BCReg topslot,
   if (irp) {
   if (irp) {
     if (!ra_hasspill(irp->s)) {
     if (!ra_hasspill(irp->s)) {
       pbase = irp->r;
       pbase = irp->r;
-      lua_assert(ra_hasreg(pbase));
+      lj_assertA(ra_hasreg(pbase), "base reg lost");
     } else if (allow) {
     } else if (allow) {
       pbase = rset_pickbot(allow);
       pbase = rset_pickbot(allow);
     } else {
     } else {
@@ -1773,7 +1748,7 @@ static void asm_stack_check(ASMState *as, BCReg topslot,
   }
   }
   emit_cond_branch(as, CC_LS, asm_exitstub_addr(as, exitno));
   emit_cond_branch(as, CC_LS, asm_exitstub_addr(as, exitno));
   k = emit_isk12((8*topslot));
   k = emit_isk12((8*topslot));
-  lua_assert(k);
+  lj_assertA(k, "slot offset %d does not fit in K12", 8*topslot);
   emit_n(as, A64I_CMPx^k, RID_TMP);
   emit_n(as, A64I_CMPx^k, RID_TMP);
   emit_dnm(as, A64I_SUBx, RID_TMP, RID_TMP, pbase);
   emit_dnm(as, A64I_SUBx, RID_TMP, RID_TMP, pbase);
   emit_lso(as, A64I_LDRx, RID_TMP, RID_TMP,
   emit_lso(as, A64I_LDRx, RID_TMP, RID_TMP,
@@ -1814,11 +1789,15 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
     }
     }
     checkmclim(as);
     checkmclim(as);
   }
   }
-  lua_assert(map + nent == flinks);
+  lj_assertA(map + nent == flinks, "inconsistent frames in snapshot");
 }
 }
 
 
 /* -- GC handling --------------------------------------------------------- */
 /* -- GC handling --------------------------------------------------------- */
 
 
+/* Marker to prevent patching the GC check exit. */
+#define ARM64_NOPATCH_GC_CHECK \
+  (A64I_ORRx|A64F_D(RID_TMP)|A64F_M(RID_TMP)|A64F_N(RID_TMP))
+
 /* Check GC threshold and do one or more GC steps. */
 /* Check GC threshold and do one or more GC steps. */
 static void asm_gc_check(ASMState *as)
 static void asm_gc_check(ASMState *as)
 {
 {
@@ -1830,6 +1809,7 @@ static void asm_gc_check(ASMState *as)
   l_end = emit_label(as);
   l_end = emit_label(as);
   /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
   /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
   asm_guardcnb(as, A64I_CBNZ, RID_RET); /* Assumes asm_snap_prep() is done. */
   asm_guardcnb(as, A64I_CBNZ, RID_RET); /* Assumes asm_snap_prep() is done. */
+  *--as->mcp = ARM64_NOPATCH_GC_CHECK;
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[1] = ASMREF_TMP2;  /* MSize steps     */
   args[1] = ASMREF_TMP2;  /* MSize steps     */
   asm_gencall(as, ci, args);
   asm_gencall(as, ci, args);
@@ -1902,7 +1882,7 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
     rset_clear(allow, ra_dest(as, ir, allow));
     rset_clear(allow, ra_dest(as, ir, allow));
   } else {
   } else {
     Reg r = irp->r;
     Reg r = irp->r;
-    lua_assert(ra_hasreg(r));
+    lj_assertA(ra_hasreg(r), "base reg lost");
     rset_clear(allow, r);
     rset_clear(allow, r);
     if (r != ir->r && !rset_test(as->freeset, r))
     if (r != ir->r && !rset_test(as->freeset, r))
       ra_restore(as, regcost_ref(as->cost[r]));
       ra_restore(as, regcost_ref(as->cost[r]));
@@ -1926,7 +1906,7 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk)
   } else {
   } else {
     /* Patch stack adjustment. */
     /* Patch stack adjustment. */
     uint32_t k = emit_isk12(spadj);
     uint32_t k = emit_isk12(spadj);
-    lua_assert(k);
+    lj_assertA(k, "stack adjustment %d does not fit in K12", spadj);
     p[-2] = (A64I_ADDx^k) | A64F_D(RID_SP) | A64F_N(RID_SP);
     p[-2] = (A64I_ADDx^k) | A64F_D(RID_SP) | A64F_N(RID_SP);
   }
   }
   /* Patch exit branch. */
   /* Patch exit branch. */
@@ -1997,6 +1977,7 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
   MCode *cstart = NULL;
   MCode *cstart = NULL;
   MCode *mcarea = lj_mcode_patch(J, p, 0);
   MCode *mcarea = lj_mcode_patch(J, p, 0);
   MCode *px = exitstub_trace_addr(T, exitno);
   MCode *px = exitstub_trace_addr(T, exitno);
+  int patchlong = 1;
   /* Note: this assumes a trace exit is only ever patched once. */
   /* Note: this assumes a trace exit is only ever patched once. */
   for (; p < pe; p++) {
   for (; p < pe; p++) {
     /* Look for exitstub branch, replace with branch to target. */
     /* Look for exitstub branch, replace with branch to target. */
@@ -2012,13 +1993,15 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
     } else if ((ins & 0xfc000000u) == 0x14000000u &&
     } else if ((ins & 0xfc000000u) == 0x14000000u &&
 	       ((ins ^ (px-p)) & 0x03ffffffu) == 0) {
 	       ((ins ^ (px-p)) & 0x03ffffffu) == 0) {
       /* Patch b. */
       /* Patch b. */
-      lua_assert(A64F_S_OK(delta, 26));
+      lj_assertJ(A64F_S_OK(delta, 26), "branch target out of range");
       *p = A64I_LE((ins & 0xfc000000u) | A64F_S26(delta));
       *p = A64I_LE((ins & 0xfc000000u) | A64F_S26(delta));
       if (!cstart) cstart = p;
       if (!cstart) cstart = p;
     } else if ((ins & 0x7e000000u) == 0x34000000u &&
     } else if ((ins & 0x7e000000u) == 0x34000000u &&
 	       ((ins ^ ((px-p)<<5)) & 0x00ffffe0u) == 0) {
 	       ((ins ^ ((px-p)<<5)) & 0x00ffffe0u) == 0) {
       /* Patch cbz/cbnz, if within range. */
       /* Patch cbz/cbnz, if within range. */
-      if (A64F_S_OK(delta, 19)) {
+      if (p[-1] == ARM64_NOPATCH_GC_CHECK) {
+	patchlong = 0;
+      } else if (A64F_S_OK(delta, 19)) {
 	*p = A64I_LE((ins & 0xff00001fu) | A64F_S19(delta));
 	*p = A64I_LE((ins & 0xff00001fu) | A64F_S19(delta));
 	if (!cstart) cstart = p;
 	if (!cstart) cstart = p;
       }
       }
@@ -2031,13 +2014,14 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
       }
       }
     }
     }
   }
   }
-  {  /* Always patch long-range branch in exit stub itself. */
+  /* Always patch long-range branch in exit stub itself. Except, if we can't. */
+  if (patchlong) {
     ptrdiff_t delta = target - px;
     ptrdiff_t delta = target - px;
-    lua_assert(A64F_S_OK(delta, 26));
+    lj_assertJ(A64F_S_OK(delta, 26), "branch target out of range");
     *px = A64I_B | A64F_S26(delta);
     *px = A64I_B | A64F_S26(delta);
     if (!cstart) cstart = px;
     if (!cstart) cstart = px;
   }
   }
-  lj_mcode_sync(cstart, px+1);
+  if (cstart) lj_mcode_sync(cstart, px+1);
   lj_mcode_patch(J, mcarea, 1);
   lj_mcode_patch(J, mcarea, 1);
 }
 }
 
 

+ 198 - 118
libs/LuaJIT/src/lj_asm_mips.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** MIPS IR assembler (SSA IR -> machine code).
 ** MIPS IR assembler (SSA IR -> machine code).
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 /* -- Register allocator extensions --------------------------------------- */
 /* -- Register allocator extensions --------------------------------------- */
@@ -23,7 +23,7 @@ static Reg ra_alloc1z(ASMState *as, IRRef ref, RegSet allow)
 {
 {
   Reg r = IR(ref)->r;
   Reg r = IR(ref)->r;
   if (ra_noreg(r)) {
   if (ra_noreg(r)) {
-    if (!(allow & RSET_FPR) && irref_isk(ref) && get_kval(IR(ref)) == 0)
+    if (!(allow & RSET_FPR) && irref_isk(ref) && get_kval(as, ref) == 0)
       return RID_ZERO;
       return RID_ZERO;
     r = ra_allocref(as, ref, allow);
     r = ra_allocref(as, ref, allow);
   } else {
   } else {
@@ -66,10 +66,10 @@ static void asm_sparejump_setup(ASMState *as)
 {
 {
   MCode *mxp = as->mcbot;
   MCode *mxp = as->mcbot;
   if (((uintptr_t)mxp & (LJ_PAGESIZE-1)) == sizeof(MCLink)) {
   if (((uintptr_t)mxp & (LJ_PAGESIZE-1)) == sizeof(MCLink)) {
-    lua_assert(MIPSI_NOP == 0);
+    lj_assertA(MIPSI_NOP == 0, "bad NOP");
     memset(mxp, 0, MIPS_SPAREJUMP*2*sizeof(MCode));
     memset(mxp, 0, MIPS_SPAREJUMP*2*sizeof(MCode));
     mxp += MIPS_SPAREJUMP*2;
     mxp += MIPS_SPAREJUMP*2;
-    lua_assert(mxp < as->mctop);
+    lj_assertA(mxp < as->mctop, "MIPS_SPAREJUMP too big");
     lj_mcode_sync(as->mcbot, mxp);
     lj_mcode_sync(as->mcbot, mxp);
     lj_mcode_commitbot(as->J, mxp);
     lj_mcode_commitbot(as->J, mxp);
     as->mcbot = mxp;
     as->mcbot = mxp;
@@ -84,7 +84,8 @@ static void asm_exitstub_setup(ASMState *as)
   /* sw TMP, 0(sp); j ->vm_exit_handler; li TMP, traceno */
   /* sw TMP, 0(sp); j ->vm_exit_handler; li TMP, traceno */
   *--mxp = MIPSI_LI|MIPSF_T(RID_TMP)|as->T->traceno;
   *--mxp = MIPSI_LI|MIPSF_T(RID_TMP)|as->T->traceno;
   *--mxp = MIPSI_J|((((uintptr_t)(void *)lj_vm_exit_handler)>>2)&0x03ffffffu);
   *--mxp = MIPSI_J|((((uintptr_t)(void *)lj_vm_exit_handler)>>2)&0x03ffffffu);
-  lua_assert(((uintptr_t)mxp ^ (uintptr_t)(void *)lj_vm_exit_handler)>>28 == 0);
+  lj_assertA(((uintptr_t)mxp ^ (uintptr_t)(void *)lj_vm_exit_handler)>>28 == 0,
+	     "branch target out of range");
   *--mxp = MIPSI_SW|MIPSF_T(RID_TMP)|MIPSF_S(RID_SP)|0;
   *--mxp = MIPSI_SW|MIPSF_T(RID_TMP)|MIPSF_S(RID_SP)|0;
   as->mctop = mxp;
   as->mctop = mxp;
 }
 }
@@ -101,7 +102,12 @@ static void asm_guard(ASMState *as, MIPSIns mi, Reg rs, Reg rt)
     as->invmcp = NULL;
     as->invmcp = NULL;
     as->loopinv = 1;
     as->loopinv = 1;
     as->mcp = p+1;
     as->mcp = p+1;
+#if !LJ_TARGET_MIPSR6
     mi = mi ^ ((mi>>28) == 1 ? 0x04000000u : 0x00010000u);  /* Invert cond. */
     mi = mi ^ ((mi>>28) == 1 ? 0x04000000u : 0x00010000u);  /* Invert cond. */
+#else
+    mi = mi ^ ((mi>>28) == 1 ? 0x04000000u :
+	       (mi>>28) == 4 ? 0x00800000u : 0x00010000u);  /* Invert cond. */
+#endif
     target = p;  /* Patch target later in asm_loop_fixup. */
     target = p;  /* Patch target later in asm_loop_fixup. */
   }
   }
   emit_ti(as, MIPSI_LI, RID_TMP, as->snapno);
   emit_ti(as, MIPSI_LI, RID_TMP, as->snapno);
@@ -190,20 +196,20 @@ static void asm_fusexref(ASMState *as, MIPSIns mi, Reg rt, IRRef ref,
   if (ra_noreg(ir->r) && canfuse(as, ir)) {
   if (ra_noreg(ir->r) && canfuse(as, ir)) {
     if (ir->o == IR_ADD) {
     if (ir->o == IR_ADD) {
       intptr_t ofs2;
       intptr_t ofs2;
-      if (irref_isk(ir->op2) && (ofs2 = ofs + get_kval(IR(ir->op2)),
+      if (irref_isk(ir->op2) && (ofs2 = ofs + get_kval(as, ir->op2),
 				 checki16(ofs2))) {
 				 checki16(ofs2))) {
 	ref = ir->op1;
 	ref = ir->op1;
 	ofs = (int32_t)ofs2;
 	ofs = (int32_t)ofs2;
       }
       }
     } else if (ir->o == IR_STRREF) {
     } else if (ir->o == IR_STRREF) {
       intptr_t ofs2 = 65536;
       intptr_t ofs2 = 65536;
-      lua_assert(ofs == 0);
+      lj_assertA(ofs == 0, "bad usage");
       ofs = (int32_t)sizeof(GCstr);
       ofs = (int32_t)sizeof(GCstr);
       if (irref_isk(ir->op2)) {
       if (irref_isk(ir->op2)) {
-	ofs2 = ofs + get_kval(IR(ir->op2));
+	ofs2 = ofs + get_kval(as, ir->op2);
 	ref = ir->op1;
 	ref = ir->op1;
       } else if (irref_isk(ir->op1)) {
       } else if (irref_isk(ir->op1)) {
-	ofs2 = ofs + get_kval(IR(ir->op1));
+	ofs2 = ofs + get_kval(as, ir->op1);
 	ref = ir->op2;
 	ref = ir->op2;
       }
       }
       if (!checki16(ofs2)) {
       if (!checki16(ofs2)) {
@@ -247,7 +253,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
       if (irt_isfp(ir->t) && fpr <= REGARG_LASTFPR &&
       if (irt_isfp(ir->t) && fpr <= REGARG_LASTFPR &&
 	  !(ci->flags & CCI_VARARG)) {
 	  !(ci->flags & CCI_VARARG)) {
-	lua_assert(rset_test(as->freeset, fpr));  /* Already evicted. */
+	lj_assertA(rset_test(as->freeset, fpr),
+		   "reg %d not free", fpr);  /* Already evicted. */
 	ra_leftov(as, fpr, ref);
 	ra_leftov(as, fpr, ref);
 	fpr += LJ_32 ? 2 : 1;
 	fpr += LJ_32 ? 2 : 1;
 	gpr += (LJ_32 && irt_isnum(ir->t)) ? 2 : 1;
 	gpr += (LJ_32 && irt_isnum(ir->t)) ? 2 : 1;
@@ -259,7 +266,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
 #endif
 #endif
 	if (LJ_32 && irt_isnum(ir->t)) gpr = (gpr+1) & ~1;
 	if (LJ_32 && irt_isnum(ir->t)) gpr = (gpr+1) & ~1;
 	if (gpr <= REGARG_LASTGPR) {
 	if (gpr <= REGARG_LASTGPR) {
-	  lua_assert(rset_test(as->freeset, gpr));  /* Already evicted. */
+	  lj_assertA(rset_test(as->freeset, gpr),
+		     "reg %d not free", gpr);  /* Already evicted. */
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
 	  if (irt_isfp(ir->t)) {
 	  if (irt_isfp(ir->t)) {
 	    RegSet of = as->freeset;
 	    RegSet of = as->freeset;
@@ -272,7 +280,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
 #if LJ_32
 #if LJ_32
 	      emit_tg(as, MIPSI_MFC1, gpr+(LJ_BE?0:1), r+1);
 	      emit_tg(as, MIPSI_MFC1, gpr+(LJ_BE?0:1), r+1);
 	      emit_tg(as, MIPSI_MFC1, gpr+(LJ_BE?1:0), r);
 	      emit_tg(as, MIPSI_MFC1, gpr+(LJ_BE?1:0), r);
-	      lua_assert(rset_test(as->freeset, gpr+1));  /* Already evicted. */
+	      lj_assertA(rset_test(as->freeset, gpr+1),
+			 "reg %d not free", gpr+1);  /* Already evicted. */
 	      gpr += 2;
 	      gpr += 2;
 #else
 #else
 	      emit_tg(as, MIPSI_DMFC1, gpr, r);
 	      emit_tg(as, MIPSI_DMFC1, gpr, r);
@@ -342,7 +351,7 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
 #endif
 #endif
   ra_evictset(as, drop);  /* Evictions must be performed first. */
   ra_evictset(as, drop);  /* Evictions must be performed first. */
   if (ra_used(ir)) {
   if (ra_used(ir)) {
-    lua_assert(!irt_ispri(ir->t));
+    lj_assertA(!irt_ispri(ir->t), "PRI dest");
     if (!LJ_SOFTFP && irt_isfp(ir->t)) {
     if (!LJ_SOFTFP && irt_isfp(ir->t)) {
       if ((ci->flags & CCI_CASTU64)) {
       if ((ci->flags & CCI_CASTU64)) {
 	int32_t ofs = sps_scale(ir->s);
 	int32_t ofs = sps_scale(ir->s);
@@ -390,7 +399,7 @@ static void asm_callx(ASMState *as, IRIns *ir)
   func = ir->op2; irf = IR(func);
   func = ir->op2; irf = IR(func);
   if (irf->o == IR_CARG) { func = irf->op1; irf = IR(func); }
   if (irf->o == IR_CARG) { func = irf->op1; irf = IR(func); }
   if (irref_isk(func)) {  /* Call to constant address. */
   if (irref_isk(func)) {  /* Call to constant address. */
-    ci.func = (ASMFunction)(void *)get_kval(irf);
+    ci.func = (ASMFunction)(void *)get_kval(as, func);
   } else {  /* Need specific register for indirect calls. */
   } else {  /* Need specific register for indirect calls. */
     Reg r = ra_alloc1(as, func, RID2RSET(RID_CFUNCADDR));
     Reg r = ra_alloc1(as, func, RID2RSET(RID_CFUNCADDR));
     MCode *p = as->mcp;
     MCode *p = as->mcp;
@@ -410,7 +419,11 @@ static void asm_callround(ASMState *as, IRIns *ir, IRCallID id)
 {
 {
   /* The modified regs must match with the *.dasc implementation. */
   /* The modified regs must match with the *.dasc implementation. */
   RegSet drop = RID2RSET(RID_R1)|RID2RSET(RID_R12)|RID2RSET(RID_FPRET)|
   RegSet drop = RID2RSET(RID_R1)|RID2RSET(RID_R12)|RID2RSET(RID_FPRET)|
-		RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(REGARG_FIRSTFPR);
+		RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(REGARG_FIRSTFPR)
+#if LJ_TARGET_MIPSR6
+		|RID2RSET(RID_F21)
+#endif
+		;
   if (ra_hasreg(ir->r)) rset_clear(drop, ir->r);
   if (ra_hasreg(ir->r)) rset_clear(drop, ir->r);
   ra_evictset(as, drop);
   ra_evictset(as, drop);
   ra_destreg(as, ir, RID_FPRET);
   ra_destreg(as, ir, RID_FPRET);
@@ -444,8 +457,13 @@ static void asm_tointg(ASMState *as, IRIns *ir, Reg left)
 {
 {
   Reg tmp = ra_scratch(as, rset_exclude(RSET_FPR, left));
   Reg tmp = ra_scratch(as, rset_exclude(RSET_FPR, left));
   Reg dest = ra_dest(as, ir, RSET_GPR);
   Reg dest = ra_dest(as, ir, RSET_GPR);
+#if !LJ_TARGET_MIPSR6
   asm_guard(as, MIPSI_BC1F, 0, 0);
   asm_guard(as, MIPSI_BC1F, 0, 0);
   emit_fgh(as, MIPSI_C_EQ_D, 0, tmp, left);
   emit_fgh(as, MIPSI_C_EQ_D, 0, tmp, left);
+#else
+  asm_guard(as, MIPSI_BC1EQZ, 0, (tmp&31));
+  emit_fgh(as, MIPSI_CMP_EQ_D, tmp, tmp, left);
+#endif
   emit_fg(as, MIPSI_CVT_D_W, tmp, tmp);
   emit_fg(as, MIPSI_CVT_D_W, tmp, tmp);
   emit_tg(as, MIPSI_MFC1, dest, tmp);
   emit_tg(as, MIPSI_MFC1, dest, tmp);
   emit_fg(as, MIPSI_CVT_W_D, tmp, left);
   emit_fg(as, MIPSI_CVT_W_D, tmp, left);
@@ -498,15 +516,19 @@ static void asm_conv(ASMState *as, IRIns *ir)
 #endif
 #endif
   IRRef lref = ir->op1;
   IRRef lref = ir->op1;
 #if LJ_32
 #if LJ_32
-  lua_assert(!(irt_isint64(ir->t) ||
-	       (st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */
+  /* 64 bit integer conversions are handled by SPLIT. */
+  lj_assertA(!(irt_isint64(ir->t) || (st == IRT_I64 || st == IRT_U64)),
+	     "IR %04d has unsplit 64 bit type",
+	     (int)(ir - as->ir) - REF_BIAS);
 #endif
 #endif
 #if LJ_SOFTFP32
 #if LJ_SOFTFP32
   /* FP conversions are handled by SPLIT. */
   /* FP conversions are handled by SPLIT. */
-  lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT));
+  lj_assertA(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT),
+	     "IR %04d has FP type",
+	     (int)(ir - as->ir) - REF_BIAS);
   /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */
   /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */
 #else
 #else
-  lua_assert(irt_type(ir->t) != st);
+  lj_assertA(irt_type(ir->t) != st, "inconsistent types for CONV");
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
   if (irt_isfp(ir->t)) {
   if (irt_isfp(ir->t)) {
     Reg dest = ra_dest(as, ir, RSET_FPR);
     Reg dest = ra_dest(as, ir, RSET_FPR);
@@ -565,7 +587,8 @@ static void asm_conv(ASMState *as, IRIns *ir)
   } else if (stfp) {  /* FP to integer conversion. */
   } else if (stfp) {  /* FP to integer conversion. */
     if (irt_isguard(ir->t)) {
     if (irt_isguard(ir->t)) {
       /* Checked conversions are only supported from number to int. */
       /* Checked conversions are only supported from number to int. */
-      lua_assert(irt_isint(ir->t) && st == IRT_NUM);
+      lj_assertA(irt_isint(ir->t) && st == IRT_NUM,
+		 "bad type for checked CONV");
       asm_tointg(as, ir, ra_alloc1(as, lref, RSET_FPR));
       asm_tointg(as, ir, ra_alloc1(as, lref, RSET_FPR));
     } else {
     } else {
       Reg dest = ra_dest(as, ir, RSET_GPR);
       Reg dest = ra_dest(as, ir, RSET_GPR);
@@ -599,8 +622,13 @@ static void asm_conv(ASMState *as, IRIns *ir)
 		     (void *)&as->J->k64[LJ_K64_M2P64],
 		     (void *)&as->J->k64[LJ_K64_M2P64],
 		     rset_exclude(RSET_GPR, dest));
 		     rset_exclude(RSET_GPR, dest));
 	  emit_fg(as, MIPSI_TRUNC_L_D, tmp, left);  /* Delay slot. */
 	  emit_fg(as, MIPSI_TRUNC_L_D, tmp, left);  /* Delay slot. */
-	  emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
-	  emit_fgh(as, MIPSI_C_OLT_D, 0, left, tmp);
+#if !LJ_TARGET_MIPSR6
+	 emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
+	 emit_fgh(as, MIPSI_C_OLT_D, 0, left, tmp);
+#else
+	 emit_branch(as, MIPSI_BC1NEZ, 0, (left&31), l_end);
+	 emit_fgh(as, MIPSI_CMP_LT_D, left, left, tmp);
+#endif
 	  emit_lsptr(as, MIPSI_LDC1, (tmp & 31),
 	  emit_lsptr(as, MIPSI_LDC1, (tmp & 31),
 		     (void *)&as->J->k64[LJ_K64_2P63],
 		     (void *)&as->J->k64[LJ_K64_2P63],
 		     rset_exclude(RSET_GPR, dest));
 		     rset_exclude(RSET_GPR, dest));
@@ -611,8 +639,13 @@ static void asm_conv(ASMState *as, IRIns *ir)
 		     (void *)&as->J->k32[LJ_K32_M2P64],
 		     (void *)&as->J->k32[LJ_K32_M2P64],
 		     rset_exclude(RSET_GPR, dest));
 		     rset_exclude(RSET_GPR, dest));
 	  emit_fg(as, MIPSI_TRUNC_L_S, tmp, left);  /* Delay slot. */
 	  emit_fg(as, MIPSI_TRUNC_L_S, tmp, left);  /* Delay slot. */
-	  emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
-	  emit_fgh(as, MIPSI_C_OLT_S, 0, left, tmp);
+#if !LJ_TARGET_MIPSR6
+	 emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
+	 emit_fgh(as, MIPSI_C_OLT_S, 0, left, tmp);
+#else
+	 emit_branch(as, MIPSI_BC1NEZ, 0, (left&31), l_end);
+	 emit_fgh(as, MIPSI_CMP_LT_S, left, left, tmp);
+#endif
 	  emit_lsptr(as, MIPSI_LWC1, (tmp & 31),
 	  emit_lsptr(as, MIPSI_LWC1, (tmp & 31),
 		     (void *)&as->J->k32[LJ_K32_2P63],
 		     (void *)&as->J->k32[LJ_K32_2P63],
 		     rset_exclude(RSET_GPR, dest));
 		     rset_exclude(RSET_GPR, dest));
@@ -655,7 +688,8 @@ static void asm_conv(ASMState *as, IRIns *ir)
   } else if (stfp) {  /* FP to integer conversion. */
   } else if (stfp) {  /* FP to integer conversion. */
     if (irt_isguard(ir->t)) {
     if (irt_isguard(ir->t)) {
       /* Checked conversions are only supported from number to int. */
       /* Checked conversions are only supported from number to int. */
-      lua_assert(irt_isint(ir->t) && st == IRT_NUM);
+      lj_assertA(irt_isint(ir->t) && st == IRT_NUM,
+		 "bad type for checked CONV");
       asm_tointg(as, ir, RID_NONE);
       asm_tointg(as, ir, RID_NONE);
     } else {
     } else {
       IRCallID cid = irt_is64(ir->t) ?
       IRCallID cid = irt_is64(ir->t) ?
@@ -674,7 +708,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
     Reg dest = ra_dest(as, ir, RSET_GPR);
     Reg dest = ra_dest(as, ir, RSET_GPR);
     if (st >= IRT_I8 && st <= IRT_U16) {  /* Extend to 32 bit integer. */
     if (st >= IRT_I8 && st <= IRT_U16) {  /* Extend to 32 bit integer. */
       Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
       Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
-      lua_assert(irt_isint(ir->t) || irt_isu32(ir->t));
+      lj_assertA(irt_isint(ir->t) || irt_isu32(ir->t), "bad type for CONV EXT");
       if ((ir->op2 & IRCONV_SEXT)) {
       if ((ir->op2 & IRCONV_SEXT)) {
 	if (LJ_64 || (as->flags & JIT_F_MIPSXXR2)) {
 	if (LJ_64 || (as->flags & JIT_F_MIPSXXR2)) {
 	  emit_dst(as, st == IRT_I8 ? MIPSI_SEB : MIPSI_SEH, dest, 0, left);
 	  emit_dst(as, st == IRT_I8 ? MIPSI_SEB : MIPSI_SEH, dest, 0, left);
@@ -771,7 +805,8 @@ static void asm_tvstore64(ASMState *as, Reg base, int32_t ofs, IRRef ref)
 {
 {
   RegSet allow = rset_exclude(RSET_GPR, base);
   RegSet allow = rset_exclude(RSET_GPR, base);
   IRIns *ir = IR(ref);
   IRIns *ir = IR(ref);
-  lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t));
+  lj_assertA(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t),
+	     "store of IR type %d", irt_type(ir->t));
   if (irref_isk(ref)) {
   if (irref_isk(ref)) {
     TValue k;
     TValue k;
     lj_ir_kvalue(as->J->L, &k, ir);
     lj_ir_kvalue(as->J->L, &k, ir);
@@ -840,8 +875,12 @@ static void asm_aref(ASMState *as, IRIns *ir)
   }
   }
   base = ra_alloc1(as, ir->op1, RSET_GPR);
   base = ra_alloc1(as, ir->op1, RSET_GPR);
   idx = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, base));
   idx = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, base));
+#if !LJ_TARGET_MIPSR6
   emit_dst(as, MIPSI_AADDU, dest, RID_TMP, base);
   emit_dst(as, MIPSI_AADDU, dest, RID_TMP, base);
   emit_dta(as, MIPSI_SLL, RID_TMP, idx, 3);
   emit_dta(as, MIPSI_SLL, RID_TMP, idx, 3);
+#else
+  emit_dst(as, MIPSI_ALSA | MIPSF_A(3-1), dest, idx, base);
+#endif
 }
 }
 
 
 /* Inlined hash lookup. Specialized for key type and for const keys.
 /* Inlined hash lookup. Specialized for key type and for const keys.
@@ -916,7 +955,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
       if (isk && irt_isaddr(kt)) {
       if (isk && irt_isaddr(kt)) {
 	k = ((int64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64;
 	k = ((int64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64;
       } else {
       } else {
-	lua_assert(irt_ispri(kt) && !irt_isnil(kt));
+	lj_assertA(irt_ispri(kt) && !irt_isnil(kt), "bad HREF key type");
 	k = ~((int64_t)~irt_toitype(ir->t) << 47);
 	k = ~((int64_t)~irt_toitype(ir->t) << 47);
       }
       }
       cmp64 = ra_allock(as, k, allow);
       cmp64 = ra_allock(as, k, allow);
@@ -944,8 +983,13 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
     l_end = asm_exitstub_addr(as);
     l_end = asm_exitstub_addr(as);
   }
   }
   if (!LJ_SOFTFP && irt_isnum(kt)) {
   if (!LJ_SOFTFP && irt_isnum(kt)) {
+#if !LJ_TARGET_MIPSR6
     emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
     emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
     emit_fgh(as, MIPSI_C_EQ_D, 0, tmpnum, key);
     emit_fgh(as, MIPSI_C_EQ_D, 0, tmpnum, key);
+#else
+    emit_branch(as, MIPSI_BC1NEZ, 0, (tmpnum&31), l_end);
+    emit_fgh(as, MIPSI_CMP_EQ_D, tmpnum, tmpnum, key);
+#endif
     *--as->mcp = MIPSI_NOP;  /* Avoid NaN comparison overhead. */
     *--as->mcp = MIPSI_NOP;  /* Avoid NaN comparison overhead. */
     emit_branch(as, MIPSI_BEQ, tmp1, RID_ZERO, l_next);
     emit_branch(as, MIPSI_BEQ, tmp1, RID_ZERO, l_next);
     emit_tsi(as, MIPSI_SLTIU, tmp1, tmp1, (int32_t)LJ_TISNUM);
     emit_tsi(as, MIPSI_SLTIU, tmp1, tmp1, (int32_t)LJ_TISNUM);
@@ -979,7 +1023,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
 #endif
 #endif
 
 
   /* Load main position relative to tab->node into dest. */
   /* Load main position relative to tab->node into dest. */
-  khash = isk ? ir_khash(irkey) : 1;
+  khash = isk ? ir_khash(as, irkey) : 1;
   if (khash == 0) {
   if (khash == 0) {
     emit_tsi(as, MIPSI_AL, dest, tab, (int32_t)offsetof(GCtab, node));
     emit_tsi(as, MIPSI_AL, dest, tab, (int32_t)offsetof(GCtab, node));
   } else {
   } else {
@@ -987,7 +1031,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
     if (isk)
     if (isk)
       tmphash = ra_allock(as, khash, allow);
       tmphash = ra_allock(as, khash, allow);
     emit_dst(as, MIPSI_AADDU, dest, dest, tmp1);
     emit_dst(as, MIPSI_AADDU, dest, dest, tmp1);
-    lua_assert(sizeof(Node) == 24);
+    lj_assertA(sizeof(Node) == 24, "bad Node size");
     emit_dst(as, MIPSI_SUBU, tmp1, tmp2, tmp1);
     emit_dst(as, MIPSI_SUBU, tmp1, tmp2, tmp1);
     emit_dta(as, MIPSI_SLL, tmp1, tmp1, 3);
     emit_dta(as, MIPSI_SLL, tmp1, tmp1, 3);
     emit_dta(as, MIPSI_SLL, tmp2, tmp1, 5);
     emit_dta(as, MIPSI_SLL, tmp2, tmp1, 5);
@@ -997,7 +1041,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
     if (isk) {
     if (isk) {
       /* Nothing to do. */
       /* Nothing to do. */
     } else if (irt_isstr(kt)) {
     } else if (irt_isstr(kt)) {
-      emit_tsi(as, MIPSI_LW, tmp1, key, (int32_t)offsetof(GCstr, hash));
+      emit_tsi(as, MIPSI_LW, tmp1, key, (int32_t)offsetof(GCstr, sid));
     } else {  /* Must match with hash*() in lj_tab.c. */
     } else {  /* Must match with hash*() in lj_tab.c. */
       emit_dst(as, MIPSI_SUBU, tmp1, tmp1, tmp2);
       emit_dst(as, MIPSI_SUBU, tmp1, tmp1, tmp2);
       emit_rotr(as, tmp2, tmp2, dest, (-HASH_ROT3)&31);
       emit_rotr(as, tmp2, tmp2, dest, (-HASH_ROT3)&31);
@@ -1065,7 +1109,7 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
   Reg key = ra_scratch(as, allow);
   Reg key = ra_scratch(as, allow);
   int64_t k;
   int64_t k;
 #endif
 #endif
-  lua_assert(ofs % sizeof(Node) == 0);
+  lj_assertA(ofs % sizeof(Node) == 0, "unaligned HREFK slot");
   if (ofs > 32736) {
   if (ofs > 32736) {
     idx = dest;
     idx = dest;
     rset_clear(allow, dest);
     rset_clear(allow, dest);
@@ -1094,7 +1138,7 @@ nolo:
   emit_tsi(as, MIPSI_LW, type, idx, kofs+(LJ_BE?0:4));
   emit_tsi(as, MIPSI_LW, type, idx, kofs+(LJ_BE?0:4));
 #else
 #else
   if (irt_ispri(irkey->t)) {
   if (irt_ispri(irkey->t)) {
-    lua_assert(!irt_isnil(irkey->t));
+    lj_assertA(!irt_isnil(irkey->t), "bad HREFK key type");
     k = ~((int64_t)~irt_toitype(irkey->t) << 47);
     k = ~((int64_t)~irt_toitype(irkey->t) << 47);
   } else if (irt_isnum(irkey->t)) {
   } else if (irt_isnum(irkey->t)) {
     k = (int64_t)ir_knum(irkey)->u64;
     k = (int64_t)ir_knum(irkey)->u64;
@@ -1133,7 +1177,7 @@ static void asm_uref(ASMState *as, IRIns *ir)
 static void asm_fref(ASMState *as, IRIns *ir)
 static void asm_fref(ASMState *as, IRIns *ir)
 {
 {
   UNUSED(as); UNUSED(ir);
   UNUSED(as); UNUSED(ir);
-  lua_assert(!ra_used(ir));
+  lj_assertA(!ra_used(ir), "unfused FREF");
 }
 }
 
 
 static void asm_strref(ASMState *as, IRIns *ir)
 static void asm_strref(ASMState *as, IRIns *ir)
@@ -1188,26 +1232,36 @@ static void asm_strref(ASMState *as, IRIns *ir)
 
 
 /* -- Loads and stores ---------------------------------------------------- */
 /* -- Loads and stores ---------------------------------------------------- */
 
 
-static MIPSIns asm_fxloadins(IRIns *ir)
+static MIPSIns asm_fxloadins(ASMState *as, IRIns *ir)
 {
 {
+  UNUSED(as);
   switch (irt_type(ir->t)) {
   switch (irt_type(ir->t)) {
   case IRT_I8: return MIPSI_LB;
   case IRT_I8: return MIPSI_LB;
   case IRT_U8: return MIPSI_LBU;
   case IRT_U8: return MIPSI_LBU;
   case IRT_I16: return MIPSI_LH;
   case IRT_I16: return MIPSI_LH;
   case IRT_U16: return MIPSI_LHU;
   case IRT_U16: return MIPSI_LHU;
-  case IRT_NUM: lua_assert(!LJ_SOFTFP32); if (!LJ_SOFTFP) return MIPSI_LDC1;
+  case IRT_NUM:
+    lj_assertA(!LJ_SOFTFP32, "unsplit FP op");
+    if (!LJ_SOFTFP) return MIPSI_LDC1;
+  /* fallthrough */
   case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_LWC1;
   case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_LWC1;
+  /* fallthrough */
   default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_LD : MIPSI_LW;
   default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_LD : MIPSI_LW;
   }
   }
 }
 }
 
 
-static MIPSIns asm_fxstoreins(IRIns *ir)
+static MIPSIns asm_fxstoreins(ASMState *as, IRIns *ir)
 {
 {
+  UNUSED(as);
   switch (irt_type(ir->t)) {
   switch (irt_type(ir->t)) {
   case IRT_I8: case IRT_U8: return MIPSI_SB;
   case IRT_I8: case IRT_U8: return MIPSI_SB;
   case IRT_I16: case IRT_U16: return MIPSI_SH;
   case IRT_I16: case IRT_U16: return MIPSI_SH;
-  case IRT_NUM: lua_assert(!LJ_SOFTFP32); if (!LJ_SOFTFP) return MIPSI_SDC1;
+  case IRT_NUM:
+    lj_assertA(!LJ_SOFTFP32, "unsplit FP op");
+    if (!LJ_SOFTFP) return MIPSI_SDC1;
+  /* fallthrough */
   case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_SWC1;
   case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_SWC1;
+  /* fallthrough */
   default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_SD : MIPSI_SW;
   default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_SD : MIPSI_SW;
   }
   }
 }
 }
@@ -1215,10 +1269,10 @@ static MIPSIns asm_fxstoreins(IRIns *ir)
 static void asm_fload(ASMState *as, IRIns *ir)
 static void asm_fload(ASMState *as, IRIns *ir)
 {
 {
   Reg dest = ra_dest(as, ir, RSET_GPR);
   Reg dest = ra_dest(as, ir, RSET_GPR);
-  MIPSIns mi = asm_fxloadins(ir);
+  MIPSIns mi = asm_fxloadins(as, ir);
   Reg idx;
   Reg idx;
   int32_t ofs;
   int32_t ofs;
-  if (ir->op1 == REF_NIL) {
+  if (ir->op1 == REF_NIL) {  /* FLOAD from GG_State with offset. */
     idx = RID_JGL;
     idx = RID_JGL;
     ofs = (ir->op2 << 2) - 32768 - GG_OFS(g);
     ofs = (ir->op2 << 2) - 32768 - GG_OFS(g);
   } else {
   } else {
@@ -1232,7 +1286,7 @@ static void asm_fload(ASMState *as, IRIns *ir)
     }
     }
     ofs = field_ofs[ir->op2];
     ofs = field_ofs[ir->op2];
   }
   }
-  lua_assert(!irt_isfp(ir->t));
+  lj_assertA(!irt_isfp(ir->t), "bad FP FLOAD");
   emit_tsi(as, mi, dest, idx, ofs);
   emit_tsi(as, mi, dest, idx, ofs);
 }
 }
 
 
@@ -1243,8 +1297,8 @@ static void asm_fstore(ASMState *as, IRIns *ir)
     IRIns *irf = IR(ir->op1);
     IRIns *irf = IR(ir->op1);
     Reg idx = ra_alloc1(as, irf->op1, rset_exclude(RSET_GPR, src));
     Reg idx = ra_alloc1(as, irf->op1, rset_exclude(RSET_GPR, src));
     int32_t ofs = field_ofs[irf->op2];
     int32_t ofs = field_ofs[irf->op2];
-    MIPSIns mi = asm_fxstoreins(ir);
-    lua_assert(!irt_isfp(ir->t));
+    MIPSIns mi = asm_fxstoreins(as, ir);
+    lj_assertA(!irt_isfp(ir->t), "bad FP FSTORE");
     emit_tsi(as, mi, src, idx, ofs);
     emit_tsi(as, mi, src, idx, ofs);
   }
   }
 }
 }
@@ -1253,8 +1307,9 @@ static void asm_xload(ASMState *as, IRIns *ir)
 {
 {
   Reg dest = ra_dest(as, ir,
   Reg dest = ra_dest(as, ir,
     (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
     (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
-  lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));
-  asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0);
+  lj_assertA(LJ_TARGET_UNALIGNED || !(ir->op2 & IRXLOAD_UNALIGNED),
+	     "unaligned XLOAD");
+  asm_fusexref(as, asm_fxloadins(as, ir), dest, ir->op1, RSET_GPR, 0);
 }
 }
 
 
 static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
 static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
@@ -1262,7 +1317,7 @@ static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
   if (ir->r != RID_SINK) {
   if (ir->r != RID_SINK) {
     Reg src = ra_alloc1z(as, ir->op2,
     Reg src = ra_alloc1z(as, ir->op2,
       (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
       (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
-    asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1,
+    asm_fusexref(as, asm_fxstoreins(as, ir), src, ir->op1,
 		 rset_exclude(RSET_GPR, src), ofs);
 		 rset_exclude(RSET_GPR, src), ofs);
   }
   }
 }
 }
@@ -1284,8 +1339,9 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
     }
     }
   }
   }
   if (ra_used(ir)) {
   if (ra_used(ir)) {
-    lua_assert((LJ_SOFTFP32 ? 0 : irt_isnum(ir->t)) ||
-	       irt_isint(ir->t) || irt_isaddr(ir->t));
+    lj_assertA((LJ_SOFTFP32 ? 0 : irt_isnum(ir->t)) ||
+	       irt_isint(ir->t) || irt_isaddr(ir->t),
+	       "bad load type %d", irt_type(ir->t));
     dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
     dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
     rset_clear(allow, dest);
     rset_clear(allow, dest);
 #if LJ_64
 #if LJ_64
@@ -1390,10 +1446,13 @@ static void asm_sload(ASMState *as, IRIns *ir)
 #else
 #else
   int32_t ofs = 8*((int32_t)ir->op1-2);
   int32_t ofs = 8*((int32_t)ir->op1-2);
 #endif
 #endif
-  lua_assert(!(ir->op2 & IRSLOAD_PARENT));  /* Handled by asm_head_side(). */
-  lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK));
+  lj_assertA(!(ir->op2 & IRSLOAD_PARENT),
+	     "bad parent SLOAD");  /* Handled by asm_head_side(). */
+  lj_assertA(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK),
+	     "inconsistent SLOAD variant");
 #if LJ_SOFTFP32
 #if LJ_SOFTFP32
-  lua_assert(!(ir->op2 & IRSLOAD_CONVERT));  /* Handled by LJ_SOFTFP SPLIT. */
+  lj_assertA(!(ir->op2 & IRSLOAD_CONVERT),
+	     "unsplit SLOAD convert");  /* Handled by LJ_SOFTFP SPLIT. */
   if (hiop && ra_used(ir+1)) {
   if (hiop && ra_used(ir+1)) {
     type = ra_dest(as, ir+1, allow);
     type = ra_dest(as, ir+1, allow);
     rset_clear(allow, type);
     rset_clear(allow, type);
@@ -1406,8 +1465,9 @@ static void asm_sload(ASMState *as, IRIns *ir)
   } else
   } else
 #endif
 #endif
   if (ra_used(ir)) {
   if (ra_used(ir)) {
-    lua_assert((LJ_SOFTFP32 ? 0 : irt_isnum(ir->t)) ||
-	       irt_isint(ir->t) || irt_isaddr(ir->t));
+    lj_assertA((LJ_SOFTFP32 ? 0 : irt_isnum(ir->t)) ||
+	       irt_isint(ir->t) || irt_isaddr(ir->t),
+	       "bad SLOAD type %d", irt_type(ir->t));
     dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
     dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
     rset_clear(allow, dest);
     rset_clear(allow, dest);
     base = ra_alloc1(as, REF_BASE, allow);
     base = ra_alloc1(as, REF_BASE, allow);
@@ -1517,7 +1577,8 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
   IRRef args[4];
   IRRef args[4];
   RegSet drop = RSET_SCRATCH;
   RegSet drop = RSET_SCRATCH;
-  lua_assert(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL));
+  lj_assertA(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL),
+	     "bad CNEW/CNEWI operands");
 
 
   as->gcsteps++;
   as->gcsteps++;
   if (ra_hasreg(ir->r))
   if (ra_hasreg(ir->r))
@@ -1533,7 +1594,7 @@ static void asm_cnew(ASMState *as, IRIns *ir)
     int32_t ofs = sizeof(GCcdata);
     int32_t ofs = sizeof(GCcdata);
     if (sz == 8) {
     if (sz == 8) {
       ofs += 4;
       ofs += 4;
-      lua_assert((ir+1)->o == IR_HIOP);
+      lj_assertA((ir+1)->o == IR_HIOP, "expected HIOP for CNEWI");
       if (LJ_LE) ir++;
       if (LJ_LE) ir++;
     }
     }
     for (;;) {
     for (;;) {
@@ -1544,10 +1605,10 @@ static void asm_cnew(ASMState *as, IRIns *ir)
       ofs -= 4; if (LJ_BE) ir++; else ir--;
       ofs -= 4; if (LJ_BE) ir++; else ir--;
     }
     }
 #else
 #else
-    emit_tsi(as, MIPSI_SD, ra_alloc1(as, ir->op2, allow),
+    emit_tsi(as, sz == 8 ? MIPSI_SD : MIPSI_SW, ra_alloc1(as, ir->op2, allow),
 	     RID_RET, sizeof(GCcdata));
 	     RID_RET, sizeof(GCcdata));
 #endif
 #endif
-    lua_assert(sz == 4 || sz == 8);
+    lj_assertA(sz == 4 || sz == 8, "bad CNEWI size %d", sz);
   } else if (ir->op2 != REF_NIL) {  /* Create VLA/VLS/aligned cdata. */
   } else if (ir->op2 != REF_NIL) {  /* Create VLA/VLS/aligned cdata. */
     ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv];
     ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv];
     args[0] = ASMREF_L;     /* lua_State *L */
     args[0] = ASMREF_L;     /* lua_State *L */
@@ -1570,8 +1631,6 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
   ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
 	       ra_releasetmp(as, ASMREF_TMP1));
 	       ra_releasetmp(as, ASMREF_TMP1));
 }
 }
-#else
-#define asm_cnew(as, ir)	((void)0)
 #endif
 #endif
 
 
 /* -- Write barriers ------------------------------------------------------ */
 /* -- Write barriers ------------------------------------------------------ */
@@ -1599,7 +1658,7 @@ static void asm_obar(ASMState *as, IRIns *ir)
   MCLabel l_end;
   MCLabel l_end;
   Reg obj, val, tmp;
   Reg obj, val, tmp;
   /* No need for other object barriers (yet). */
   /* No need for other object barriers (yet). */
-  lua_assert(IR(ir->op1)->o == IR_UREFC);
+  lj_assertA(IR(ir->op1)->o == IR_UREFC, "bad OBAR type");
   ra_evictset(as, RSET_SCRATCH);
   ra_evictset(as, RSET_SCRATCH);
   l_end = emit_label(as);
   l_end = emit_label(as);
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[0] = ASMREF_TMP1;  /* global_State *g */
@@ -1640,8 +1699,6 @@ static void asm_fpunary(ASMState *as, IRIns *ir, MIPSIns mi)
 #if !LJ_SOFTFP32
 #if !LJ_SOFTFP32
 static void asm_fpmath(ASMState *as, IRIns *ir)
 static void asm_fpmath(ASMState *as, IRIns *ir)
 {
 {
-  if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir))
-    return;
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
   if (ir->op2 <= IRFPM_TRUNC)
   if (ir->op2 <= IRFPM_TRUNC)
     asm_callround(as, ir, IRCALL_lj_vm_floor + ir->op2);
     asm_callround(as, ir, IRCALL_lj_vm_floor + ir->op2);
@@ -1672,10 +1729,11 @@ static void asm_add(ASMState *as, IRIns *ir)
   } else
   } else
 #endif
 #endif
   {
   {
+    /* TODO MIPSR6: Fuse ADD(BSHL(a,1-4),b) or ADD(ADD(a,a),b) to MIPSI_ALSA. */
     Reg dest = ra_dest(as, ir, RSET_GPR);
     Reg dest = ra_dest(as, ir, RSET_GPR);
     Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
     Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
     if (irref_isk(ir->op2)) {
     if (irref_isk(ir->op2)) {
-      intptr_t k = get_kval(IR(ir->op2));
+      intptr_t k = get_kval(as, ir->op2);
       if (checki16(k)) {
       if (checki16(k)) {
 	emit_tsi(as, (LJ_64 && irt_is64(t)) ? MIPSI_DADDIU : MIPSI_ADDIU, dest,
 	emit_tsi(as, (LJ_64 && irt_is64(t)) ? MIPSI_DADDIU : MIPSI_ADDIU, dest,
 		 left, k);
 		 left, k);
@@ -1716,49 +1774,25 @@ static void asm_mul(ASMState *as, IRIns *ir)
     Reg right, left = ra_alloc2(as, ir, RSET_GPR);
     Reg right, left = ra_alloc2(as, ir, RSET_GPR);
     right = (left >> 8); left &= 255;
     right = (left >> 8); left &= 255;
     if (LJ_64 && irt_is64(ir->t)) {
     if (LJ_64 && irt_is64(ir->t)) {
+#if !LJ_TARGET_MIPSR6
       emit_dst(as, MIPSI_MFLO, dest, 0, 0);
       emit_dst(as, MIPSI_MFLO, dest, 0, 0);
       emit_dst(as, MIPSI_DMULT, 0, left, right);
       emit_dst(as, MIPSI_DMULT, 0, left, right);
+#else
+      emit_dst(as, MIPSI_DMUL, dest, left, right);
+#endif
     } else {
     } else {
       emit_dst(as, MIPSI_MUL, dest, left, right);
       emit_dst(as, MIPSI_MUL, dest, left, right);
     }
     }
   }
   }
 }
 }
 
 
-static void asm_mod(ASMState *as, IRIns *ir)
-{
-#if LJ_64 && LJ_HASFFI
-  if (!irt_isint(ir->t))
-    asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_modi64 :
-					  IRCALL_lj_carith_modu64);
-  else
-#endif
-    asm_callid(as, ir, IRCALL_lj_vm_modi);
-}
-
 #if !LJ_SOFTFP32
 #if !LJ_SOFTFP32
-static void asm_pow(ASMState *as, IRIns *ir)
-{
-#if LJ_64 && LJ_HASFFI
-  if (!irt_isnum(ir->t))
-    asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 :
-					  IRCALL_lj_carith_powu64);
-  else
-#endif
-    asm_callid(as, ir, IRCALL_lj_vm_powi);
-}
-
-static void asm_div(ASMState *as, IRIns *ir)
+static void asm_fpdiv(ASMState *as, IRIns *ir)
 {
 {
-#if LJ_64 && LJ_HASFFI
-  if (!irt_isnum(ir->t))
-    asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_divi64 :
-					  IRCALL_lj_carith_divu64);
-  else
-#endif
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
     asm_fparith(as, ir, MIPSI_DIV_D);
     asm_fparith(as, ir, MIPSI_DIV_D);
 #else
 #else
-  asm_callid(as, ir, IRCALL_softfp_div);
+    asm_callid(as, ir, IRCALL_softfp_div);
 #endif
 #endif
 }
 }
 #endif
 #endif
@@ -1796,13 +1830,11 @@ static void asm_abs(ASMState *as, IRIns *ir)
 }
 }
 #endif
 #endif
 
 
-#define asm_atan2(as, ir)	asm_callid(as, ir, IRCALL_atan2)
-#define asm_ldexp(as, ir)	asm_callid(as, ir, IRCALL_ldexp)
-
 static void asm_arithov(ASMState *as, IRIns *ir)
 static void asm_arithov(ASMState *as, IRIns *ir)
 {
 {
+  /* TODO MIPSR6: bovc/bnvc. Caveat: no delay slot to load RID_TMP. */
   Reg right, left, tmp, dest = ra_dest(as, ir, RSET_GPR);
   Reg right, left, tmp, dest = ra_dest(as, ir, RSET_GPR);
-  lua_assert(!irt_is64(ir->t));
+  lj_assertA(!irt_is64(ir->t), "bad usage");
   if (irref_isk(ir->op2)) {
   if (irref_isk(ir->op2)) {
     int k = IR(ir->op2)->i;
     int k = IR(ir->op2)->i;
     if (ir->o == IR_SUBOV) k = -k;
     if (ir->o == IR_SUBOV) k = -k;
@@ -1845,9 +1877,14 @@ static void asm_mulov(ASMState *as, IRIns *ir)
 						 right), dest));
 						 right), dest));
   asm_guard(as, MIPSI_BNE, RID_TMP, tmp);
   asm_guard(as, MIPSI_BNE, RID_TMP, tmp);
   emit_dta(as, MIPSI_SRA, RID_TMP, dest, 31);
   emit_dta(as, MIPSI_SRA, RID_TMP, dest, 31);
+#if !LJ_TARGET_MIPSR6
   emit_dst(as, MIPSI_MFHI, tmp, 0, 0);
   emit_dst(as, MIPSI_MFHI, tmp, 0, 0);
   emit_dst(as, MIPSI_MFLO, dest, 0, 0);
   emit_dst(as, MIPSI_MFLO, dest, 0, 0);
   emit_dst(as, MIPSI_MULT, 0, left, right);
   emit_dst(as, MIPSI_MULT, 0, left, right);
+#else
+  emit_dst(as, MIPSI_MUL, dest, left, right);
+  emit_dst(as, MIPSI_MUH, tmp, left, right);
+#endif
 }
 }
 
 
 #if LJ_32 && LJ_HASFFI
 #if LJ_32 && LJ_HASFFI
@@ -1984,7 +2021,7 @@ static void asm_bitop(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik)
   Reg dest = ra_dest(as, ir, RSET_GPR);
   Reg dest = ra_dest(as, ir, RSET_GPR);
   Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
   Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
   if (irref_isk(ir->op2)) {
   if (irref_isk(ir->op2)) {
-    intptr_t k = get_kval(IR(ir->op2));
+    intptr_t k = get_kval(as, ir->op2);
     if (checku16(k)) {
     if (checku16(k)) {
       emit_tsi(as, mik, dest, left, k);
       emit_tsi(as, mik, dest, left, k);
       return;
       return;
@@ -2017,7 +2054,7 @@ static void asm_bitshift(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik)
 #define asm_bshl(as, ir)	asm_bitshift(as, ir, MIPSI_SLLV, MIPSI_SLL)
 #define asm_bshl(as, ir)	asm_bitshift(as, ir, MIPSI_SLLV, MIPSI_SLL)
 #define asm_bshr(as, ir)	asm_bitshift(as, ir, MIPSI_SRLV, MIPSI_SRL)
 #define asm_bshr(as, ir)	asm_bitshift(as, ir, MIPSI_SRLV, MIPSI_SRL)
 #define asm_bsar(as, ir)	asm_bitshift(as, ir, MIPSI_SRAV, MIPSI_SRA)
 #define asm_bsar(as, ir)	asm_bitshift(as, ir, MIPSI_SRAV, MIPSI_SRA)
-#define asm_brol(as, ir)	lua_assert(0)
+#define asm_brol(as, ir)	lj_assertA(0, "unexpected BROL")
 
 
 static void asm_bror(ASMState *as, IRIns *ir)
 static void asm_bror(ASMState *as, IRIns *ir)
 {
 {
@@ -2071,26 +2108,45 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
     Reg dest = ra_dest(as, ir, RSET_FPR);
     Reg dest = ra_dest(as, ir, RSET_FPR);
     Reg right, left = ra_alloc2(as, ir, RSET_FPR);
     Reg right, left = ra_alloc2(as, ir, RSET_FPR);
     right = (left >> 8); left &= 255;
     right = (left >> 8); left &= 255;
+#if !LJ_TARGET_MIPSR6
     if (dest == left) {
     if (dest == left) {
-      emit_fg(as, MIPSI_MOVT_D, dest, right);
+      emit_fg(as, MIPSI_MOVF_D, dest, right);
     } else {
     } else {
-      emit_fg(as, MIPSI_MOVF_D, dest, left);
+      emit_fg(as, MIPSI_MOVT_D, dest, left);
       if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right);
       if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right);
     }
     }
-    emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? left : right, ismax ? right : left);
+    emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? right : left, ismax ? left : right);
+#else
+    emit_fgh(as, ismax ? MIPSI_MAX_D : MIPSI_MIN_D, dest, left, right);
+#endif
 #endif
 #endif
   } else {
   } else {
     Reg dest = ra_dest(as, ir, RSET_GPR);
     Reg dest = ra_dest(as, ir, RSET_GPR);
     Reg right, left = ra_alloc2(as, ir, RSET_GPR);
     Reg right, left = ra_alloc2(as, ir, RSET_GPR);
     right = (left >> 8); left &= 255;
     right = (left >> 8); left &= 255;
-    if (dest == left) {
-      emit_dst(as, MIPSI_MOVN, dest, right, RID_TMP);
+    if (left == right) {
+      if (dest != left) emit_move(as, dest, left);
     } else {
     } else {
-      emit_dst(as, MIPSI_MOVZ, dest, left, RID_TMP);
-      if (dest != right) emit_move(as, dest, right);
+#if !LJ_TARGET_MIPSR6
+      if (dest == left) {
+	emit_dst(as, MIPSI_MOVN, dest, right, RID_TMP);
+      } else {
+	emit_dst(as, MIPSI_MOVZ, dest, left, RID_TMP);
+	if (dest != right) emit_move(as, dest, right);
+      }
+#else
+      emit_dst(as, MIPSI_OR, dest, dest, RID_TMP);
+      if (dest != right) {
+	emit_dst(as, MIPSI_SELNEZ, RID_TMP, right, RID_TMP);
+	emit_dst(as, MIPSI_SELEQZ, dest, left, RID_TMP);
+      } else {
+	emit_dst(as, MIPSI_SELEQZ, RID_TMP, left, RID_TMP);
+	emit_dst(as, MIPSI_SELNEZ, dest, right, RID_TMP);
+      }
+#endif
+      emit_dst(as, MIPSI_SLT, RID_TMP,
+	       ismax ? left : right, ismax ? right : left);
     }
     }
-    emit_dst(as, MIPSI_SLT, RID_TMP,
-	     ismax ? left : right, ismax ? right : left);
   }
   }
 }
 }
 
 
@@ -2174,21 +2230,29 @@ static void asm_comp(ASMState *as, IRIns *ir)
 #if LJ_SOFTFP
 #if LJ_SOFTFP
     asm_sfpcomp(as, ir);
     asm_sfpcomp(as, ir);
 #else
 #else
+#if !LJ_TARGET_MIPSR6
     Reg right, left = ra_alloc2(as, ir, RSET_FPR);
     Reg right, left = ra_alloc2(as, ir, RSET_FPR);
     right = (left >> 8); left &= 255;
     right = (left >> 8); left &= 255;
     asm_guard(as, (op&1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0);
     asm_guard(as, (op&1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0);
     emit_fgh(as, MIPSI_C_OLT_D + ((op&3) ^ ((op>>2)&1)), 0, left, right);
     emit_fgh(as, MIPSI_C_OLT_D + ((op&3) ^ ((op>>2)&1)), 0, left, right);
+#else
+    Reg tmp, right, left = ra_alloc2(as, ir, RSET_FPR);
+    right = (left >> 8); left &= 255;
+    tmp = ra_scratch(as, rset_exclude(rset_exclude(RSET_FPR, left), right));
+    asm_guard(as, (op&1) ? MIPSI_BC1NEZ : MIPSI_BC1EQZ, 0, (tmp&31));
+    emit_fgh(as, MIPSI_CMP_LT_D + ((op&3) ^ ((op>>2)&1)), tmp, left, right);
+#endif
 #endif
 #endif
   } else {
   } else {
     Reg right, left = ra_alloc1(as, ir->op1, RSET_GPR);
     Reg right, left = ra_alloc1(as, ir->op1, RSET_GPR);
     if (op == IR_ABC) op = IR_UGT;
     if (op == IR_ABC) op = IR_UGT;
-    if ((op&4) == 0 && irref_isk(ir->op2) && get_kval(IR(ir->op2)) == 0) {
+    if ((op&4) == 0 && irref_isk(ir->op2) && get_kval(as, ir->op2) == 0) {
       MIPSIns mi = (op&2) ? ((op&1) ? MIPSI_BLEZ : MIPSI_BGTZ) :
       MIPSIns mi = (op&2) ? ((op&1) ? MIPSI_BLEZ : MIPSI_BGTZ) :
 			    ((op&1) ? MIPSI_BLTZ : MIPSI_BGEZ);
 			    ((op&1) ? MIPSI_BLTZ : MIPSI_BGEZ);
       asm_guard(as, mi, left, 0);
       asm_guard(as, mi, left, 0);
     } else {
     } else {
       if (irref_isk(ir->op2)) {
       if (irref_isk(ir->op2)) {
-	intptr_t k = get_kval(IR(ir->op2));
+	intptr_t k = get_kval(as, ir->op2);
 	if ((op&2)) k++;
 	if ((op&2)) k++;
 	if (checki16(k)) {
 	if (checki16(k)) {
 	  asm_guard(as, (op&1) ? MIPSI_BNE : MIPSI_BEQ, RID_TMP, RID_ZERO);
 	  asm_guard(as, (op&1) ? MIPSI_BNE : MIPSI_BEQ, RID_TMP, RID_ZERO);
@@ -2213,9 +2277,13 @@ static void asm_equal(ASMState *as, IRIns *ir)
   if (!LJ_SOFTFP32 && irt_isnum(ir->t)) {
   if (!LJ_SOFTFP32 && irt_isnum(ir->t)) {
 #if LJ_SOFTFP
 #if LJ_SOFTFP
     asm_sfpcomp(as, ir);
     asm_sfpcomp(as, ir);
-#else
+#elif !LJ_TARGET_MIPSR6
     asm_guard(as, (ir->o & 1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0);
     asm_guard(as, (ir->o & 1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0);
     emit_fgh(as, MIPSI_C_EQ_D, 0, left, right);
     emit_fgh(as, MIPSI_C_EQ_D, 0, left, right);
+#else
+    Reg tmp = ra_scratch(as, rset_exclude(rset_exclude(RSET_FPR, left), right));
+    asm_guard(as, (ir->o & 1) ? MIPSI_BC1NEZ : MIPSI_BC1EQZ, 0, (tmp&31));
+    emit_fgh(as, MIPSI_CMP_EQ_D, tmp, left, right);
 #endif
 #endif
   } else {
   } else {
     asm_guard(as, (ir->o & 1) ? MIPSI_BEQ : MIPSI_BNE, left, right);
     asm_guard(as, (ir->o & 1) ? MIPSI_BEQ : MIPSI_BNE, left, right);
@@ -2340,10 +2408,11 @@ static void asm_hiop(ASMState *as, IRIns *ir)
   case IR_CNEWI:
   case IR_CNEWI:
     /* Nothing to do here. Handled by lo op itself. */
     /* Nothing to do here. Handled by lo op itself. */
     break;
     break;
-  default: lua_assert(0); break;
+  default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
   }
   }
 #else
 #else
-  UNUSED(as); UNUSED(ir); lua_assert(0);  /* Unused without FFI. */
+  /* Unused on MIPS64 or without SOFTFP or FFI. */
+  UNUSED(as); UNUSED(ir); lj_assertA(0, "unexpected HIOP");
 #endif
 #endif
 }
 }
 
 
@@ -2412,7 +2481,8 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
 #if LJ_SOFTFP32
 #if LJ_SOFTFP32
       Reg tmp;
       Reg tmp;
       RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
       RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
-      lua_assert(irref_isk(ref));  /* LJ_SOFTFP: must be a number constant. */
+      /* LJ_SOFTFP: must be a number constant. */
+      lj_assertA(irref_isk(ref), "unsplit FP op");
       tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, allow);
       tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, allow);
       emit_tsi(as, MIPSI_SW, tmp, RID_BASE, ofs+(LJ_BE?4:0));
       emit_tsi(as, MIPSI_SW, tmp, RID_BASE, ofs+(LJ_BE?4:0));
       if (rset_test(as->freeset, tmp+1)) allow = RID2RSET(tmp+1);
       if (rset_test(as->freeset, tmp+1)) allow = RID2RSET(tmp+1);
@@ -2429,7 +2499,8 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
 #if LJ_32
 #if LJ_32
       RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
       RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
       Reg type;
       Reg type;
-      lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t));
+      lj_assertA(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t),
+		 "restore of IR type %d", irt_type(ir->t));
       if (!irt_ispri(ir->t)) {
       if (!irt_ispri(ir->t)) {
 	Reg src = ra_alloc1(as, ref, allow);
 	Reg src = ra_alloc1(as, ref, allow);
 	rset_clear(allow, src);
 	rset_clear(allow, src);
@@ -2452,11 +2523,14 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
     }
     }
     checkmclim(as);
     checkmclim(as);
   }
   }
-  lua_assert(map + nent == flinks);
+  lj_assertA(map + nent == flinks, "inconsistent frames in snapshot");
 }
 }
 
 
 /* -- GC handling --------------------------------------------------------- */
 /* -- GC handling --------------------------------------------------------- */
 
 
+/* Marker to prevent patching the GC check exit. */
+#define MIPS_NOPATCH_GC_CHECK	MIPSI_OR
+
 /* Check GC threshold and do one or more GC steps. */
 /* Check GC threshold and do one or more GC steps. */
 static void asm_gc_check(ASMState *as)
 static void asm_gc_check(ASMState *as)
 {
 {
@@ -2472,6 +2546,7 @@ static void asm_gc_check(ASMState *as)
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[1] = ASMREF_TMP2;  /* MSize steps     */
   args[1] = ASMREF_TMP2;  /* MSize steps     */
   asm_gencall(as, ci, args);
   asm_gencall(as, ci, args);
+  l_end[-3] = MIPS_NOPATCH_GC_CHECK;  /* Replace the nop after the call. */
   emit_tsi(as, MIPSI_AADDIU, ra_releasetmp(as, ASMREF_TMP1), RID_JGL, -32768);
   emit_tsi(as, MIPSI_AADDIU, ra_releasetmp(as, ASMREF_TMP1), RID_JGL, -32768);
   tmp = ra_releasetmp(as, ASMREF_TMP2);
   tmp = ra_releasetmp(as, ASMREF_TMP2);
   emit_loadi(as, tmp, as->gcsteps);
   emit_loadi(as, tmp, as->gcsteps);
@@ -2618,7 +2693,12 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
       if (((p[-1] ^ (px-p)) & 0xffffu) == 0 &&
       if (((p[-1] ^ (px-p)) & 0xffffu) == 0 &&
 	  ((p[-1] & 0xf0000000u) == MIPSI_BEQ ||
 	  ((p[-1] & 0xf0000000u) == MIPSI_BEQ ||
 	   (p[-1] & 0xfc1e0000u) == MIPSI_BLTZ ||
 	   (p[-1] & 0xfc1e0000u) == MIPSI_BLTZ ||
-	   (p[-1] & 0xffe00000u) == MIPSI_BC1F)) {
+#if !LJ_TARGET_MIPSR6
+	   (p[-1] & 0xffe00000u) == MIPSI_BC1F
+#else
+	   (p[-1] & 0xff600000u) == MIPSI_BC1EQZ
+#endif
+	  ) && p[-2] != MIPS_NOPATCH_GC_CHECK) {
 	ptrdiff_t delta = target - p;
 	ptrdiff_t delta = target - p;
 	if (((delta + 0x8000) >> 16) == 0) {  /* Patch in-range branch. */
 	if (((delta + 0x8000) >> 16) == 0) {  /* Patch in-range branch. */
 	patchbranch:
 	patchbranch:
@@ -2645,7 +2725,7 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
 	}
 	}
       } else if (p+1 == pe) {
       } else if (p+1 == pe) {
 	/* Patch NOP after code for inverted loop branch. Use of J is ok. */
 	/* Patch NOP after code for inverted loop branch. Use of J is ok. */
-	lua_assert(p[1] == MIPSI_NOP);
+	lj_assertJ(p[1] == MIPSI_NOP, "expected NOP");
 	p[1] = tjump;
 	p[1] = tjump;
 	*p = MIPSI_NOP;  /* Replace the load of the exit number. */
 	*p = MIPSI_NOP;  /* Replace the load of the exit number. */
 	cstop = p+2;
 	cstop = p+2;

+ 82 - 63
libs/LuaJIT/src/lj_asm_ppc.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** PPC IR assembler (SSA IR -> machine code).
 ** PPC IR assembler (SSA IR -> machine code).
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 /* -- Register allocator extensions --------------------------------------- */
 /* -- Register allocator extensions --------------------------------------- */
@@ -181,7 +181,7 @@ static void asm_fusexref(ASMState *as, PPCIns pi, Reg rt, IRRef ref,
 	return;
 	return;
       }
       }
     } else if (ir->o == IR_STRREF) {
     } else if (ir->o == IR_STRREF) {
-      lua_assert(ofs == 0);
+      lj_assertA(ofs == 0, "bad usage");
       ofs = (int32_t)sizeof(GCstr);
       ofs = (int32_t)sizeof(GCstr);
       if (irref_isk(ir->op2)) {
       if (irref_isk(ir->op2)) {
 	ofs += IR(ir->op2)->i;
 	ofs += IR(ir->op2)->i;
@@ -268,7 +268,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
       if (irt_isfp(ir->t)) {
       if (irt_isfp(ir->t)) {
 	if (fpr <= REGARG_LASTFPR) {
 	if (fpr <= REGARG_LASTFPR) {
-	  lua_assert(rset_test(as->freeset, fpr));  /* Already evicted. */
+	  lj_assertA(rset_test(as->freeset, fpr),
+		     "reg %d not free", fpr);  /* Already evicted. */
 	  ra_leftov(as, fpr, ref);
 	  ra_leftov(as, fpr, ref);
 	  fpr++;
 	  fpr++;
 	} else {
 	} else {
@@ -281,7 +282,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
 #endif
 #endif
       {
       {
 	if (gpr <= REGARG_LASTGPR) {
 	if (gpr <= REGARG_LASTGPR) {
-	  lua_assert(rset_test(as->freeset, gpr));  /* Already evicted. */
+	  lj_assertA(rset_test(as->freeset, gpr),
+		     "reg %d not free", gpr);  /* Already evicted. */
 	  ra_leftov(as, gpr, ref);
 	  ra_leftov(as, gpr, ref);
 	  gpr++;
 	  gpr++;
 	} else {
 	} else {
@@ -319,7 +321,7 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
     rset_clear(drop, (ir+1)->r);  /* Dest reg handled below. */
     rset_clear(drop, (ir+1)->r);  /* Dest reg handled below. */
   ra_evictset(as, drop);  /* Evictions must be performed first. */
   ra_evictset(as, drop);  /* Evictions must be performed first. */
   if (ra_used(ir)) {
   if (ra_used(ir)) {
-    lua_assert(!irt_ispri(ir->t));
+    lj_assertA(!irt_ispri(ir->t), "PRI dest");
     if (!LJ_SOFTFP && irt_isfp(ir->t)) {
     if (!LJ_SOFTFP && irt_isfp(ir->t)) {
       if ((ci->flags & CCI_CASTU64)) {
       if ((ci->flags & CCI_CASTU64)) {
 	/* Use spill slot or temp slots. */
 	/* Use spill slot or temp slots. */
@@ -431,14 +433,18 @@ static void asm_conv(ASMState *as, IRIns *ir)
   int stfp = (st == IRT_NUM || st == IRT_FLOAT);
   int stfp = (st == IRT_NUM || st == IRT_FLOAT);
 #endif
 #endif
   IRRef lref = ir->op1;
   IRRef lref = ir->op1;
-  lua_assert(!(irt_isint64(ir->t) ||
-	       (st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */
+  /* 64 bit integer conversions are handled by SPLIT. */
+  lj_assertA(!(irt_isint64(ir->t) || (st == IRT_I64 || st == IRT_U64)),
+	     "IR %04d has unsplit 64 bit type",
+	     (int)(ir - as->ir) - REF_BIAS);
 #if LJ_SOFTFP
 #if LJ_SOFTFP
   /* FP conversions are handled by SPLIT. */
   /* FP conversions are handled by SPLIT. */
-  lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT));
+  lj_assertA(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT),
+	     "IR %04d has FP type",
+	     (int)(ir - as->ir) - REF_BIAS);
   /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */
   /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */
 #else
 #else
-  lua_assert(irt_type(ir->t) != st);
+  lj_assertA(irt_type(ir->t) != st, "inconsistent types for CONV");
   if (irt_isfp(ir->t)) {
   if (irt_isfp(ir->t)) {
     Reg dest = ra_dest(as, ir, RSET_FPR);
     Reg dest = ra_dest(as, ir, RSET_FPR);
     if (stfp) {  /* FP to FP conversion. */
     if (stfp) {  /* FP to FP conversion. */
@@ -467,7 +473,8 @@ static void asm_conv(ASMState *as, IRIns *ir)
   } else if (stfp) {  /* FP to integer conversion. */
   } else if (stfp) {  /* FP to integer conversion. */
     if (irt_isguard(ir->t)) {
     if (irt_isguard(ir->t)) {
       /* Checked conversions are only supported from number to int. */
       /* Checked conversions are only supported from number to int. */
-      lua_assert(irt_isint(ir->t) && st == IRT_NUM);
+      lj_assertA(irt_isint(ir->t) && st == IRT_NUM,
+		 "bad type for checked CONV");
       asm_tointg(as, ir, ra_alloc1(as, lref, RSET_FPR));
       asm_tointg(as, ir, ra_alloc1(as, lref, RSET_FPR));
     } else {
     } else {
       Reg dest = ra_dest(as, ir, RSET_GPR);
       Reg dest = ra_dest(as, ir, RSET_GPR);
@@ -503,7 +510,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
     Reg dest = ra_dest(as, ir, RSET_GPR);
     Reg dest = ra_dest(as, ir, RSET_GPR);
     if (st >= IRT_I8 && st <= IRT_U16) {  /* Extend to 32 bit integer. */
     if (st >= IRT_I8 && st <= IRT_U16) {  /* Extend to 32 bit integer. */
       Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
       Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
-      lua_assert(irt_isint(ir->t) || irt_isu32(ir->t));
+      lj_assertA(irt_isint(ir->t) || irt_isu32(ir->t), "bad type for CONV EXT");
       if ((ir->op2 & IRCONV_SEXT))
       if ((ir->op2 & IRCONV_SEXT))
 	emit_as(as, st == IRT_I8 ? PPCI_EXTSB : PPCI_EXTSH, dest, left);
 	emit_as(as, st == IRT_I8 ? PPCI_EXTSB : PPCI_EXTSH, dest, left);
       else
       else
@@ -699,7 +706,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
 	    (((char *)as->mcp-(char *)l_loop) & 0xffffu);
 	    (((char *)as->mcp-(char *)l_loop) & 0xffffu);
 
 
   /* Load main position relative to tab->node into dest. */
   /* Load main position relative to tab->node into dest. */
-  khash = isk ? ir_khash(irkey) : 1;
+  khash = isk ? ir_khash(as, irkey) : 1;
   if (khash == 0) {
   if (khash == 0) {
     emit_tai(as, PPCI_LWZ, dest, tab, (int32_t)offsetof(GCtab, node));
     emit_tai(as, PPCI_LWZ, dest, tab, (int32_t)offsetof(GCtab, node));
   } else {
   } else {
@@ -714,7 +721,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
     if (isk) {
     if (isk) {
       /* Nothing to do. */
       /* Nothing to do. */
     } else if (irt_isstr(kt)) {
     } else if (irt_isstr(kt)) {
-      emit_tai(as, PPCI_LWZ, tmp1, key, (int32_t)offsetof(GCstr, hash));
+      emit_tai(as, PPCI_LWZ, tmp1, key, (int32_t)offsetof(GCstr, sid));
     } else {  /* Must match with hash*() in lj_tab.c. */
     } else {  /* Must match with hash*() in lj_tab.c. */
       emit_tab(as, PPCI_SUBF, tmp1, tmp2, tmp1);
       emit_tab(as, PPCI_SUBF, tmp1, tmp2, tmp1);
       emit_rotlwi(as, tmp2, tmp2, HASH_ROT3);
       emit_rotlwi(as, tmp2, tmp2, HASH_ROT3);
@@ -754,7 +761,7 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
   Reg node = ra_alloc1(as, ir->op1, RSET_GPR);
   Reg node = ra_alloc1(as, ir->op1, RSET_GPR);
   Reg key = RID_NONE, type = RID_TMP, idx = node;
   Reg key = RID_NONE, type = RID_TMP, idx = node;
   RegSet allow = rset_exclude(RSET_GPR, node);
   RegSet allow = rset_exclude(RSET_GPR, node);
-  lua_assert(ofs % sizeof(Node) == 0);
+  lj_assertA(ofs % sizeof(Node) == 0, "unaligned HREFK slot");
   if (ofs > 32736) {
   if (ofs > 32736) {
     idx = dest;
     idx = dest;
     rset_clear(allow, dest);
     rset_clear(allow, dest);
@@ -813,7 +820,7 @@ static void asm_uref(ASMState *as, IRIns *ir)
 static void asm_fref(ASMState *as, IRIns *ir)
 static void asm_fref(ASMState *as, IRIns *ir)
 {
 {
   UNUSED(as); UNUSED(ir);
   UNUSED(as); UNUSED(ir);
-  lua_assert(!ra_used(ir));
+  lj_assertA(!ra_used(ir), "unfused FREF");
 }
 }
 
 
 static void asm_strref(ASMState *as, IRIns *ir)
 static void asm_strref(ASMState *as, IRIns *ir)
@@ -853,25 +860,27 @@ static void asm_strref(ASMState *as, IRIns *ir)
 
 
 /* -- Loads and stores ---------------------------------------------------- */
 /* -- Loads and stores ---------------------------------------------------- */
 
 
-static PPCIns asm_fxloadins(IRIns *ir)
+static PPCIns asm_fxloadins(ASMState *as, IRIns *ir)
 {
 {
+  UNUSED(as);
   switch (irt_type(ir->t)) {
   switch (irt_type(ir->t)) {
   case IRT_I8: return PPCI_LBZ;  /* Needs sign-extension. */
   case IRT_I8: return PPCI_LBZ;  /* Needs sign-extension. */
   case IRT_U8: return PPCI_LBZ;
   case IRT_U8: return PPCI_LBZ;
   case IRT_I16: return PPCI_LHA;
   case IRT_I16: return PPCI_LHA;
   case IRT_U16: return PPCI_LHZ;
   case IRT_U16: return PPCI_LHZ;
-  case IRT_NUM: lua_assert(!LJ_SOFTFP); return PPCI_LFD;
+  case IRT_NUM: lj_assertA(!LJ_SOFTFP, "unsplit FP op"); return PPCI_LFD;
   case IRT_FLOAT: if (!LJ_SOFTFP) return PPCI_LFS;
   case IRT_FLOAT: if (!LJ_SOFTFP) return PPCI_LFS;
   default: return PPCI_LWZ;
   default: return PPCI_LWZ;
   }
   }
 }
 }
 
 
-static PPCIns asm_fxstoreins(IRIns *ir)
+static PPCIns asm_fxstoreins(ASMState *as, IRIns *ir)
 {
 {
+  UNUSED(as);
   switch (irt_type(ir->t)) {
   switch (irt_type(ir->t)) {
   case IRT_I8: case IRT_U8: return PPCI_STB;
   case IRT_I8: case IRT_U8: return PPCI_STB;
   case IRT_I16: case IRT_U16: return PPCI_STH;
   case IRT_I16: case IRT_U16: return PPCI_STH;
-  case IRT_NUM: lua_assert(!LJ_SOFTFP); return PPCI_STFD;
+  case IRT_NUM: lj_assertA(!LJ_SOFTFP, "unsplit FP op"); return PPCI_STFD;
   case IRT_FLOAT: if (!LJ_SOFTFP) return PPCI_STFS;
   case IRT_FLOAT: if (!LJ_SOFTFP) return PPCI_STFS;
   default: return PPCI_STW;
   default: return PPCI_STW;
   }
   }
@@ -880,10 +889,10 @@ static PPCIns asm_fxstoreins(IRIns *ir)
 static void asm_fload(ASMState *as, IRIns *ir)
 static void asm_fload(ASMState *as, IRIns *ir)
 {
 {
   Reg dest = ra_dest(as, ir, RSET_GPR);
   Reg dest = ra_dest(as, ir, RSET_GPR);
-  PPCIns pi = asm_fxloadins(ir);
+  PPCIns pi = asm_fxloadins(as, ir);
   Reg idx;
   Reg idx;
   int32_t ofs;
   int32_t ofs;
-  if (ir->op1 == REF_NIL) {
+  if (ir->op1 == REF_NIL) {  /* FLOAD from GG_State with offset. */
     idx = RID_JGL;
     idx = RID_JGL;
     ofs = (ir->op2 << 2) - 32768;
     ofs = (ir->op2 << 2) - 32768;
   } else {
   } else {
@@ -897,7 +906,7 @@ static void asm_fload(ASMState *as, IRIns *ir)
     }
     }
     ofs = field_ofs[ir->op2];
     ofs = field_ofs[ir->op2];
   }
   }
-  lua_assert(!irt_isi8(ir->t));
+  lj_assertA(!irt_isi8(ir->t), "unsupported FLOAD I8");
   emit_tai(as, pi, dest, idx, ofs);
   emit_tai(as, pi, dest, idx, ofs);
 }
 }
 
 
@@ -908,7 +917,7 @@ static void asm_fstore(ASMState *as, IRIns *ir)
     IRIns *irf = IR(ir->op1);
     IRIns *irf = IR(ir->op1);
     Reg idx = ra_alloc1(as, irf->op1, rset_exclude(RSET_GPR, src));
     Reg idx = ra_alloc1(as, irf->op1, rset_exclude(RSET_GPR, src));
     int32_t ofs = field_ofs[irf->op2];
     int32_t ofs = field_ofs[irf->op2];
-    PPCIns pi = asm_fxstoreins(ir);
+    PPCIns pi = asm_fxstoreins(as, ir);
     emit_tai(as, pi, src, idx, ofs);
     emit_tai(as, pi, src, idx, ofs);
   }
   }
 }
 }
@@ -917,10 +926,10 @@ static void asm_xload(ASMState *as, IRIns *ir)
 {
 {
   Reg dest = ra_dest(as, ir,
   Reg dest = ra_dest(as, ir,
     (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
     (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
-  lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));
+  lj_assertA(!(ir->op2 & IRXLOAD_UNALIGNED), "unaligned XLOAD");
   if (irt_isi8(ir->t))
   if (irt_isi8(ir->t))
     emit_as(as, PPCI_EXTSB, dest, dest);
     emit_as(as, PPCI_EXTSB, dest, dest);
-  asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0);
+  asm_fusexref(as, asm_fxloadins(as, ir), dest, ir->op1, RSET_GPR, 0);
 }
 }
 
 
 static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
 static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
@@ -936,7 +945,7 @@ static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
   } else {
   } else {
     Reg src = ra_alloc1(as, ir->op2,
     Reg src = ra_alloc1(as, ir->op2,
       (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
       (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
-    asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1,
+    asm_fusexref(as, asm_fxstoreins(as, ir), src, ir->op1,
 		 rset_exclude(RSET_GPR, src), ofs);
 		 rset_exclude(RSET_GPR, src), ofs);
   }
   }
 }
 }
@@ -958,8 +967,9 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
     ofs = 0;
     ofs = 0;
   }
   }
   if (ra_used(ir)) {
   if (ra_used(ir)) {
-    lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||
-	       irt_isint(ir->t) || irt_isaddr(ir->t));
+    lj_assertA((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||
+	       irt_isint(ir->t) || irt_isaddr(ir->t),
+	       "bad load type %d", irt_type(ir->t));
     if (LJ_SOFTFP || !irt_isnum(t)) ofs = 0;
     if (LJ_SOFTFP || !irt_isnum(t)) ofs = 0;
     dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
     dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
     rset_clear(allow, dest);
     rset_clear(allow, dest);
@@ -1042,12 +1052,16 @@ static void asm_sload(ASMState *as, IRIns *ir)
   int hiop = (LJ_SOFTFP && (ir+1)->o == IR_HIOP);
   int hiop = (LJ_SOFTFP && (ir+1)->o == IR_HIOP);
   if (hiop)
   if (hiop)
     t.irt = IRT_NUM;
     t.irt = IRT_NUM;
-  lua_assert(!(ir->op2 & IRSLOAD_PARENT));  /* Handled by asm_head_side(). */
-  lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK));
-  lua_assert(LJ_DUALNUM ||
-	     !irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)));
+  lj_assertA(!(ir->op2 & IRSLOAD_PARENT),
+	     "bad parent SLOAD");  /* Handled by asm_head_side(). */
+  lj_assertA(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK),
+	     "inconsistent SLOAD variant");
+  lj_assertA(LJ_DUALNUM ||
+	     !irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)),
+	     "bad SLOAD type");
 #if LJ_SOFTFP
 #if LJ_SOFTFP
-  lua_assert(!(ir->op2 & IRSLOAD_CONVERT));  /* Handled by LJ_SOFTFP SPLIT. */
+  lj_assertA(!(ir->op2 & IRSLOAD_CONVERT),
+	     "unsplit SLOAD convert");  /* Handled by LJ_SOFTFP SPLIT. */
   if (hiop && ra_used(ir+1)) {
   if (hiop && ra_used(ir+1)) {
     type = ra_dest(as, ir+1, allow);
     type = ra_dest(as, ir+1, allow);
     rset_clear(allow, type);
     rset_clear(allow, type);
@@ -1060,7 +1074,8 @@ static void asm_sload(ASMState *as, IRIns *ir)
   } else
   } else
 #endif
 #endif
   if (ra_used(ir)) {
   if (ra_used(ir)) {
-    lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t));
+    lj_assertA(irt_isnum(t) || irt_isint(t) || irt_isaddr(t),
+	       "bad SLOAD type %d", irt_type(ir->t));
     dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
     dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
     rset_clear(allow, dest);
     rset_clear(allow, dest);
     base = ra_alloc1(as, REF_BASE, allow);
     base = ra_alloc1(as, REF_BASE, allow);
@@ -1127,7 +1142,8 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
   IRRef args[4];
   IRRef args[4];
   RegSet drop = RSET_SCRATCH;
   RegSet drop = RSET_SCRATCH;
-  lua_assert(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL));
+  lj_assertA(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL),
+	     "bad CNEW/CNEWI operands");
 
 
   as->gcsteps++;
   as->gcsteps++;
   if (ra_hasreg(ir->r))
   if (ra_hasreg(ir->r))
@@ -1140,10 +1156,10 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   if (ir->o == IR_CNEWI) {
   if (ir->o == IR_CNEWI) {
     RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
     RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
     int32_t ofs = sizeof(GCcdata);
     int32_t ofs = sizeof(GCcdata);
-    lua_assert(sz == 4 || sz == 8);
+    lj_assertA(sz == 4 || sz == 8, "bad CNEWI size %d", sz);
     if (sz == 8) {
     if (sz == 8) {
       ofs += 4;
       ofs += 4;
-      lua_assert((ir+1)->o == IR_HIOP);
+      lj_assertA((ir+1)->o == IR_HIOP, "expected HIOP for CNEWI");
     }
     }
     for (;;) {
     for (;;) {
       Reg r = ra_alloc1(as, ir->op2, allow);
       Reg r = ra_alloc1(as, ir->op2, allow);
@@ -1174,8 +1190,6 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
   ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
 	       ra_releasetmp(as, ASMREF_TMP1));
 	       ra_releasetmp(as, ASMREF_TMP1));
 }
 }
-#else
-#define asm_cnew(as, ir)	((void)0)
 #endif
 #endif
 
 
 /* -- Write barriers ------------------------------------------------------ */
 /* -- Write barriers ------------------------------------------------------ */
@@ -1189,7 +1203,7 @@ static void asm_tbar(ASMState *as, IRIns *ir)
   emit_tai(as, PPCI_STW, link, tab, (int32_t)offsetof(GCtab, gclist));
   emit_tai(as, PPCI_STW, link, tab, (int32_t)offsetof(GCtab, gclist));
   emit_tai(as, PPCI_STB, mark, tab, (int32_t)offsetof(GCtab, marked));
   emit_tai(as, PPCI_STB, mark, tab, (int32_t)offsetof(GCtab, marked));
   emit_setgl(as, tab, gc.grayagain);
   emit_setgl(as, tab, gc.grayagain);
-  lua_assert(LJ_GC_BLACK == 0x04);
+  lj_assertA(LJ_GC_BLACK == 0x04, "bad LJ_GC_BLACK");
   emit_rot(as, PPCI_RLWINM, mark, mark, 0, 30, 28);  /* Clear black bit. */
   emit_rot(as, PPCI_RLWINM, mark, mark, 0, 30, 28);  /* Clear black bit. */
   emit_getgl(as, link, gc.grayagain);
   emit_getgl(as, link, gc.grayagain);
   emit_condbranch(as, PPCI_BC|PPCF_Y, CC_EQ, l_end);
   emit_condbranch(as, PPCI_BC|PPCF_Y, CC_EQ, l_end);
@@ -1204,7 +1218,7 @@ static void asm_obar(ASMState *as, IRIns *ir)
   MCLabel l_end;
   MCLabel l_end;
   Reg obj, val, tmp;
   Reg obj, val, tmp;
   /* No need for other object barriers (yet). */
   /* No need for other object barriers (yet). */
-  lua_assert(IR(ir->op1)->o == IR_UREFC);
+  lj_assertA(IR(ir->op1)->o == IR_UREFC, "bad OBAR type");
   ra_evictset(as, RSET_SCRATCH);
   ra_evictset(as, RSET_SCRATCH);
   l_end = emit_label(as);
   l_end = emit_label(as);
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[0] = ASMREF_TMP1;  /* global_State *g */
@@ -1246,8 +1260,6 @@ static void asm_fpunary(ASMState *as, IRIns *ir, PPCIns pi)
 
 
 static void asm_fpmath(ASMState *as, IRIns *ir)
 static void asm_fpmath(ASMState *as, IRIns *ir)
 {
 {
-  if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir))
-    return;
   if (ir->op2 == IRFPM_SQRT && (as->flags & JIT_F_SQRT))
   if (ir->op2 == IRFPM_SQRT && (as->flags & JIT_F_SQRT))
     asm_fpunary(as, ir, PPCI_FSQRT);
     asm_fpunary(as, ir, PPCI_FSQRT);
   else
   else
@@ -1361,9 +1373,7 @@ static void asm_mul(ASMState *as, IRIns *ir)
   }
   }
 }
 }
 
 
-#define asm_div(as, ir)		asm_fparith(as, ir, PPCI_FDIV)
-#define asm_mod(as, ir)		asm_callid(as, ir, IRCALL_lj_vm_modi)
-#define asm_pow(as, ir)		asm_callid(as, ir, IRCALL_lj_vm_powi)
+#define asm_fpdiv(as, ir)	asm_fparith(as, ir, PPCI_FDIV)
 
 
 static void asm_neg(ASMState *as, IRIns *ir)
 static void asm_neg(ASMState *as, IRIns *ir)
 {
 {
@@ -1387,8 +1397,6 @@ static void asm_neg(ASMState *as, IRIns *ir)
 }
 }
 
 
 #define asm_abs(as, ir)		asm_fpunary(as, ir, PPCI_FABS)
 #define asm_abs(as, ir)		asm_fpunary(as, ir, PPCI_FABS)
-#define asm_atan2(as, ir)	asm_callid(as, ir, IRCALL_atan2)
-#define asm_ldexp(as, ir)	asm_callid(as, ir, IRCALL_ldexp)
 
 
 static void asm_arithov(ASMState *as, IRIns *ir, PPCIns pi)
 static void asm_arithov(ASMState *as, IRIns *ir, PPCIns pi)
 {
 {
@@ -1681,7 +1689,7 @@ static void asm_bitshift(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pik)
 #define asm_brol(as, ir) \
 #define asm_brol(as, ir) \
   asm_bitshift(as, ir, PPCI_RLWNM|PPCF_MB(0)|PPCF_ME(31), \
   asm_bitshift(as, ir, PPCI_RLWNM|PPCF_MB(0)|PPCF_ME(31), \
 		       PPCI_RLWINM|PPCF_MB(0)|PPCF_ME(31))
 		       PPCI_RLWINM|PPCF_MB(0)|PPCF_ME(31))
-#define asm_bror(as, ir)	lua_assert(0)
+#define asm_bror(as, ir)	lj_assertA(0, "unexpected BROR")
 
 
 #if LJ_SOFTFP
 #if LJ_SOFTFP
 static void asm_sfpmin_max(ASMState *as, IRIns *ir)
 static void asm_sfpmin_max(ASMState *as, IRIns *ir)
@@ -1724,9 +1732,8 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
     if (tmp == left || tmp == right)
     if (tmp == left || tmp == right)
       tmp = ra_scratch(as, rset_exclude(rset_exclude(rset_exclude(RSET_FPR,
       tmp = ra_scratch(as, rset_exclude(rset_exclude(rset_exclude(RSET_FPR,
 					dest), left), right));
 					dest), left), right));
-    emit_facb(as, PPCI_FSEL, dest, tmp,
-	      ismax ? left : right, ismax ? right : left);
-    emit_fab(as, PPCI_FSUB, tmp, left, right);
+    emit_facb(as, PPCI_FSEL, dest, tmp, left, right);
+    emit_fab(as, PPCI_FSUB, tmp, ismax ? left : right, ismax ? right : left);
   } else {
   } else {
     Reg dest = ra_dest(as, ir, RSET_GPR);
     Reg dest = ra_dest(as, ir, RSET_GPR);
     Reg tmp1 = RID_TMP, tmp2 = dest;
     Reg tmp1 = RID_TMP, tmp2 = dest;
@@ -1956,10 +1963,11 @@ static void asm_hiop(ASMState *as, IRIns *ir)
   case IR_CNEWI:
   case IR_CNEWI:
     /* Nothing to do here. Handled by lo op itself. */
     /* Nothing to do here. Handled by lo op itself. */
     break;
     break;
-  default: lua_assert(0); break;
+  default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
   }
   }
 #else
 #else
-  UNUSED(as); UNUSED(ir); lua_assert(0);  /* Unused without FFI. */
+  /* Unused without SOFTFP or FFI. */
+  UNUSED(as); UNUSED(ir); lj_assertA(0, "unexpected HIOP");
 #endif
 #endif
 }
 }
 
 
@@ -2019,7 +2027,8 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
 #if LJ_SOFTFP
 #if LJ_SOFTFP
       Reg tmp;
       Reg tmp;
       RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
       RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
-      lua_assert(irref_isk(ref));  /* LJ_SOFTFP: must be a number constant. */
+      /* LJ_SOFTFP: must be a number constant. */
+      lj_assertA(irref_isk(ref), "unsplit FP op");
       tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, allow);
       tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, allow);
       emit_tai(as, PPCI_STW, tmp, RID_BASE, ofs+(LJ_BE?4:0));
       emit_tai(as, PPCI_STW, tmp, RID_BASE, ofs+(LJ_BE?4:0));
       if (rset_test(as->freeset, tmp+1)) allow = RID2RSET(tmp+1);
       if (rset_test(as->freeset, tmp+1)) allow = RID2RSET(tmp+1);
@@ -2032,7 +2041,8 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
     } else {
     } else {
       Reg type;
       Reg type;
       RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
       RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
-      lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t));
+      lj_assertA(irt_ispri(ir->t) || irt_isaddr(ir->t) || irt_isinteger(ir->t),
+		 "restore of IR type %d", irt_type(ir->t));
       if (!irt_ispri(ir->t)) {
       if (!irt_ispri(ir->t)) {
 	Reg src = ra_alloc1(as, ref, allow);
 	Reg src = ra_alloc1(as, ref, allow);
 	rset_clear(allow, src);
 	rset_clear(allow, src);
@@ -2052,11 +2062,14 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
     }
     }
     checkmclim(as);
     checkmclim(as);
   }
   }
-  lua_assert(map + nent == flinks);
+  lj_assertA(map + nent == flinks, "inconsistent frames in snapshot");
 }
 }
 
 
 /* -- GC handling --------------------------------------------------------- */
 /* -- GC handling --------------------------------------------------------- */
 
 
+/* Marker to prevent patching the GC check exit. */
+#define PPC_NOPATCH_GC_CHECK	PPCI_ORIS
+
 /* Check GC threshold and do one or more GC steps. */
 /* Check GC threshold and do one or more GC steps. */
 static void asm_gc_check(ASMState *as)
 static void asm_gc_check(ASMState *as)
 {
 {
@@ -2068,6 +2081,7 @@ static void asm_gc_check(ASMState *as)
   l_end = emit_label(as);
   l_end = emit_label(as);
   /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
   /* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
   asm_guardcc(as, CC_NE);  /* Assumes asm_snap_prep() already done. */
   asm_guardcc(as, CC_NE);  /* Assumes asm_snap_prep() already done. */
+  *--as->mcp = PPC_NOPATCH_GC_CHECK;
   emit_ai(as, PPCI_CMPWI, RID_RET, 0);
   emit_ai(as, PPCI_CMPWI, RID_RET, 0);
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[1] = ASMREF_TMP2;  /* MSize steps     */
   args[1] = ASMREF_TMP2;  /* MSize steps     */
@@ -2150,7 +2164,7 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk)
     as->mctop = p;
     as->mctop = p;
   } else {
   } else {
     /* Patch stack adjustment. */
     /* Patch stack adjustment. */
-    lua_assert(checki16(CFRAME_SIZE+spadj));
+    lj_assertA(checki16(CFRAME_SIZE+spadj), "stack adjustment out of range");
     p[-3] = PPCI_ADDI | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | (CFRAME_SIZE+spadj);
     p[-3] = PPCI_ADDI | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | (CFRAME_SIZE+spadj);
     p[-2] = PPCI_STWU | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | spadj;
     p[-2] = PPCI_STWU | PPCF_T(RID_TMP) | PPCF_A(RID_SP) | spadj;
   }
   }
@@ -2207,7 +2221,7 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
   MCode *px = exitstub_trace_addr(T, exitno);
   MCode *px = exitstub_trace_addr(T, exitno);
   MCode *cstart = NULL;
   MCode *cstart = NULL;
   MCode *mcarea = lj_mcode_patch(J, p, 0);
   MCode *mcarea = lj_mcode_patch(J, p, 0);
-  int clearso = 0;
+  int clearso = 0, patchlong = 1;
   for (; p < pe; p++) {
   for (; p < pe; p++) {
     /* Look for exitstub branch, try to replace with branch to target. */
     /* Look for exitstub branch, try to replace with branch to target. */
     uint32_t ins = *p;
     uint32_t ins = *p;
@@ -2219,7 +2233,9 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
 	delta -= sizeof(MCode);
 	delta -= sizeof(MCode);
       }
       }
       /* Many, but not all short-range branches can be patched directly. */
       /* Many, but not all short-range branches can be patched directly. */
-      if (((delta + 0x8000) >> 16) == 0) {
+      if (p[-1] == PPC_NOPATCH_GC_CHECK) {
+	patchlong = 0;
+      } else if (((delta + 0x8000) >> 16) == 0) {
 	*p = (ins & 0xffdf0000u) | ((uint32_t)delta & 0xffffu) |
 	*p = (ins & 0xffdf0000u) | ((uint32_t)delta & 0xffffu) |
 	     ((delta & 0x8000) * (PPCF_Y/0x8000));
 	     ((delta & 0x8000) * (PPCF_Y/0x8000));
 	if (!cstart) cstart = p;
 	if (!cstart) cstart = p;
@@ -2227,14 +2243,17 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
     } else if ((ins & 0xfc000000u) == PPCI_B &&
     } else if ((ins & 0xfc000000u) == PPCI_B &&
 	       ((ins ^ ((char *)px-(char *)p)) & 0x03ffffffu) == 0) {
 	       ((ins ^ ((char *)px-(char *)p)) & 0x03ffffffu) == 0) {
       ptrdiff_t delta = (char *)target - (char *)p;
       ptrdiff_t delta = (char *)target - (char *)p;
-      lua_assert(((delta + 0x02000000) >> 26) == 0);
+      lj_assertJ(((delta + 0x02000000) >> 26) == 0,
+		 "branch target out of range");
       *p = PPCI_B | ((uint32_t)delta & 0x03ffffffu);
       *p = PPCI_B | ((uint32_t)delta & 0x03ffffffu);
       if (!cstart) cstart = p;
       if (!cstart) cstart = p;
     }
     }
   }
   }
-  {  /* Always patch long-range branch in exit stub itself. */
+  /* Always patch long-range branch in exit stub itself. Except, if we can't. */
+  if (patchlong) {
     ptrdiff_t delta = (char *)target - (char *)px - clearso;
     ptrdiff_t delta = (char *)target - (char *)px - clearso;
-    lua_assert(((delta + 0x02000000) >> 26) == 0);
+    lj_assertJ(((delta + 0x02000000) >> 26) == 0,
+	       "branch target out of range");
     *px = PPCI_B | ((uint32_t)delta & 0x03ffffffu);
     *px = PPCI_B | ((uint32_t)delta & 0x03ffffffu);
   }
   }
   if (!cstart) cstart = px;
   if (!cstart) cstart = px;

+ 118 - 137
libs/LuaJIT/src/lj_asm_x86.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** x86/x64 IR assembler (SSA IR -> machine code).
 ** x86/x64 IR assembler (SSA IR -> machine code).
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 /* -- Guard handling ------------------------------------------------------ */
 /* -- Guard handling ------------------------------------------------------ */
@@ -31,7 +31,7 @@ static MCode *asm_exitstub_gen(ASMState *as, ExitNo group)
 #endif
 #endif
   /* Jump to exit handler which fills in the ExitState. */
   /* Jump to exit handler which fills in the ExitState. */
   *mxp++ = XI_JMP; mxp += 4;
   *mxp++ = XI_JMP; mxp += 4;
-  *((int32_t *)(mxp-4)) = jmprel(mxp, (MCode *)(void *)lj_vm_exit_handler);
+  *((int32_t *)(mxp-4)) = jmprel(as->J, mxp, (MCode *)(void *)lj_vm_exit_handler);
   /* Commit the code for this group (even if assembly fails later on). */
   /* Commit the code for this group (even if assembly fails later on). */
   lj_mcode_commitbot(as->J, mxp);
   lj_mcode_commitbot(as->J, mxp);
   as->mcbot = mxp;
   as->mcbot = mxp;
@@ -60,7 +60,7 @@ static void asm_guardcc(ASMState *as, int cc)
   MCode *p = as->mcp;
   MCode *p = as->mcp;
   if (LJ_UNLIKELY(p == as->invmcp)) {
   if (LJ_UNLIKELY(p == as->invmcp)) {
     as->loopinv = 1;
     as->loopinv = 1;
-    *(int32_t *)(p+1) = jmprel(p+5, target);
+    *(int32_t *)(p+1) = jmprel(as->J, p+5, target);
     target = p;
     target = p;
     cc ^= 1;
     cc ^= 1;
     if (as->realign) {
     if (as->realign) {
@@ -131,7 +131,7 @@ static IRRef asm_fuseabase(ASMState *as, IRRef ref)
   as->mrm.ofs = 0;
   as->mrm.ofs = 0;
   if (irb->o == IR_FLOAD) {
   if (irb->o == IR_FLOAD) {
     IRIns *ira = IR(irb->op1);
     IRIns *ira = IR(irb->op1);
-    lua_assert(irb->op2 == IRFL_TAB_ARRAY);
+    lj_assertA(irb->op2 == IRFL_TAB_ARRAY, "expected FLOAD TAB_ARRAY");
     /* We can avoid the FLOAD of t->array for colocated arrays. */
     /* We can avoid the FLOAD of t->array for colocated arrays. */
     if (ira->o == IR_TNEW && ira->op1 <= LJ_MAX_COLOSIZE &&
     if (ira->o == IR_TNEW && ira->op1 <= LJ_MAX_COLOSIZE &&
 	!neverfuse(as) && noconflict(as, irb->op1, IR_NEWREF, 1)) {
 	!neverfuse(as) && noconflict(as, irb->op1, IR_NEWREF, 1)) {
@@ -150,7 +150,7 @@ static IRRef asm_fuseabase(ASMState *as, IRRef ref)
 static void asm_fusearef(ASMState *as, IRIns *ir, RegSet allow)
 static void asm_fusearef(ASMState *as, IRIns *ir, RegSet allow)
 {
 {
   IRIns *irx;
   IRIns *irx;
-  lua_assert(ir->o == IR_AREF);
+  lj_assertA(ir->o == IR_AREF, "expected AREF");
   as->mrm.base = (uint8_t)ra_alloc1(as, asm_fuseabase(as, ir->op1), allow);
   as->mrm.base = (uint8_t)ra_alloc1(as, asm_fuseabase(as, ir->op1), allow);
   irx = IR(ir->op2);
   irx = IR(ir->op2);
   if (irref_isk(ir->op2)) {
   if (irref_isk(ir->op2)) {
@@ -217,8 +217,9 @@ static void asm_fuseahuref(ASMState *as, IRRef ref, RegSet allow)
       }
       }
       break;
       break;
     default:
     default:
-      lua_assert(ir->o == IR_HREF || ir->o == IR_NEWREF || ir->o == IR_UREFO ||
-		 ir->o == IR_KKPTR);
+      lj_assertA(ir->o == IR_HREF || ir->o == IR_NEWREF || ir->o == IR_UREFO ||
+		 ir->o == IR_KKPTR,
+		 "bad IR op %d", ir->o);
       break;
       break;
     }
     }
   }
   }
@@ -230,9 +231,10 @@ static void asm_fuseahuref(ASMState *as, IRRef ref, RegSet allow)
 /* Fuse FLOAD/FREF reference into memory operand. */
 /* Fuse FLOAD/FREF reference into memory operand. */
 static void asm_fusefref(ASMState *as, IRIns *ir, RegSet allow)
 static void asm_fusefref(ASMState *as, IRIns *ir, RegSet allow)
 {
 {
-  lua_assert(ir->o == IR_FLOAD || ir->o == IR_FREF);
+  lj_assertA(ir->o == IR_FLOAD || ir->o == IR_FREF,
+	     "bad IR op %d", ir->o);
   as->mrm.idx = RID_NONE;
   as->mrm.idx = RID_NONE;
-  if (ir->op1 == REF_NIL) {
+  if (ir->op1 == REF_NIL) {  /* FLOAD from GG_State with offset. */
 #if LJ_GC64
 #if LJ_GC64
     as->mrm.ofs = (int32_t)(ir->op2 << 2) - GG_OFS(dispatch);
     as->mrm.ofs = (int32_t)(ir->op2 << 2) - GG_OFS(dispatch);
     as->mrm.base = RID_DISPATCH;
     as->mrm.base = RID_DISPATCH;
@@ -271,7 +273,7 @@ static void asm_fusefref(ASMState *as, IRIns *ir, RegSet allow)
 static void asm_fusestrref(ASMState *as, IRIns *ir, RegSet allow)
 static void asm_fusestrref(ASMState *as, IRIns *ir, RegSet allow)
 {
 {
   IRIns *irr;
   IRIns *irr;
-  lua_assert(ir->o == IR_STRREF);
+  lj_assertA(ir->o == IR_STRREF, "bad IR op %d", ir->o);
   as->mrm.base = as->mrm.idx = RID_NONE;
   as->mrm.base = as->mrm.idx = RID_NONE;
   as->mrm.scale = XM_SCALE1;
   as->mrm.scale = XM_SCALE1;
   as->mrm.ofs = sizeof(GCstr);
   as->mrm.ofs = sizeof(GCstr);
@@ -378,9 +380,10 @@ static Reg asm_fuseloadk64(ASMState *as, IRIns *ir)
 	     checki32(mctopofs(as, k)) && checki32(mctopofs(as, k+1))) {
 	     checki32(mctopofs(as, k)) && checki32(mctopofs(as, k+1))) {
     as->mrm.ofs = (int32_t)mcpofs(as, k);
     as->mrm.ofs = (int32_t)mcpofs(as, k);
     as->mrm.base = RID_RIP;
     as->mrm.base = RID_RIP;
-  } else {
+  } else {  /* Intern 64 bit constant at bottom of mcode. */
     if (ir->i) {
     if (ir->i) {
-      lua_assert(*k == *(uint64_t*)(as->mctop - ir->i));
+      lj_assertA(*k == *(uint64_t*)(as->mctop - ir->i),
+		 "bad interned 64 bit constant");
     } else {
     } else {
       while ((uintptr_t)as->mcbot & 7) *as->mcbot++ = XI_INT3;
       while ((uintptr_t)as->mcbot & 7) *as->mcbot++ = XI_INT3;
       *(uint64_t*)as->mcbot = *k;
       *(uint64_t*)as->mcbot = *k;
@@ -420,12 +423,12 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
   }
   }
   if (ir->o == IR_KNUM) {
   if (ir->o == IR_KNUM) {
     RegSet avail = as->freeset & ~as->modset & RSET_FPR;
     RegSet avail = as->freeset & ~as->modset & RSET_FPR;
-    lua_assert(allow != RSET_EMPTY);
+    lj_assertA(allow != RSET_EMPTY, "no register allowed");
     if (!(avail & (avail-1)))  /* Fuse if less than two regs available. */
     if (!(avail & (avail-1)))  /* Fuse if less than two regs available. */
       return asm_fuseloadk64(as, ir);
       return asm_fuseloadk64(as, ir);
   } else if (ref == REF_BASE || ir->o == IR_KINT64) {
   } else if (ref == REF_BASE || ir->o == IR_KINT64) {
     RegSet avail = as->freeset & ~as->modset & RSET_GPR;
     RegSet avail = as->freeset & ~as->modset & RSET_GPR;
-    lua_assert(allow != RSET_EMPTY);
+    lj_assertA(allow != RSET_EMPTY, "no register allowed");
     if (!(avail & (avail-1))) {  /* Fuse if less than two regs available. */
     if (!(avail & (avail-1))) {  /* Fuse if less than two regs available. */
       if (ref == REF_BASE) {
       if (ref == REF_BASE) {
 #if LJ_GC64
 #if LJ_GC64
@@ -606,7 +609,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
 #endif
 #endif
 	  emit_loadi(as, r, ir->i);
 	  emit_loadi(as, r, ir->i);
       } else {
       } else {
-	lua_assert(rset_test(as->freeset, r));  /* Must have been evicted. */
+	/* Must have been evicted. */
+	lj_assertA(rset_test(as->freeset, r), "reg %d not free", r);
 	if (ra_hasreg(ir->r)) {
 	if (ra_hasreg(ir->r)) {
 	  ra_noweak(as, ir->r);
 	  ra_noweak(as, ir->r);
 	  emit_movrr(as, ir, r, ir->r);
 	  emit_movrr(as, ir, r, ir->r);
@@ -615,7 +619,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
 	}
 	}
       }
       }
     } else if (irt_isfp(ir->t)) {  /* FP argument is on stack. */
     } else if (irt_isfp(ir->t)) {  /* FP argument is on stack. */
-      lua_assert(!(irt_isfloat(ir->t) && irref_isk(ref)));  /* No float k. */
+      lj_assertA(!(irt_isfloat(ir->t) && irref_isk(ref)),
+		 "unexpected float constant");
       if (LJ_32 && (ofs & 4) && irref_isk(ref)) {
       if (LJ_32 && (ofs & 4) && irref_isk(ref)) {
 	/* Split stores for unaligned FP consts. */
 	/* Split stores for unaligned FP consts. */
 	emit_movmroi(as, RID_ESP, ofs, (int32_t)ir_knum(ir)->u32.lo);
 	emit_movmroi(as, RID_ESP, ofs, (int32_t)ir_knum(ir)->u32.lo);
@@ -691,7 +696,7 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
       ra_destpair(as, ir);
       ra_destpair(as, ir);
 #endif
 #endif
     } else {
     } else {
-      lua_assert(!irt_ispri(ir->t));
+      lj_assertA(!irt_ispri(ir->t), "PRI dest");
       ra_destreg(as, ir, RID_RET);
       ra_destreg(as, ir, RID_RET);
     }
     }
   } else if (LJ_32 && irt_isfp(ir->t) && !(ci->flags & CCI_CASTU64)) {
   } else if (LJ_32 && irt_isfp(ir->t) && !(ci->flags & CCI_CASTU64)) {
@@ -810,8 +815,10 @@ static void asm_conv(ASMState *as, IRIns *ir)
   int st64 = (st == IRT_I64 || st == IRT_U64 || (LJ_64 && st == IRT_P64));
   int st64 = (st == IRT_I64 || st == IRT_U64 || (LJ_64 && st == IRT_P64));
   int stfp = (st == IRT_NUM || st == IRT_FLOAT);
   int stfp = (st == IRT_NUM || st == IRT_FLOAT);
   IRRef lref = ir->op1;
   IRRef lref = ir->op1;
-  lua_assert(irt_type(ir->t) != st);
-  lua_assert(!(LJ_32 && (irt_isint64(ir->t) || st64)));  /* Handled by SPLIT. */
+  lj_assertA(irt_type(ir->t) != st, "inconsistent types for CONV");
+  lj_assertA(!(LJ_32 && (irt_isint64(ir->t) || st64)),
+	     "IR %04d has unsplit 64 bit type",
+	     (int)(ir - as->ir) - REF_BIAS);
   if (irt_isfp(ir->t)) {
   if (irt_isfp(ir->t)) {
     Reg dest = ra_dest(as, ir, RSET_FPR);
     Reg dest = ra_dest(as, ir, RSET_FPR);
     if (stfp) {  /* FP to FP conversion. */
     if (stfp) {  /* FP to FP conversion. */
@@ -847,7 +854,8 @@ static void asm_conv(ASMState *as, IRIns *ir)
   } else if (stfp) {  /* FP to integer conversion. */
   } else if (stfp) {  /* FP to integer conversion. */
     if (irt_isguard(ir->t)) {
     if (irt_isguard(ir->t)) {
       /* Checked conversions are only supported from number to int. */
       /* Checked conversions are only supported from number to int. */
-      lua_assert(irt_isint(ir->t) && st == IRT_NUM);
+      lj_assertA(irt_isint(ir->t) && st == IRT_NUM,
+		 "bad type for checked CONV");
       asm_tointg(as, ir, ra_alloc1(as, lref, RSET_FPR));
       asm_tointg(as, ir, ra_alloc1(as, lref, RSET_FPR));
     } else {
     } else {
       Reg dest = ra_dest(as, ir, RSET_GPR);
       Reg dest = ra_dest(as, ir, RSET_GPR);
@@ -882,7 +890,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
     Reg left, dest = ra_dest(as, ir, RSET_GPR);
     Reg left, dest = ra_dest(as, ir, RSET_GPR);
     RegSet allow = RSET_GPR;
     RegSet allow = RSET_GPR;
     x86Op op;
     x86Op op;
-    lua_assert(irt_isint(ir->t) || irt_isu32(ir->t));
+    lj_assertA(irt_isint(ir->t) || irt_isu32(ir->t), "bad type for CONV EXT");
     if (st == IRT_I8) {
     if (st == IRT_I8) {
       op = XO_MOVSXb; allow = RSET_GPR8; dest |= FORCE_REX;
       op = XO_MOVSXb; allow = RSET_GPR8; dest |= FORCE_REX;
     } else if (st == IRT_U8) {
     } else if (st == IRT_U8) {
@@ -953,7 +961,7 @@ static void asm_conv_fp_int64(ASMState *as, IRIns *ir)
     emit_sjcc(as, CC_NS, l_end);
     emit_sjcc(as, CC_NS, l_end);
     emit_rr(as, XO_TEST, hi, hi);  /* Check if u64 >= 2^63. */
     emit_rr(as, XO_TEST, hi, hi);  /* Check if u64 >= 2^63. */
   } else {
   } else {
-    lua_assert(((ir-1)->op2 & IRCONV_SRCMASK) == IRT_I64);
+    lj_assertA(((ir-1)->op2 & IRCONV_SRCMASK) == IRT_I64, "bad type for CONV");
   }
   }
   emit_rmro(as, XO_FILDq, XOg_FILDq, RID_ESP, 0);
   emit_rmro(as, XO_FILDq, XOg_FILDq, RID_ESP, 0);
   /* NYI: Avoid narrow-to-wide store-to-load forwarding stall. */
   /* NYI: Avoid narrow-to-wide store-to-load forwarding stall. */
@@ -967,8 +975,8 @@ static void asm_conv_int64_fp(ASMState *as, IRIns *ir)
   IRType st = (IRType)((ir-1)->op2 & IRCONV_SRCMASK);
   IRType st = (IRType)((ir-1)->op2 & IRCONV_SRCMASK);
   IRType dt = (((ir-1)->op2 & IRCONV_DSTMASK) >> IRCONV_DSH);
   IRType dt = (((ir-1)->op2 & IRCONV_DSTMASK) >> IRCONV_DSH);
   Reg lo, hi;
   Reg lo, hi;
-  lua_assert(st == IRT_NUM || st == IRT_FLOAT);
-  lua_assert(dt == IRT_I64 || dt == IRT_U64);
+  lj_assertA(st == IRT_NUM || st == IRT_FLOAT, "bad type for CONV");
+  lj_assertA(dt == IRT_I64 || dt == IRT_U64, "bad type for CONV");
   hi = ra_dest(as, ir, RSET_GPR);
   hi = ra_dest(as, ir, RSET_GPR);
   lo = ra_dest(as, ir-1, rset_exclude(RSET_GPR, hi));
   lo = ra_dest(as, ir-1, rset_exclude(RSET_GPR, hi));
   if (ra_used(ir-1)) emit_rmro(as, XO_MOV, lo, RID_ESP, 0);
   if (ra_used(ir-1)) emit_rmro(as, XO_MOV, lo, RID_ESP, 0);
@@ -1180,13 +1188,13 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
       emit_rmro(as, XO_CMP, tmp|REX_64, dest, offsetof(Node, key.u64));
       emit_rmro(as, XO_CMP, tmp|REX_64, dest, offsetof(Node, key.u64));
     }
     }
   } else {
   } else {
-    lua_assert(irt_ispri(kt) && !irt_isnil(kt));
+    lj_assertA(irt_ispri(kt) && !irt_isnil(kt), "bad HREF key type");
     emit_u32(as, (irt_toitype(kt)<<15)|0x7fff);
     emit_u32(as, (irt_toitype(kt)<<15)|0x7fff);
     emit_rmro(as, XO_ARITHi, XOg_CMP, dest, offsetof(Node, key.it));
     emit_rmro(as, XO_ARITHi, XOg_CMP, dest, offsetof(Node, key.it));
 #else
 #else
   } else {
   } else {
     if (!irt_ispri(kt)) {
     if (!irt_ispri(kt)) {
-      lua_assert(irt_isaddr(kt));
+      lj_assertA(irt_isaddr(kt), "bad HREF key type");
       if (isk)
       if (isk)
 	emit_gmroi(as, XG_ARITHi(XOg_CMP), dest, offsetof(Node, key.gcr),
 	emit_gmroi(as, XG_ARITHi(XOg_CMP), dest, offsetof(Node, key.gcr),
 		   ptr2addr(ir_kgc(irkey)));
 		   ptr2addr(ir_kgc(irkey)));
@@ -1194,7 +1202,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
 	emit_rmro(as, XO_CMP, key, dest, offsetof(Node, key.gcr));
 	emit_rmro(as, XO_CMP, key, dest, offsetof(Node, key.gcr));
       emit_sjcc(as, CC_NE, l_next);
       emit_sjcc(as, CC_NE, l_next);
     }
     }
-    lua_assert(!irt_isnil(kt));
+    lj_assertA(!irt_isnil(kt), "bad HREF key type");
     emit_i8(as, irt_toitype(kt));
     emit_i8(as, irt_toitype(kt));
     emit_rmro(as, XO_ARITHi8, XOg_CMP, dest, offsetof(Node, key.it));
     emit_rmro(as, XO_ARITHi8, XOg_CMP, dest, offsetof(Node, key.it));
 #endif
 #endif
@@ -1209,23 +1217,18 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
 #endif
 #endif
 
 
   /* Load main position relative to tab->node into dest. */
   /* Load main position relative to tab->node into dest. */
-  khash = isk ? ir_khash(irkey) : 1;
+  khash = isk ? ir_khash(as, irkey) : 1;
   if (khash == 0) {
   if (khash == 0) {
     emit_rmro(as, XO_MOV, dest|REX_GC64, tab, offsetof(GCtab, node));
     emit_rmro(as, XO_MOV, dest|REX_GC64, tab, offsetof(GCtab, node));
   } else {
   } else {
     emit_rmro(as, XO_ARITH(XOg_ADD), dest|REX_GC64, tab, offsetof(GCtab,node));
     emit_rmro(as, XO_ARITH(XOg_ADD), dest|REX_GC64, tab, offsetof(GCtab,node));
-    if ((as->flags & JIT_F_PREFER_IMUL)) {
-      emit_i8(as, sizeof(Node));
-      emit_rr(as, XO_IMULi8, dest, dest);
-    } else {
-      emit_shifti(as, XOg_SHL, dest, 3);
-      emit_rmrxo(as, XO_LEA, dest, dest, dest, XM_SCALE2, 0);
-    }
+    emit_shifti(as, XOg_SHL, dest, 3);
+    emit_rmrxo(as, XO_LEA, dest, dest, dest, XM_SCALE2, 0);
     if (isk) {
     if (isk) {
       emit_gri(as, XG_ARITHi(XOg_AND), dest, (int32_t)khash);
       emit_gri(as, XG_ARITHi(XOg_AND), dest, (int32_t)khash);
       emit_rmro(as, XO_MOV, dest, tab, offsetof(GCtab, hmask));
       emit_rmro(as, XO_MOV, dest, tab, offsetof(GCtab, hmask));
     } else if (irt_isstr(kt)) {
     } else if (irt_isstr(kt)) {
-      emit_rmro(as, XO_ARITH(XOg_AND), dest, key, offsetof(GCstr, hash));
+      emit_rmro(as, XO_ARITH(XOg_AND), dest, key, offsetof(GCstr, sid));
       emit_rmro(as, XO_MOV, dest, tab, offsetof(GCtab, hmask));
       emit_rmro(as, XO_MOV, dest, tab, offsetof(GCtab, hmask));
     } else {  /* Must match with hashrot() in lj_tab.c. */
     } else {  /* Must match with hashrot() in lj_tab.c. */
       emit_rmro(as, XO_ARITH(XOg_AND), dest, tab, offsetof(GCtab, hmask));
       emit_rmro(as, XO_ARITH(XOg_AND), dest, tab, offsetof(GCtab, hmask));
@@ -1276,10 +1279,10 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
 #if !LJ_64
 #if !LJ_64
   MCLabel l_exit;
   MCLabel l_exit;
 #endif
 #endif
-  lua_assert(ofs % sizeof(Node) == 0);
+  lj_assertA(ofs % sizeof(Node) == 0, "unaligned HREFK slot");
   if (ra_hasreg(dest)) {
   if (ra_hasreg(dest)) {
     if (ofs != 0) {
     if (ofs != 0) {
-      if (dest == node && !(as->flags & JIT_F_LEA_AGU))
+      if (dest == node)
 	emit_gri(as, XG_ARITHi(XOg_ADD), dest|REX_GC64, ofs);
 	emit_gri(as, XG_ARITHi(XOg_ADD), dest|REX_GC64, ofs);
       else
       else
 	emit_rmro(as, XO_LEA, dest|REX_GC64, node, ofs);
 	emit_rmro(as, XO_LEA, dest|REX_GC64, node, ofs);
@@ -1293,7 +1296,8 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
     Reg key = ra_scratch(as, rset_exclude(RSET_GPR, node));
     Reg key = ra_scratch(as, rset_exclude(RSET_GPR, node));
     emit_rmro(as, XO_CMP, key|REX_64, node,
     emit_rmro(as, XO_CMP, key|REX_64, node,
 	       ofs + (int32_t)offsetof(Node, key.u64));
 	       ofs + (int32_t)offsetof(Node, key.u64));
-    lua_assert(irt_isnum(irkey->t) || irt_isgcv(irkey->t));
+    lj_assertA(irt_isnum(irkey->t) || irt_isgcv(irkey->t),
+	       "bad HREFK key type");
     /* Assumes -0.0 is already canonicalized to +0.0. */
     /* Assumes -0.0 is already canonicalized to +0.0. */
     emit_loadu64(as, key, irt_isnum(irkey->t) ? ir_knum(irkey)->u64 :
     emit_loadu64(as, key, irt_isnum(irkey->t) ? ir_knum(irkey)->u64 :
 #if LJ_GC64
 #if LJ_GC64
@@ -1304,7 +1308,7 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
 			  (uint64_t)(uint32_t)ptr2addr(ir_kgc(irkey)));
 			  (uint64_t)(uint32_t)ptr2addr(ir_kgc(irkey)));
 #endif
 #endif
   } else {
   } else {
-    lua_assert(!irt_isnil(irkey->t));
+    lj_assertA(!irt_isnil(irkey->t), "bad HREFK key type");
 #if LJ_GC64
 #if LJ_GC64
     emit_i32(as, (irt_toitype(irkey->t)<<15)|0x7fff);
     emit_i32(as, (irt_toitype(irkey->t)<<15)|0x7fff);
     emit_rmro(as, XO_ARITHi, XOg_CMP, node,
     emit_rmro(as, XO_ARITHi, XOg_CMP, node,
@@ -1328,13 +1332,13 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
 	       (int32_t)ir_knum(irkey)->u32.hi);
 	       (int32_t)ir_knum(irkey)->u32.hi);
   } else {
   } else {
     if (!irt_ispri(irkey->t)) {
     if (!irt_ispri(irkey->t)) {
-      lua_assert(irt_isgcv(irkey->t));
+      lj_assertA(irt_isgcv(irkey->t), "bad HREFK key type");
       emit_gmroi(as, XG_ARITHi(XOg_CMP), node,
       emit_gmroi(as, XG_ARITHi(XOg_CMP), node,
 		 ofs + (int32_t)offsetof(Node, key.gcr),
 		 ofs + (int32_t)offsetof(Node, key.gcr),
 		 ptr2addr(ir_kgc(irkey)));
 		 ptr2addr(ir_kgc(irkey)));
       emit_sjcc(as, CC_NE, l_exit);
       emit_sjcc(as, CC_NE, l_exit);
     }
     }
-    lua_assert(!irt_isnil(irkey->t));
+    lj_assertA(!irt_isnil(irkey->t), "bad HREFK key type");
     emit_i8(as, irt_toitype(irkey->t));
     emit_i8(as, irt_toitype(irkey->t));
     emit_rmro(as, XO_ARITHi8, XOg_CMP, node,
     emit_rmro(as, XO_ARITHi8, XOg_CMP, node,
 	      ofs + (int32_t)offsetof(Node, key.it));
 	      ofs + (int32_t)offsetof(Node, key.it));
@@ -1407,7 +1411,8 @@ static void asm_fxload(ASMState *as, IRIns *ir)
     if (LJ_64 && irt_is64(ir->t))
     if (LJ_64 && irt_is64(ir->t))
       dest |= REX_64;
       dest |= REX_64;
     else
     else
-      lua_assert(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t));
+      lj_assertA(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t),
+		 "unsplit 64 bit load");
     xo = XO_MOV;
     xo = XO_MOV;
     break;
     break;
   }
   }
@@ -1452,13 +1457,16 @@ static void asm_fxstore(ASMState *as, IRIns *ir)
     case IRT_NUM: xo = XO_MOVSDto; break;
     case IRT_NUM: xo = XO_MOVSDto; break;
     case IRT_FLOAT: xo = XO_MOVSSto; break;
     case IRT_FLOAT: xo = XO_MOVSSto; break;
 #if LJ_64 && !LJ_GC64
 #if LJ_64 && !LJ_GC64
-    case IRT_LIGHTUD: lua_assert(0);  /* NYI: mask 64 bit lightuserdata. */
+    case IRT_LIGHTUD:
+      /* NYI: mask 64 bit lightuserdata. */
+      lj_assertA(0, "store of lightuserdata");
 #endif
 #endif
     default:
     default:
       if (LJ_64 && irt_is64(ir->t))
       if (LJ_64 && irt_is64(ir->t))
 	src |= REX_64;
 	src |= REX_64;
       else
       else
-	lua_assert(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t));
+	lj_assertA(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t),
+		   "unsplit 64 bit store");
       xo = XO_MOVto;
       xo = XO_MOVto;
       break;
       break;
     }
     }
@@ -1472,8 +1480,8 @@ static void asm_fxstore(ASMState *as, IRIns *ir)
       emit_i8(as, k);
       emit_i8(as, k);
       emit_mrm(as, XO_MOVmib, 0, RID_MRM);
       emit_mrm(as, XO_MOVmib, 0, RID_MRM);
     } else {
     } else {
-      lua_assert(irt_is64(ir->t) || irt_isint(ir->t) || irt_isu32(ir->t) ||
-		 irt_isaddr(ir->t));
+      lj_assertA(irt_is64(ir->t) || irt_isint(ir->t) || irt_isu32(ir->t) ||
+		 irt_isaddr(ir->t), "bad store type");
       emit_i32(as, k);
       emit_i32(as, k);
       emit_mrm(as, XO_MOVmi, REX_64IR(ir, 0), RID_MRM);
       emit_mrm(as, XO_MOVmi, REX_64IR(ir, 0), RID_MRM);
     }
     }
@@ -1508,8 +1516,9 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
 #if LJ_GC64
 #if LJ_GC64
   Reg tmp = RID_NONE;
   Reg tmp = RID_NONE;
 #endif
 #endif
-  lua_assert(irt_isnum(ir->t) || irt_ispri(ir->t) || irt_isaddr(ir->t) ||
-	     (LJ_DUALNUM && irt_isint(ir->t)));
+  lj_assertA(irt_isnum(ir->t) || irt_ispri(ir->t) || irt_isaddr(ir->t) ||
+	     (LJ_DUALNUM && irt_isint(ir->t)),
+	     "bad load type %d", irt_type(ir->t));
 #if LJ_64 && !LJ_GC64
 #if LJ_64 && !LJ_GC64
   if (irt_islightud(ir->t)) {
   if (irt_islightud(ir->t)) {
     Reg dest = asm_load_lightud64(as, ir, 1);
     Reg dest = asm_load_lightud64(as, ir, 1);
@@ -1556,7 +1565,8 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
   as->mrm.ofs += 4;
   as->mrm.ofs += 4;
   asm_guardcc(as, irt_isnum(ir->t) ? CC_AE : CC_NE);
   asm_guardcc(as, irt_isnum(ir->t) ? CC_AE : CC_NE);
   if (LJ_64 && irt_type(ir->t) >= IRT_NUM) {
   if (LJ_64 && irt_type(ir->t) >= IRT_NUM) {
-    lua_assert(irt_isinteger(ir->t) || irt_isnum(ir->t));
+    lj_assertA(irt_isinteger(ir->t) || irt_isnum(ir->t),
+	       "bad load type %d", irt_type(ir->t));
 #if LJ_GC64
 #if LJ_GC64
     emit_u32(as, LJ_TISNUM << 15);
     emit_u32(as, LJ_TISNUM << 15);
 #else
 #else
@@ -1638,13 +1648,14 @@ static void asm_ahustore(ASMState *as, IRIns *ir)
 #endif
 #endif
       emit_mrm(as, XO_MOVto, src, RID_MRM);
       emit_mrm(as, XO_MOVto, src, RID_MRM);
     } else if (!irt_ispri(irr->t)) {
     } else if (!irt_ispri(irr->t)) {
-      lua_assert(irt_isaddr(ir->t) || (LJ_DUALNUM && irt_isinteger(ir->t)));
+      lj_assertA(irt_isaddr(ir->t) || (LJ_DUALNUM && irt_isinteger(ir->t)),
+		 "bad store type");
       emit_i32(as, irr->i);
       emit_i32(as, irr->i);
       emit_mrm(as, XO_MOVmi, 0, RID_MRM);
       emit_mrm(as, XO_MOVmi, 0, RID_MRM);
     }
     }
     as->mrm.ofs += 4;
     as->mrm.ofs += 4;
 #if LJ_GC64
 #if LJ_GC64
-    lua_assert(LJ_DUALNUM && irt_isinteger(ir->t));
+    lj_assertA(LJ_DUALNUM && irt_isinteger(ir->t), "bad store type");
     emit_i32(as, LJ_TNUMX << 15);
     emit_i32(as, LJ_TNUMX << 15);
 #else
 #else
     emit_i32(as, (int32_t)irt_toitype(ir->t));
     emit_i32(as, (int32_t)irt_toitype(ir->t));
@@ -1659,10 +1670,13 @@ static void asm_sload(ASMState *as, IRIns *ir)
 		(!LJ_FR2 && (ir->op2 & IRSLOAD_FRAME) ? 4 : 0);
 		(!LJ_FR2 && (ir->op2 & IRSLOAD_FRAME) ? 4 : 0);
   IRType1 t = ir->t;
   IRType1 t = ir->t;
   Reg base;
   Reg base;
-  lua_assert(!(ir->op2 & IRSLOAD_PARENT));  /* Handled by asm_head_side(). */
-  lua_assert(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK));
-  lua_assert(LJ_DUALNUM ||
-	     !irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)));
+  lj_assertA(!(ir->op2 & IRSLOAD_PARENT),
+	     "bad parent SLOAD"); /* Handled by asm_head_side(). */
+  lj_assertA(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK),
+	     "inconsistent SLOAD variant");
+  lj_assertA(LJ_DUALNUM ||
+	     !irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)),
+	     "bad SLOAD type");
   if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {
   if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {
     Reg left = ra_scratch(as, RSET_FPR);
     Reg left = ra_scratch(as, RSET_FPR);
     asm_tointg(as, ir, left);  /* Frees dest reg. Do this before base alloc. */
     asm_tointg(as, ir, left);  /* Frees dest reg. Do this before base alloc. */
@@ -1682,7 +1696,8 @@ static void asm_sload(ASMState *as, IRIns *ir)
     RegSet allow = irt_isnum(t) ? RSET_FPR : RSET_GPR;
     RegSet allow = irt_isnum(t) ? RSET_FPR : RSET_GPR;
     Reg dest = ra_dest(as, ir, allow);
     Reg dest = ra_dest(as, ir, allow);
     base = ra_alloc1(as, REF_BASE, RSET_GPR);
     base = ra_alloc1(as, REF_BASE, RSET_GPR);
-    lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t));
+    lj_assertA(irt_isnum(t) || irt_isint(t) || irt_isaddr(t),
+	       "bad SLOAD type %d", irt_type(t));
     if ((ir->op2 & IRSLOAD_CONVERT)) {
     if ((ir->op2 & IRSLOAD_CONVERT)) {
       t.irt = irt_isint(t) ? IRT_NUM : IRT_INT;  /* Check for original type. */
       t.irt = irt_isint(t) ? IRT_NUM : IRT_INT;  /* Check for original type. */
       emit_rmro(as, irt_isint(t) ? XO_CVTSI2SD : XO_CVTTSD2SI, dest, base, ofs);
       emit_rmro(as, irt_isint(t) ? XO_CVTSI2SD : XO_CVTTSD2SI, dest, base, ofs);
@@ -1728,7 +1743,8 @@ static void asm_sload(ASMState *as, IRIns *ir)
     /* Need type check, even if the load result is unused. */
     /* Need type check, even if the load result is unused. */
     asm_guardcc(as, irt_isnum(t) ? CC_AE : CC_NE);
     asm_guardcc(as, irt_isnum(t) ? CC_AE : CC_NE);
     if (LJ_64 && irt_type(t) >= IRT_NUM) {
     if (LJ_64 && irt_type(t) >= IRT_NUM) {
-      lua_assert(irt_isinteger(t) || irt_isnum(t));
+      lj_assertA(irt_isinteger(t) || irt_isnum(t),
+		 "bad SLOAD type %d", irt_type(t));
 #if LJ_GC64
 #if LJ_GC64
       emit_u32(as, LJ_TISNUM << 15);
       emit_u32(as, LJ_TISNUM << 15);
 #else
 #else
@@ -1780,7 +1796,8 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   CTInfo info = lj_ctype_info(cts, id, &sz);
   CTInfo info = lj_ctype_info(cts, id, &sz);
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
   IRRef args[4];
   IRRef args[4];
-  lua_assert(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL));
+  lj_assertA(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL),
+	     "bad CNEW/CNEWI operands");
 
 
   as->gcsteps++;
   as->gcsteps++;
   asm_setupresult(as, ir, ci);  /* GCcdata * */
   asm_setupresult(as, ir, ci);  /* GCcdata * */
@@ -1810,7 +1827,7 @@ static void asm_cnew(ASMState *as, IRIns *ir)
     int32_t ofs = sizeof(GCcdata);
     int32_t ofs = sizeof(GCcdata);
     if (sz == 8) {
     if (sz == 8) {
       ofs += 4; ir++;
       ofs += 4; ir++;
-      lua_assert(ir->o == IR_HIOP);
+      lj_assertA(ir->o == IR_HIOP, "missing CNEWI HIOP");
     }
     }
     do {
     do {
       if (irref_isk(ir->op2)) {
       if (irref_isk(ir->op2)) {
@@ -1824,7 +1841,7 @@ static void asm_cnew(ASMState *as, IRIns *ir)
       ofs -= 4; ir--;
       ofs -= 4; ir--;
     } while (1);
     } while (1);
 #endif
 #endif
-    lua_assert(sz == 4 || sz == 8);
+    lj_assertA(sz == 4 || sz == 8, "bad CNEWI size %d", sz);
   } else if (ir->op2 != REF_NIL) {  /* Create VLA/VLS/aligned cdata. */
   } else if (ir->op2 != REF_NIL) {  /* Create VLA/VLS/aligned cdata. */
     ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv];
     ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv];
     args[0] = ASMREF_L;     /* lua_State *L */
     args[0] = ASMREF_L;     /* lua_State *L */
@@ -1848,8 +1865,6 @@ static void asm_cnew(ASMState *as, IRIns *ir)
   asm_gencall(as, ci, args);
   asm_gencall(as, ci, args);
   emit_loadi(as, ra_releasetmp(as, ASMREF_TMP1), (int32_t)(sz+sizeof(GCcdata)));
   emit_loadi(as, ra_releasetmp(as, ASMREF_TMP1), (int32_t)(sz+sizeof(GCcdata)));
 }
 }
-#else
-#define asm_cnew(as, ir)	((void)0)
 #endif
 #endif
 
 
 /* -- Write barriers ------------------------------------------------------ */
 /* -- Write barriers ------------------------------------------------------ */
@@ -1876,7 +1891,7 @@ static void asm_obar(ASMState *as, IRIns *ir)
   MCLabel l_end;
   MCLabel l_end;
   Reg obj;
   Reg obj;
   /* No need for other object barriers (yet). */
   /* No need for other object barriers (yet). */
-  lua_assert(IR(ir->op1)->o == IR_UREFC);
+  lj_assertA(IR(ir->op1)->o == IR_UREFC, "bad OBAR type");
   ra_evictset(as, RSET_SCRATCH);
   ra_evictset(as, RSET_SCRATCH);
   l_end = emit_label(as);
   l_end = emit_label(as);
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[0] = ASMREF_TMP1;  /* global_State *g */
@@ -1955,15 +1970,11 @@ static void asm_fpmath(ASMState *as, IRIns *ir)
 		    fpm == IRFPM_CEIL ? lj_vm_ceil_sse : lj_vm_trunc_sse);
 		    fpm == IRFPM_CEIL ? lj_vm_ceil_sse : lj_vm_trunc_sse);
       ra_left(as, RID_XMM0, ir->op1);
       ra_left(as, RID_XMM0, ir->op1);
     }
     }
-  } else if (fpm == IRFPM_EXP2 && asm_fpjoin_pow(as, ir)) {
-    /* Rejoined to pow(). */
   } else {
   } else {
     asm_callid(as, ir, IRCALL_lj_vm_floor + fpm);
     asm_callid(as, ir, IRCALL_lj_vm_floor + fpm);
   }
   }
 }
 }
 
 
-#define asm_atan2(as, ir)	asm_callid(as, ir, IRCALL_atan2)
-
 static void asm_ldexp(ASMState *as, IRIns *ir)
 static void asm_ldexp(ASMState *as, IRIns *ir)
 {
 {
   int32_t ofs = sps_scale(ir->s);  /* Use spill slot or temp slots. */
   int32_t ofs = sps_scale(ir->s);  /* Use spill slot or temp slots. */
@@ -1993,22 +2004,11 @@ static void asm_fppowi(ASMState *as, IRIns *ir)
   ra_left(as, RID_EAX, ir->op2);
   ra_left(as, RID_EAX, ir->op2);
 }
 }
 
 
-static void asm_pow(ASMState *as, IRIns *ir)
-{
-#if LJ_64 && LJ_HASFFI
-  if (!irt_isnum(ir->t))
-    asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 :
-					  IRCALL_lj_carith_powu64);
-  else
-#endif
-    asm_fppowi(as, ir);
-}
-
 static int asm_swapops(ASMState *as, IRIns *ir)
 static int asm_swapops(ASMState *as, IRIns *ir)
 {
 {
   IRIns *irl = IR(ir->op1);
   IRIns *irl = IR(ir->op1);
   IRIns *irr = IR(ir->op2);
   IRIns *irr = IR(ir->op2);
-  lua_assert(ra_noreg(irr->r));
+  lj_assertA(ra_noreg(irr->r), "bad usage");
   if (!irm_iscomm(lj_ir_mode[ir->o]))
   if (!irm_iscomm(lj_ir_mode[ir->o]))
     return 0;  /* Can't swap non-commutative operations. */
     return 0;  /* Can't swap non-commutative operations. */
   if (irref_isk(ir->op2))
   if (irref_isk(ir->op2))
@@ -2061,8 +2061,9 @@ static void asm_intarith(ASMState *as, IRIns *ir, x86Arith xa)
   int32_t k = 0;
   int32_t k = 0;
   if (as->flagmcp == as->mcp) {  /* Drop test r,r instruction. */
   if (as->flagmcp == as->mcp) {  /* Drop test r,r instruction. */
     MCode *p = 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 */
+    MCode *q = p[0] == 0x0f ? p+1 : p;
+    if ((*q & 15) < 14) {
+      if ((*q & 15) >= 12) *q -= 4;  /* L <->S, NL <-> NS */
       as->flagmcp = NULL;
       as->flagmcp = NULL;
       as->mcp = p;
       as->mcp = p;
     }  /* else: cannot transform LE/NLE to cc without use of OF. */
     }  /* else: cannot transform LE/NLE to cc without use of OF. */
@@ -2179,8 +2180,7 @@ static void asm_add(ASMState *as, IRIns *ir)
 {
 {
   if (irt_isnum(ir->t))
   if (irt_isnum(ir->t))
     asm_fparith(as, ir, XO_ADDSD);
     asm_fparith(as, ir, XO_ADDSD);
-  else if ((as->flags & JIT_F_LEA_AGU) || as->flagmcp == as->mcp ||
-	   irt_is64(ir->t) || !asm_lea(as, ir))
+  else if (as->flagmcp == as->mcp || irt_is64(ir->t) || !asm_lea(as, ir))
     asm_intarith(as, ir, XOg_ADD);
     asm_intarith(as, ir, XOg_ADD);
 }
 }
 
 
@@ -2200,27 +2200,7 @@ static void asm_mul(ASMState *as, IRIns *ir)
     asm_intarith(as, ir, XOg_X_IMUL);
     asm_intarith(as, ir, XOg_X_IMUL);
 }
 }
 
 
-static void asm_div(ASMState *as, IRIns *ir)
-{
-#if LJ_64 && LJ_HASFFI
-  if (!irt_isnum(ir->t))
-    asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_divi64 :
-					  IRCALL_lj_carith_divu64);
-  else
-#endif
-    asm_fparith(as, ir, XO_DIVSD);
-}
-
-static void asm_mod(ASMState *as, IRIns *ir)
-{
-#if LJ_64 && LJ_HASFFI
-  if (!irt_isint(ir->t))
-    asm_callid(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_modi64 :
-					  IRCALL_lj_carith_modu64);
-  else
-#endif
-    asm_callid(as, ir, IRCALL_lj_vm_modi);
-}
+#define asm_fpdiv(as, ir)	asm_fparith(as, ir, XO_DIVSD)
 
 
 static void asm_neg_not(ASMState *as, IRIns *ir, x86Group3 xg)
 static void asm_neg_not(ASMState *as, IRIns *ir, x86Group3 xg)
 {
 {
@@ -2320,7 +2300,7 @@ static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs, x86Op xv)
     dest = ra_dest(as, ir, rset_exclude(RSET_GPR, RID_ECX));
     dest = ra_dest(as, ir, rset_exclude(RSET_GPR, RID_ECX));
     if (dest == RID_ECX) {
     if (dest == RID_ECX) {
       dest = ra_scratch(as, rset_exclude(RSET_GPR, RID_ECX));
       dest = ra_scratch(as, rset_exclude(RSET_GPR, RID_ECX));
-      emit_rr(as, XO_MOV, RID_ECX, dest);
+      emit_rr(as, XO_MOV, REX_64IR(ir, RID_ECX), dest);
     }
     }
     right = irr->r;
     right = irr->r;
     if (ra_noreg(right))
     if (ra_noreg(right))
@@ -2418,8 +2398,9 @@ static void asm_comp(ASMState *as, IRIns *ir)
     IROp leftop = (IROp)(IR(lref)->o);
     IROp leftop = (IROp)(IR(lref)->o);
     Reg r64 = REX_64IR(ir, 0);
     Reg r64 = REX_64IR(ir, 0);
     int32_t imm = 0;
     int32_t imm = 0;
-    lua_assert(irt_is64(ir->t) || irt_isint(ir->t) ||
-	       irt_isu32(ir->t) || irt_isaddr(ir->t) || irt_isu8(ir->t));
+    lj_assertA(irt_is64(ir->t) || irt_isint(ir->t) ||
+	       irt_isu32(ir->t) || irt_isaddr(ir->t) || irt_isu8(ir->t),
+	       "bad comparison data type %d", irt_type(ir->t));
     /* Swap constants (only for ABC) and fusable loads to the right. */
     /* Swap constants (only for ABC) and fusable loads to the right. */
     if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) {
     if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) {
       if ((cc & 0xc) == 0xc) cc ^= 0x53;  /* L <-> G, LE <-> GE */
       if ((cc & 0xc) == 0xc) cc ^= 0x53;  /* L <-> G, LE <-> GE */
@@ -2501,7 +2482,7 @@ static void asm_comp(ASMState *as, IRIns *ir)
 	  /* Use test r,r instead of cmp r,0. */
 	  /* Use test r,r instead of cmp r,0. */
 	  x86Op xo = XO_TEST;
 	  x86Op xo = XO_TEST;
 	  if (irt_isu8(ir->t)) {
 	  if (irt_isu8(ir->t)) {
-	    lua_assert(ir->o == IR_EQ || ir->o == IR_NE);
+	    lj_assertA(ir->o == IR_EQ || ir->o == IR_NE, "bad usage");
 	    xo = XO_TESTb;
 	    xo = XO_TESTb;
 	    if (!rset_test(RSET_RANGE(RID_EAX, RID_EBX+1), left)) {
 	    if (!rset_test(RSET_RANGE(RID_EAX, RID_EBX+1), left)) {
 	      if (LJ_64) {
 	      if (LJ_64) {
@@ -2657,10 +2638,11 @@ static void asm_hiop(ASMState *as, IRIns *ir)
   case IR_CNEWI:
   case IR_CNEWI:
     /* Nothing to do here. Handled by CNEWI itself. */
     /* Nothing to do here. Handled by CNEWI itself. */
     break;
     break;
-  default: lua_assert(0); break;
+  default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
   }
   }
 #else
 #else
-  UNUSED(as); UNUSED(ir); lua_assert(0);  /* Unused on x64 or without FFI. */
+  /* Unused on x64 or without FFI. */
+  UNUSED(as); UNUSED(ir); lj_assertA(0, "unexpected HIOP");
 #endif
 #endif
 }
 }
 
 
@@ -2726,8 +2708,9 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
       Reg src = ra_alloc1(as, ref, RSET_FPR);
       Reg src = ra_alloc1(as, ref, RSET_FPR);
       emit_rmro(as, XO_MOVSDto, src, RID_BASE, ofs);
       emit_rmro(as, XO_MOVSDto, src, RID_BASE, ofs);
     } else {
     } else {
-      lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) ||
-		 (LJ_DUALNUM && irt_isinteger(ir->t)));
+      lj_assertA(irt_ispri(ir->t) || irt_isaddr(ir->t) ||
+		 (LJ_DUALNUM && irt_isinteger(ir->t)),
+		 "restore of IR type %d", irt_type(ir->t));
       if (!irref_isk(ref)) {
       if (!irref_isk(ref)) {
 	Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE));
 	Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE));
 #if LJ_GC64
 #if LJ_GC64
@@ -2772,7 +2755,7 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
     }
     }
     checkmclim(as);
     checkmclim(as);
   }
   }
-  lua_assert(map + nent == flinks);
+  lj_assertA(map + nent == flinks, "inconsistent frames in snapshot");
 }
 }
 
 
 /* -- GC handling --------------------------------------------------------- */
 /* -- GC handling --------------------------------------------------------- */
@@ -2816,16 +2799,16 @@ static void asm_loop_fixup(ASMState *as)
   MCode *target = as->mcp;
   MCode *target = as->mcp;
   if (as->realign) {  /* Realigned loops use short jumps. */
   if (as->realign) {  /* Realigned loops use short jumps. */
     as->realign = NULL;  /* Stop another retry. */
     as->realign = NULL;  /* Stop another retry. */
-    lua_assert(((intptr_t)target & 15) == 0);
+    lj_assertA(((intptr_t)target & 15) == 0, "loop realign failed");
     if (as->loopinv) {  /* Inverted loop branch? */
     if (as->loopinv) {  /* Inverted loop branch? */
       p -= 5;
       p -= 5;
       p[0] = XI_JMP;
       p[0] = XI_JMP;
-      lua_assert(target - p >= -128);
+      lj_assertA(target - p >= -128, "loop realign failed");
       p[-1] = (MCode)(target - p);  /* Patch sjcc. */
       p[-1] = (MCode)(target - p);  /* Patch sjcc. */
       if (as->loopinv == 2)
       if (as->loopinv == 2)
 	p[-3] = (MCode)(target - p + 2);  /* Patch opt. short jp. */
 	p[-3] = (MCode)(target - p + 2);  /* Patch opt. short jp. */
     } else {
     } else {
-      lua_assert(target - p >= -128);
+      lj_assertA(target - p >= -128, "loop realign failed");
       p[-1] = (MCode)(int8_t)(target - p);  /* Patch short jmp. */
       p[-1] = (MCode)(int8_t)(target - p);  /* Patch short jmp. */
       p[-2] = XI_JMPs;
       p[-2] = XI_JMPs;
     }
     }
@@ -2902,7 +2885,7 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk)
   MCode *target, *q;
   MCode *target, *q;
   int32_t spadj = as->T->spadjust;
   int32_t spadj = as->T->spadjust;
   if (spadj == 0) {
   if (spadj == 0) {
-    p -= ((as->flags & JIT_F_LEA_AGU) ? 7 : 6) + (LJ_64 ? 1 : 0);
+    p -= LJ_64 ? 7 : 6;
   } else {
   } else {
     MCode *p1;
     MCode *p1;
     /* Patch stack adjustment. */
     /* Patch stack adjustment. */
@@ -2914,24 +2897,15 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk)
       p1 = p-9;
       p1 = p-9;
       *(int32_t *)p1 = spadj;
       *(int32_t *)p1 = spadj;
     }
     }
-    if ((as->flags & JIT_F_LEA_AGU)) {
 #if LJ_64
 #if LJ_64
-      p1[-4] = 0x48;
+    p1[-3] = 0x48;
 #endif
 #endif
-      p1[-3] = (MCode)XI_LEA;
-      p1[-2] = MODRM(checki8(spadj) ? XM_OFS8 : XM_OFS32, RID_ESP, RID_ESP);
-      p1[-1] = MODRM(XM_SCALE1, RID_ESP, RID_ESP);
-    } else {
-#if LJ_64
-      p1[-3] = 0x48;
-#endif
-      p1[-2] = (MCode)(checki8(spadj) ? XI_ARITHi8 : XI_ARITHi);
-      p1[-1] = MODRM(XM_REG, XOg_ADD, RID_ESP);
-    }
+    p1[-2] = (MCode)(checki8(spadj) ? XI_ARITHi8 : XI_ARITHi);
+    p1[-1] = MODRM(XM_REG, XOg_ADD, RID_ESP);
   }
   }
   /* Patch exit branch. */
   /* Patch exit branch. */
   target = lnk ? traceref(as->J, lnk)->mcode : (MCode *)lj_vm_exit_interp;
   target = lnk ? traceref(as->J, lnk)->mcode : (MCode *)lj_vm_exit_interp;
-  *(int32_t *)(p-4) = jmprel(p, target);
+  *(int32_t *)(p-4) = jmprel(as->J, p, target);
   p[-5] = XI_JMP;
   p[-5] = XI_JMP;
   /* Drop unused mcode tail. Fill with NOPs to make the prefetcher happy. */
   /* Drop unused mcode tail. Fill with NOPs to make the prefetcher happy. */
   for (q = as->mctop-1; q >= p; q--)
   for (q = as->mctop-1; q >= p; q--)
@@ -2958,7 +2932,7 @@ static void asm_tail_prep(ASMState *as)
     as->invmcp = as->mcp = p;
     as->invmcp = as->mcp = p;
   } else {
   } else {
     /* Leave room for ESP adjustment: add esp, imm or lea esp, [esp+imm] */
     /* Leave room for ESP adjustment: add esp, imm or lea esp, [esp+imm] */
-    as->mcp = p - (((as->flags & JIT_F_LEA_AGU) ? 7 : 6)  + (LJ_64 ? 1 : 0));
+    as->mcp = p - (LJ_64 ? 7 : 6);
     as->invmcp = NULL;
     as->invmcp = NULL;
   }
   }
 }
 }
@@ -3098,23 +3072,30 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
   MSize len = T->szmcode;
   MSize len = T->szmcode;
   MCode *px = exitstub_addr(J, exitno) - 6;
   MCode *px = exitstub_addr(J, exitno) - 6;
   MCode *pe = p+len-6;
   MCode *pe = p+len-6;
+  MCode *pgc = NULL;
 #if LJ_GC64
 #if LJ_GC64
   uint32_t statei = (uint32_t)(GG_OFS(g.vmstate) - GG_OFS(dispatch));
   uint32_t statei = (uint32_t)(GG_OFS(g.vmstate) - GG_OFS(dispatch));
 #else
 #else
   uint32_t statei = u32ptr(&J2G(J)->vmstate);
   uint32_t statei = u32ptr(&J2G(J)->vmstate);
 #endif
 #endif
   if (len > 5 && p[len-5] == XI_JMP && p+len-6 + *(int32_t *)(p+len-4) == px)
   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);
+    *(int32_t *)(p+len-4) = jmprel(J, p+len, target);
   /* Do not patch parent exit for a stack check. Skip beyond vmstate update. */
   /* Do not patch parent exit for a stack check. Skip beyond vmstate update. */
   for (; p < pe; p += asm_x86_inslen(p)) {
   for (; p < pe; p += asm_x86_inslen(p)) {
     intptr_t ofs = LJ_GC64 ? (p[0] & 0xf0) == 0x40 : LJ_64;
     intptr_t ofs = LJ_GC64 ? (p[0] & 0xf0) == 0x40 : LJ_64;
     if (*(uint32_t *)(p+2+ofs) == statei && p[ofs+LJ_GC64-LJ_64] == XI_MOVmi)
     if (*(uint32_t *)(p+2+ofs) == statei && p[ofs+LJ_GC64-LJ_64] == XI_MOVmi)
       break;
       break;
   }
   }
-  lua_assert(p < pe);
-  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);
+  lj_assertJ(p < pe, "instruction length decoder failed");
+  for (; p < pe; p += asm_x86_inslen(p)) {
+    if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px &&
+	p != pgc) {
+      *(int32_t *)(p+2) = jmprel(J, p+6, target);
+    } else if (*p == XI_CALL &&
+	      (void *)(p+5+*(int32_t *)(p+1)) == (void *)lj_gc_step_jit) {
+      pgc = p+7;  /* Do not patch GC check exit. */
+    }
+  }
   lj_mcode_sync(T->mcode, T->mcode + T->szmcode);
   lj_mcode_sync(T->mcode, T->mcode + T->szmcode);
   lj_mcode_patch(J, mcarea, 1);
   lj_mcode_patch(J, mcarea, 1);
 }
 }

+ 28 - 0
libs/LuaJIT/src/lj_assert.c

@@ -0,0 +1,28 @@
+/*
+** Internal assertions.
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#define lj_assert_c
+#define LUA_CORE
+
+#if defined(LUA_USE_ASSERT) || defined(LUA_USE_APICHECK)
+
+#include <stdio.h>
+
+#include "lj_obj.h"
+
+void lj_assert_fail(global_State *g, const char *file, int line,
+		    const char *func, const char *fmt, ...)
+{
+  va_list argp;
+  va_start(argp, fmt);
+  fprintf(stderr, "LuaJIT ASSERT %s:%d: %s: ", file, line, func);
+  vfprintf(stderr, fmt, argp);
+  fputc('\n', stderr);
+  va_end(argp);
+  UNUSED(g);  /* May be NULL. TODO: optionally dump state. */
+  abort();
+}
+
+#endif

+ 1 - 1
libs/LuaJIT/src/lj_bc.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Bytecode instruction modes.
 ** Bytecode instruction modes.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lj_bc_c
 #define lj_bc_c

+ 1 - 1
libs/LuaJIT/src/lj_bc.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** Bytecode instruction format.
 ** Bytecode instruction format.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _LJ_BC_H
 #ifndef _LJ_BC_H

+ 1 - 1
libs/LuaJIT/src/lj_bcdump.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** Bytecode dump definitions.
 ** Bytecode dump definitions.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _LJ_BCDUMP_H
 #ifndef _LJ_BCDUMP_H

+ 16 - 16
libs/LuaJIT/src/lj_bcread.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Bytecode reader.
 ** Bytecode reader.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lj_bcread_c
 #define lj_bcread_c
@@ -47,7 +47,7 @@ static LJ_NOINLINE void bcread_error(LexState *ls, ErrMsg em)
 /* Refill buffer. */
 /* Refill buffer. */
 static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
 static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
 {
 {
-  lua_assert(len != 0);
+  lj_assertLS(len != 0, "empty refill");
   if (len > LJ_MAX_BUF || ls->c < 0)
   if (len > LJ_MAX_BUF || ls->c < 0)
     bcread_error(ls, LJ_ERR_BCBAD);
     bcread_error(ls, LJ_ERR_BCBAD);
   do {
   do {
@@ -57,7 +57,7 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
     MSize n = (MSize)(ls->pe - ls->p);
     MSize n = (MSize)(ls->pe - ls->p);
     if (n) {  /* Copy remainder to buffer. */
     if (n) {  /* Copy remainder to buffer. */
       if (sbuflen(&ls->sb)) {  /* Move down in buffer. */
       if (sbuflen(&ls->sb)) {  /* Move down in buffer. */
-	lua_assert(ls->pe == sbufP(&ls->sb));
+	lj_assertLS(ls->pe == sbufP(&ls->sb), "bad buffer pointer");
 	if (ls->p != p) memmove(p, ls->p, n);
 	if (ls->p != p) memmove(p, ls->p, n);
       } else {  /* Copy from buffer provided by reader. */
       } else {  /* Copy from buffer provided by reader. */
 	p = lj_buf_need(&ls->sb, len);
 	p = lj_buf_need(&ls->sb, len);
@@ -73,6 +73,7 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
       ls->c = -1;  /* Only bad if we get called again. */
       ls->c = -1;  /* Only bad if we get called again. */
       break;
       break;
     }
     }
+    if (sz >= LJ_MAX_BUF - n) lj_err_mem(ls->L);
     if (n) {  /* Append to buffer. */
     if (n) {  /* Append to buffer. */
       n += (MSize)sz;
       n += (MSize)sz;
       p = lj_buf_need(&ls->sb, n < len ? len : n);
       p = lj_buf_need(&ls->sb, n < len ? len : n);
@@ -84,20 +85,20 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
       ls->p = buf;
       ls->p = buf;
       ls->pe = buf + sz;
       ls->pe = buf + sz;
     }
     }
-  } while (ls->p + len > ls->pe);
+  } while ((MSize)(ls->pe - ls->p) < len);
 }
 }
 
 
 /* Need a certain number of bytes. */
 /* Need a certain number of bytes. */
 static LJ_AINLINE void bcread_need(LexState *ls, MSize len)
 static LJ_AINLINE void bcread_need(LexState *ls, MSize len)
 {
 {
-  if (LJ_UNLIKELY(ls->p + len > ls->pe))
+  if (LJ_UNLIKELY((MSize)(ls->pe - ls->p) < len))
     bcread_fill(ls, len, 1);
     bcread_fill(ls, len, 1);
 }
 }
 
 
 /* Want to read up to a certain number of bytes, but may need less. */
 /* Want to read up to a certain number of bytes, but may need less. */
 static LJ_AINLINE void bcread_want(LexState *ls, MSize len)
 static LJ_AINLINE void bcread_want(LexState *ls, MSize len)
 {
 {
-  if (LJ_UNLIKELY(ls->p + len > ls->pe))
+  if (LJ_UNLIKELY((MSize)(ls->pe - ls->p) < len))
     bcread_fill(ls, len, 0);
     bcread_fill(ls, len, 0);
 }
 }
 
 
@@ -106,7 +107,7 @@ static LJ_AINLINE uint8_t *bcread_mem(LexState *ls, MSize len)
 {
 {
   uint8_t *p = (uint8_t *)ls->p;
   uint8_t *p = (uint8_t *)ls->p;
   ls->p += len;
   ls->p += len;
-  lua_assert(ls->p <= ls->pe);
+  lj_assertLS(ls->p <= ls->pe, "buffer read overflow");
   return p;
   return p;
 }
 }
 
 
@@ -119,7 +120,7 @@ static void bcread_block(LexState *ls, void *q, MSize len)
 /* Read byte from buffer. */
 /* Read byte from buffer. */
 static LJ_AINLINE uint32_t bcread_byte(LexState *ls)
 static LJ_AINLINE uint32_t bcread_byte(LexState *ls)
 {
 {
-  lua_assert(ls->p < ls->pe);
+  lj_assertLS(ls->p < ls->pe, "buffer read overflow");
   return (uint32_t)(uint8_t)*ls->p++;
   return (uint32_t)(uint8_t)*ls->p++;
 }
 }
 
 
@@ -127,7 +128,7 @@ static LJ_AINLINE uint32_t bcread_byte(LexState *ls)
 static LJ_AINLINE uint32_t bcread_uleb128(LexState *ls)
 static LJ_AINLINE uint32_t bcread_uleb128(LexState *ls)
 {
 {
   uint32_t v = lj_buf_ruleb128(&ls->p);
   uint32_t v = lj_buf_ruleb128(&ls->p);
-  lua_assert(ls->p <= ls->pe);
+  lj_assertLS(ls->p <= ls->pe, "buffer read overflow");
   return v;
   return v;
 }
 }
 
 
@@ -144,7 +145,7 @@ static uint32_t bcread_uleb128_33(LexState *ls)
    } while (*p++ >= 0x80);
    } while (*p++ >= 0x80);
   }
   }
   ls->p = (char *)p;
   ls->p = (char *)p;
-  lua_assert(ls->p <= ls->pe);
+  lj_assertLS(ls->p <= ls->pe, "buffer read overflow");
   return v;
   return v;
 }
 }
 
 
@@ -191,7 +192,7 @@ static void bcread_ktabk(LexState *ls, TValue *o)
     o->u32.lo = bcread_uleb128(ls);
     o->u32.lo = bcread_uleb128(ls);
     o->u32.hi = bcread_uleb128(ls);
     o->u32.hi = bcread_uleb128(ls);
   } else {
   } else {
-    lua_assert(tp <= BCDUMP_KTAB_TRUE);
+    lj_assertLS(tp <= BCDUMP_KTAB_TRUE, "bad constant type %d", tp);
     setpriV(o, ~tp);
     setpriV(o, ~tp);
   }
   }
 }
 }
@@ -213,7 +214,7 @@ static GCtab *bcread_ktab(LexState *ls)
     for (i = 0; i < nhash; i++) {
     for (i = 0; i < nhash; i++) {
       TValue key;
       TValue key;
       bcread_ktabk(ls, &key);
       bcread_ktabk(ls, &key);
-      lua_assert(!tvisnil(&key));
+      lj_assertLS(!tvisnil(&key), "nil key");
       bcread_ktabk(ls, lj_tab_set(ls->L, t, &key));
       bcread_ktabk(ls, lj_tab_set(ls->L, t, &key));
     }
     }
   }
   }
@@ -250,7 +251,7 @@ static void bcread_kgc(LexState *ls, GCproto *pt, MSize sizekgc)
 #endif
 #endif
     } else {
     } else {
       lua_State *L = ls->L;
       lua_State *L = ls->L;
-      lua_assert(tp == BCDUMP_KGC_CHILD);
+      lj_assertLS(tp == BCDUMP_KGC_CHILD, "bad constant type %d", tp);
       if (L->top <= bcread_oldtop(L, ls))  /* Stack underflow? */
       if (L->top <= bcread_oldtop(L, ls))  /* Stack underflow? */
 	bcread_error(ls, LJ_ERR_BCBAD);
 	bcread_error(ls, LJ_ERR_BCBAD);
       L->top--;
       L->top--;
@@ -421,7 +422,7 @@ static int bcread_header(LexState *ls)
 GCproto *lj_bcread(LexState *ls)
 GCproto *lj_bcread(LexState *ls)
 {
 {
   lua_State *L = ls->L;
   lua_State *L = ls->L;
-  lua_assert(ls->c == BCDUMP_HEAD1);
+  lj_assertLS(ls->c == BCDUMP_HEAD1, "bad bytecode header");
   bcread_savetop(L, ls, L->top);
   bcread_savetop(L, ls, L->top);
   lj_buf_reset(&ls->sb);
   lj_buf_reset(&ls->sb);
   /* Check for a valid bytecode dump header. */
   /* Check for a valid bytecode dump header. */
@@ -447,8 +448,7 @@ GCproto *lj_bcread(LexState *ls)
     setprotoV(L, L->top, pt);
     setprotoV(L, L->top, pt);
     incr_top(L);
     incr_top(L);
   }
   }
-  if ((int32_t)(2*(uint32_t)(ls->pe - ls->p)) > 0 ||
-      L->top-1 != bcread_oldtop(L, ls))
+  if ((ls->pe != ls->p && !ls->endmark) || L->top-1 != bcread_oldtop(L, ls))
     bcread_error(ls, LJ_ERR_BCBAD);
     bcread_error(ls, LJ_ERR_BCBAD);
   /* Pop off last prototype. */
   /* Pop off last prototype. */
   L->top--;
   L->top--;

+ 20 - 6
libs/LuaJIT/src/lj_bcwrite.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Bytecode writer.
 ** Bytecode writer.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lj_bcwrite_c
 #define lj_bcwrite_c
@@ -29,8 +29,17 @@ typedef struct BCWriteCtx {
   void *wdata;			/* Writer callback data. */
   void *wdata;			/* Writer callback data. */
   int strip;			/* Strip debug info. */
   int strip;			/* Strip debug info. */
   int status;			/* Status from writer callback. */
   int status;			/* Status from writer callback. */
+#ifdef LUA_USE_ASSERT
+  global_State *g;
+#endif
 } BCWriteCtx;
 } BCWriteCtx;
 
 
+#ifdef LUA_USE_ASSERT
+#define lj_assertBCW(c, ...)	lj_assertG_(ctx->g, (c), __VA_ARGS__)
+#else
+#define lj_assertBCW(c, ...)	((void)ctx)
+#endif
+
 /* -- Bytecode writer ----------------------------------------------------- */
 /* -- Bytecode writer ----------------------------------------------------- */
 
 
 /* Write a single constant key/value of a template table. */
 /* Write a single constant key/value of a template table. */
@@ -61,7 +70,7 @@ static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
     p = lj_strfmt_wuleb128(p, o->u32.lo);
     p = lj_strfmt_wuleb128(p, o->u32.lo);
     p = lj_strfmt_wuleb128(p, o->u32.hi);
     p = lj_strfmt_wuleb128(p, o->u32.hi);
   } else {
   } else {
-    lua_assert(tvispri(o));
+    lj_assertBCW(tvispri(o), "unhandled type %d", itype(o));
     *p++ = BCDUMP_KTAB_NIL+~itype(o);
     *p++ = BCDUMP_KTAB_NIL+~itype(o);
   }
   }
   setsbufP(&ctx->sb, p);
   setsbufP(&ctx->sb, p);
@@ -121,7 +130,7 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
       tp = BCDUMP_KGC_STR + gco2str(o)->len;
       tp = BCDUMP_KGC_STR + gco2str(o)->len;
       need = 5+gco2str(o)->len;
       need = 5+gco2str(o)->len;
     } else if (o->gch.gct == ~LJ_TPROTO) {
     } else if (o->gch.gct == ~LJ_TPROTO) {
-      lua_assert((pt->flags & PROTO_CHILD));
+      lj_assertBCW((pt->flags & PROTO_CHILD), "prototype has unexpected child");
       tp = BCDUMP_KGC_CHILD;
       tp = BCDUMP_KGC_CHILD;
 #if LJ_HASFFI
 #if LJ_HASFFI
     } else if (o->gch.gct == ~LJ_TCDATA) {
     } else if (o->gch.gct == ~LJ_TCDATA) {
@@ -132,12 +141,14 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
       } else if (id == CTID_UINT64) {
       } else if (id == CTID_UINT64) {
 	tp = BCDUMP_KGC_U64;
 	tp = BCDUMP_KGC_U64;
       } else {
       } else {
-	lua_assert(id == CTID_COMPLEX_DOUBLE);
+	lj_assertBCW(id == CTID_COMPLEX_DOUBLE,
+		     "bad cdata constant CTID %d", id);
 	tp = BCDUMP_KGC_COMPLEX;
 	tp = BCDUMP_KGC_COMPLEX;
       }
       }
 #endif
 #endif
     } else {
     } else {
-      lua_assert(o->gch.gct == ~LJ_TTAB);
+      lj_assertBCW(o->gch.gct == ~LJ_TTAB,
+		   "bad constant GC type %d", o->gch.gct);
       tp = BCDUMP_KGC_TAB;
       tp = BCDUMP_KGC_TAB;
       need = 1+2*5;
       need = 1+2*5;
     }
     }
@@ -289,7 +300,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
     MSize nn = (lj_fls(n)+8)*9 >> 6;
     MSize nn = (lj_fls(n)+8)*9 >> 6;
     char *q = sbufB(&ctx->sb) + (5 - nn);
     char *q = sbufB(&ctx->sb) + (5 - nn);
     p = lj_strfmt_wuleb128(q, n);  /* Fill in final size. */
     p = lj_strfmt_wuleb128(q, n);  /* Fill in final size. */
-    lua_assert(p == sbufB(&ctx->sb) + 5);
+    lj_assertBCW(p == sbufB(&ctx->sb) + 5, "bad ULEB128 write");
     ctx->status = ctx->wfunc(sbufL(&ctx->sb), q, nn+n, ctx->wdata);
     ctx->status = ctx->wfunc(sbufL(&ctx->sb), q, nn+n, ctx->wdata);
   }
   }
 }
 }
@@ -349,6 +360,9 @@ int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer, void *data,
   ctx.wdata = data;
   ctx.wdata = data;
   ctx.strip = strip;
   ctx.strip = strip;
   ctx.status = 0;
   ctx.status = 0;
+#ifdef LUA_USE_ASSERT
+  ctx.g = G(L);
+#endif
   lj_buf_init(L, &ctx.sb);
   lj_buf_init(L, &ctx.sb);
   status = lj_vm_cpcall(L, NULL, &ctx, cpwriter);
   status = lj_vm_cpcall(L, NULL, &ctx, cpwriter);
   if (status == 0) status = ctx.status;
   if (status == 0) status = ctx.status;

+ 3 - 3
libs/LuaJIT/src/lj_buf.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Buffer handling.
 ** Buffer handling.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lj_buf_c
 #define lj_buf_c
@@ -30,7 +30,7 @@ static void buf_grow(SBuf *sb, MSize sz)
 
 
 LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz)
 LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz)
 {
 {
-  lua_assert(sz > sbufsz(sb));
+  lj_assertG_(G(sbufL(sb)), sz > sbufsz(sb), "SBuf overflow");
   if (LJ_UNLIKELY(sz > LJ_MAX_BUF))
   if (LJ_UNLIKELY(sz > LJ_MAX_BUF))
     lj_err_mem(sbufL(sb));
     lj_err_mem(sbufL(sb));
   buf_grow(sb, sz);
   buf_grow(sb, sz);
@@ -40,7 +40,7 @@ LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz)
 LJ_NOINLINE char *LJ_FASTCALL lj_buf_more2(SBuf *sb, MSize sz)
 LJ_NOINLINE char *LJ_FASTCALL lj_buf_more2(SBuf *sb, MSize sz)
 {
 {
   MSize len = sbuflen(sb);
   MSize len = sbuflen(sb);
-  lua_assert(sz > sbufleft(sb));
+  lj_assertG_(G(sbufL(sb)), sz > sbufleft(sb), "SBuf overflow");
   if (LJ_UNLIKELY(sz > LJ_MAX_BUF || len + sz > LJ_MAX_BUF))
   if (LJ_UNLIKELY(sz > LJ_MAX_BUF || len + sz > LJ_MAX_BUF))
     lj_err_mem(sbufL(sb));
     lj_err_mem(sbufL(sb));
   buf_grow(sb, len + sz);
   buf_grow(sb, len + sz);

+ 1 - 1
libs/LuaJIT/src/lj_buf.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** Buffer handling.
 ** Buffer handling.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _LJ_BUF_H
 #ifndef _LJ_BUF_H

+ 9 - 14
libs/LuaJIT/src/lj_carith.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** C data arithmetic.
 ** C data arithmetic.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #include "lj_obj.h"
 #include "lj_obj.h"
@@ -122,7 +122,7 @@ static int carith_ptr(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
 	setboolV(L->top-1, ((uintptr_t)pp < (uintptr_t)pp2));
 	setboolV(L->top-1, ((uintptr_t)pp < (uintptr_t)pp2));
 	return 1;
 	return 1;
       } else {
       } else {
-	lua_assert(mm == MM_le);
+	lj_assertL(mm == MM_le, "bad metamethod %d", mm);
 	setboolV(L->top-1, ((uintptr_t)pp <= (uintptr_t)pp2));
 	setboolV(L->top-1, ((uintptr_t)pp <= (uintptr_t)pp2));
 	return 1;
 	return 1;
       }
       }
@@ -208,7 +208,9 @@ static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
 	*up = lj_carith_powu64(u0, u1);
 	*up = lj_carith_powu64(u0, u1);
       break;
       break;
     case MM_unm: *up = (uint64_t)-(int64_t)u0; break;
     case MM_unm: *up = (uint64_t)-(int64_t)u0; break;
-    default: lua_assert(0); break;
+    default:
+      lj_assertL(0, "bad metamethod %d", mm);
+      break;
     }
     }
     lj_gc_check(L);
     lj_gc_check(L);
     return 1;
     return 1;
@@ -265,7 +267,7 @@ int lj_carith_op(lua_State *L, MMS mm)
 {
 {
   CTState *cts = ctype_cts(L);
   CTState *cts = ctype_cts(L);
   CDArith ca;
   CDArith ca;
-  if (carith_checkarg(L, cts, &ca)) {
+  if (carith_checkarg(L, cts, &ca) && mm != MM_len && mm != MM_concat) {
     if (carith_int64(L, cts, &ca, mm) || carith_ptr(L, cts, &ca, mm)) {
     if (carith_int64(L, cts, &ca, mm) || carith_ptr(L, cts, &ca, mm)) {
       copyTV(L, &G(L)->tmptv2, L->top-1);  /* Remember for trace recorder. */
       copyTV(L, &G(L)->tmptv2, L->top-1);  /* Remember for trace recorder. */
       return 1;
       return 1;
@@ -274,15 +276,6 @@ int lj_carith_op(lua_State *L, MMS mm)
   return lj_carith_meta(L, cts, &ca, mm);
   return lj_carith_meta(L, cts, &ca, mm);
 }
 }
 
 
-/* No built-in functionality for length of cdata. */
-int lj_carith_len(lua_State *L)
-{
-  CTState *cts = ctype_cts(L);
-  CDArith ca;
-  carith_checkarg(L, cts, &ca);
-  return lj_carith_meta(L, cts, &ca, MM_len);
-}
-
 /* -- 64 bit bit operations helpers --------------------------------------- */
 /* -- 64 bit bit operations helpers --------------------------------------- */
 
 
 #if LJ_64
 #if LJ_64
@@ -310,7 +303,9 @@ uint64_t lj_carith_shift64(uint64_t x, int32_t sh, int op)
   case IR_BSAR-IR_BSHL: x = lj_carith_sar64(x, sh); break;
   case IR_BSAR-IR_BSHL: x = lj_carith_sar64(x, sh); break;
   case IR_BROL-IR_BSHL: x = lj_carith_rol64(x, sh); break;
   case IR_BROL-IR_BSHL: x = lj_carith_rol64(x, sh); break;
   case IR_BROR-IR_BSHL: x = lj_carith_ror64(x, sh); break;
   case IR_BROR-IR_BSHL: x = lj_carith_ror64(x, sh); break;
-  default: lua_assert(0); break;
+  default:
+    lj_assertX(0, "bad shift op %d", op);
+    break;
   }
   }
   return x;
   return x;
 }
 }

+ 1 - 2
libs/LuaJIT/src/lj_carith.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** C data arithmetic.
 ** C data arithmetic.
-** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _LJ_CARITH_H
 #ifndef _LJ_CARITH_H
@@ -11,7 +11,6 @@
 #if LJ_HASFFI
 #if LJ_HASFFI
 
 
 LJ_FUNC int lj_carith_op(lua_State *L, MMS mm);
 LJ_FUNC int lj_carith_op(lua_State *L, MMS mm);
-LJ_FUNC int lj_carith_len(lua_State *L);
 
 
 #if LJ_32
 #if LJ_32
 LJ_FUNC uint64_t lj_carith_shl64(uint64_t x, int32_t sh);
 LJ_FUNC uint64_t lj_carith_shl64(uint64_t x, int32_t sh);

Some files were not shown because too many files changed in this diff