Browse Source

Update LuaJIT to the latest 2.1.0 source (f3c8569)

Alex Szpakowski 4 years ago
parent
commit
c3986a9541
100 changed files with 2627 additions and 958 deletions
  1. 1 1
      CMakeLists.txt
  2. 1 1
      libs/LuaJIT/COPYRIGHT
  3. 1 1
      libs/LuaJIT/Makefile
  4. 1 1
      libs/LuaJIT/README
  5. 1 1
      libs/LuaJIT/doc/bluequad-print.css
  6. 1 1
      libs/LuaJIT/doc/bluequad.css
  7. 7 5
      libs/LuaJIT/doc/contact.html
  8. 693 0
      libs/LuaJIT/doc/ext_buffer.html
  9. 6 4
      libs/LuaJIT/doc/ext_c_api.html
  10. 6 4
      libs/LuaJIT/doc/ext_ffi.html
  11. 6 4
      libs/LuaJIT/doc/ext_ffi_api.html
  12. 6 4
      libs/LuaJIT/doc/ext_ffi_semantics.html
  13. 6 4
      libs/LuaJIT/doc/ext_ffi_tutorial.html
  14. 7 5
      libs/LuaJIT/doc/ext_jit.html
  15. 6 4
      libs/LuaJIT/doc/ext_profiler.html
  16. 15 21
      libs/LuaJIT/doc/extensions.html
  17. 42 47
      libs/LuaJIT/doc/faq.html
  18. 38 33
      libs/LuaJIT/doc/install.html
  19. 8 6
      libs/LuaJIT/doc/luajit.html
  20. 8 6
      libs/LuaJIT/doc/running.html
  21. 15 14
      libs/LuaJIT/doc/status.html
  22. 6 3
      libs/LuaJIT/dynasm/dasm_arm.h
  23. 4 4
      libs/LuaJIT/dynasm/dasm_arm.lua
  24. 51 9
      libs/LuaJIT/dynasm/dasm_arm64.h
  25. 95 42
      libs/LuaJIT/dynasm/dasm_arm64.lua
  26. 6 3
      libs/LuaJIT/dynasm/dasm_mips.h
  27. 4 4
      libs/LuaJIT/dynasm/dasm_mips.lua
  28. 1 1
      libs/LuaJIT/dynasm/dasm_mips64.lua
  29. 6 3
      libs/LuaJIT/dynasm/dasm_ppc.h
  30. 4 4
      libs/LuaJIT/dynasm/dasm_ppc.lua
  31. 3 3
      libs/LuaJIT/dynasm/dasm_proto.h
  32. 1 1
      libs/LuaJIT/dynasm/dasm_x64.lua
  33. 21 5
      libs/LuaJIT/dynasm/dasm_x86.h
  34. 40 12
      libs/LuaJIT/dynasm/dasm_x86.lua
  35. 5 5
      libs/LuaJIT/dynasm/dynasm.lua
  36. 1 1
      libs/LuaJIT/etc/luajit.1
  37. 15 8
      libs/LuaJIT/src/Makefile
  38. 41 33
      libs/LuaJIT/src/Makefile.dep
  39. 1 1
      libs/LuaJIT/src/host/buildvm.c
  40. 1 1
      libs/LuaJIT/src/host/buildvm.h
  41. 1 1
      libs/LuaJIT/src/host/buildvm_asm.c
  42. 1 1
      libs/LuaJIT/src/host/buildvm_fold.c
  43. 3 1
      libs/LuaJIT/src/host/buildvm_lib.c
  44. 1 1
      libs/LuaJIT/src/host/buildvm_peobj.c
  45. 1 1
      libs/LuaJIT/src/host/genlibbc.lua
  46. 1 1
      libs/LuaJIT/src/host/genminilua.lua
  47. 1 1
      libs/LuaJIT/src/host/minilua.c
  48. 1 1
      libs/LuaJIT/src/jit/bc.lua
  49. 1 1
      libs/LuaJIT/src/jit/bcsave.lua
  50. 1 1
      libs/LuaJIT/src/jit/dis_arm.lua
  51. 2 2
      libs/LuaJIT/src/jit/dis_arm64.lua
  52. 1 1
      libs/LuaJIT/src/jit/dis_arm64be.lua
  53. 1 1
      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. 1 1
      libs/LuaJIT/src/jit/dis_mips64r6.lua
  57. 1 1
      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. 26 14
      libs/LuaJIT/src/jit/dump.lua
  63. 2 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. 1 1
      libs/LuaJIT/src/lib_aux.c
  67. 19 5
      libs/LuaJIT/src/lib_base.c
  68. 1 1
      libs/LuaJIT/src/lib_bit.c
  69. 356 0
      libs/LuaJIT/src/lib_buffer.c
  70. 1 1
      libs/LuaJIT/src/lib_debug.c
  71. 2 1
      libs/LuaJIT/src/lib_ffi.c
  72. 1 1
      libs/LuaJIT/src/lib_init.c
  73. 20 14
      libs/LuaJIT/src/lib_io.c
  74. 2 6
      libs/LuaJIT/src/lib_jit.c
  75. 1 1
      libs/LuaJIT/src/lib_math.c
  76. 1 1
      libs/LuaJIT/src/lib_os.c
  77. 1 1
      libs/LuaJIT/src/lib_package.c
  78. 9 81
      libs/LuaJIT/src/lib_string.c
  79. 2 2
      libs/LuaJIT/src/lib_table.c
  80. 1 1
      libs/LuaJIT/src/lj_alloc.c
  81. 8 32
      libs/LuaJIT/src/lj_api.c
  82. 36 18
      libs/LuaJIT/src/lj_arch.h
  83. 155 63
      libs/LuaJIT/src/lj_asm.c
  84. 1 1
      libs/LuaJIT/src/lj_asm.h
  85. 90 39
      libs/LuaJIT/src/lj_asm_arm.h
  86. 79 36
      libs/LuaJIT/src/lj_asm_arm64.h
  87. 142 92
      libs/LuaJIT/src/lj_asm_mips.h
  88. 91 41
      libs/LuaJIT/src/lj_asm_ppc.h
  89. 94 56
      libs/LuaJIT/src/lj_asm_x86.h
  90. 1 1
      libs/LuaJIT/src/lj_assert.c
  91. 1 1
      libs/LuaJIT/src/lj_bc.c
  92. 1 1
      libs/LuaJIT/src/lj_bc.h
  93. 1 1
      libs/LuaJIT/src/lj_bcdump.h
  94. 7 11
      libs/LuaJIT/src/lj_bcread.c
  95. 12 12
      libs/LuaJIT/src/lj_bcwrite.c
  96. 133 60
      libs/LuaJIT/src/lj_buf.c
  97. 115 20
      libs/LuaJIT/src/lj_buf.h
  98. 1 1
      libs/LuaJIT/src/lj_carith.c
  99. 1 1
      libs/LuaJIT/src/lj_carith.h
  100. 5 5
      libs/LuaJIT/src/lj_ccall.c

+ 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-1d8b747")
+set(MEGA_LUAJIT_VER "2.1.0-f3c8569")
 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")

+ 1 - 1
libs/LuaJIT/COPYRIGHT

@@ -1,7 +1,7 @@
 ===============================================================================
 ===============================================================================
 LuaJIT -- a Just-In-Time Compiler for Lua. https://luajit.org/
 LuaJIT -- a Just-In-Time Compiler for Lua. https://luajit.org/
 
 
-Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+Copyright (C) 2005-2021 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

+ 1 - 1
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-2020 Mike Pall. See Copyright Notice in luajit.h
+# Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 ##############################################################################
 ##############################################################################
 
 
 MAJVER=  2
 MAJVER=  2

+ 1 - 1
libs/LuaJIT/README

@@ -5,7 +5,7 @@ LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
 
 
 Project Homepage: https://luajit.org/
 Project Homepage: https://luajit.org/
 
 
-LuaJIT is Copyright (C) 2005-2020 Mike Pall.
+LuaJIT is Copyright (C) 2005-2021 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-2020 Mike Pall.
+/* Copyright (C) 2004-2021 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-2020 Mike Pall.
+/* Copyright (C) 2004-2021 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.

+ 7 - 5
libs/LuaJIT/doc/contact.html

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
 <title>Contact</title>
 <title>Contact</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -37,6 +37,8 @@
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -87,7 +89,7 @@ xD("fyZKB8xv\"FJytmz8.KAB0u52D")
 <h2>Copyright</h2>
 <h2>Copyright</h2>
 <p>
 <p>
 All documentation is
 All documentation is
-Copyright &copy; 2005-2020 Mike Pall.
+Copyright &copy; 2005-2021 Mike Pall.
 </p>
 </p>
 
 
 
 
@@ -95,7 +97,7 @@ Copyright &copy; 2005-2020 Mike Pall.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 693 - 0
libs/LuaJIT/doc/ext_buffer.html

@@ -0,0 +1,693 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>String Buffer Library</title>
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
+<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">
+.lib {
+  vertical-align: middle;
+  margin-left: 5px;
+  padding: 0 5px;
+  font-size: 60%;
+  border-radius: 5px;
+  background: #c5d5ff;
+  color: #000;
+}
+</style>
+</head>
+<body>
+<div id="site">
+<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
+</div>
+<div id="head">
+<h1>String Buffer Library</h1>
+</div>
+<div id="nav">
+<ul><li>
+<a href="luajit.html">LuaJIT</a>
+<ul><li>
+<a href="https://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 class="current" href="ext_buffer.html">String Buffers</a>
+</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>
+</li><li>
+<a href="faq.html">FAQ</a>
+</li><li>
+<a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
+</li><li>
+<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
+</li></ul>
+</div>
+<div id="main">
+<p>
+The string buffer library allows <b>high-performance manipulation of
+string-like data</b>.
+</p>
+<p>
+Unlike Lua strings, which are constants, string buffers are
+<b>mutable</b> sequences of 8-bit (binary-transparent) characters. Data
+can be stored, formatted and encoded into a string buffer and later
+converted, extracted or decoded.
+</p>
+<p>
+The convenient string buffer API simplifies common string manipulation
+tasks, that would otherwise require creating many intermediate strings.
+String buffers improve performance by eliminating redundant memory
+copies, object creation, string interning and garbage collection
+overhead. In conjunction with the FFI library, they allow zero-copy
+operations.
+</p>
+<p>
+The string buffer libary also includes a high-performance
+<a href="serialize">serializer</a> for Lua objects.
+</p>
+
+<h2 id="wip" style="color:#ff0000">Work in Progress</h2>
+<p>
+<b style="color:#ff0000">This library is a work in progress. More
+functionality will be added soon.</b>
+</p>
+
+<h2 id="use">Using the String Buffer Library</h2>
+<p>
+The string buffer library is built into LuaJIT by default, but it's not
+loaded by default. Add this to the start of every Lua file that needs
+one of its functions:
+</p>
+<pre class="code">
+local buffer = require("string.buffer")
+</pre>
+<p>
+The convention for the syntax shown on this page is that <tt>buffer</tt>
+refers to the buffer library and <tt>buf</tt> refers to an individual
+buffer object.
+</p>
+<p>
+Please note the difference between a Lua function call, e.g.
+<tt>buffer.new()</tt> (with a dot) and a Lua method call, e.g.
+<tt>buf:reset()</tt> (with a colon).
+</p>
+
+<h3 id="buffer_object">Buffer Objects</h3>
+<p>
+A buffer object is a garbage-collected Lua object. After creation with
+<tt>buffer.new()</tt>, it can (and should) be reused for many operations.
+When the last reference to a buffer object is gone, it will eventually
+be freed by the garbage collector, along with the allocated buffer
+space.
+</p>
+<p>
+Buffers operate like a FIFO (first-in first-out) data structure. Data
+can be appended (written) to the end of the buffer and consumed (read)
+from the front of the buffer. These operations may be freely mixed.
+</p>
+<p>
+The buffer space that holds the characters is managed automatically
+&mdash; it grows as needed and already consumed space is recycled. Use
+<tt>buffer.new(size)</tt> and <tt>buf:free()</tt>, if you need more
+control.
+</p>
+<p>
+The maximum size of a single buffer is the same as the maximum size of a
+Lua string, which is slightly below two gigabytes. For huge data sizes,
+neither strings nor buffers are the right data structure &mdash; use the
+FFI library to directly map memory or files up to the virtual memory
+limit of your OS.
+</p>
+
+<h3 id="buffer_overview">Buffer Method Overview</h3>
+<ul>
+<li>
+The <tt>buf:put*()</tt>-like methods append (write) characters to the
+end of the buffer.
+</li>
+<li>
+The <tt>buf:get*()</tt>-like methods consume (read) characters from the
+front of the buffer.
+</li>
+<li>
+Other methods, like <tt>buf:tostring()</tt> only read the buffer
+contents, but don't change the buffer.
+</li>
+<li>
+The <tt>buf:set()</tt> method allows zero-copy consumption of a string
+or an FFI cdata object as a buffer.
+</li>
+<li>
+The FFI-specific methods allow zero-copy read/write-style operations or
+modifying the buffer contents in-place. Please check the
+<a href="#ffi_caveats">FFI caveats</a> below, too.
+</li>
+<li>
+Methods that don't need to return anything specific, return the buffer
+object itself as a convenience. This allows method chaining, e.g.:
+<tt>buf:reset():encode(obj)</tt> or <tt>buf:skip(len):get()</tt>
+</li>
+</ul>
+
+<h2 id="create">Buffer Creation and Management</h2>
+
+<h3 id="buffer_new"><tt>local buf = buffer.new([size [,options]])<br>
+local buf = buffer.new([options])</tt></h3>
+<p>
+Creates a new buffer object.
+</p>
+<p>
+The optional <tt>size</tt> argument ensures a minimum initial buffer
+size. This is strictly an optimization when the required buffer size is
+known beforehand. The buffer space will grow as needed, in any case.
+</p>
+<p>
+The optional table <tt>options</tt> sets various
+<a href="#serialize_options">serialization options</a>.
+</p>
+
+<h3 id="buffer_reset"><tt>buf = buf:reset()</tt></h3>
+<p>
+Reset (empty) the buffer. The allocated buffer space is not freed and
+may be reused.
+</p>
+
+<h3 id="buffer_free"><tt>buf = buf:free()</tt></h3>
+<p>
+The buffer space of the buffer object is freed. The object itself
+remains intact, empty and may be reused.
+</p>
+<p>
+Note: you normally don't need to use this method. The garbage collector
+automatically frees the buffer space, when the buffer object is
+collected. Use this method, if you need to free the associated memory
+immediately.
+</p>
+
+<h2 id="write">Buffer Writers</h2>
+
+<h3 id="buffer_put"><tt>buf = buf:put([str|num|obj] [,…])</tt></h3>
+<p>
+Appends a string <tt>str</tt>, a number <tt>num</tt> or any object
+<tt>obj</tt> with a <tt>__tostring</tt> metamethod to the buffer.
+Multiple arguments are appended in the given order.
+</p>
+<p>
+Appending a buffer to a buffer is possible and short-circuited
+internally. But it still involves a copy. Better combine the buffer
+writes to use a single buffer.
+</p>
+
+<h3 id="buffer_putf"><tt>buf = buf:putf(format, …)</tt></h3>
+<p>
+Appends the formatted arguments to the buffer. The <tt>format</tt>
+string supports the same options as <tt>string.format()</tt>.
+</p>
+
+<h3 id="buffer_putcdata"><tt>buf = buf:putcdata(cdata, len)</tt><span class="lib">FFI</span></h3>
+<p>
+Appends the given <tt>len</tt> number of bytes from the memory pointed
+to by the FFI <tt>cdata</tt> object to the buffer. The object needs to
+be convertible to a (constant) pointer.
+</p>
+
+<h3 id="buffer_set"><tt>buf = buf:set(str)<br>
+buf = buf:set(cdata, len)</tt><span class="lib">FFI</span></h3>
+<p>
+This method allows zero-copy consumption of a string or an FFI cdata
+object as a buffer. It stores a reference to the passed string
+<tt>str</tt> or the FFI <tt>cdata</tt> object in the buffer. Any buffer
+space originally allocated is freed. This is <i>not</i> an append
+operation, unlike the <tt>buf:put*()</tt> methods.
+</p>
+<p>
+After calling this method, the buffer behaves as if
+<tt>buf:free():put(str)</tt> or <tt>buf:free():put(cdata,&nbsp;len)</tt>
+had been called. However, the data is only referenced and not copied, as
+long as the buffer is only consumed.
+</p>
+<p>
+In case the buffer is written to later on, the referenced data is copied
+and the object reference is removed (copy-on-write semantics).
+</p>
+<p>
+The stored reference is an anchor for the garbage collector and keeps the
+originally passed string or FFI cdata object alive.
+</p>
+
+<h3 id="buffer_reserve"><tt>ptr, len = buf:reserve(size)</tt><span class="lib">FFI</span><br>
+<tt>buf = buf:commit(used)</tt><span class="lib">FFI</span></h3>
+<p>
+The <tt>reserve</tt> method reserves at least <tt>size</tt> bytes of
+write space in the buffer. It returns an <tt>uint8_t&nbsp;*</tt> FFI
+cdata pointer <tt>ptr</tt> that points to this space.
+</p>
+<p>
+The available length in bytes is returned in <tt>len</tt>. This is at
+least <tt>size</tt> bytes, but may be more to facilitate efficient
+buffer growth. You can either make use of the additional space or ignore
+<tt>len</tt> and only use <tt>size</tt> bytes.
+</p>
+<p>
+The <tt>commit</tt> method appends the <tt>used</tt> bytes of the
+previously returned write space to the buffer data.
+</p>
+<p>
+This pair of methods allows zero-copy use of C read-style APIs:
+</p>
+<pre class="code">
+local MIN_SIZE = 65536
+repeat
+  local ptr, len = buf:reserve(MIN_SIZE)
+  local n = C.read(fd, ptr, len)
+  if n == 0 then break end -- EOF.
+  if n &lt; 0 then error("read error") end
+  buf:commit(n)
+until false
+</pre>
+<p>
+The reserved write space is <i>not</i> initialized. At least the
+<tt>used</tt> bytes <b>must</b> be written to before calling the
+<tt>commit</tt> method. There's no need to call the <tt>commit</tt>
+method, if nothing is added to the buffer (e.g. on error).
+</p>
+
+<h2 id="read">Buffer Readers</h2>
+
+<h3 id="buffer_length"><tt>len = #buf</tt></h3>
+<p>
+Returns the current length of the buffer data in bytes.
+</p>
+
+<h3 id="buffer_concat"><tt>res = str|num|buf .. str|num|buf […]</tt></h3>
+<p>
+The Lua concatenation operator <tt>..</tt> also accepts buffers, just
+like strings or numbers. It always returns a string and not a buffer.
+</p>
+<p>
+Note that although this is supported for convenience, this thwarts one
+of the main reasons to use buffers, which is to avoid string
+allocations. Rewrite it with <tt>buf:put()</tt> and <tt>buf:get()</tt>.
+</p>
+<p>
+Mixing this with unrelated objects that have a <tt>__concat</tt>
+metamethod may not work, since these probably only expect strings.
+</p>
+
+<h3 id="buffer_skip"><tt>buf = buf:skip(len)</tt></h3>
+<p>
+Skips (consumes) <tt>len</tt> bytes from the buffer up to the current
+length of the buffer data.
+</p>
+
+<h3 id="buffer_get"><tt>str, … = buf:get([len|nil] [,…])</tt></h3>
+<p>
+Consumes the buffer data and returns one or more strings. If called
+without arguments, the whole buffer data is consumed. If called with a
+number, up to <tt>len</tt> bytes are consumed. A <tt>nil</tt> argument
+consumes the remaining buffer space (this only makes sense as the last
+argument). Multiple arguments consume the buffer data in the given
+order.
+</p>
+<p>
+Note: a zero length or no remaining buffer data returns an empty string
+and not <tt>nil</tt>.
+</p>
+
+<h3 id="buffer_tostring"><tt>str = buf:tostring()<br>
+str = tostring(buf)</tt></h3>
+<p>
+Creates a string from the buffer data, but doesn't consume it. The
+buffer remains unchanged.
+</p>
+<p>
+Buffer objects also define a <tt>__tostring</tt> metamethod. This means
+buffers can be passed to the global <tt>tostring()</tt> function and
+many other functions that accept this in place of strings. The important
+internal uses in functions like <tt>io.write()</tt> are short-circuited
+to avoid the creation of an intermediate string object.
+</p>
+
+<h3 id="buffer_ref"><tt>ptr, len = buf:ref()</tt><span class="lib">FFI</span></h3>
+<p>
+Returns an <tt>uint8_t&nbsp;*</tt> FFI cdata pointer <tt>ptr</tt> that
+points to the buffer data. The length of the buffer data in bytes is
+returned in <tt>len</tt>.
+</p>
+<p>
+The returned pointer can be directly passed to C functions that expect a
+buffer and a length. You can also do bytewise reads
+(<tt>local&nbsp;x&nbsp;=&nbsp;ptr[i]</tt>) or writes
+(<tt>ptr[i]&nbsp;=&nbsp;0x40</tt>) of the buffer data.
+</p>
+<p>
+In conjunction with the <tt>skip</tt> method, this allows zero-copy use
+of C write-style APIs:
+</p>
+<pre class="code">
+repeat
+  local ptr, len = buf:ref()
+  if len == 0 then break end
+  local n = C.write(fd, ptr, len)
+  if n &lt; 0 then error("write error") end
+  buf:skip(n)
+until n >= len
+</pre>
+<p>
+Unlike Lua strings, buffer data is <i>not</i> implicitly
+zero-terminated. It's not safe to pass <tt>ptr</tt> to C functions that
+expect zero-terminated strings. If you're not using <tt>len</tt>, then
+you're doing something wrong.
+</p>
+
+<h2 id="serialize">Serialization of Lua Objects</h2>
+<p>
+The following functions and methods allow <b>high-speed serialization</b>
+(encoding) of a Lua object into a string and decoding it back to a Lua
+object. This allows convenient storage and transport of <b>structured
+data</b>.
+</p>
+<p>
+The encoded data is in an <a href="#serialize_format">internal binary
+format</a>. The data can be stored in files, binary-transparent
+databases or transmitted to other LuaJIT instances across threads,
+processes or networks.
+</p>
+<p>
+Encoding speed can reach up to 1 Gigabyte/second on a modern desktop- or
+server-class system, even when serializing many small objects. Decoding
+speed is mostly constrained by object creation cost.
+</p>
+<p>
+The serializer handles most Lua types, common FFI number types and
+nested structures. Functions, thread objects, other FFI cdata and full
+userdata cannot be serialized (yet).
+</p>
+<p>
+The encoder serializes nested structures as trees. Multiple references
+to a single object will be stored separately and create distinct objects
+after decoding. Circular references cause an error.
+</p>
+
+<h3 id="serialize_methods">Serialization Functions and Methods</h3>
+
+<h3 id="buffer_encode"><tt>str = buffer.encode(obj)<br>
+buf = buf:encode(obj)</tt></h3>
+<p>
+Serializes (encodes) the Lua object <tt>obj</tt>. The stand-alone
+function returns a string <tt>str</tt>. The buffer method appends the
+encoding to the buffer.
+</p>
+<p>
+<tt>obj</tt> can be any of the supported Lua types &mdash; it doesn't
+need to be a Lua table.
+</p>
+<p>
+This function may throw an error when attempting to serialize
+unsupported object types, circular references or deeply nested tables.
+</p>
+
+<h3 id="buffer_decode"><tt>obj = buffer.decode(str)<br>
+obj = buf:decode()</tt></h3>
+<p>
+The stand-alone function de-serializes (decodes) the string
+<tt>str</tt>, the buffer method de-serializes one object from the
+buffer. Both return a Lua object <tt>obj</tt>.
+</p>
+<p>
+The returned object may be any of the supported Lua types &mdash;
+even <tt>nil</tt>.
+</p>
+<p>
+This function may throw an error when fed with malformed or incomplete
+encoded data. The stand-alone function throws when there's left-over
+data after decoding a single top-level object. The buffer method leaves
+any left-over data in the buffer.
+</p>
+
+<h3 id="serialize_options">Serialization Options</h3>
+<p>
+The <tt>options</tt> table passed to <tt>buffer.new()</tt> may contain
+the following members (all optional):
+</p>
+<ul>
+<li>
+<tt>dict</tt> is a Lua table holding a <b>dictionary of strings</b> that
+commonly occur as table keys of objects you are serializing. These keys
+are compactly encoded as indexes during serialization. A well chosen
+dictionary saves space and improves serialization performance.
+</li>
+<li>
+<tt>metatable</tt> is a Lua table holding a <b>dictionary of metatables</b>
+for the table objects you are serializing.
+</li>
+</ul>
+<p>
+<tt>dict</tt> needs to be an array of strings and <tt>metatable</tt> needs
+to be an array of tables. Both starting at index 1 and without holes (no
+<tt>nil</tt> inbetween). The tables are anchored in the buffer object and
+internally modified into a two-way index (don't do this yourself, just pass
+a plain array). The tables must not be modified after they have been passed
+to <tt>buffer.new()</tt>.
+</p>
+<p>
+The <tt>dict</tt> and <tt>metatable</tt> tables used by the encoder and
+decoder must be the same. Put the most common entries at the front. Extend
+at the end to ensure backwards-compatibility &mdash; older encodings can
+then still be read. You may also set some indexes to <tt>false</tt> to
+explicitly drop backwards-compatibility. Old encodings that use these
+indexes will throw an error when decoded.
+</p>
+<p>
+Metatables that are not found in the <tt>metatable</tt> dictionary are
+ignored when encoding. Decoding returns a table with a <tt>nil</tt>
+metatable.
+</p>
+<p>
+Note: parsing and preparation of the options table is somewhat
+expensive. Create a buffer object only once and recycle it for multiple
+uses. Avoid mixing encoder and decoder buffers, since the
+<tt>buf:set()</tt> method frees the already allocated buffer space:
+</p>
+<pre class="code">
+local options = {
+  dict = { "commonly", "used", "string", "keys" },
+}
+local buf_enc = buffer.new(options)
+local buf_dec = buffer.new(options)
+
+local function encode(obj)
+  return buf_enc:reset():encode(obj):get()
+end
+
+local function decode(str)
+  return buf_dec:set(str):decode()
+end
+</pre>
+
+<h3 id="serialize_stream">Streaming Serialization</h3>
+<p>
+In some contexts, it's desirable to do piecewise serialization of large
+datasets, also known as <i>streaming</i>.
+</p>
+<p>
+This serialization format can be safely concatenated and supports streaming.
+Multiple encodings can simply be appended to a buffer and later decoded
+individually:
+</p>
+<pre class="code">
+local buf = buffer.new()
+buf:encode(obj1)
+buf:encode(obj2)
+local copy1 = buf:decode()
+local copy2 = buf:decode()
+</pre>
+<p>
+Here's how to iterate over a stream:
+</p>
+<pre class="code">
+while #buf ~= 0 do
+  local obj = buf:decode()
+  -- Do something with obj.
+end
+</pre>
+<p>
+Since the serialization format doesn't prepend a length to its encoding,
+network applications may need to transmit the length, too.
+</p>
+
+<h3 id="serialize_format">Serialization Format Specification</h3>
+<p>
+This serialization format is designed for <b>internal use</b> by LuaJIT
+applications. Serialized data is upwards-compatible and portable across
+all supported LuaJIT platforms.
+</p>
+<p>
+It's an <b>8-bit binary format</b> and not human-readable. It uses e.g.
+embedded zeroes and stores embedded Lua string objects unmodified, which
+are 8-bit-clean, too. Encoded data can be safely concatenated for
+streaming and later decoded one top-level object at a time.
+</p>
+<p>
+The encoding is reasonably compact, but tuned for maximum performance,
+not for minimum space usage. It compresses well with any of the common
+byte-oriented data compression algorithms.
+</p>
+<p>
+Although documented here for reference, this format is explicitly
+<b>not</b> intended to be a 'public standard' for structured data
+interchange across computer languages (like JSON or MessagePack). Please
+do not use it as such.
+</p>
+<p>
+The specification is given below as a context-free grammar with a
+top-level <tt>object</tt> as the starting point. Alternatives are
+separated by the <tt>|</tt> symbol and <tt>*</tt> indicates repeats.
+Grouping is implicit or indicated by <tt>{…}</tt>. Terminals are
+either plain hex numbers, encoded as bytes, or have a <tt>.format</tt>
+suffix.
+</p>
+<pre>
+object    → nil | false | true
+          | null | lightud32 | lightud64
+          | int | num | tab | tab_mt
+          | int64 | uint64 | complex
+          | string
+
+nil       → 0x00
+false     → 0x01
+true      → 0x02
+
+null      → 0x03                            // NULL lightuserdata
+lightud32 → 0x04 data.I                   // 32 bit lightuserdata
+lightud64 → 0x05 data.L                   // 64 bit lightuserdata
+
+int       → 0x06 int.I                                 // int32_t
+num       → 0x07 double.L
+
+tab       → 0x08                                   // Empty table
+          | 0x09 h.U h*{object object}          // Key/value hash
+          | 0x0a a.U a*object                    // 0-based array
+          | 0x0b a.U a*object h.U h*{object object}      // Mixed
+          | 0x0c a.U (a-1)*object                // 1-based array
+          | 0x0d a.U (a-1)*object h.U h*{object object}  // Mixed
+tab_mt    → 0x0e (index-1).U tab          // Metatable dict entry
+
+int64     → 0x10 int.L                             // FFI int64_t
+uint64    → 0x11 uint.L                           // FFI uint64_t
+complex   → 0x12 re.L im.L                         // FFI complex
+
+string    → (0x20+len).U len*char.B
+          | 0x0f (index-1).U                 // String dict entry
+
+.B = 8 bit
+.I = 32 bit little-endian
+.L = 64 bit little-endian
+.U = prefix-encoded 32 bit unsigned number n:
+     0x00..0xdf   → n.B
+     0xe0..0x1fdf → (0xe0|(((n-0xe0)>>8)&0x1f)).B ((n-0xe0)&0xff).B
+   0x1fe0..       → 0xff n.I
+</pre>
+
+<h2 id="error">Error handling</h2>
+<p>
+Many of the buffer methods can throw an error. Out-of-memory or usage
+errors are best caught with an outer wrapper for larger parts of code.
+There's not much one can do after that, anyway.
+</p>
+<p>
+OTOH you may want to catch some errors individually. Buffer methods need
+to receive the buffer object as the first argument. The Lua colon-syntax
+<tt>obj:method()</tt> does that implicitly. But to wrap a method with
+<tt>pcall()</tt>, the arguments need to be passed like this:
+</p>
+<pre class="code">
+local ok, err = pcall(buf.encode, buf, obj)
+if not ok then
+  -- Handle error in err.
+end
+</pre>
+
+<h2 id="ffi_caveats">FFI caveats</h2>
+<p>
+The string buffer library has been designed to work well together with
+the FFI library. But due to the low-level nature of the FFI library,
+some care needs to be taken:
+</p>
+<p>
+First, please remember that FFI pointers are zero-indexed. The space
+returned by <tt>buf:reserve()</tt> and <tt>buf:ref()</tt> starts at the
+returned pointer and ends before <tt>len</tt> bytes after that.
+</p>
+<p>
+I.e. the first valid index is <tt>ptr[0]</tt> and the last valid index
+is <tt>ptr[len-1]</tt>. If the returned length is zero, there's no valid
+index at all. The returned pointer may even be <tt>NULL</tt>.
+</p>
+<p>
+The space pointed to by the returned pointer is only valid as long as
+the buffer is not modified in any way (neither append, nor consume, nor
+reset, etc.). The pointer is also not a GC anchor for the buffer object
+itself.
+</p>
+<p>
+Buffer data is only guaranteed to be byte-aligned. Casting the returned
+pointer to a data type with higher alignment may cause unaligned
+accesses. It depends on the CPU architecture whether this is allowed or
+not (it's always OK on x86/x64 and mostly OK on other modern
+architectures).
+</p>
+<p>
+FFI pointers or references do not count as GC anchors for an underlying
+object. E.g. an <tt>array</tt> allocated with <tt>ffi.new()</tt> is
+anchored by <tt>buf:set(array,&nbsp;len)</tt>, but not by
+<tt>buf:set(array+offset,&nbsp;len)</tt>. The addition of the offset
+creates a new pointer, even when the offset is zero. In this case, you
+need to make sure there's still a reference to the original array as
+long as its contents are in use by the buffer.
+</p>
+<p>
+Even though each LuaJIT VM instance is single-threaded (but you can
+create multiple VMs), FFI data structures can be accessed concurrently.
+Be careful when reading/writing FFI cdata from/to buffers to avoid
+concurrent accesses or modifications. In particular, the memory
+referenced by <tt>buf:set(cdata,&nbsp;len)</tt> must not be modified
+while buffer readers are working on it. Shared, but read-only memory
+mappings of files are OK, but only if the file does not change.
+</p>
+<br class="flush">
+</div>
+<div id="foot">
+<hr class="hide">
+Copyright &copy; 2005-2021
+<span class="noprint">
+&middot;
+<a href="contact.html">Contact</a>
+</span>
+</div>
+</body>
+</html>

+ 6 - 4
libs/LuaJIT/doc/ext_c_api.html

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <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 name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -37,6 +37,8 @@
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a class="current" href="ext_c_api.html">Lua/C API</a>
 <a class="current" href="ext_c_api.html">Lua/C API</a>
@@ -173,7 +175,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-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 6 - 4
libs/LuaJIT/doc/ext_ffi.html

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
 <title>FFI Library</title>
 <title>FFI Library</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -37,6 +37,8 @@
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -316,7 +318,7 @@ without undue conversion penalties.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

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

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <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 name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -42,6 +42,8 @@ td.abiparam { font-weight: bold; width: 6em; }
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -556,7 +558,7 @@ named <tt>i</tt>.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 6 - 4
libs/LuaJIT/doc/ext_ffi_semantics.html

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
 <title>FFI Semantics</title>
 <title>FFI Semantics</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -42,6 +42,8 @@ td.convop { font-style: italic; width: 40%; }
 <a class="current" href="ext_ffi_semantics.html">FFI Semantics</a>
 <a class="current" href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -1246,7 +1248,7 @@ compiled.</li>
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 6 - 4
libs/LuaJIT/doc/ext_ffi_tutorial.html

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
 <title>FFI Tutorial</title>
 <title>FFI Tutorial</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -44,6 +44,8 @@ td.idiomlua b { font-weight: normal; color: #2142bf; }
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -587,7 +589,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-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

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

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
 <title>jit.* Library</title>
 <title>jit.* Library</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -37,6 +37,8 @@
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a class="current" href="ext_jit.html">jit.* Library</a>
 <a class="current" href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -147,7 +149,7 @@ Contains the target OS name:
 <h3 id="jit_arch"><tt>jit.arch</tt></h3>
 <h3 id="jit_arch"><tt>jit.arch</tt></h3>
 <p>
 <p>
 Contains the target architecture name:
 Contains the target architecture name:
-"x86", "x64", "arm", "arm64", "ppc", "mips" or "mips64".
+"x86", "x64", "arm", "arm64", "arm64be", "ppc", "mips", "mipsel", "mips64", "mips64el", "mips64r6", "mips64r6el".
 </p>
 </p>
 
 
 <h2 id="jit_opt"><tt>jit.opt.*</tt> &mdash; JIT compiler optimization control</h2>
 <h2 id="jit_opt"><tt>jit.opt.*</tt> &mdash; JIT compiler optimization control</h2>
@@ -185,7 +187,7 @@ if you want to know more.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 6 - 4
libs/LuaJIT/doc/ext_profiler.html

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
 <title>Profiler</title>
 <title>Profiler</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -37,6 +37,8 @@
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -349,7 +351,7 @@ use.
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

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

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
 <title>Extensions</title>
 <title>Extensions</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -54,6 +54,8 @@ td.excinterop {
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -392,29 +394,19 @@ the toolchain used to compile LuaJIT:
 <td class="excinterop">Interoperability</td>
 <td class="excinterop">Interoperability</td>
 </tr>
 </tr>
 <tr class="odd separate">
 <tr class="odd separate">
-<td class="excplatform">POSIX/x64, DWARF2 unwinding</td>
-<td class="exccompiler">GCC 4.3+, Clang</td>
+<td class="excplatform">External frame unwinding</td>
+<td class="exccompiler">GCC, Clang, 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="even">
 <tr class="even">
-<td class="excplatform">ARM <tt>-DLUAJIT_UNWIND_EXTERNAL</tt></td>
-<td class="exccompiler">GCC, Clang</td>
-<td class="excinterop"><b style="color: #00a000;">Full</b></td>
-</tr>
-<tr class="odd">
-<td class="excplatform">Other platforms, DWARF2 unwinding</td>
+<td class="excplatform">Internal frame unwinding + DWARF2</td>
 <td class="exccompiler">GCC, Clang</td>
 <td class="exccompiler">GCC, Clang</td>
 <td class="excinterop"><b style="color: #c06000;">Limited</b></td>
 <td class="excinterop"><b style="color: #c06000;">Limited</b></td>
 </tr>
 </tr>
-<tr class="even">
-<td class="excplatform">Windows/x64</td>
-<td class="exccompiler">MSVC</td>
-<td class="excinterop"><b style="color: #00a000;">Full</b></td>
-</tr>
 <tr class="odd">
 <tr class="odd">
-<td class="excplatform">Windows/x86</td>
-<td class="exccompiler">Any</td>
-<td class="excinterop"><b style="color: #00a000;">Full</b></td>
+<td class="excplatform">Windows 64 bit</td>
+<td class="exccompiler">non-MSVC</td>
+<td class="excinterop"><b style="color: #c06000;">Limited</b></td>
 </tr>
 </tr>
 <tr class="even">
 <tr class="even">
 <td class="excplatform">Other platforms</td>
 <td class="excplatform">Other platforms</td>
@@ -435,7 +427,9 @@ the toolchain used to compile LuaJIT:
 on the C&nbsp;stack. The contents of the C++&nbsp;exception object
 on the C&nbsp;stack. The contents of the C++&nbsp;exception object
 pass through unmodified.</li>
 pass through unmodified.</li>
 <li>Lua errors can be caught on the C++ side with <tt>catch(...)</tt>.
 <li>Lua errors can be caught on the C++ side with <tt>catch(...)</tt>.
-The corresponding Lua error message can be retrieved from the Lua stack.</li>
+The corresponding Lua error message can be retrieved from the Lua stack.<br>
+For MSVC for Windows 64 bit this requires compilation of your C++ code
+with <tt>/EHa</tt>.</li>
 <li>Throwing Lua errors across C++ frames is safe. C++ destructors
 <li>Throwing Lua errors across C++ frames is safe. C++ destructors
 will be called.</li>
 will be called.</li>
 </ul>
 </ul>
@@ -470,7 +464,7 @@ C++ destructors.</li>
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 42 - 47
libs/LuaJIT/doc/faq.html

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <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 name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -40,6 +40,8 @@ dd { margin-left: 1.5em; }
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -74,22 +76,20 @@ about LuaJIT.</li>
 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></dd>
 </dl>
 </dl>
 
 
 <dl id="tech">
 <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.
-In the meantime, please use the following Google Scholar searches
-to find relevant papers:<br>
+Please use the following Google Scholar searches to find relevant papers:<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=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=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=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=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>
 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>
 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>
 
 
@@ -121,19 +121,30 @@ Consider testing your application with older versions, too.<br>
 
 
 Similarly, the Borland/Delphi runtime modifies the FPU control word and
 Similarly, the Borland/Delphi runtime modifies the FPU control word and
 enables FP exceptions. Of course this violates the Windows ABI, too.
 enables FP exceptions. Of course this violates the Windows ABI, too.
-Please check the Delphi docs for the Set8087CW method.
-
+Please check the Delphi docs for the Set8087CW method.</dd>
 </dl>
 </dl>
 
 
 <dl id="ctrlc">
 <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
-your program is running in a tight loop and never falls back to the
-interpreter, the debug hook never runs and can't throw the
-"interrupted!" error.<br> In the meantime you have to press Ctrl-C
-twice to get stop your program. That's similar to when it's stuck
-running inside a C function under the Lua interpreter.</dd>
+ignored by compiled code. If your program is running in a tight loop
+and never falls back to the interpreter, the debug hook never runs and
+can't throw the "interrupted!" error.<br>
+You have to press Ctrl-C twice to get stop your program. That's similar
+to when it's stuck running inside a C function under the Lua interpreter.</dd>
+</dl>
+
+<dl id="order">
+<dt>Q: Table iteration with <tt>pairs()</tt> does not result in the same order?</dt>
+<dd>The order of table iteration is explicitly <b>undefined</b> by
+the Lua language standard.<br>
+Different Lua implementations or versions may use different orders for
+otherwise identical tables. Different ways of constructing a table may
+result in different orders, too.<br>
+Due to improved VM security, LuaJIT 2.1 may even use a different order
+on separate VM invocations or when string keys are newly interned.<br><br>
+If your program relies on a deterministic order, it has a bug. Rewrite it,
+so it doesn't rely on the key order. Or sort the table keys, if you must.</dd>
 </dl>
 </dl>
 
 
 <dl id="sandbox">
 <dl id="sandbox">
@@ -147,28 +158,18 @@ 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
 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>
 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>
+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>.<br><br>
 
 
-In general, the only promising approach is to sandbox Lua code at the
-process level and not the VM level.<br>
+Relatedly, <b>loading untrusted bytecode is not safe!</b><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>
+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><br>
 
 
-<dl id="patches">
-<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
-in common with Lua anymore. Also, if the patch introduces changes to
-the Lua semantics, these would need to be reflected everywhere in the
-VM, from the interpreter up to all stages of the compiler.<br> Please
-use only standard Lua language constructs. For many common needs you
-can use source transformations or use wrapper or proxy functions.
-The compiler will happily optimize away such indirections.</dd>
+<b>In general, the only promising approach is to sandbox Lua code at the
+process level and not the VM level.</b>
+</dd>
 </dl>
 </dl>
 
 
 <dl id="arch">
 <dl id="arch">
@@ -178,23 +179,17 @@ machine code. This means the code generator must be ported to each
 architecture. And the fast interpreter is written in assembler and
 architecture. And the fast interpreter is written in assembler and
 must be ported, too. This is quite an undertaking.<br>
 must be ported, too. This is quite an undertaking.<br>
 The <a href="install.html">install documentation</a> shows the supported
 The <a href="install.html">install documentation</a> shows the supported
-architectures. Other architectures will follow based on sufficient user
-demand and/or sponsoring.</dd>
-</dl>
-
-<dl id="when">
-<dt>Q: When will feature X be added? When will the next version be released?</dt>
-<dd>When it's ready.<br>
-C'mon, it's open source &mdash; I'm doing it on my own time and you're
-getting it for free. You can either contribute a patch or sponsor
-the development of certain features, if they are important to you.
-</dd>
+architectures.<br>
+Other architectures may follow based on sufficient user demand and
+market-relevance of the architecture. Sponsoring is required to develop
+the port itself, to integrate it and to continuously maintain it in the
+actively developed branches.</dd>
 </dl>
 </dl>
 <br class="flush">
 <br class="flush">
 </div>
 </div>
 <div id="foot">
 <div id="foot">
 <hr class="hide">
 <hr class="hide">
-Copyright &copy; 2005-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 38 - 33
libs/LuaJIT/doc/install.html

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
 <title>Installation</title>
 <title>Installation</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -65,6 +65,8 @@ td.compatno {
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -103,8 +105,8 @@ operating systems, CPUs and compilers:
 <td class="compatcpu">CPU / OS</td>
 <td class="compatcpu">CPU / OS</td>
 <td class="compatos"><a href="#posix">Linux</a> or<br><a href="#android">Android</a></td>
 <td class="compatos"><a href="#posix">Linux</a> or<br><a href="#android">Android</a></td>
 <td class="compatos"><a href="#posix">*BSD, Other</a></td>
 <td class="compatos"><a href="#posix">*BSD, Other</a></td>
-<td class="compatos"><a href="#posix">OSX 10.4+</a> or<br><a href="#ios">iOS 3.0+</a></td>
-<td class="compatos"><a href="#windows">Windows<br>XP/Vista/7</a></td>
+<td class="compatos"><a href="#posix">macOS 10.4+</a> or<br><a href="#ios">iOS 3.0+</a></td>
+<td class="compatos"><a href="#windows">Windows 7<br>or later</a></td>
 </tr>
 </tr>
 <tr class="odd separate">
 <tr class="odd separate">
 <td class="compatcpu">x86 (32 bit)</td>
 <td class="compatcpu">x86 (32 bit)</td>
@@ -128,7 +130,7 @@ operating systems, CPUs and compilers:
 <td class="compatos compatno">&nbsp;</td>
 <td class="compatos compatno">&nbsp;</td>
 </tr>
 </tr>
 <tr class="even">
 <tr class="even">
-<td class="compatcpu"><a href="#cross2">ARM64</a></td>
+<td class="compatcpu"><a href="#cross2">ARM64<br>ARM64be</a></td>
 <td class="compatos">GCC 4.8+</td>
 <td class="compatos">GCC 4.8+</td>
 <td class="compatos compatno">&nbsp;</td>
 <td class="compatos compatno">&nbsp;</td>
 <td class="compatos">XCode 6.0+<br>Clang 3.5+</td>
 <td class="compatos">XCode 6.0+<br>Clang 3.5+</td>
@@ -142,7 +144,7 @@ operating systems, CPUs and compilers:
 <td class="compatos">XEDK (<a href="#xbox360">Xbox 360</a>)</td>
 <td class="compatos">XEDK (<a href="#xbox360">Xbox 360</a>)</td>
 </tr>
 </tr>
 <tr class="even">
 <tr class="even">
-<td class="compatcpu"><a href="#cross2">MIPS32<br>MIPS64</a></td>
+<td class="compatcpu"><a href="#cross2">MIPS32<br>MIPS64<br>MIPS64r6</a></td>
 <td class="compatos">GCC 4.3+</td>
 <td class="compatos">GCC 4.3+</td>
 <td class="compatos">GCC 4.3+</td>
 <td class="compatos">GCC 4.3+</td>
 <td class="compatos compatno">&nbsp;</td>
 <td class="compatos compatno">&nbsp;</td>
@@ -177,7 +179,7 @@ Please check the note about the
 <a href="extensions.html#string_dump">bytecode format</a> differences, too.
 <a href="extensions.html#string_dump">bytecode format</a> differences, too.
 </p>
 </p>
 
 
-<h2 id="posix">POSIX Systems (Linux, OSX, *BSD etc.)</h2>
+<h2 id="posix">POSIX Systems (Linux, macOS, *BSD etc.)</h2>
 <h3>Prerequisites</h3>
 <h3>Prerequisites</h3>
 <p>
 <p>
 Depending on your distribution, you may need to install a package for
 Depending on your distribution, you may need to install a package for
@@ -185,14 +187,19 @@ GCC, the development headers and/or a complete SDK. E.g. on a current
 Debian/Ubuntu, install <tt>libc6-dev</tt> with the package manager.
 Debian/Ubuntu, install <tt>libc6-dev</tt> with the package manager.
 </p>
 </p>
 <p>
 <p>
-Download the current source package of LuaJIT (pick the .tar.gz),
-if you haven't already done so. Move it to a directory of your choice,
-open a terminal window and change to this directory. Now unpack the archive
-and change to the newly created directory:
+The recommended way to fetch the latest version is to do a pull from
+the git repository.
+</p>
+<p>
+Alternatively download the latest source package of LuaJIT (pick the .tar.gz).
+Move it to a directory of your choice, open a terminal window and change
+to this directory. Now unpack the archive and change to the newly created
+directory (replace XX.YY.ZZ with the version you downloaded):
 </p>
 </p>
 <pre class="code">
 <pre class="code">
-tar zxf LuaJIT-2.0.5.tar.gz
-cd LuaJIT-2.0.5</pre>
+tar zxf LuaJIT-XX.YY.ZZ.tar.gz
+cd LuaJIT-XX.YY.ZZ
+</pre>
 <h3>Building LuaJIT</h3>
 <h3>Building LuaJIT</h3>
 <p>
 <p>
 The supplied Makefiles try to auto-detect the settings needed for your
 The supplied Makefiles try to auto-detect the settings needed for your
@@ -216,9 +223,12 @@ You can add an extra prefix to the search paths by appending the
 make PREFIX=/home/myself/lj2
 make PREFIX=/home/myself/lj2
 </pre>
 </pre>
 <p>
 <p>
-Note for OSX: you must set the <tt>MACOSX_DEPLOYMENT_TARGET</tt>
-environment variable to a value supported by your toolchain.
+Note for macOS: you <b>must</b> set the <tt>MACOSX_DEPLOYMENT_TARGET</tt>
+environment variable to a value supported by your toolchain:
 </p>
 </p>
+<pre class="code">
+MACOSX_DEPLOYMENT_TARGET=XX.YY make
+</pre>
 <h3>Installing LuaJIT</h3>
 <h3>Installing LuaJIT</h3>
 <p>
 <p>
 The top-level Makefile installs LuaJIT by default under
 The top-level Makefile installs LuaJIT by default under
@@ -250,8 +260,9 @@ GCC plus the required development headers.
 Or install Microsoft's Visual Studio (MSVC).
 Or install Microsoft's Visual Studio (MSVC).
 </p>
 </p>
 <p>
 <p>
-Next, download the source package and unpack it using an archive manager
-(e.g. the Windows Explorer) to a directory of your choice.
+Next, pull from the git repository or download the source package and
+unpack it using an archive manager (e.g. the Windows Explorer) to
+a directory of your choice.
 </p>
 </p>
 <h3>Building with MSVC</h3>
 <h3>Building with MSVC</h3>
 <p>
 <p>
@@ -269,8 +280,8 @@ Then follow the installation instructions below.
 <h3>Building with MinGW or Cygwin</h3>
 <h3>Building with MinGW or Cygwin</h3>
 <p>
 <p>
 Open a command prompt window and make sure the MinGW or Cygwin programs
 Open a command prompt window and make sure the MinGW or Cygwin programs
-are in your path. Then <tt>cd</tt> to the directory where
-you've unpacked the sources and run this command for MinGW:
+are in your path. Then <tt>cd</tt> to the directory of the git repository
+or where you've unpacked the sources. Then run this command for MinGW:
 </p>
 </p>
 <pre class="code">
 <pre class="code">
 mingw32-make
 mingw32-make
@@ -325,7 +336,7 @@ You need to specify <tt>TARGET_SYS</tt> whenever the host OS and the
 target OS differ, or you'll get assembler or linker errors:
 target OS differ, or you'll get assembler or linker errors:
 </p>
 </p>
 <ul>
 <ul>
-<li>E.g. if you're compiling on a Windows or OSX host for embedded Linux or Android, you need to add <tt>TARGET_SYS=Linux</tt> to the examples below.</li>
+<li>E.g. if you're compiling on a Windows or macOS host for embedded Linux or Android, you need to add <tt>TARGET_SYS=Linux</tt> to the examples below.</li>
 <li>For a minimal target OS, you may need to disable the built-in allocator in <tt>src/Makefile</tt> and use <tt>TARGET_SYS=Other</tt>.</li>
 <li>For a minimal target OS, you may need to disable the built-in allocator in <tt>src/Makefile</tt> and use <tt>TARGET_SYS=Other</tt>.</li>
 <li>Don't forget to specify the same <tt>TARGET_SYS</tt> for the install step, too.</li>
 <li>Don't forget to specify the same <tt>TARGET_SYS</tt> for the install step, too.</li>
 </ul>
 </ul>
@@ -400,7 +411,8 @@ NDKCROSS=$NDKBIN/aarch64-linux-android-
 NDKCC=$NDKBIN/aarch64-linux-android21-clang
 NDKCC=$NDKBIN/aarch64-linux-android21-clang
 make CROSS=$NDKCROSS \
 make CROSS=$NDKCROSS \
      STATIC_CC=$NDKCC DYNAMIC_CC="$NDKCC -fPIC" \
      STATIC_CC=$NDKCC DYNAMIC_CC="$NDKCC -fPIC" \
-     TARGET_LD=$NDKCC
+     TARGET_LD=$NDKCC TARGET_AR=$NDKBIN/llvm-ar
+     TARGET_STRIP=$NDKBIN/llvm-strip
 
 
 # Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.1+ (JB)
 # Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.1+ (JB)
 NDKDIR=/opt/android/ndk
 NDKDIR=/opt/android/ndk
@@ -409,7 +421,8 @@ NDKCROSS=$NDKBIN/arm-linux-androideabi-
 NDKCC=$NDKBIN/armv7a-linux-androideabi16-clang
 NDKCC=$NDKBIN/armv7a-linux-androideabi16-clang
 make HOST_CC="gcc -m32" CROSS=$NDKCROSS \
 make HOST_CC="gcc -m32" CROSS=$NDKCROSS \
      STATIC_CC=$NDKCC DYNAMIC_CC="$NDKCC -fPIC" \
      STATIC_CC=$NDKCC DYNAMIC_CC="$NDKCC -fPIC" \
-     TARGET_LD=$NDKCC
+     TARGET_LD=$NDKCC TARGET_AR=$NDKBIN/llvm-ar
+     TARGET_STRIP=$NDKBIN/llvm-strip
 </pre>
 </pre>
 <p>
 <p>
 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>:
 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>:
@@ -522,14 +535,6 @@ the DLL). You may link LuaJIT statically on Windows only if you don't
 intend to load Lua/C modules at runtime.
 intend to load Lua/C modules at runtime.
 </li></ul>
 </li></ul>
 </li>
 </li>
-<li>
-If you're building a 64 bit application on OSX which links directly or
-indirectly against LuaJIT which is not built for <tt>LJ_GC64</tt> mode,
-you need to link your main executable with these flags:
-<pre class="code">
--pagezero_size 10000 -image_base 100000000
-</pre>
-</li>
 </ul>
 </ul>
 <p>Additional hints for initializing LuaJIT using the C API functions:</p>
 <p>Additional hints for initializing LuaJIT using the C API functions:</p>
 <ul>
 <ul>
@@ -538,7 +543,7 @@ you need to link your main executable with these flags:
 for embedding Lua or LuaJIT into your application.</li>
 for embedding Lua or LuaJIT into your application.</li>
 <li>Make sure you use <tt>luaL_newstate</tt>. Avoid using
 <li>Make sure you use <tt>luaL_newstate</tt>. Avoid using
 <tt>lua_newstate</tt>, since this uses the (slower) default memory
 <tt>lua_newstate</tt>, since this uses the (slower) default memory
-allocator from your system (no support for this on x64).</li>
+allocator from your system (no support for this on 64&nbsp;bit architectures).</li>
 <li>Make sure you use <tt>luaL_openlibs</tt> and not the old Lua 5.0 style
 <li>Make sure you use <tt>luaL_openlibs</tt> and not the old Lua 5.0 style
 of calling <tt>luaopen_base</tt> etc. directly.</li>
 of calling <tt>luaopen_base</tt> etc. directly.</li>
 <li>To change or extend the list of standard libraries to load, copy
 <li>To change or extend the list of standard libraries to load, copy
@@ -614,7 +619,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-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 8 - 6
libs/LuaJIT/doc/luajit.html

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
 <title>LuaJIT</title>
 <title>LuaJIT</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -122,6 +122,8 @@ table.feature small {
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -146,7 +148,7 @@ 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-2020 Mike Pall, released under the
+LuaJIT is Copyright &copy; 2005-2021 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>.
 <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>
@@ -154,7 +156,7 @@ LuaJIT is Copyright &copy; 2005-2020 Mike Pall, released under the
 
 
 <h2>Compatibility</h2>
 <h2>Compatibility</h2>
 <table class="feature os os1">
 <table class="feature os os1">
-<tr><td>Windows</td><td>Linux</td><td>BSD</td><td>OSX</td><td>POSIX</td></tr>
+<tr><td>Windows</td><td>Linux</td><td>BSD</td><td>macOS</td><td>POSIX</td></tr>
 </table>
 </table>
 <table class="feature os os2">
 <table class="feature os os2">
 <tr><td><span style="font-size:90%;">Embedded</span></td><td>Android</td><td>iOS</td></tr>
 <tr><td><span style="font-size:90%;">Embedded</span></td><td>Android</td><td>iOS</td></tr>
@@ -220,7 +222,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-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

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

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
 <title>Running LuaJIT</title>
 <title>Running LuaJIT</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -59,6 +59,8 @@ td.param_default {
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -183,8 +185,8 @@ itself. For a description of their options and output format, please
 read the comment block at the start of their source.
 read the comment block at the start of their source.
 They can be found in the <tt>lib</tt> directory of the source
 They can be found in the <tt>lib</tt> directory of the source
 distribution or installed under the <tt>jit</tt> directory. By default
 distribution or installed under the <tt>jit</tt> directory. By default
-this is <tt>/usr/local/share/luajit-2.0.5/jit</tt> on POSIX
-systems.
+this is <tt>/usr/local/share/luajit-XX.YY.ZZ>/jit</tt> on POSIX
+systems (replace XX.YY.ZZ by the installed version).
 </p>
 </p>
 
 
 <h3 id="opt_O"><tt>-O[level]</tt><br>
 <h3 id="opt_O"><tt>-O[level]</tt><br>
@@ -293,7 +295,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-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 15 - 14
libs/LuaJIT/doc/status.html

@@ -1,9 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <html>
 <head>
 <head>
 <title>Status</title>
 <title>Status</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="Copyright" content="Copyright (C) 2005-2020">
+<meta charset="utf-8">
+<meta name="Copyright" content="Copyright (C) 2005-2021">
 <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">
@@ -40,6 +40,8 @@ ul li { padding-bottom: 0.3em; }
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 <a href="ext_ffi_semantics.html">FFI Semantics</a>
 </li></ul>
 </li></ul>
 </li><li>
 </li><li>
+<a href="ext_buffer.html">String Buffers</a>
+</li><li>
 <a href="ext_jit.html">jit.* Library</a>
 <a href="ext_jit.html">jit.* Library</a>
 </li><li>
 </li><li>
 <a href="ext_c_api.html">Lua/C API</a>
 <a href="ext_c_api.html">Lua/C API</a>
@@ -58,9 +60,15 @@ ul li { padding-bottom: 0.3em; }
 </div>
 </div>
 <div id="main">
 <div id="main">
 <p>
 <p>
-<span style="color: #0000c0;">LuaJIT&nbsp;2.0</span> is the current
-<span style="color: #0000c0;">stable branch</span>. This branch is in
-feature-freeze &mdash; new features will only be added to LuaJIT&nbsp;2.1.
+This documentation is for LuaJIT 2.1.0-beta3. Please check the <tt>doc</tt>
+directory in each git branch for the version-specific documentation.
+</p>
+<p>
+The currently developed branches are LuaJIT&nbsp;2.1 and LuaJIT&nbsp;2.0.
+</p>
+<p>
+LuaJIT&nbsp;2.0 is in feature-freeze &mdash; new features will only
+be added to LuaJIT&nbsp;2.1.
 </p>
 </p>
 
 
 <h2>Current Status</h2>
 <h2>Current Status</h2>
@@ -84,19 +92,12 @@ The Lua <b>debug API</b> is missing a couple of features (return
 hooks for non-Lua functions) and shows slightly different behavior
 hooks for non-Lua functions) and shows slightly different behavior
 in LuaJIT (no per-coroutine hooks, no tail call counting).
 in LuaJIT (no per-coroutine hooks, no tail call counting).
 </li>
 </li>
-<li>
-Currently some <b>out-of-memory</b> errors from <b>on-trace code</b> are not
-handled correctly. The error may fall through an on-trace
-<tt>pcall</tt> or it may be passed on to the function set with
-<tt>lua_atpanic</tt> on x64. This issue will be fixed with the new
-garbage collector.
-</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-2020
+Copyright &copy; 2005-2021
 <span class="noprint">
 <span class="noprint">
 &middot;
 &middot;
 <a href="contact.html">Contact</a>
 <a href="contact.html">Contact</a>

+ 6 - 3
libs/LuaJIT/dynasm/dasm_arm.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** DynASM ARM encoding engine.
 ** DynASM ARM encoding engine.
-** Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+** Copyright (C) 2005-2021 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.
 */
 */
 
 
@@ -294,7 +294,7 @@ int dasm_link(Dst_DECL, size_t *szp)
 
 
   { /* Handle globals not defined in this translation unit. */
   { /* Handle globals not defined in this translation unit. */
     int idx;
     int idx;
-    for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) {
+    for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
       int n = D->lglabels[idx];
       int n = D->lglabels[idx];
       /* Undefined label: Collapse rel chain and replace with marker (< 0). */
       /* Undefined label: Collapse rel chain and replace with marker (< 0). */
       while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
       while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
@@ -371,7 +371,10 @@ int dasm_encode(Dst_DECL, void *buffer)
 	  ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;
 	  ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;
 	  break;
 	  break;
 	case DASM_REL_LG:
 	case DASM_REL_LG:
-	  CK(n >= 0, UNDEF_LG);
+	  if (n < 0) {
+	    n = (int)((ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp - 4);
+	    goto patchrel;
+	  }
 	  /* fallthrough */
 	  /* fallthrough */
 	case DASM_REL_PC:
 	case DASM_REL_PC:
 	  CK(n >= 0, UNDEF_PC);
 	  CK(n >= 0, UNDEF_PC);

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

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM ARM module.
 -- DynASM ARM module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
 -- See dynasm.lua for full copyright notice.
 -- See dynasm.lua for full copyright notice.
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
@@ -9,9 +9,9 @@
 local _info = {
 local _info = {
   arch =	"arm",
   arch =	"arm",
   description =	"DynASM ARM module",
   description =	"DynASM ARM module",
-  version =	"1.4.0",
-  vernum =	 10400,
-  release =	"2015-10-18",
+  version =	"1.5.0",
+  vernum =	 10500,
+  release =	"2021-05-02",
   author =	"Mike Pall",
   author =	"Mike Pall",
   license =	"MIT",
   license =	"MIT",
 }
 }

+ 51 - 9
libs/LuaJIT/dynasm/dasm_arm64.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** DynASM ARM64 encoding engine.
 ** DynASM ARM64 encoding engine.
-** Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+** Copyright (C) 2005-2021 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.
 */
 */
 
 
@@ -21,8 +21,9 @@ enum {
   /* The following actions need a buffer position. */
   /* The following actions need a buffer position. */
   DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
   DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
   /* The following actions also have an argument. */
   /* The following actions also have an argument. */
-  DASM_REL_PC, DASM_LABEL_PC,
+  DASM_REL_PC, DASM_LABEL_PC, DASM_REL_A,
   DASM_IMM, DASM_IMM6, DASM_IMM12, DASM_IMM13W, DASM_IMM13X, DASM_IMML,
   DASM_IMM, DASM_IMM6, DASM_IMM12, DASM_IMM13W, DASM_IMM13X, DASM_IMML,
+  DASM_IMMV, DASM_VREG,
   DASM__MAX
   DASM__MAX
 };
 };
 
 
@@ -39,6 +40,7 @@ enum {
 #define DASM_S_RANGE_LG		0x13000000
 #define DASM_S_RANGE_LG		0x13000000
 #define DASM_S_RANGE_PC		0x14000000
 #define DASM_S_RANGE_PC		0x14000000
 #define DASM_S_RANGE_REL	0x15000000
 #define DASM_S_RANGE_REL	0x15000000
+#define DASM_S_RANGE_VREG	0x16000000
 #define DASM_S_UNDEF_LG		0x21000000
 #define DASM_S_UNDEF_LG		0x21000000
 #define DASM_S_UNDEF_PC		0x22000000
 #define DASM_S_UNDEF_PC		0x22000000
 
 
@@ -247,7 +249,7 @@ void dasm_put(Dst_DECL, int start, ...)
 	n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
 	n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
 	D->section = &D->sections[n]; goto stop;
 	D->section = &D->sections[n]; goto stop;
       case DASM_ESC: p++; ofs += 4; break;
       case DASM_ESC: p++; ofs += 4; break;
-      case DASM_REL_EXT: break;
+      case DASM_REL_EXT: if ((ins & 0x8000)) ofs += 8; break;
       case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
       case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
       case DASM_REL_LG:
       case DASM_REL_LG:
 	n = (ins & 2047) - 10; pl = D->lglabels + n;
 	n = (ins & 2047) - 10; pl = D->lglabels + n;
@@ -268,6 +270,11 @@ void dasm_put(Dst_DECL, int start, ...)
 	  *pl = pos;
 	  *pl = pos;
 	}
 	}
 	pos++;
 	pos++;
+	if ((ins & 0x8000)) ofs += 8;
+	break;
+      case DASM_REL_A:
+	b[pos++] = n;
+	b[pos++] = va_arg(ap, int);
 	break;
 	break;
       case DASM_LABEL_LG:
       case DASM_LABEL_LG:
 	pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
 	pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
@@ -312,13 +319,21 @@ void dasm_put(Dst_DECL, int start, ...)
 	}
 	}
       case DASM_IMML: {
       case DASM_IMML: {
 #ifdef DASM_CHECKS
 #ifdef DASM_CHECKS
-	int scale = (p[-2] >> 30);
+	int scale = (ins & 3);
 	CK((!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ||
 	CK((!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ||
 	   (unsigned int)(n+256) < 512, RANGE_I);
 	   (unsigned int)(n+256) < 512, RANGE_I);
 #endif
 #endif
 	b[pos++] = n;
 	b[pos++] = n;
 	break;
 	break;
 	}
 	}
+      case DASM_IMMV:
+	ofs += 4;
+	b[pos++] = n;
+	break;
+      case DASM_VREG:
+	CK(n < 32, RANGE_VREG);
+	b[pos++] = n;
+	break;
       }
       }
     }
     }
   }
   }
@@ -348,7 +363,7 @@ int dasm_link(Dst_DECL, size_t *szp)
 
 
   { /* Handle globals not defined in this translation unit. */
   { /* Handle globals not defined in this translation unit. */
     int idx;
     int idx;
-    for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) {
+    for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
       int n = D->lglabels[idx];
       int n = D->lglabels[idx];
       /* Undefined label: Collapse rel chain and replace with marker (< 0). */
       /* Undefined label: Collapse rel chain and replace with marker (< 0). */
       while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
       while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
@@ -375,8 +390,8 @@ int dasm_link(Dst_DECL, size_t *szp)
 	case DASM_REL_LG: case DASM_REL_PC: pos++; break;
 	case DASM_REL_LG: case DASM_REL_PC: pos++; break;
 	case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
 	case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
 	case DASM_IMM: case DASM_IMM6: case DASM_IMM12: case DASM_IMM13W:
 	case DASM_IMM: case DASM_IMM6: case DASM_IMM12: case DASM_IMM13W:
-	case DASM_IMML: pos++; break;
-	case DASM_IMM13X: pos += 2; break;
+	case DASM_IMML: case DASM_IMMV: case DASM_VREG: pos++; break;
+	case DASM_IMM13X: case DASM_REL_A: pos += 2; break;
 	}
 	}
       }
       }
       stop: (void)0;
       stop: (void)0;
@@ -426,7 +441,12 @@ int dasm_encode(Dst_DECL, void *buffer)
 	  ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;
 	  ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;
 	  break;
 	  break;
 	case DASM_REL_LG:
 	case DASM_REL_LG:
-	  CK(n >= 0, UNDEF_LG);
+	  if (n < 0) {
+	    ptrdiff_t na = (ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp + 4;
+	    n = (int)na;
+	    CK((ptrdiff_t)n == na, RANGE_REL);
+	    goto patchrel;
+	  }
 	  /* fallthrough */
 	  /* fallthrough */
 	case DASM_REL_PC:
 	case DASM_REL_PC:
 	  CK(n >= 0, UNDEF_PC);
 	  CK(n >= 0, UNDEF_PC);
@@ -446,8 +466,24 @@ int dasm_encode(Dst_DECL, void *buffer)
 	  } else if ((ins & 0x1000)) {  /* TBZ, TBNZ */
 	  } else if ((ins & 0x1000)) {  /* TBZ, TBNZ */
 	    CK((n & 3) == 0 && ((n+0x00008000) >> 16) == 0, RANGE_REL);
 	    CK((n & 3) == 0 && ((n+0x00008000) >> 16) == 0, RANGE_REL);
 	    cp[-1] |= ((n << 3) & 0x0007ffe0);
 	    cp[-1] |= ((n << 3) & 0x0007ffe0);
+	  } else if ((ins & 0x8000)) {  /* absolute */
+	    cp[0] = (unsigned int)((ptrdiff_t)cp - 4 + n);
+	    cp[1] = (unsigned int)(((ptrdiff_t)cp - 4 + n) >> 32);
+	    cp += 2;
 	  }
 	  }
 	  break;
 	  break;
+	case DASM_REL_A: {
+	  ptrdiff_t na = (((ptrdiff_t)(*b++) << 32) | (unsigned int)n);
+	  if ((ins & 0x3000) == 0x3000) {  /* ADRP */
+	    ins &= ~0x1000;
+	    na = (na >> 12) - (((ptrdiff_t)cp - 4) >> 12);
+	  } else {
+	    na = na - (ptrdiff_t)cp + 4;
+	  }
+	  n = (int)na;
+	  CK((ptrdiff_t)n == na, RANGE_REL);
+	  goto patchrel;
+	}
 	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);
 	  break;
 	  break;
@@ -468,11 +504,17 @@ int dasm_encode(Dst_DECL, void *buffer)
 	  cp[-1] |= (dasm_imm13(n, *b++) << 10);
 	  cp[-1] |= (dasm_imm13(n, *b++) << 10);
 	  break;
 	  break;
 	case DASM_IMML: {
 	case DASM_IMML: {
-	  int scale = (p[-2] >> 30);
+	  int scale = (ins & 3);
 	  cp[-1] |= (!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ?
 	  cp[-1] |= (!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ?
 	    ((n << (10-scale)) | 0x01000000) : ((n & 511) << 12);
 	    ((n << (10-scale)) | 0x01000000) : ((n & 511) << 12);
 	  break;
 	  break;
 	  }
 	  }
+	case DASM_IMMV:
+	  *cp++ = n;
+	  break;
+	case DASM_VREG:
+	  cp[-1] |= (n & 0x1f) << (ins & 0x1f);
+	  break;
 	default: *cp++ = ins; break;
 	default: *cp++ = ins; break;
 	}
 	}
       }
       }

+ 95 - 42
libs/LuaJIT/dynasm/dasm_arm64.lua

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM ARM64 module.
 -- DynASM ARM64 module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
 -- See dynasm.lua for full copyright notice.
 -- See dynasm.lua for full copyright notice.
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
@@ -9,9 +9,9 @@
 local _info = {
 local _info = {
   arch =	"arm",
   arch =	"arm",
   description =	"DynASM ARM64 module",
   description =	"DynASM ARM64 module",
-  version =	"1.4.0",
-  vernum =	 10400,
-  release =	"2015-10-18",
+  version =	"1.5.0",
+  vernum =	 10500,
+  release =	"2021-05-02",
   author =	"Mike Pall",
   author =	"Mike Pall",
   license =	"MIT",
   license =	"MIT",
 }
 }
@@ -23,12 +23,12 @@ local _M = { _info = _info }
 local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
 local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
 local assert, setmetatable, rawget = assert, setmetatable, rawget
 local assert, setmetatable, rawget = assert, setmetatable, rawget
 local _s = string
 local _s = string
-local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
+local format, byte, char = _s.format, _s.byte, _s.char
 local match, gmatch, gsub = _s.match, _s.gmatch, _s.gsub
 local match, gmatch, gsub = _s.match, _s.gmatch, _s.gsub
 local concat, sort, insert = table.concat, table.sort, table.insert
 local concat, sort, insert = table.concat, table.sort, table.insert
 local bit = bit or require("bit")
 local bit = bit or require("bit")
 local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift
 local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift
-local ror, tohex = bit.ror, bit.tohex
+local ror, tohex, tobit = bit.ror, bit.tohex, bit.tobit
 
 
 -- Inherited tables and callbacks.
 -- Inherited tables and callbacks.
 local g_opt, g_arch
 local g_opt, g_arch
@@ -39,7 +39,9 @@ local wline, werror, wfatal, wwarn
 local action_names = {
 local action_names = {
   "STOP", "SECTION", "ESC", "REL_EXT",
   "STOP", "SECTION", "ESC", "REL_EXT",
   "ALIGN", "REL_LG", "LABEL_LG",
   "ALIGN", "REL_LG", "LABEL_LG",
-  "REL_PC", "LABEL_PC", "IMM", "IMM6", "IMM12", "IMM13W", "IMM13X", "IMML",
+  "REL_PC", "LABEL_PC", "REL_A",
+  "IMM", "IMM6", "IMM12", "IMM13W", "IMM13X", "IMML", "IMMV",
+  "VREG",
 }
 }
 
 
 -- Maximum number of section buffer positions for dasm_put().
 -- Maximum number of section buffer positions for dasm_put().
@@ -246,9 +248,12 @@ local map_cond = {
 
 
 local parse_reg_type
 local parse_reg_type
 
 
-local function parse_reg(expr)
+local function parse_reg(expr, shift)
   if not expr then werror("expected register name") end
   if not expr then werror("expected register name") end
   local tname, ovreg = match(expr, "^([%w_]+):(@?%l%d+)$")
   local tname, ovreg = match(expr, "^([%w_]+):(@?%l%d+)$")
+  if not tname then
+    tname, ovreg = match(expr, "^([%w_]+):(R[xwqdshb]%b())$")
+  end
   local tp = map_type[tname or expr]
   local tp = map_type[tname or expr]
   if tp then
   if tp then
     local reg = ovreg or tp.reg
     local reg = ovreg or tp.reg
@@ -266,18 +271,28 @@ local function parse_reg(expr)
       elseif parse_reg_type ~= rt then
       elseif parse_reg_type ~= rt then
 	werror("register size mismatch")
 	werror("register size mismatch")
       end
       end
-      return r, tp
+      return shl(r, shift), tp
+    end
+  end
+  local vrt, vreg = match(expr, "^R([xwqdshb])(%b())$")
+  if vreg then
+    if not parse_reg_type then
+      parse_reg_type = vrt
+    elseif parse_reg_type ~= vrt then
+      werror("register size mismatch")
     end
     end
+    if shift then waction("VREG", shift, vreg) end
+    return 0
   end
   end
   werror("bad register name `"..expr.."'")
   werror("bad register name `"..expr.."'")
 end
 end
 
 
 local function parse_reg_base(expr)
 local function parse_reg_base(expr)
   if expr == "sp" then return 0x3e0 end
   if expr == "sp" then return 0x3e0 end
-  local base, tp = parse_reg(expr)
+  local base, tp = parse_reg(expr, 5)
   if parse_reg_type ~= "x" then werror("bad register type") end
   if parse_reg_type ~= "x" then werror("bad register type") end
   parse_reg_type = false
   parse_reg_type = false
-  return shl(base, 5), tp
+  return base, tp
 end
 end
 
 
 local parse_ctx = {}
 local parse_ctx = {}
@@ -297,7 +312,7 @@ local function parse_number(n)
   local code = loadenv("return "..n)
   local code = loadenv("return "..n)
   if code then
   if code then
     local ok, y = pcall(code)
     local ok, y = pcall(code)
-    if ok then return y end
+    if ok and type(y) == "number" then return y end
   end
   end
   return nil
   return nil
 end
 end
@@ -403,7 +418,7 @@ local function parse_imm_load(imm, scale)
     end
     end
     werror("out of range immediate `"..imm.."'")
     werror("out of range immediate `"..imm.."'")
   else
   else
-    waction("IMML", 0, imm)
+    waction("IMML", scale, imm)
     return 0
     return 0
   end
   end
 end
 end
@@ -462,6 +477,7 @@ end
 
 
 local function parse_load(params, nparams, n, op)
 local function parse_load(params, nparams, n, op)
   if params[n+2] then werror("too many operands") end
   if params[n+2] then werror("too many operands") end
+  local scale = shr(op, 30)
   local pn, p2 = params[n], params[n+1]
   local pn, p2 = params[n], params[n+1]
   local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
   local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
   if not p1 then
   if not p1 then
@@ -470,14 +486,13 @@ local function parse_load(params, nparams, n, op)
       if reg and tailr ~= "" then
       if reg and tailr ~= "" then
 	local base, tp = parse_reg_base(reg)
 	local base, tp = parse_reg_base(reg)
 	if tp then
 	if tp then
-	  waction("IMML", 0, format(tp.ctypefmt, tailr))
+	  waction("IMML", scale, format(tp.ctypefmt, tailr))
 	  return op + base
 	  return op + base
 	end
 	end
       end
       end
     end
     end
     werror("expected address operand")
     werror("expected address operand")
   end
   end
-  local scale = shr(op, 30)
   if p2 then
   if p2 then
     if wb == "!" then werror("bad use of '!'") end
     if wb == "!" then werror("bad use of '!'") end
     op = op + parse_reg_base(p1) + parse_imm(p2, 9, 12, 0, true) + 0x400
     op = op + parse_reg_base(p1) + parse_imm(p2, 9, 12, 0, true) + 0x400
@@ -494,7 +509,7 @@ local function parse_load(params, nparams, n, op)
 	op = op + parse_imm_load(imm, scale)
 	op = op + parse_imm_load(imm, scale)
       else
       else
 	local p2b, p3b, p3s = match(p2a, "^,%s*([^,%s]*)%s*,?%s*(%S*)%s*(.*)$")
 	local p2b, p3b, p3s = match(p2a, "^,%s*([^,%s]*)%s*,?%s*(%S*)%s*(.*)$")
-	op = op + shl(parse_reg(p2b), 16) + 0x00200800
+	op = op + parse_reg(p2b, 16) + 0x00200800
 	if parse_reg_type ~= "x" and parse_reg_type ~= "w" then
 	if parse_reg_type ~= "x" and parse_reg_type ~= "w" then
 	  werror("bad index register type")
 	  werror("bad index register type")
 	end
 	end
@@ -561,14 +576,14 @@ local function parse_load_pair(params, nparams, n, op)
 end
 end
 
 
 local function parse_label(label, def)
 local function parse_label(label, def)
-  local prefix = sub(label, 1, 2)
+  local prefix = label:sub(1, 2)
   -- =>label (pc label reference)
   -- =>label (pc label reference)
   if prefix == "=>" then
   if prefix == "=>" then
-    return "PC", 0, sub(label, 3)
+    return "PC", 0, label:sub(3)
   end
   end
   -- ->name (global label reference)
   -- ->name (global label reference)
   if prefix == "->" then
   if prefix == "->" then
-    return "LG", map_global[sub(label, 3)]
+    return "LG", map_global[label:sub(3)]
   end
   end
   if def then
   if def then
     -- [1-9] (local label definition)
     -- [1-9] (local label definition)
@@ -586,8 +601,11 @@ local function parse_label(label, def)
     if extname then
     if extname then
       return "EXT", map_extern[extname]
       return "EXT", map_extern[extname]
     end
     end
+    -- &expr (pointer)
+    if label:sub(1, 1) == "&" then
+      return "A", 0, format("(ptrdiff_t)(%s)", label:sub(2))
+    end
   end
   end
-  werror("bad label `"..label.."'")
 end
 end
 
 
 local function branch_type(op)
 local function branch_type(op)
@@ -620,24 +638,24 @@ local function alias_bfx(p)
 end
 end
 
 
 local function alias_bfiz(p)
 local function alias_bfiz(p)
-  parse_reg(p[1])
+  parse_reg(p[1], 0)
   if parse_reg_type == "w" then
   if parse_reg_type == "w" then
-    p[3] = "#-("..p[3]:sub(2)..")%32"
+    p[3] = "#(32-("..p[3]:sub(2).."))%32"
     p[4] = "#("..p[4]:sub(2)..")-1"
     p[4] = "#("..p[4]:sub(2)..")-1"
   else
   else
-    p[3] = "#-("..p[3]:sub(2)..")%64"
+    p[3] = "#(64-("..p[3]:sub(2).."))%64"
     p[4] = "#("..p[4]:sub(2)..")-1"
     p[4] = "#("..p[4]:sub(2)..")-1"
   end
   end
 end
 end
 
 
 local alias_lslimm = op_alias("ubfm_4", function(p)
 local alias_lslimm = op_alias("ubfm_4", function(p)
-  parse_reg(p[1])
+  parse_reg(p[1], 0)
   local sh = p[3]:sub(2)
   local sh = p[3]:sub(2)
   if parse_reg_type == "w" then
   if parse_reg_type == "w" then
-    p[3] = "#-("..sh..")%32"
+    p[3] = "#(32-("..sh.."))%32"
     p[4] = "#31-("..sh..")"
     p[4] = "#31-("..sh..")"
   else
   else
-    p[3] = "#-("..sh..")%64"
+    p[3] = "#(64-("..sh.."))%64"
     p[4] = "#63-("..sh..")"
     p[4] = "#63-("..sh..")"
   end
   end
 end)
 end)
@@ -881,25 +899,25 @@ end
 
 
 -- Handle opcodes defined with template strings.
 -- Handle opcodes defined with template strings.
 local function parse_template(params, template, nparams, pos)
 local function parse_template(params, template, nparams, pos)
-  local op = tonumber(sub(template, 1, 8), 16)
+  local op = tonumber(template:sub(1, 8), 16)
   local n = 1
   local n = 1
   local rtt = {}
   local rtt = {}
 
 
   parse_reg_type = false
   parse_reg_type = false
 
 
   -- Process each character.
   -- Process each character.
-  for p in gmatch(sub(template, 9), ".") do
+  for p in gmatch(template:sub(9), ".") do
     local q = params[n]
     local q = params[n]
     if p == "D" then
     if p == "D" then
-      op = op + parse_reg(q); n = n + 1
+      op = op + parse_reg(q, 0); n = n + 1
     elseif p == "N" then
     elseif p == "N" then
-      op = op + shl(parse_reg(q), 5); n = n + 1
+      op = op + parse_reg(q, 5); n = n + 1
     elseif p == "M" then
     elseif p == "M" then
-      op = op + shl(parse_reg(q), 16); n = n + 1
+      op = op + parse_reg(q, 16); n = n + 1
     elseif p == "A" then
     elseif p == "A" then
-      op = op + shl(parse_reg(q), 10); n = n + 1
+      op = op + parse_reg(q, 10); n = n + 1
     elseif p == "m" then
     elseif p == "m" then
-      op = op + shl(parse_reg(params[n-1]), 16)
+      op = op + parse_reg(params[n-1], 16)
 
 
     elseif p == "p" then
     elseif p == "p" then
       if q == "sp" then params[n] = "@x31" end
       if q == "sp" then params[n] = "@x31" end
@@ -930,8 +948,14 @@ local function parse_template(params, template, nparams, pos)
 
 
     elseif p == "B" then
     elseif p == "B" then
       local mode, v, s = parse_label(q, false); n = n + 1
       local mode, v, s = parse_label(q, false); n = n + 1
+      if not mode then werror("bad label `"..q.."'") end
       local m = branch_type(op)
       local m = branch_type(op)
-      waction("REL_"..mode, v+m, s, 1)
+      if mode == "A" then
+	waction("REL_"..mode, v+m, format("(unsigned int)(%s)", s))
+	actargs[#actargs+1] = format("(unsigned int)((%s)>>32)", s)
+      else
+	waction("REL_"..mode, v+m, s, 1)
+      end
 
 
     elseif p == "I" then
     elseif p == "I" then
       op = op + parse_imm12(q); n = n + 1
       op = op + parse_imm12(q); n = n + 1
@@ -977,8 +1001,8 @@ function op_template(params, template, nparams)
   if not params then return template:gsub("%x%x%x%x%x%x%x%x", "") end
   if not params then return template:gsub("%x%x%x%x%x%x%x%x", "") end
 
 
   -- Limit number of section buffer positions used by a single dasm_put().
   -- Limit number of section buffer positions used by a single dasm_put().
-  -- A single opcode needs a maximum of 3 positions.
-  if secpos+3 > maxsecpos then wflush() end
+  -- A single opcode needs a maximum of 4 positions.
+  if secpos+4 > maxsecpos then wflush() end
   local pos = wpos()
   local pos = wpos()
   local lpos, apos, spos = #actlist, #actargs, secpos
   local lpos, apos, spos = #actlist, #actargs, secpos
 
 
@@ -990,9 +1014,11 @@ function op_template(params, template, nparams)
     actlist[lpos+1] = nil
     actlist[lpos+1] = nil
     actlist[lpos+2] = nil
     actlist[lpos+2] = nil
     actlist[lpos+3] = nil
     actlist[lpos+3] = nil
+    actlist[lpos+4] = nil
     actargs[apos+1] = nil
     actargs[apos+1] = nil
     actargs[apos+2] = nil
     actargs[apos+2] = nil
     actargs[apos+3] = nil
     actargs[apos+3] = nil
+    actargs[apos+4] = nil
   end
   end
   error(err, 0)
   error(err, 0)
 end
 end
@@ -1036,23 +1062,50 @@ map_op[".label_1"] = function(params)
   if not params then return "[1-9] | ->global | =>pcexpr" end
   if not params then return "[1-9] | ->global | =>pcexpr" end
   if secpos+1 > maxsecpos then wflush() end
   if secpos+1 > maxsecpos then wflush() end
   local mode, n, s = parse_label(params[1], true)
   local mode, n, s = parse_label(params[1], true)
-  if mode == "EXT" then werror("bad label definition") end
+  if not mode or mode == "EXT" then werror("bad label definition") end
   waction("LABEL_"..mode, n, s, 1)
   waction("LABEL_"..mode, n, s, 1)
 end
 end
 
 
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
 -- Pseudo-opcodes for data storage.
 -- Pseudo-opcodes for data storage.
-map_op[".long_*"] = function(params)
+local function op_data(params)
   if not params then return "imm..." end
   if not params then return "imm..." end
+  local sz = params.op == ".long" and 4 or 8
   for _,p in ipairs(params) do
   for _,p in ipairs(params) do
-    local n = tonumber(p)
-    if not n then werror("bad immediate `"..p.."'") end
-    if n < 0 then n = n + 2^32 end
-    wputw(n)
+    local imm = parse_number(p)
+    if imm then
+      local n = tobit(imm)
+      if n == imm or (n < 0 and n + 2^32 == imm) then
+	wputw(n < 0 and n + 2^32 or n)
+	if sz == 8 then
+	  wputw(imm < 0 and 0xffffffff or 0)
+	end
+      elseif sz == 4 then
+	werror("bad immediate `"..p.."'")
+      else
+	imm = nil
+      end
+    end
+    if not imm then
+      local mode, v, s = parse_label(p, false)
+      if sz == 4 then
+	if mode then werror("label does not fit into .long") end
+	waction("IMMV", 0, p)
+      elseif mode and mode ~= "A" then
+	waction("REL_"..mode, v+0x8000, s, 1)
+      else
+	if mode == "A" then p = s end
+	waction("IMMV", 0, format("(unsigned int)(%s)", p))
+	waction("IMMV", 0, format("(unsigned int)((unsigned long long)(%s)>>32)", p))
+      end
+    end
     if secpos+2 > maxsecpos then wflush() end
     if secpos+2 > maxsecpos then wflush() end
   end
   end
 end
 end
+map_op[".long_*"] = op_data
+map_op[".quad_*"] = op_data
+map_op[".addr_*"] = op_data
 
 
 -- Alignment pseudo-opcode.
 -- Alignment pseudo-opcode.
 map_op[".align_1"] = function(params)
 map_op[".align_1"] = function(params)

+ 6 - 3
libs/LuaJIT/dynasm/dasm_mips.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** DynASM MIPS encoding engine.
 ** DynASM MIPS encoding engine.
-** Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+** Copyright (C) 2005-2021 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.
 */
 */
 
 
@@ -273,7 +273,7 @@ int dasm_link(Dst_DECL, size_t *szp)
 
 
   { /* Handle globals not defined in this translation unit. */
   { /* Handle globals not defined in this translation unit. */
     int idx;
     int idx;
-    for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) {
+    for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
       int n = D->lglabels[idx];
       int n = D->lglabels[idx];
       /* Undefined label: Collapse rel chain and replace with marker (< 0). */
       /* Undefined label: Collapse rel chain and replace with marker (< 0). */
       while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
       while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
@@ -349,7 +349,10 @@ int dasm_encode(Dst_DECL, void *buffer)
 	  ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
 	  ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
 	  break;
 	  break;
 	case DASM_REL_LG:
 	case DASM_REL_LG:
-	  CK(n >= 0, UNDEF_LG);
+	  if (n < 0) {
+	    n = (int)((ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp);
+	    goto patchrel;
+	  }
 	  /* fallthrough */
 	  /* fallthrough */
 	case DASM_REL_PC:
 	case DASM_REL_PC:
 	  CK(n >= 0, UNDEF_PC);
 	  CK(n >= 0, UNDEF_PC);

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

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM MIPS32/MIPS64 module.
 -- DynASM MIPS32/MIPS64 module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
 -- See dynasm.lua for full copyright notice.
 -- See dynasm.lua for full copyright notice.
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
@@ -12,9 +12,9 @@ local mipsr6 = _map_def.MIPSR6
 local _info = {
 local _info = {
   arch =	mips64 and "mips64" or "mips",
   arch =	mips64 and "mips64" or "mips",
   description =	"DynASM MIPS32/MIPS64 module",
   description =	"DynASM MIPS32/MIPS64 module",
-  version =	"1.4.0",
-  vernum =	 10400,
-  release =	"2020-01-20",
+  version =	"1.5.0",
+  vernum =	 10500,
+  release =	"2021-05-02",
   author =	"Mike Pall",
   author =	"Mike Pall",
   license =	"MIT",
   license =	"MIT",
 }
 }

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

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM MIPS64 module.
 -- DynASM MIPS64 module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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.

+ 6 - 3
libs/LuaJIT/dynasm/dasm_ppc.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** DynASM PPC/PPC64 encoding engine.
 ** DynASM PPC/PPC64 encoding engine.
-** Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+** Copyright (C) 2005-2021 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.
 */
 */
 
 
@@ -277,7 +277,7 @@ int dasm_link(Dst_DECL, size_t *szp)
 
 
   { /* Handle globals not defined in this translation unit. */
   { /* Handle globals not defined in this translation unit. */
     int idx;
     int idx;
-    for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) {
+    for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
       int n = D->lglabels[idx];
       int n = D->lglabels[idx];
       /* Undefined label: Collapse rel chain and replace with marker (< 0). */
       /* Undefined label: Collapse rel chain and replace with marker (< 0). */
       while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
       while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
@@ -353,7 +353,10 @@ int dasm_encode(Dst_DECL, void *buffer)
 	  ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
 	  ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
 	  break;
 	  break;
 	case DASM_REL_LG:
 	case DASM_REL_LG:
-	  CK(n >= 0, UNDEF_LG);
+	  if (n < 0) {
+	    n = (int)((ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp);
+	    goto patchrel;
+	  }
 	  /* fallthrough */
 	  /* fallthrough */
 	case DASM_REL_PC:
 	case DASM_REL_PC:
 	  CK(n >= 0, UNDEF_PC);
 	  CK(n >= 0, UNDEF_PC);

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

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM PPC/PPC64 module.
 -- DynASM PPC/PPC64 module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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.
@@ -11,9 +11,9 @@
 local _info = {
 local _info = {
   arch =	"ppc",
   arch =	"ppc",
   description =	"DynASM PPC module",
   description =	"DynASM PPC module",
-  version =	"1.4.0",
-  vernum =	 10400,
-  release =	"2015-10-18",
+  version =	"1.5.0",
+  vernum =	 10500,
+  release =	"2021-05-02",
   author =	"Mike Pall",
   author =	"Mike Pall",
   license =	"MIT",
   license =	"MIT",
 }
 }

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** DynASM encoding engine prototypes.
 ** DynASM encoding engine prototypes.
-** Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+** Copyright (C) 2005-2021 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.
 */
 */
 
 
@@ -10,8 +10,8 @@
 #include <stddef.h>
 #include <stddef.h>
 #include <stdarg.h>
 #include <stdarg.h>
 
 
-#define DASM_IDENT	"DynASM 1.4.0"
-#define DASM_VERSION	10400	/* 1.4.0 */
+#define DASM_IDENT	"DynASM 1.5.0"
+#define DASM_VERSION	10500	/* 1.5.0 */
 
 
 #ifndef Dst_DECL
 #ifndef Dst_DECL
 #define Dst_DECL	dasm_State **Dst
 #define Dst_DECL	dasm_State **Dst

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

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM x64 module.
 -- DynASM x64 module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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.

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** DynASM x86 encoding engine.
 ** DynASM x86 encoding engine.
-** Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+** Copyright (C) 2005-2021 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.
 */
 */
 
 
@@ -239,8 +239,11 @@ void dasm_put(Dst_DECL, int start, ...)
 	}
 	}
 	pos++;
 	pos++;
 	ofs += 4;  /* Maximum offset needed. */
 	ofs += 4;  /* Maximum offset needed. */
-	if (action == DASM_REL_LG || action == DASM_REL_PC)
+	if (action == DASM_REL_LG || action == DASM_REL_PC) {
 	  b[pos++] = ofs;  /* Store pass1 offset estimate. */
 	  b[pos++] = ofs;  /* Store pass1 offset estimate. */
+	} else if (sizeof(ptrdiff_t) == 8) {
+	  ofs += 4;
+	}
 	break;
 	break;
       case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
       case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
       case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
       case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
@@ -365,10 +368,22 @@ int dasm_link(Dst_DECL, size_t *szp)
   do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
   do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
 #define dasmd(x) \
 #define dasmd(x) \
   do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
   do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
+#define dasmq(x) \
+  do { *((unsigned long long *)cp) = (unsigned long long)(x); cp+=8; } while (0)
 #else
 #else
 #define dasmw(x)	do { dasmb(x); dasmb((x)>>8); } while (0)
 #define dasmw(x)	do { dasmb(x); dasmb((x)>>8); } while (0)
 #define dasmd(x)	do { dasmw(x); dasmw((x)>>16); } while (0)
 #define dasmd(x)	do { dasmw(x); dasmw((x)>>16); } while (0)
+#define dasmq(x)	do { dasmd(x); dasmd((x)>>32); } while (0)
 #endif
 #endif
+static unsigned char *dasma_(unsigned char *cp, ptrdiff_t x)
+{
+  if (sizeof(ptrdiff_t) == 8)
+    dasmq((unsigned long long)x);
+  else
+    dasmd((unsigned int)x);
+  return cp;
+}
+#define dasma(x)	(cp = dasma_(cp, (x)))
 
 
 /* Pass 3: Encode sections. */
 /* Pass 3: Encode sections. */
 int dasm_encode(Dst_DECL, void *buffer)
 int dasm_encode(Dst_DECL, void *buffer)
@@ -443,12 +458,13 @@ int dasm_encode(Dst_DECL, void *buffer)
 	  goto wb;
 	  goto wb;
 	}
 	}
 	case DASM_IMM_LG:
 	case DASM_IMM_LG:
-	  p++; if (n < 0) { n = (int)(ptrdiff_t)D->globals[-n]; goto wd; }
+	  p++;
+	  if (n < 0) { dasma((ptrdiff_t)D->globals[-n]); break; }
 	  /* fallthrough */
 	  /* fallthrough */
 	case DASM_IMM_PC: {
 	case DASM_IMM_PC: {
 	  int *pb = DASM_POS2PTR(D, n);
 	  int *pb = DASM_POS2PTR(D, n);
-	  n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);
-	  goto wd;
+	  dasma(*pb < 0 ? (ptrdiff_t)pb[1] : (*pb + (ptrdiff_t)base));
+	  break;
 	}
 	}
 	case DASM_LABEL_LG: {
 	case DASM_LABEL_LG: {
 	  int idx = *p++;
 	  int idx = *p++;

+ 40 - 12
libs/LuaJIT/dynasm/dasm_x86.lua

@@ -1,7 +1,7 @@
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 -- DynASM x86/x64 module.
 -- DynASM x86/x64 module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
 -- See dynasm.lua for full copyright notice.
 -- See dynasm.lua for full copyright notice.
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
@@ -11,9 +11,9 @@ local x64 = x64
 local _info = {
 local _info = {
   arch =	x64 and "x64" or "x86",
   arch =	x64 and "x64" or "x86",
   description =	"DynASM x86/x64 module",
   description =	"DynASM x86/x64 module",
-  version =	"1.4.0",
-  vernum =	 10400,
-  release =	"2015-10-18",
+  version =	"1.5.0",
+  vernum =	 10500,
+  release =	"2021-05-02",
   author =	"Mike Pall",
   author =	"Mike Pall",
   license =	"MIT",
   license =	"MIT",
 }
 }
@@ -484,6 +484,22 @@ local function wputdarg(n)
   end
   end
 end
 end
 
 
+-- Put signed or unsigned qword or arg.
+local function wputqarg(n)
+  local tn = type(n)
+  if tn == "number" then -- This is only used for numbers from -2^31..2^32-1.
+    wputb(band(n, 255))
+    wputb(band(shr(n, 8), 255))
+    wputb(band(shr(n, 16), 255))
+    wputb(shr(n, 24))
+    local sign = n < 0 and 255 or 0
+    wputb(sign); wputb(sign); wputb(sign); wputb(sign)
+  else
+    waction("IMM_D", format("(unsigned int)(%s)", n))
+    waction("IMM_D", format("(unsigned int)((unsigned long long)(%s)>>32)", n))
+  end
+end
+
 -- Put operand-size dependent number or arg (defaults to dword).
 -- Put operand-size dependent number or arg (defaults to dword).
 local function wputszarg(sz, n)
 local function wputszarg(sz, n)
   if not sz or sz == "d" or sz == "q" then wputdarg(n)
   if not sz or sz == "d" or sz == "q" then wputdarg(n)
@@ -663,10 +679,16 @@ local function opmodestr(op, args)
 end
 end
 
 
 -- Convert number to valid integer or nil.
 -- Convert number to valid integer or nil.
-local function toint(expr)
+local function toint(expr, isqword)
   local n = tonumber(expr)
   local n = tonumber(expr)
   if n then
   if n then
-    if n % 1 ~= 0 or n < -2147483648 or n > 4294967295 then
+    if n % 1 ~= 0 then
+      werror("not an integer number `"..expr.."'")
+    elseif isqword then
+      if n < -2147483648 or n > 2147483647 then
+	n = nil -- Handle it as an expression to avoid precision loss.
+      end
+    elseif n < -2147483648 or n > 4294967295 then
       werror("bad integer number `"..expr.."'")
       werror("bad integer number `"..expr.."'")
     end
     end
     return n
     return n
@@ -749,7 +771,7 @@ local function rtexpr(expr)
 end
 end
 
 
 -- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
 -- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
-local function parseoperand(param)
+local function parseoperand(param, isqword)
   local t = {}
   local t = {}
 
 
   local expr = param
   local expr = param
@@ -810,7 +832,7 @@ local function parseoperand(param)
       if t.disp then break end
       if t.disp then break end
 
 
       -- [reg+xreg...]
       -- [reg+xreg...]
-      local xreg, tailx = match(tailr, "^+%s*([@%w_:]+)%s*(.*)$")
+      local xreg, tailx = match(tailr, "^%+%s*([@%w_:]+)%s*(.*)$")
       xreg, t.xreg, tp = rtexpr(xreg)
       xreg, t.xreg, tp = rtexpr(xreg)
       if not t.xreg then
       if not t.xreg then
 	-- [reg+-expr]
 	-- [reg+-expr]
@@ -837,7 +859,7 @@ local function parseoperand(param)
       t.disp = dispexpr(tailx)
       t.disp = dispexpr(tailx)
     else
     else
       -- imm or opsize*imm
       -- imm or opsize*imm
-      local imm = toint(expr)
+      local imm = toint(expr, isqword)
       if not imm and sub(expr, 1, 1) == "*" and t.opsize then
       if not imm and sub(expr, 1, 1) == "*" and t.opsize then
 	imm = toint(sub(expr, 2))
 	imm = toint(sub(expr, 2))
 	if imm then
 	if imm then
@@ -1952,7 +1974,7 @@ local function dopattern(pat, args, sz, op, needrex)
 	local a = args[narg]
 	local a = args[narg]
 	narg = narg + 1
 	narg = narg + 1
 	local mode, imm = a.mode, a.imm
 	local mode, imm = a.mode, a.imm
-	if mode == "iJ" and not match("iIJ", c) then
+	if mode == "iJ" and not match(x64 and "J" or "iIJ", c) then
 	  werror("bad operand size for label")
 	  werror("bad operand size for label")
 	end
 	end
 	if c == "S" then
 	if c == "S" then
@@ -2144,14 +2166,16 @@ end
 local function op_data(params)
 local function op_data(params)
   if not params then return "imm..." end
   if not params then return "imm..." end
   local sz = sub(params.op, 2, 2)
   local sz = sub(params.op, 2, 2)
-  if sz == "a" then sz = addrsize end
+  if sz == "l" then sz = "d" elseif sz == "a" then sz = addrsize end
   for _,p in ipairs(params) do
   for _,p in ipairs(params) do
-    local a = parseoperand(p)
+    local a = parseoperand(p, sz == "q")
     if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
     if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
       werror("bad mode or size in `"..p.."'")
       werror("bad mode or size in `"..p.."'")
     end
     end
     if a.mode == "iJ" then
     if a.mode == "iJ" then
       wputlabel("IMM_", a.imm, 1)
       wputlabel("IMM_", a.imm, 1)
+    elseif sz == "q" then
+      wputqarg(a.imm)
     else
     else
       wputszarg(sz, a.imm)
       wputszarg(sz, a.imm)
     end
     end
@@ -2163,7 +2187,11 @@ map_op[".byte_*"] = op_data
 map_op[".sbyte_*"] = op_data
 map_op[".sbyte_*"] = op_data
 map_op[".word_*"] = op_data
 map_op[".word_*"] = op_data
 map_op[".dword_*"] = op_data
 map_op[".dword_*"] = op_data
+map_op[".qword_*"] = op_data
 map_op[".aword_*"] = op_data
 map_op[".aword_*"] = op_data
+map_op[".long_*"] = op_data
+map_op[".quad_*"] = op_data
+map_op[".addr_*"] = op_data
 
 
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 

+ 5 - 5
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-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 Mike Pall. All rights reserved.
 -- See below for full copyright notice.
 -- See below for full copyright notice.
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
@@ -10,14 +10,14 @@
 local _info = {
 local _info = {
   name =	"DynASM",
   name =	"DynASM",
   description =	"A dynamic assembler for code generation engines",
   description =	"A dynamic assembler for code generation engines",
-  version =	"1.4.0",
-  vernum =	 10400,
-  release =	"2015-10-18",
+  version =	"1.5.0",
+  vernum =	 10500,
+  release =	"2021-05-02",
   author =	"Mike Pall",
   author =	"Mike Pall",
   url =		"https://luajit.org/dynasm.html",
   url =		"https://luajit.org/dynasm.html",
   license =	"MIT",
   license =	"MIT",
   copyright =	[[
   copyright =	[[
-Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+Copyright (C) 2005-2021 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

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

@@ -74,7 +74,7 @@ luajit \-jv \-e "for i=1,10 do for j=1,10 do for k=1,100 do end end end"
 Runs some nested loops and shows the resulting traces.
 Runs some nested loops and shows the resulting traces.
 .SH COPYRIGHT
 .SH COPYRIGHT
 .PP
 .PP
-\fBLuaJIT\fR is Copyright \(co 2005-2020 Mike Pall.
+\fBLuaJIT\fR is Copyright \(co 2005-2021 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

+ 15 - 8
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-2020 Mike Pall. See Copyright Notice in luajit.h
+# Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 ##############################################################################
 ##############################################################################
 
 
 MAJVER=  2
 MAJVER=  2
@@ -211,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 2>/dev/null
+TARGET_AR= $(CROSS)ar rcus
 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,6 +311,7 @@ ifeq (Windows,$(TARGET_SYS))
   TARGET_XSHLDFLAGS= -shared -Wl,--out-implib,$(TARGET_DLLDOTANAME)
   TARGET_XSHLDFLAGS= -shared -Wl,--out-implib,$(TARGET_DLLDOTANAME)
   TARGET_DYNXLDOPTS=
   TARGET_DYNXLDOPTS=
 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
@@ -319,13 +320,10 @@ ifeq (Darwin,$(TARGET_SYS))
     $(error missing: export MACOSX_DEPLOYMENT_TARGET=XX.YY)
     $(error missing: export MACOSX_DEPLOYMENT_TARGET=XX.YY)
   endif
   endif
   TARGET_STRIP+= -x
   TARGET_STRIP+= -x
+  TARGET_XCFLAGS+= -DLUAJIT_UNWIND_EXTERNAL
   TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
   TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
   TARGET_DYNXLDOPTS=
   TARGET_DYNXLDOPTS=
   TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER)
   TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER)
-  ifeq (x64,$(TARGET_LJARCH))
-    TARGET_XLDFLAGS+= -pagezero_size 10000 -image_base 100000000
-    TARGET_XSHLDFLAGS+= -image_base 7fff04c4a000
-  endif
 else
 else
 ifeq (iOS,$(TARGET_SYS))
 ifeq (iOS,$(TARGET_SYS))
   TARGET_STRIP+= -x
   TARGET_STRIP+= -x
@@ -336,6 +334,13 @@ ifeq (iOS,$(TARGET_SYS))
     TARGET_XCFLAGS+= -fno-omit-frame-pointer
     TARGET_XCFLAGS+= -fno-omit-frame-pointer
   endif
   endif
 else
 else
+  ifeq (,$(findstring LJ_NO_UNWIND 1,$(TARGET_TESTARCH)))
+    # Find out whether the target toolchain always generates unwind tables.
+    TARGET_TESTUNWIND=$(shell exec 2>/dev/null; echo 'extern void b(void);int a(void){b();return 0;}' | $(TARGET_CC) -c -x c - -o tmpunwind.o && { grep -qa -e eh_frame -e __unwind_info tmpunwind.o || grep -qU -e eh_frame -e __unwind_info tmpunwind.o; } && echo E; rm -f tmpunwind.o)
+    ifneq (,$(findstring E,$(TARGET_TESTUNWIND)))
+      TARGET_XCFLAGS+= -DLUAJIT_UNWIND_EXTERNAL
+    endif
+  endif
   ifneq (SunOS,$(TARGET_SYS))
   ifneq (SunOS,$(TARGET_SYS))
     ifneq (PS3,$(TARGET_SYS))
     ifneq (PS3,$(TARGET_SYS))
       TARGET_XLDFLAGS+= -Wl,-E
       TARGET_XLDFLAGS+= -Wl,-E
@@ -479,13 +484,15 @@ LJVM_BOUT= $(LJVM_S)
 LJVM_MODE= elfasm
 LJVM_MODE= elfasm
 
 
 LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \
 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 \
+	 lib_buffer.o
 LJLIB_C= $(LJLIB_O:.o=.c)
 LJLIB_C= $(LJLIB_O:.o=.c)
 
 
 LJCORE_O= lj_assert.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_prng.o lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.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_strscan.o lj_strfmt.o lj_strfmt_num.o lj_serialize.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 \

+ 41 - 33
libs/LuaJIT/src/Makefile.dep

@@ -2,14 +2,18 @@ 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_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_tab.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cconv.h \
- lj_ff.h lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \
- lj_strfmt.h lj_lib.h lj_libdef.h
+ lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.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_ff.h lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h \
+ lj_strscan.h lj_strfmt.h lj_lib.h lj_libdef.h
 lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
 lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
  lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strscan.h \
  lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strscan.h \
  lj_strfmt.h lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h \
  lj_strfmt.h lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h \
  lj_ffdef.h lj_lib.h lj_libdef.h
  lj_ffdef.h lj_lib.h lj_libdef.h
+lib_buffer.o: lib_buffer.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_tab.h lj_udata.h lj_meta.h lj_ctype.h lj_cdata.h lj_cconv.h \
+ lj_strfmt.h lj_serialize.h lj_lib.h lj_libdef.h
 lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
 lib_debug.o: lib_debug.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_lib.h \
  lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_lib.h \
  lj_libdef.h
  lj_libdef.h
@@ -48,10 +52,10 @@ lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.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 \
  lj_dispatch.h lj_traceerr.h lj_vm.h lj_strscan.h lj_strfmt.h
  lj_dispatch.h lj_traceerr.h lj_vm.h lj_strscan.h lj_strfmt.h
 lj_asm.o: lj_asm.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
 lj_asm.o: lj_asm.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
- lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_ir.h lj_jit.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_asm_*.h
+ lj_buf.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_ir.h \
+ lj_jit.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_asm_*.h
 lj_assert.o: lj_assert.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.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
@@ -77,8 +81,8 @@ lj_ccallback.o: lj_ccallback.c lj_obj.h lua.h luaconf.h lj_def.h \
  lj_target_*.h lj_mcode.h lj_jit.h lj_ir.h lj_trace.h lj_dispatch.h \
  lj_target_*.h lj_mcode.h lj_jit.h lj_ir.h lj_trace.h lj_dispatch.h \
  lj_traceerr.h lj_vm.h
  lj_traceerr.h lj_vm.h
 lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h \
- lj_ccallback.h
+ lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_tab.h lj_ctype.h \
+ lj_cdata.h lj_cconv.h lj_ccallback.h
 lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_cconv.h lj_cdata.h
  lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_cconv.h lj_cdata.h
 lj_char.o: lj_char.c lj_char.h lj_def.h lua.h luaconf.h
 lj_char.o: lj_char.c lj_char.h lj_def.h lua.h luaconf.h
@@ -110,10 +114,10 @@ lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \
  lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
  lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
  lj_traceerr.h lj_vm.h lj_strfmt.h
  lj_traceerr.h lj_vm.h lj_strfmt.h
 lj_ffrecord.o: lj_ffrecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_ffrecord.o: lj_ffrecord.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_frame.h lj_bc.h lj_ff.h \
- lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
- lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_crecord.h \
- lj_vm.h lj_strscan.h lj_strfmt.h lj_recdef.h
+ lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_tab.h lj_frame.h \
+ lj_bc.h lj_ff.h lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h \
+ lj_trace.h lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h \
+ lj_crecord.h lj_vm.h lj_strscan.h lj_strfmt.h lj_serialize.h lj_recdef.h
 lj_func.o: lj_func.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
 lj_func.o: lj_func.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
  lj_func.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
  lj_func.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
  lj_traceerr.h lj_vm.h
  lj_traceerr.h lj_vm.h
@@ -127,15 +131,15 @@ 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_prng.h
+ lj_carith.h lj_vm.h lj_strscan.h lj_serialize.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 \
  lj_strfmt.h
  lj_strfmt.h
 lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
 lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
- lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lex.h \
- lj_bcdump.h lj_lib.h
+ lj_dispatch.h lj_jit.h lj_ir.h lj_ctype.h lj_vm.h lj_strscan.h \
+ lj_strfmt.h lj_lex.h lj_bcdump.h lj_lib.h
 lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
 lj_load.o: lj_load.c lua.h luaconf.h lauxlib.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_func.h \
  lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_func.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
@@ -170,15 +174,18 @@ lj_parse.o: lj_parse.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_buf.h lj_str.h lj_tab.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \
  lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_strfmt.h lj_lex.h lj_parse.h \
  lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_strfmt.h lj_lex.h lj_parse.h \
  lj_vm.h lj_vmevent.h
  lj_vm.h lj_vmevent.h
+lj_prng.o: lj_prng.c lj_def.h lua.h luaconf.h lj_arch.h lj_prng.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_prng.h
  lj_record.h lj_ffrecord.h lj_snap.h lj_vm.h lj_prng.h
+lj_serialize.o: lj_serialize.c lj_obj.h lua.h luaconf.h lj_def.h \
+ lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \
+ lj_udata.h lj_ctype.h lj_cdata.h lj_ir.h lj_serialize.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 \
@@ -189,9 +196,10 @@ lj_state.o: lj_state.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_prng.h lj_lex.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_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_prng.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 \
- lj_buf.h lj_gc.h lj_str.h lj_state.h lj_char.h lj_strfmt.h
+ lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_meta.h lj_state.h \
+ lj_char.h lj_strfmt.h lj_ctype.h lj_lib.h
 lj_strfmt_num.o: lj_strfmt_num.c lj_obj.h lua.h luaconf.h lj_def.h \
 lj_strfmt_num.o: lj_strfmt_num.c lj_obj.h lua.h luaconf.h lj_def.h \
  lj_arch.h lj_buf.h lj_gc.h lj_str.h lj_strfmt.h
  lj_arch.h lj_buf.h lj_gc.h lj_str.h lj_strfmt.h
 lj_strscan.o: lj_strscan.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
 lj_strscan.o: lj_strscan.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
@@ -204,7 +212,7 @@ lj_trace.o: lj_trace.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.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_prng.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_err.h lj_errmsg.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 \
  lj_str.h lj_tab.h lj_state.h lj_dispatch.h lj_bc.h lj_jit.h lj_ir.h \
  lj_str.h lj_tab.h lj_state.h lj_dispatch.h lj_bc.h lj_jit.h lj_ir.h \
  lj_vm.h lj_vmevent.h
  lj_vm.h lj_vmevent.h
@@ -216,23 +224,23 @@ ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_assert.c lj_obj.h \
  lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.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_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_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_prng.h 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_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_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_vmmath.c lj_strscan.c lj_strfmt.c lj_strfmt_num.c lj_serialize.c \
+ lj_serialize.h 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_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 \
  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_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_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c \
- lib_init.c
+ lib_buffer.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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _BUILDVM_H
 #ifndef _BUILDVM_H

+ 1 - 1
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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #include "buildvm.h"
 #include "buildvm.h"

+ 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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #include "buildvm.h"
 #include "buildvm.h"

+ 3 - 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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #include "buildvm.h"
 #include "buildvm.h"
@@ -385,6 +385,8 @@ void emit_lib(BuildCtx *ctx)
 	  ok = LJ_HASJIT;
 	  ok = LJ_HASJIT;
 	else if (!strcmp(buf, "#if LJ_HASFFI\n"))
 	else if (!strcmp(buf, "#if LJ_HASFFI\n"))
 	  ok = LJ_HASFFI;
 	  ok = LJ_HASFFI;
+	else if (!strcmp(buf, "#if LJ_HASBUFFER\n"))
+	  ok = LJ_HASBUFFER;
 	if (!ok) {
 	if (!ok) {
 	  int lvl = 1;
 	  int lvl = 1;
 	  while (fgets(buf, sizeof(buf), fp) != NULL) {
 	  while (fgets(buf, sizeof(buf), fp) != NULL) {

+ 1 - 1
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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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.

+ 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-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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/minilua.c

@@ -1134,7 +1134,7 @@ if(!cl->isC){
 CallInfo*ci;
 CallInfo*ci;
 StkId st,base;
 StkId st,base;
 Proto*p=cl->p;
 Proto*p=cl->p;
-luaD_checkstack(L,p->maxstacksize);
+luaD_checkstack(L,p->maxstacksize+p->numparams);
 func=restorestack(L,funcr);
 func=restorestack(L,funcr);
 if(!p->is_vararg){
 if(!p->is_vararg){
 base=func+1;
 base=func+1;

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

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT bytecode listing module.
 -- LuaJIT bytecode listing module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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/bcsave.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT module to save/list bytecode.
 -- LuaJIT module to save/list bytecode.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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/dis_arm.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT ARM disassembler module.
 -- LuaJIT ARM disassembler module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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.

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

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT ARM64 disassembler module.
 -- LuaJIT ARM64 disassembler module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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.
@@ -1089,7 +1089,7 @@ local function disass_ins(ctx)
 	  last = "#"..(sf+32 - immr)
 	  last = "#"..(sf+32 - immr)
 	  operands[#operands] = last
 	  operands[#operands] = last
 	  x = x + 1
 	  x = x + 1
-	elseif x >= immr then
+	else
 	  name = a2
 	  name = a2
 	  x = x - immr + 1
 	  x = x - immr + 1
 	end
 	end

+ 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-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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

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

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT MIPS disassembler module.
 -- LuaJIT MIPS disassembler module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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_mips64.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT MIPS64 disassembler wrapper module.
 -- LuaJIT MIPS64 disassembler wrapper module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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_mips64r6.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT MIPS64R6 disassembler wrapper module.
 -- LuaJIT MIPS64R6 disassembler wrapper module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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 r6 big-endian functions from the
 -- This module just exports the r6 big-endian functions from the

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

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT MIPS64R6EL disassembler wrapper module.
 -- LuaJIT MIPS64R6EL disassembler wrapper module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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 r6 little-endian functions from the
 -- This module just exports the r6 little-endian functions from the

+ 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-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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.

+ 26 - 14
libs/LuaJIT/src/jit/dump.lua

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT compiler dump module.
 -- LuaJIT compiler dump module.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 --
 --
@@ -102,10 +102,12 @@ end
 local function fillsymtab(tr, nexit)
 local function fillsymtab(tr, nexit)
   local t = symtab
   local t = symtab
   if nexitsym == 0 then
   if nexitsym == 0 then
+    local maskaddr = jit.arch == "arm" and -2
     local ircall = vmdef.ircall
     local ircall = vmdef.ircall
     for i=0,#ircall do
     for i=0,#ircall do
       local addr = ircalladdr(i)
       local addr = ircalladdr(i)
       if addr ~= 0 then
       if addr ~= 0 then
+	if maskaddr then addr = band(addr, maskaddr) end
 	if addr < 0 then addr = addr + 2^32 end
 	if addr < 0 then addr = addr + 2^32 end
 	t[addr] = ircall[i]
 	t[addr] = ircall[i]
       end
       end
@@ -217,8 +219,10 @@ local function colorize_text(s)
   return s
   return s
 end
 end
 
 
-local function colorize_ansi(s, t)
-  return format(colortype_ansi[t], s)
+local function colorize_ansi(s, t, extra)
+  local out = format(colortype_ansi[t], s)
+  if extra then out = "\027[3m"..out end
+  return out
 end
 end
 
 
 local irtype_ansi = setmetatable({},
 local irtype_ansi = setmetatable({},
@@ -227,9 +231,10 @@ local irtype_ansi = setmetatable({},
 
 
 local html_escape = { ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;", }
 local html_escape = { ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;", }
 
 
-local function colorize_html(s, t)
+local function colorize_html(s, t, extra)
   s = gsub(s, "[<>&]", html_escape)
   s = gsub(s, "[<>&]", html_escape)
-  return format('<span class="irt_%s">%s</span>', irtype_text[t], s)
+  return format('<span class="irt_%s%s">%s</span>',
+		irtype_text[t], extra and " irt_extra" or "", s)
 end
 end
 
 
 local irtype_html = setmetatable({},
 local irtype_html = setmetatable({},
@@ -254,6 +259,7 @@ span.irt_tab { color: #c00000; }
 span.irt_udt, span.irt_lud { color: #00c0c0; }
 span.irt_udt, span.irt_lud { color: #00c0c0; }
 span.irt_num { color: #4040c0; }
 span.irt_num { color: #4040c0; }
 span.irt_int, span.irt_i8, span.irt_u8, span.irt_i16, span.irt_u16 { color: #b040b0; }
 span.irt_int, span.irt_i8, span.irt_u8, span.irt_i16, span.irt_u16 { color: #b040b0; }
+span.irt_extra { font-style: italic; }
 </style>
 </style>
 ]]
 ]]
 
 
@@ -269,6 +275,7 @@ local litname = {
     if band(mode, 8) ~= 0 then s = s.."C" end
     if band(mode, 8) ~= 0 then s = s.."C" end
     if band(mode, 16) ~= 0 then s = s.."R" end
     if band(mode, 16) ~= 0 then s = s.."R" end
     if band(mode, 32) ~= 0 then s = s.."I" end
     if band(mode, 32) ~= 0 then s = s.."I" end
+    if band(mode, 64) ~= 0 then s = s.."K" end
     t[mode] = s
     t[mode] = s
     return s
     return s
   end}),
   end}),
@@ -277,15 +284,18 @@ local litname = {
     local s = irtype[band(mode, 31)]
     local s = irtype[band(mode, 31)]
     s = irtype[band(shr(mode, 5), 31)].."."..s
     s = irtype[band(shr(mode, 5), 31)].."."..s
     if band(mode, 0x800) ~= 0 then s = s.." sext" end
     if band(mode, 0x800) ~= 0 then s = s.." sext" end
-    local c = shr(mode, 14)
-    if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end
+    local c = shr(mode, 12)
+    if c == 1 then s = s.." none"
+    elseif c == 2 then s = s.." index"
+    elseif c == 3 then s = s.." check" end
     t[mode] = s
     t[mode] = s
     return s
     return s
   end}),
   end}),
   ["FLOAD "] = vmdef.irfield,
   ["FLOAD "] = vmdef.irfield,
   ["FREF  "] = vmdef.irfield,
   ["FREF  "] = vmdef.irfield,
   ["FPMATH"] = vmdef.irfpm,
   ["FPMATH"] = vmdef.irfpm,
-  ["BUFHDR"] = { [0] = "RESET", "APPEND" },
+  ["TMPREF"] = { [0] = "", "IN", "OUT", "INOUT", "", "", "OUT2", "INOUT2" },
+  ["BUFHDR"] = { [0] = "RESET", "APPEND", "WRITE" },
   ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" },
   ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" },
 }
 }
 
 
@@ -345,7 +355,7 @@ local function formatk(tr, idx, sn)
   else
   else
     s = tostring(k) -- For primitives.
     s = tostring(k) -- For primitives.
   end
   end
-  s = colorize(format("%-4s", s), t)
+  s = colorize(format("%-4s", s), t, band(sn or 0, 0x100000) ~= 0)
   if slot then
   if slot then
     s = format("%s @%d", s, slot)
     s = format("%s @%d", s, slot)
   end
   end
@@ -365,7 +375,7 @@ local function printsnap(tr, snap)
 	out:write(colorize(format("%04d/%04d", ref, ref+1), 14))
 	out:write(colorize(format("%04d/%04d", ref, ref+1), 14))
       else
       else
 	local m, ot, op1, op2 = traceir(tr, ref)
 	local m, ot, op1, op2 = traceir(tr, ref)
-	out:write(colorize(format("%04d", ref), band(ot, 31)))
+	out:write(colorize(format("%04d", ref), band(ot, 31), band(sn, 0x100000) ~= 0))
       end
       end
       out:write(band(sn, 0x10000) == 0 and " " or "|") -- SNAP_FRAME
       out:write(band(sn, 0x10000) == 0 and " " or "|") -- SNAP_FRAME
     else
     else
@@ -584,7 +594,7 @@ local function dump_trace(what, tr, func, pc, otr, oex)
 end
 end
 
 
 -- Dump recorded bytecode.
 -- Dump recorded bytecode.
-local function dump_record(tr, func, pc, depth, callee)
+local function dump_record(tr, func, pc, depth)
   if depth ~= recdepth then
   if depth ~= recdepth then
     recdepth = depth
     recdepth = depth
     recprefix = rep(" .", depth)
     recprefix = rep(" .", depth)
@@ -595,7 +605,6 @@ local function dump_record(tr, func, pc, depth, callee)
     if dumpmode.H then line = gsub(line, "[<>&]", html_escape) end
     if dumpmode.H then line = gsub(line, "[<>&]", html_escape) end
   else
   else
     line = "0000 "..recprefix.." FUNCC      \n"
     line = "0000 "..recprefix.." FUNCC      \n"
-    callee = func
   end
   end
   if pc <= 0 then
   if pc <= 0 then
     out:write(sub(line, 1, -2), "         ; ", fmtfunc(func), "\n")
     out:write(sub(line, 1, -2), "         ; ", fmtfunc(func), "\n")
@@ -609,12 +618,15 @@ end
 
 
 ------------------------------------------------------------------------------
 ------------------------------------------------------------------------------
 
 
+local gpr64 = jit.arch:match("64")
+local fprmips32 = jit.arch == "mips" or jit.arch == "mipsel"
+
 -- Dump taken trace exits.
 -- Dump taken trace exits.
 local function dump_texit(tr, ex, ngpr, nfpr, ...)
 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:sub(-2) == "64" then
+    if gpr64 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
@@ -625,7 +637,7 @@ local function dump_texit(tr, ex, ngpr, nfpr, ...)
 	if i % 8 == 0 then out:write("\n") end
 	if i % 8 == 0 then out:write("\n") end
       end
       end
     end
     end
-    if jit.arch == "mips" or jit.arch == "mipsel" then
+    if fprmips32 then
       for i=1,nfpr,2 do
       for i=1,nfpr,2 do
 	out:write(format(" %+17.14g", regs[ngpr+i]))
 	out:write(format(" %+17.14g", regs[ngpr+i]))
 	if i % 8 == 7 then out:write("\n") end
 	if i % 8 == 7 then out:write("\n") end

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

@@ -1,7 +1,7 @@
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- LuaJIT profiler.
 -- LuaJIT profiler.
 --
 --
--- Copyright (C) 2005-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 --
 --
@@ -238,6 +238,7 @@ local function prof_finish()
     prof_count1 = nil
     prof_count1 = nil
     prof_count2 = nil
     prof_count2 = nil
     prof_ud = nil
     prof_ud = nil
+    if out ~= stdout then out:close() end
   end
   end
 end
 end
 
 

+ 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-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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-2020 Mike Pall. All rights reserved.
+-- Copyright (C) 2005-2021 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/lib_aux.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Auxiliary library for the Lua/C API.
 ** Auxiliary library for the Lua/C API.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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

+ 19 - 5
libs/LuaJIT/src/lib_base.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Base and coroutine library.
 ** Base and coroutine library.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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
@@ -19,6 +19,7 @@
 #include "lj_gc.h"
 #include "lj_gc.h"
 #include "lj_err.h"
 #include "lj_err.h"
 #include "lj_debug.h"
 #include "lj_debug.h"
+#include "lj_buf.h"
 #include "lj_str.h"
 #include "lj_str.h"
 #include "lj_tab.h"
 #include "lj_tab.h"
 #include "lj_meta.h"
 #include "lj_meta.h"
@@ -75,9 +76,10 @@ LJLIB_ASM_(type)		LJLIB_REC(.)
 /* This solves a circular dependency problem -- change FF_next_N as needed. */
 /* This solves a circular dependency problem -- change FF_next_N as needed. */
 LJ_STATIC_ASSERT((int)FF_next == FF_next_N);
 LJ_STATIC_ASSERT((int)FF_next == FF_next_N);
 
 
-LJLIB_ASM(next)
+LJLIB_ASM(next)			LJLIB_REC(.)
 {
 {
   lj_lib_checktab(L, 1);
   lj_lib_checktab(L, 1);
+  lj_err_msg(L, LJ_ERR_NEXTIDX);
   return FFH_UNREACHABLE;
   return FFH_UNREACHABLE;
 }
 }
 
 
@@ -406,10 +408,22 @@ LJLIB_CF(load)
   GCstr *name = lj_lib_optstr(L, 2);
   GCstr *name = lj_lib_optstr(L, 2);
   GCstr *mode = lj_lib_optstr(L, 3);
   GCstr *mode = lj_lib_optstr(L, 3);
   int status;
   int status;
-  if (L->base < L->top && (tvisstr(L->base) || tvisnumber(L->base))) {
-    GCstr *s = lj_lib_checkstr(L, 1);
+  if (L->base < L->top &&
+      (tvisstr(L->base) || tvisnumber(L->base) || tvisbuf(L->base))) {
+    const char *s;
+    MSize len;
+    if (tvisbuf(L->base)) {
+      SBufExt *sbx = bufV(L->base);
+      s = sbx->r;
+      len = sbufxlen(sbx);
+      if (!name) name = &G(L)->strempty;  /* Buffers are not NUL-terminated. */
+    } else {
+      GCstr *str = lj_lib_checkstr(L, 1);
+      s = strdata(str);
+      len = str->len;
+    }
     lua_settop(L, 4);  /* Ensure env arg exists. */
     lua_settop(L, 4);  /* Ensure env arg exists. */
-    status = luaL_loadbufferx(L, strdata(s), s->len, strdata(name ? name : s),
+    status = luaL_loadbufferx(L, s, len, name ? strdata(name) : s,
 			      mode ? strdata(mode) : NULL);
 			      mode ? strdata(mode) : NULL);
   } else {
   } else {
     lj_lib_checkfunc(L, 1);
     lj_lib_checkfunc(L, 1);

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

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

+ 356 - 0
libs/LuaJIT/src/lib_buffer.c

@@ -0,0 +1,356 @@
+/*
+** Buffer library.
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#define lib_buffer_c
+#define LUA_LIB
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+
+#include "lj_obj.h"
+
+#if LJ_HASBUFFER
+#include "lj_gc.h"
+#include "lj_err.h"
+#include "lj_buf.h"
+#include "lj_str.h"
+#include "lj_tab.h"
+#include "lj_udata.h"
+#include "lj_meta.h"
+#if LJ_HASFFI
+#include "lj_ctype.h"
+#include "lj_cdata.h"
+#include "lj_cconv.h"
+#endif
+#include "lj_strfmt.h"
+#include "lj_serialize.h"
+#include "lj_lib.h"
+
+/* -- Helper functions ---------------------------------------------------- */
+
+/* Check that the first argument is a string buffer. */
+static SBufExt *buffer_tobuf(lua_State *L)
+{
+  if (!(L->base < L->top && tvisbuf(L->base)))
+    lj_err_argtype(L, 1, "buffer");
+  return bufV(L->base);
+}
+
+/* Ditto, but for writers. */
+static LJ_AINLINE SBufExt *buffer_tobufw(lua_State *L)
+{
+  SBufExt *sbx = buffer_tobuf(L);
+  setsbufXL_(sbx, L);
+  return sbx;
+}
+
+#define buffer_toudata(sbx)	((GCudata *)(sbx)-1)
+
+/* -- Buffer methods ------------------------------------------------------ */
+
+#define LJLIB_MODULE_buffer_method
+
+LJLIB_CF(buffer_method_free)
+{
+  SBufExt *sbx = buffer_tobuf(L);
+  lj_bufx_free(L, sbx);
+  L->top = L->base+1;  /* Chain buffer object. */
+  return 1;
+}
+
+LJLIB_CF(buffer_method_reset)		LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobuf(L);
+  lj_bufx_reset(sbx);
+  L->top = L->base+1;  /* Chain buffer object. */
+  return 1;
+}
+
+LJLIB_CF(buffer_method_skip)		LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobuf(L);
+  MSize n = (MSize)lj_lib_checkintrange(L, 2, 0, LJ_MAX_BUF);
+  MSize len = sbufxlen(sbx);
+  if (n < len) {
+    sbx->r += n;
+  } else {
+    sbx->r = sbx->w = sbx->b;
+  }
+  L->top = L->base+1;  /* Chain buffer object. */
+  return 1;
+}
+
+LJLIB_CF(buffer_method_set)		LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobuf(L);
+  GCobj *ref;
+  const char *p;
+  MSize len;
+#if LJ_HASFFI
+  if (tviscdata(L->base+1)) {
+    CTState *cts = ctype_cts(L);
+    lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p,
+		   L->base+1, CCF_ARG(2));
+    len = (MSize)lj_lib_checkintrange(L, 3, 0, LJ_MAX_BUF);
+  } else
+#endif
+  {
+    GCstr *str = lj_lib_checkstrx(L, 2);
+    p = strdata(str);
+    len = str->len;
+  }
+  lj_bufx_free(L, sbx);
+  lj_bufx_set_cow(L, sbx, p, len);
+  ref = gcV(L->base+1);
+  setgcref(sbx->cowref, ref);
+  lj_gc_objbarrier(L, buffer_toudata(sbx), ref);
+  L->top = L->base+1;  /* Chain buffer object. */
+  return 1;
+}
+
+LJLIB_CF(buffer_method_put)		LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobufw(L);
+  ptrdiff_t arg, narg = L->top - L->base;
+  for (arg = 1; arg < narg; arg++) {
+    cTValue *o = &L->base[arg], *mo = NULL;
+  retry:
+    if (tvisstr(o)) {
+      lj_buf_putstr((SBuf *)sbx, strV(o));
+    } else if (tvisint(o)) {
+      lj_strfmt_putint((SBuf *)sbx, intV(o));
+    } else if (tvisnum(o)) {
+      lj_strfmt_putfnum((SBuf *)sbx, STRFMT_G14, numV(o));
+    } else if (tvisbuf(o)) {
+      SBufExt *sbx2 = bufV(o);
+      if (sbx2 == sbx) lj_err_arg(L, arg+1, LJ_ERR_BUFFER_SELF);
+      lj_buf_putmem((SBuf *)sbx, sbx2->r, sbufxlen(sbx2));
+    } else if (!mo && !tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
+      /* Call __tostring metamethod inline. */
+      copyTV(L, L->top++, mo);
+      copyTV(L, L->top++, o);
+      lua_call(L, 1, 1);
+      o = &L->base[arg];  /* The stack may have been reallocated. */
+      copyTV(L, &L->base[arg], L->top-1);
+      L->top = L->base + narg;
+      goto retry;  /* Retry with the result. */
+    } else {
+      lj_err_argtype(L, arg+1, "string/number/__tostring");
+    }
+    /* Probably not useful to inline other __tostring MMs, e.g. FFI numbers. */
+  }
+  L->top = L->base+1;  /* Chain buffer object. */
+  lj_gc_check(L);
+  return 1;
+}
+
+LJLIB_CF(buffer_method_putf)		LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobufw(L);
+  lj_strfmt_putarg(L, (SBuf *)sbx, 2, 2);
+  L->top = L->base+1;  /* Chain buffer object. */
+  lj_gc_check(L);
+  return 1;
+}
+
+LJLIB_CF(buffer_method_get)		LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobuf(L);
+  ptrdiff_t arg, narg = L->top - L->base;
+  if (narg == 1) {
+    narg++;
+    setnilV(L->top++);  /* get() is the same as get(nil). */
+  }
+  for (arg = 1; arg < narg; arg++) {
+    TValue *o = &L->base[arg];
+    MSize n = tvisnil(o) ? LJ_MAX_BUF :
+	      (MSize) lj_lib_checkintrange(L, arg+1, 0, LJ_MAX_BUF);
+    MSize len = sbufxlen(sbx);
+    if (n > len) n = len;
+    setstrV(L, o, lj_str_new(L, sbx->r, n));
+    sbx->r += n;
+  }
+  if (sbx->r == sbx->w) sbx->r = sbx->w = sbx->b;
+  lj_gc_check(L);
+  return narg-1;
+}
+
+#if LJ_HASFFI
+LJLIB_CF(buffer_method_putcdata)	LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobufw(L);
+  const char *p;
+  MSize len;
+  if (tviscdata(L->base+1)) {
+    CTState *cts = ctype_cts(L);
+    lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p,
+		   L->base+1, CCF_ARG(2));
+  } else {
+    lj_err_argtype(L, 2, "cdata");
+  }
+  len = (MSize)lj_lib_checkintrange(L, 3, 0, LJ_MAX_BUF);
+  lj_buf_putmem((SBuf *)sbx, p, len);
+  L->top = L->base+1;  /* Chain buffer object. */
+  return 1;
+}
+
+LJLIB_CF(buffer_method_reserve)		LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobufw(L);
+  MSize sz = (MSize)lj_lib_checkintrange(L, 2, 0, LJ_MAX_BUF);
+  GCcdata *cd;
+  lj_buf_more((SBuf *)sbx, sz);
+  ctype_loadffi(L);
+  cd = lj_cdata_new_(L, CTID_P_UINT8, CTSIZE_PTR);
+  *(void **)cdataptr(cd) = sbx->w;
+  setcdataV(L, L->top++, cd);
+  setintV(L->top++, sbufleft(sbx));
+  return 2;
+}
+
+LJLIB_CF(buffer_method_commit)		LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobuf(L);
+  MSize len = (MSize)lj_lib_checkintrange(L, 2, 0, LJ_MAX_BUF);
+  if (len > sbufleft(sbx)) lj_err_arg(L, 2, LJ_ERR_NUMRNG);
+  sbx->w += len;
+  L->top = L->base+1;  /* Chain buffer object. */
+  return 1;
+}
+
+LJLIB_CF(buffer_method_ref)		LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobuf(L);
+  GCcdata *cd;
+  ctype_loadffi(L);
+  cd = lj_cdata_new_(L, CTID_P_UINT8, CTSIZE_PTR);
+  *(void **)cdataptr(cd) = sbx->r;
+  setcdataV(L, L->top++, cd);
+  setintV(L->top++, sbufxlen(sbx));
+  return 2;
+}
+#endif
+
+LJLIB_CF(buffer_method_encode)		LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobufw(L);
+  cTValue *o = lj_lib_checkany(L, 2);
+  lj_serialize_put(sbx, o);
+  lj_gc_check(L);
+  L->top = L->base+1;  /* Chain buffer object. */
+  return 1;
+}
+
+LJLIB_CF(buffer_method_decode)		LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobufw(L);
+  setnilV(L->top++);
+  sbx->r = lj_serialize_get(sbx, L->top-1);
+  lj_gc_check(L);
+  return 1;
+}
+
+LJLIB_CF(buffer_method___gc)
+{
+  SBufExt *sbx = buffer_tobuf(L);
+  lj_bufx_free(L, sbx);
+  return 0;
+}
+
+LJLIB_CF(buffer_method___tostring)	LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobuf(L);
+  setstrV(L, L->top-1, lj_str_new(L, sbx->r, sbufxlen(sbx)));
+  lj_gc_check(L);
+  return 1;
+}
+
+LJLIB_CF(buffer_method___len)		LJLIB_REC(.)
+{
+  SBufExt *sbx = buffer_tobuf(L);
+  setintV(L->top-1, (int32_t)sbufxlen(sbx));
+  return 1;
+}
+
+LJLIB_PUSH("buffer") LJLIB_SET(__metatable)
+LJLIB_PUSH(top-1) LJLIB_SET(__index)
+
+/* -- Buffer library functions -------------------------------------------- */
+
+#define LJLIB_MODULE_buffer
+
+LJLIB_PUSH(top-2) LJLIB_SET(!)  /* Set environment. */
+
+LJLIB_CF(buffer_new)
+{
+  MSize sz = 0;
+  int targ = 1;
+  GCtab *env, *dict_str = NULL, *dict_mt = NULL;
+  GCudata *ud;
+  SBufExt *sbx;
+  if (L->base < L->top && !tvistab(L->base)) {
+    targ = 2;
+    if (!tvisnil(L->base))
+      sz = (MSize)lj_lib_checkintrange(L, 1, 0, LJ_MAX_BUF);
+  }
+  if (L->base+targ-1 < L->top) {
+    GCtab *options = lj_lib_checktab(L, targ);
+    cTValue *opt_dict, *opt_mt;
+    opt_dict = lj_tab_getstr(options, lj_str_newlit(L, "dict"));
+    if (opt_dict && tvistab(opt_dict)) {
+      dict_str = tabV(opt_dict);
+      lj_serialize_dict_prep_str(L, dict_str);
+    }
+    opt_mt = lj_tab_getstr(options, lj_str_newlit(L, "metatable"));
+    if (opt_mt && tvistab(opt_mt)) {
+      dict_mt = tabV(opt_mt);
+      lj_serialize_dict_prep_mt(L, dict_mt);
+    }
+  }
+  env = tabref(curr_func(L)->c.env);
+  ud = lj_udata_new(L, sizeof(SBufExt), env);
+  ud->udtype = UDTYPE_BUFFER;
+  /* NOBARRIER: The GCudata is new (marked white). */
+  setgcref(ud->metatable, obj2gco(env));
+  setudataV(L, L->top++, ud);
+  sbx = (SBufExt *)uddata(ud);
+  lj_bufx_init(L, sbx);
+  setgcref(sbx->dict_str, obj2gco(dict_str));
+  setgcref(sbx->dict_mt, obj2gco(dict_mt));
+  if (sz > 0) lj_buf_need2((SBuf *)sbx, sz);
+  return 1;
+}
+
+LJLIB_CF(buffer_encode)			LJLIB_REC(.)
+{
+  cTValue *o = lj_lib_checkany(L, 1);
+  setstrV(L, L->top++, lj_serialize_encode(L, o));
+  lj_gc_check(L);
+  return 1;
+}
+
+LJLIB_CF(buffer_decode)			LJLIB_REC(.)
+{
+  GCstr *str = lj_lib_checkstrx(L, 1);
+  setnilV(L->top++);
+  lj_serialize_decode(L, L->top-1, str);
+  return 1;
+}
+
+/* ------------------------------------------------------------------------ */
+
+#include "lj_libdef.h"
+
+int luaopen_string_buffer(lua_State *L)
+{
+  LJ_LIB_REG(L, NULL, buffer_method);
+  lua_getfield(L, -1, "__tostring");
+  lua_setfield(L, -2, "tostring");
+  LJ_LIB_REG(L, NULL, buffer);
+  return 1;
+}
+
+#endif

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** Debug library.
 ** Debug library.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** FFI library.
 ** FFI library.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lib_ffi_c
 #define lib_ffi_c
@@ -573,6 +573,7 @@ LJLIB_CF(ffi_typeinfo)
       setintV(lj_tab_setstr(L, t, lj_str_newlit(L, "sib")), (int32_t)ct->sib);
       setintV(lj_tab_setstr(L, t, lj_str_newlit(L, "sib")), (int32_t)ct->sib);
     if (gcref(ct->name)) {
     if (gcref(ct->name)) {
       GCstr *s = gco2str(gcref(ct->name));
       GCstr *s = gco2str(gcref(ct->name));
+      if (isdead(G(L), obj2gco(s))) flipwhite(obj2gco(s));
       setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "name")), s);
       setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "name")), s);
     }
     }
     lj_gc_check(L);
     lj_gc_check(L);

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** Library initialization.
 ** Library initialization.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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

+ 20 - 14
libs/LuaJIT/src/lib_io.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** I/O library.
 ** I/O library.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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
@@ -60,12 +60,12 @@ static IOFileUD *io_tofile(lua_State *L)
   return iof;
   return iof;
 }
 }
 
 
-static FILE *io_stdfile(lua_State *L, ptrdiff_t id)
+static IOFileUD *io_stdfile(lua_State *L, ptrdiff_t id)
 {
 {
   IOFileUD *iof = IOSTDF_IOF(L, id);
   IOFileUD *iof = IOSTDF_IOF(L, id);
   if (iof->fp == NULL)
   if (iof->fp == NULL)
     lj_err_caller(L, LJ_ERR_IOSTDCL);
     lj_err_caller(L, LJ_ERR_IOSTDCL);
-  return iof->fp;
+  return iof;
 }
 }
 
 
 static IOFileUD *io_file_new(lua_State *L)
 static IOFileUD *io_file_new(lua_State *L)
@@ -178,7 +178,7 @@ static int io_file_readlen(lua_State *L, FILE *fp, MSize m)
     MSize n = (MSize)fread(buf, 1, m, fp);
     MSize n = (MSize)fread(buf, 1, m, fp);
     setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
     setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
     lj_gc_check(L);
     lj_gc_check(L);
-    return (n > 0 || m == 0);
+    return n > 0;
   } else {
   } else {
     int c = getc(fp);
     int c = getc(fp);
     ungetc(c, fp);
     ungetc(c, fp);
@@ -187,8 +187,9 @@ static int io_file_readlen(lua_State *L, FILE *fp, MSize m)
   }
   }
 }
 }
 
 
-static int io_file_read(lua_State *L, FILE *fp, int start)
+static int io_file_read(lua_State *L, IOFileUD *iof, int start)
 {
 {
+  FILE *fp = iof->fp;
   int ok, n, nargs = (int)(L->top - L->base) - start;
   int ok, n, nargs = (int)(L->top - L->base) - start;
   clearerr(fp);
   clearerr(fp);
   if (nargs == 0) {
   if (nargs == 0) {
@@ -224,8 +225,9 @@ static int io_file_read(lua_State *L, FILE *fp, int start)
   return n - start;
   return n - start;
 }
 }
 
 
-static int io_file_write(lua_State *L, FILE *fp, int start)
+static int io_file_write(lua_State *L, IOFileUD *iof, int start)
 {
 {
+  FILE *fp = iof->fp;
   cTValue *tv;
   cTValue *tv;
   int status = 1;
   int status = 1;
   for (tv = L->base+start; tv < L->top; tv++) {
   for (tv = L->base+start; tv < L->top; tv++) {
@@ -253,13 +255,11 @@ static int io_file_iter(lua_State *L)
     lj_err_caller(L, LJ_ERR_IOCLFL);
     lj_err_caller(L, LJ_ERR_IOCLFL);
   L->top = L->base;
   L->top = L->base;
   if (n) {  /* Copy upvalues with options to stack. */
   if (n) {  /* Copy upvalues with options to stack. */
-    if (n > LUAI_MAXCSTACK)
-      lj_err_caller(L, LJ_ERR_STKOV);
     lj_state_checkstack(L, (MSize)n);
     lj_state_checkstack(L, (MSize)n);
     memcpy(L->top, &fn->c.upvalue[1], n*sizeof(TValue));
     memcpy(L->top, &fn->c.upvalue[1], n*sizeof(TValue));
     L->top += n;
     L->top += n;
   }
   }
-  n = io_file_read(L, iof->fp, 0);
+  n = io_file_read(L, iof, 0);
   if (ferror(iof->fp))
   if (ferror(iof->fp))
     lj_err_callermsg(L, strVdata(L->top-2));
     lj_err_callermsg(L, strVdata(L->top-2));
   if (tvisnil(L->base) && (iof->type & IOFILE_FLAG_CLOSE)) {
   if (tvisnil(L->base) && (iof->type & IOFILE_FLAG_CLOSE)) {
@@ -284,19 +284,25 @@ static int io_file_lines(lua_State *L)
 
 
 LJLIB_CF(io_method_close)
 LJLIB_CF(io_method_close)
 {
 {
-  IOFileUD *iof = L->base < L->top ? io_tofile(L) :
-		  IOSTDF_IOF(L, GCROOT_IO_OUTPUT);
+  IOFileUD *iof;
+  if (L->base < L->top) {
+    iof = io_tofile(L);
+  } else {
+    iof = IOSTDF_IOF(L, GCROOT_IO_OUTPUT);
+    if (iof->fp == NULL)
+      lj_err_caller(L, LJ_ERR_IOCLFL);
+  }
   return io_file_close(L, iof);
   return io_file_close(L, iof);
 }
 }
 
 
 LJLIB_CF(io_method_read)
 LJLIB_CF(io_method_read)
 {
 {
-  return io_file_read(L, io_tofile(L)->fp, 1);
+  return io_file_read(L, io_tofile(L), 1);
 }
 }
 
 
 LJLIB_CF(io_method_write)		LJLIB_REC(io_write 0)
 LJLIB_CF(io_method_write)		LJLIB_REC(io_write 0)
 {
 {
-  return io_file_write(L, io_tofile(L)->fp, 1);
+  return io_file_write(L, io_tofile(L), 1);
 }
 }
 
 
 LJLIB_CF(io_method_flush)		LJLIB_REC(io_flush 0)
 LJLIB_CF(io_method_flush)		LJLIB_REC(io_flush 0)
@@ -458,7 +464,7 @@ LJLIB_CF(io_write)		LJLIB_REC(io_write GCROOT_IO_OUTPUT)
 
 
 LJLIB_CF(io_flush)		LJLIB_REC(io_flush GCROOT_IO_OUTPUT)
 LJLIB_CF(io_flush)		LJLIB_REC(io_flush GCROOT_IO_OUTPUT)
 {
 {
-  return luaL_fileresult(L, fflush(io_stdfile(L, GCROOT_IO_OUTPUT)) == 0, NULL);
+  return luaL_fileresult(L, fflush(io_stdfile(L, GCROOT_IO_OUTPUT)->fp) == 0, NULL);
 }
 }
 
 
 static int io_std_getset(lua_State *L, ptrdiff_t id, const char *mode)
 static int io_std_getset(lua_State *L, ptrdiff_t id, const char *mode)

+ 2 - 6
libs/LuaJIT/src/lib_jit.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** JIT library.
 ** JIT library.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lib_jit_c
 #define lib_jit_c
@@ -346,11 +346,7 @@ LJLIB_CF(jit_util_tracek)
       ir = &T->ir[ir->op1];
       ir = &T->ir[ir->op1];
     }
     }
 #if LJ_HASFFI
 #if LJ_HASFFI
-    if (ir->o == IR_KINT64 && !ctype_ctsG(G(L))) {
-      ptrdiff_t oldtop = savestack(L, L->top);
-      luaopen_ffi(L);  /* Load FFI library on-demand. */
-      L->top = restorestack(L, oldtop);
-    }
+    if (ir->o == IR_KINT64) ctype_loadffi(L);
 #endif
 #endif
     lj_ir_kvalue(L, L->top-2, ir);
     lj_ir_kvalue(L, L->top-2, ir);
     setintV(L->top-1, (int32_t)irt_type(ir->t));
     setintV(L->top-1, (int32_t)irt_type(ir->t));

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** Math library.
 ** Math library.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #include <math.h>
 #include <math.h>

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** OS library.
 ** OS library.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** Package library.
 ** Package library.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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

+ 9 - 81
libs/LuaJIT/src/lib_string.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** String library.
 ** String library.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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
@@ -640,89 +640,14 @@ LJLIB_CF(string_gsub)
 
 
 /* ------------------------------------------------------------------------ */
 /* ------------------------------------------------------------------------ */
 
 
-/* Emulate tostring() inline. */
-static GCstr *string_fmt_tostring(lua_State *L, int arg, int retry)
-{
-  TValue *o = L->base+arg-1;
-  cTValue *mo;
-  lj_assertL(o < L->top, "bad usage");  /* Caller already checks for existence. */
-  if (LJ_LIKELY(tvisstr(o)))
-    return strV(o);
-  if (retry != 2 && !tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
-    copyTV(L, L->top++, mo);
-    copyTV(L, L->top++, o);
-    lua_call(L, 1, 1);
-    copyTV(L, L->base+arg-1, --L->top);
-    return NULL;  /* Buffer may be overwritten, retry. */
-  }
-  return lj_strfmt_obj(L, o);
-}
-
 LJLIB_CF(string_format)		LJLIB_REC(.)
 LJLIB_CF(string_format)		LJLIB_REC(.)
 {
 {
-  int arg, top = (int)(L->top - L->base);
-  GCstr *fmt;
-  SBuf *sb;
-  FormatState fs;
-  SFormat sf;
   int retry = 0;
   int retry = 0;
-again:
-  arg = 1;
-  sb = lj_buf_tmp_(L);
-  fmt = lj_lib_checkstr(L, arg);
-  lj_strfmt_init(&fs, strdata(fmt), fmt->len);
-  while ((sf = lj_strfmt_parse(&fs)) != STRFMT_EOF) {
-    if (sf == STRFMT_LIT) {
-      lj_buf_putmem(sb, fs.str, fs.len);
-    } else if (sf == STRFMT_ERR) {
-      lj_err_callerv(L, LJ_ERR_STRFMT, strdata(lj_str_new(L, fs.str, fs.len)));
-    } else {
-      if (++arg > top)
-	luaL_argerror(L, arg, lj_obj_typename[0]);
-      switch (STRFMT_TYPE(sf)) {
-      case STRFMT_INT:
-	if (tvisint(L->base+arg-1)) {
-	  int32_t k = intV(L->base+arg-1);
-	  if (sf == STRFMT_INT)
-	    lj_strfmt_putint(sb, k);  /* Shortcut for plain %d. */
-	  else
-	    lj_strfmt_putfxint(sb, sf, k);
-	} else {
-	  lj_strfmt_putfnum_int(sb, sf, lj_lib_checknum(L, arg));
-	}
-	break;
-      case STRFMT_UINT:
-	if (tvisint(L->base+arg-1))
-	  lj_strfmt_putfxint(sb, sf, intV(L->base+arg-1));
-	else
-	  lj_strfmt_putfnum_uint(sb, sf, lj_lib_checknum(L, arg));
-	break;
-      case STRFMT_NUM:
-	lj_strfmt_putfnum(sb, sf, lj_lib_checknum(L, arg));
-	break;
-      case STRFMT_STR: {
-	GCstr *str = string_fmt_tostring(L, arg, retry);
-	if (str == NULL)
-	  retry = 1;
-	else if ((sf & STRFMT_T_QUOTED))
-	  lj_strfmt_putquoted(sb, str);  /* No formatting. */
-	else
-	  lj_strfmt_putfstr(sb, sf, str);
-	break;
-	}
-      case STRFMT_CHAR:
-	lj_strfmt_putfchar(sb, sf, lj_lib_checkint(L, arg));
-	break;
-      case STRFMT_PTR:  /* No formatting. */
-	lj_strfmt_putptr(sb, lj_obj_ptr(G(L), L->base+arg-1));
-	break;
-      default:
-	lj_assertL(0, "bad string format type");
-	break;
-      }
-    }
-  }
-  if (retry++ == 1) goto again;
+  SBuf *sb;
+  do {
+    sb = lj_buf_tmp_(L);
+    retry = lj_strfmt_putarg(L, sb, 1, -retry);
+  } while (retry > 0);
   setstrV(L, L->top-1, lj_buf_str(L, sb));
   setstrV(L, L->top-1, lj_buf_str(L, sb));
   lj_gc_check(L);
   lj_gc_check(L);
   return 1;
   return 1;
@@ -743,6 +668,9 @@ LUALIB_API int luaopen_string(lua_State *L)
   setgcref(basemt_it(g, LJ_TSTR), obj2gco(mt));
   setgcref(basemt_it(g, LJ_TSTR), obj2gco(mt));
   settabV(L, lj_tab_setstr(L, mt, mmname_str(g, MM_index)), tabV(L->top-1));
   settabV(L, lj_tab_setstr(L, mt, mmname_str(g, MM_index)), tabV(L->top-1));
   mt->nomm = (uint8_t)(~(1u<<MM_index));
   mt->nomm = (uint8_t)(~(1u<<MM_index));
+#if LJ_HASBUFFER
+  lj_lib_prereg(L, LUA_STRLIBNAME ".buffer", luaopen_string_buffer, tabV(L->top-1));
+#endif
   return 1;
   return 1;
 }
 }
 
 

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** Table library.
 ** Table library.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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
@@ -159,7 +159,7 @@ LJLIB_CF(table_concat)		LJLIB_REC(.)
   SBuf *sb = lj_buf_tmp_(L);
   SBuf *sb = lj_buf_tmp_(L);
   SBuf *sbx = lj_buf_puttab(sb, t, sep, i, e);
   SBuf *sbx = lj_buf_puttab(sb, t, sep, i, e);
   if (LJ_UNLIKELY(!sbx)) {  /* Error: bad element type. */
   if (LJ_UNLIKELY(!sbx)) {  /* Error: bad element type. */
-    int32_t idx = (int32_t)(intptr_t)sbufP(sb);
+    int32_t idx = (int32_t)(intptr_t)sb->w;
     cTValue *o = lj_tab_getint(t, idx);
     cTValue *o = lj_tab_getint(t, idx);
     lj_err_callerv(L, LJ_ERR_TABCAT,
     lj_err_callerv(L, LJ_ERR_TABCAT,
 		   lj_obj_itypename[o ? itypemap(o) : ~LJ_TNIL], idx);
 		   lj_obj_itypename[o ? itypemap(o) : ~LJ_TNIL], idx);

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

@@ -365,7 +365,7 @@ static void *CALL_MREMAP_(void *ptr, size_t osz, size_t nsz, int flags)
 #define CALL_MREMAP(addr, osz, nsz, mv) CALL_MREMAP_((addr), (osz), (nsz), (mv))
 #define CALL_MREMAP(addr, osz, nsz, mv) CALL_MREMAP_((addr), (osz), (nsz), (mv))
 #define CALL_MREMAP_NOMOVE	0
 #define CALL_MREMAP_NOMOVE	0
 #define CALL_MREMAP_MAYMOVE	1
 #define CALL_MREMAP_MAYMOVE	1
-#if LJ_64 && !LJ_GC64
+#if LJ_64 && (!LJ_GC64 || LJ_TARGET_ARM64)
 #define CALL_MREMAP_MV		CALL_MREMAP_NOMOVE
 #define CALL_MREMAP_MV		CALL_MREMAP_NOMOVE
 #else
 #else
 #define CALL_MREMAP_MV		CALL_MREMAP_MAYMOVE
 #define CALL_MREMAP_MV		CALL_MREMAP_MAYMOVE

+ 8 - 32
libs/LuaJIT/src/lj_api.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Public Lua/C API.
 ** Public Lua/C API.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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
@@ -707,36 +707,10 @@ 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)
 {
 {
 #if LJ_64
 #if LJ_64
-  p = lightud_intern(L, p);
+  p = lj_lightud_intern(L, p);
 #endif
 #endif
   setrawlightudV(L->top, p);
   setrawlightudV(L->top, p);
   incr_top(L);
   incr_top(L);
@@ -919,11 +893,13 @@ LUA_API int lua_next(lua_State *L, int idx)
   cTValue *t = index2adr(L, idx);
   cTValue *t = index2adr(L, idx);
   int more;
   int more;
   lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
   lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
-  more = lj_tab_next(L, tabV(t), L->top-1);
-  if (more) {
+  more = lj_tab_next(tabV(t), L->top-1, L->top-1);
+  if (more > 0) {
     incr_top(L);  /* Return new key and value slot. */
     incr_top(L);  /* Return new key and value slot. */
-  } else {  /* End of traversal. */
+  } else if (!more) {  /* End of traversal. */
     L->top--;  /* Remove key slot. */
     L->top--;  /* Remove key slot. */
+  } else {
+    lj_err_msg(L, LJ_ERR_NEXTIDX);
   }
   }
   return more;
   return more;
 }
 }
@@ -1179,7 +1155,7 @@ static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
   setfuncV(L, top++, fn);
   setfuncV(L, top++, fn);
   if (LJ_FR2) setnilV(top++);
   if (LJ_FR2) setnilV(top++);
 #if LJ_64
 #if LJ_64
-  ud = lightud_intern(L, ud);
+  ud = lj_lightud_intern(L, ud);
 #endif
 #endif
   setrawlightudV(top++, ud);
   setrawlightudV(top++, ud);
   cframe_nres(L->cframe) = 1+0;  /* Zero results. */
   cframe_nres(L->cframe) = 1+0;  /* Zero results. */

+ 36 - 18
libs/LuaJIT/src/lj_arch.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** Target architecture selection.
 ** Target architecture selection.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _LJ_ARCH_H
 #ifndef _LJ_ARCH_H
@@ -170,14 +170,10 @@
 #define LJ_ARCH_NAME		"x86"
 #define LJ_ARCH_NAME		"x86"
 #define LJ_ARCH_BITS		32
 #define LJ_ARCH_BITS		32
 #define LJ_ARCH_ENDIAN		LUAJIT_LE
 #define LJ_ARCH_ENDIAN		LUAJIT_LE
-#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN
-#define LJ_ABI_WIN		1
-#else
-#define LJ_ABI_WIN		0
-#endif
 #define LJ_TARGET_X86		1
 #define LJ_TARGET_X86		1
 #define LJ_TARGET_X86ORX64	1
 #define LJ_TARGET_X86ORX64	1
 #define LJ_TARGET_EHRETREG	0
 #define LJ_TARGET_EHRETREG	0
+#define LJ_TARGET_EHRAREG	8
 #define LJ_TARGET_MASKSHIFT	1
 #define LJ_TARGET_MASKSHIFT	1
 #define LJ_TARGET_MASKROT	1
 #define LJ_TARGET_MASKROT	1
 #define LJ_TARGET_UNALIGNED	1
 #define LJ_TARGET_UNALIGNED	1
@@ -188,14 +184,10 @@
 #define LJ_ARCH_NAME		"x64"
 #define LJ_ARCH_NAME		"x64"
 #define LJ_ARCH_BITS		64
 #define LJ_ARCH_BITS		64
 #define LJ_ARCH_ENDIAN		LUAJIT_LE
 #define LJ_ARCH_ENDIAN		LUAJIT_LE
-#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN
-#define LJ_ABI_WIN		1
-#else
-#define LJ_ABI_WIN		0
-#endif
 #define LJ_TARGET_X64		1
 #define LJ_TARGET_X64		1
 #define LJ_TARGET_X86ORX64	1
 #define LJ_TARGET_X86ORX64	1
 #define LJ_TARGET_EHRETREG	0
 #define LJ_TARGET_EHRETREG	0
+#define LJ_TARGET_EHRAREG	16
 #define LJ_TARGET_JUMPRANGE	31	/* +-2^31 = +-2GB */
 #define LJ_TARGET_JUMPRANGE	31	/* +-2^31 = +-2GB */
 #define LJ_TARGET_MASKSHIFT	1
 #define LJ_TARGET_MASKSHIFT	1
 #define LJ_TARGET_MASKROT	1
 #define LJ_TARGET_MASKROT	1
@@ -203,6 +195,8 @@
 #define LJ_ARCH_NUMMODE		LJ_NUMMODE_SINGLE_DUAL
 #define LJ_ARCH_NUMMODE		LJ_NUMMODE_SINGLE_DUAL
 #ifndef LUAJIT_DISABLE_GC64
 #ifndef LUAJIT_DISABLE_GC64
 #define LJ_TARGET_GC64		1
 #define LJ_TARGET_GC64		1
+#elif LJ_TARGET_OSX
+#error "macOS requires GC64 -- don't disable it"
 #endif
 #endif
 
 
 #elif LUAJIT_TARGET == LUAJIT_ARCH_ARM
 #elif LUAJIT_TARGET == LUAJIT_ARCH_ARM
@@ -219,6 +213,7 @@
 #define LJ_ABI_EABI		1
 #define LJ_ABI_EABI		1
 #define LJ_TARGET_ARM		1
 #define LJ_TARGET_ARM		1
 #define LJ_TARGET_EHRETREG	0
 #define LJ_TARGET_EHRETREG	0
+#define LJ_TARGET_EHRAREG	14
 #define LJ_TARGET_JUMPRANGE	25	/* +-2^25 = +-32MB */
 #define LJ_TARGET_JUMPRANGE	25	/* +-2^25 = +-32MB */
 #define LJ_TARGET_MASKSHIFT	0
 #define LJ_TARGET_MASKSHIFT	0
 #define LJ_TARGET_MASKROT	1
 #define LJ_TARGET_MASKROT	1
@@ -249,6 +244,7 @@
 #endif
 #endif
 #define LJ_TARGET_ARM64		1
 #define LJ_TARGET_ARM64		1
 #define LJ_TARGET_EHRETREG	0
 #define LJ_TARGET_EHRETREG	0
+#define LJ_TARGET_EHRAREG	30
 #define LJ_TARGET_JUMPRANGE	27	/* +-2^27 = +-128MB */
 #define LJ_TARGET_JUMPRANGE	27	/* +-2^27 = +-128MB */
 #define LJ_TARGET_MASKSHIFT	1
 #define LJ_TARGET_MASKSHIFT	1
 #define LJ_TARGET_MASKROT	1
 #define LJ_TARGET_MASKROT	1
@@ -304,6 +300,7 @@
 
 
 #define LJ_TARGET_PPC		1
 #define LJ_TARGET_PPC		1
 #define LJ_TARGET_EHRETREG	3
 #define LJ_TARGET_EHRETREG	3
+#define LJ_TARGET_EHRAREG	65
 #define LJ_TARGET_JUMPRANGE	25	/* +-2^25 = +-32MB */
 #define LJ_TARGET_JUMPRANGE	25	/* +-2^25 = +-32MB */
 #define LJ_TARGET_MASKSHIFT	0
 #define LJ_TARGET_MASKSHIFT	0
 #define LJ_TARGET_MASKROT	1
 #define LJ_TARGET_MASKROT	1
@@ -406,6 +403,7 @@
 #endif
 #endif
 #define LJ_TARGET_MIPS		1
 #define LJ_TARGET_MIPS		1
 #define LJ_TARGET_EHRETREG	4
 #define LJ_TARGET_EHRETREG	4
+#define LJ_TARGET_EHRAREG	31
 #define LJ_TARGET_JUMPRANGE	27	/* 2*2^27 = 256MB-aligned region */
 #define LJ_TARGET_JUMPRANGE	27	/* 2*2^27 = 256MB-aligned region */
 #define LJ_TARGET_MASKSHIFT	1
 #define LJ_TARGET_MASKSHIFT	1
 #define LJ_TARGET_MASKROT	1
 #define LJ_TARGET_MASKROT	1
@@ -551,6 +549,13 @@
 #define LJ_HASFFI		1
 #define LJ_HASFFI		1
 #endif
 #endif
 
 
+/* Disable or enable the string buffer extension. */
+#if defined(LUAJIT_DISABLE_BUFFER)
+#define LJ_HASBUFFER		0
+#else
+#define LJ_HASBUFFER		1
+#endif
+
 #if defined(LUAJIT_DISABLE_PROFILE)
 #if defined(LUAJIT_DISABLE_PROFILE)
 #define LJ_HASPROFILE		0
 #define LJ_HASPROFILE		0
 #elif LJ_TARGET_POSIX
 #elif LJ_TARGET_POSIX
@@ -611,13 +616,10 @@
 #define LJ_NO_SYSTEM		1
 #define LJ_NO_SYSTEM		1
 #endif
 #endif
 
 
-#if !defined(LUAJIT_NO_UNWIND) && __GNU_COMPACT_EH__
-/* NYI: no support for compact unwind specification, yet. */
-#define LUAJIT_NO_UNWIND	1
-#endif
-
-#if defined(LUAJIT_NO_UNWIND) || defined(__symbian__) || LJ_TARGET_IOS || LJ_TARGET_PS3 || LJ_TARGET_PS4
-#define LJ_NO_UNWIND		1
+#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN
+#define LJ_ABI_WIN		1
+#else
+#define LJ_ABI_WIN		0
 #endif
 #endif
 
 
 #if LJ_TARGET_WINDOWS
 #if LJ_TARGET_WINDOWS
@@ -632,6 +634,22 @@ extern void *LJ_WIN_LOADLIBA(const char *path);
 #endif
 #endif
 #endif
 #endif
 
 
+#if defined(LUAJIT_NO_UNWIND) || __GNU_COMPACT_EH__ || defined(__symbian__) || LJ_TARGET_IOS || LJ_TARGET_PS3 || LJ_TARGET_PS4
+#define LJ_NO_UNWIND		1
+#endif
+
+#if !LJ_NO_UNWIND && !defined(LUAJIT_UNWIND_INTERNAL) && (LJ_ABI_WIN || (defined(LUAJIT_UNWIND_EXTERNAL) && (defined(__GNUC__) || defined(__clang__))))
+#define LJ_UNWIND_EXT		1
+#else
+#define LJ_UNWIND_EXT		0
+#endif
+
+#if LJ_UNWIND_EXT && LJ_HASJIT && !LJ_TARGET_ARM && !(LJ_ABI_WIN && LJ_TARGET_X86)
+#define LJ_UNWIND_JIT		1
+#else
+#define LJ_UNWIND_JIT		0
+#endif
+
 /* Compatibility with Lua 5.1 vs. 5.2. */
 /* Compatibility with Lua 5.1 vs. 5.2. */
 #ifdef LUAJIT_ENABLE_LUA52COMPAT
 #ifdef LUAJIT_ENABLE_LUA52COMPAT
 #define LJ_52			1
 #define LJ_52			1

+ 155 - 63
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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lj_asm_c
 #define lj_asm_c
@@ -11,6 +11,7 @@
 #if LJ_HASJIT
 #if LJ_HASJIT
 
 
 #include "lj_gc.h"
 #include "lj_gc.h"
+#include "lj_buf.h"
 #include "lj_str.h"
 #include "lj_str.h"
 #include "lj_tab.h"
 #include "lj_tab.h"
 #include "lj_frame.h"
 #include "lj_frame.h"
@@ -71,6 +72,8 @@ typedef struct ASMState {
   IRRef snaprename;	/* Rename highwater mark for snapshot check. */
   IRRef snaprename;	/* Rename highwater mark for snapshot check. */
   SnapNo snapno;	/* Current snapshot number. */
   SnapNo snapno;	/* Current snapshot number. */
   SnapNo loopsnapno;	/* Loop snapshot number. */
   SnapNo loopsnapno;	/* Loop snapshot number. */
+  int snapalloc;	/* Current snapshot needs allocation. */
+  BloomFilter snapfilt1, snapfilt2;	/* Filled with snapshot refs. */
 
 
   IRRef fuseref;	/* Fusion limit (loopref, 0 or FUSE_DISABLED). */
   IRRef fuseref;	/* Fusion limit (loopref, 0 or FUSE_DISABLED). */
   IRRef sectref;	/* Section base reference (loopref or 0). */
   IRRef sectref;	/* Section base reference (loopref or 0). */
@@ -84,6 +87,7 @@ typedef struct ASMState {
 
 
   MCode *mcbot;		/* Bottom of reserved MCode. */
   MCode *mcbot;		/* Bottom of reserved MCode. */
   MCode *mctop;		/* Top of generated MCode. */
   MCode *mctop;		/* Top of generated MCode. */
+  MCode *mctoporig;	/* Original top of generated MCode. */
   MCode *mcloop;	/* Pointer to loop MCode (or NULL). */
   MCode *mcloop;	/* Pointer to loop MCode (or NULL). */
   MCode *invmcp;	/* Points to invertible loop branch (or NULL). */
   MCode *invmcp;	/* Points to invertible loop branch (or NULL). */
   MCode *flagmcp;	/* Pending opportunity to merge flag setting ins. */
   MCode *flagmcp;	/* Pending opportunity to merge flag setting ins. */
@@ -694,7 +698,14 @@ static void ra_rename(ASMState *as, Reg down, Reg up)
   RA_DBGX((as, "rename    $f $r $r", regcost_ref(as->cost[up]), down, up));
   RA_DBGX((as, "rename    $f $r $r", regcost_ref(as->cost[up]), down, up));
   emit_movrr(as, ir, down, up);  /* Backwards codegen needs inverse move. */
   emit_movrr(as, ir, down, up);  /* Backwards codegen needs inverse move. */
   if (!ra_hasspill(IR(ref)->s)) {  /* Add the rename to the IR. */
   if (!ra_hasspill(IR(ref)->s)) {  /* Add the rename to the IR. */
-    ra_addrename(as, down, ref, as->snapno);
+    /*
+    ** The rename is effective at the subsequent (already emitted) exit
+    ** branch. This is for the current snapshot (as->snapno). Except if we
+    ** haven't yet allocated any refs for the snapshot (as->snapalloc == 1),
+    ** then it belongs to the next snapshot.
+    ** See also the discussion at asm_snap_checkrename().
+    */
+    ra_addrename(as, down, ref, as->snapno + as->snapalloc);
   }
   }
 }
 }
 
 
@@ -807,11 +818,11 @@ static void ra_leftov(ASMState *as, Reg dest, IRRef lref)
 }
 }
 #endif
 #endif
 
 
-#if !LJ_64
 /* Force a RID_RETLO/RID_RETHI destination register pair (marked as free). */
 /* Force a RID_RETLO/RID_RETHI destination register pair (marked as free). */
 static void ra_destpair(ASMState *as, IRIns *ir)
 static void ra_destpair(ASMState *as, IRIns *ir)
 {
 {
   Reg destlo = ir->r, desthi = (ir+1)->r;
   Reg destlo = ir->r, desthi = (ir+1)->r;
+  IRIns *irx = (LJ_64 && !irt_is64(ir->t)) ? ir+1 : ir;
   /* First spill unrelated refs blocking the destination registers. */
   /* First spill unrelated refs blocking the destination registers. */
   if (!rset_test(as->freeset, RID_RETLO) &&
   if (!rset_test(as->freeset, RID_RETLO) &&
       destlo != RID_RETLO && desthi != RID_RETLO)
       destlo != RID_RETLO && desthi != RID_RETLO)
@@ -835,29 +846,28 @@ static void ra_destpair(ASMState *as, IRIns *ir)
   /* Check for conflicts and shuffle the registers as needed. */
   /* Check for conflicts and shuffle the registers as needed. */
   if (destlo == RID_RETHI) {
   if (destlo == RID_RETHI) {
     if (desthi == RID_RETLO) {
     if (desthi == RID_RETLO) {
-#if LJ_TARGET_X86
-      *--as->mcp = XI_XCHGa + RID_RETHI;
+#if LJ_TARGET_X86ORX64
+      *--as->mcp = REX_64IR(irx, XI_XCHGa + RID_RETHI);
 #else
 #else
-      emit_movrr(as, ir, RID_RETHI, RID_TMP);
-      emit_movrr(as, ir, RID_RETLO, RID_RETHI);
-      emit_movrr(as, ir, RID_TMP, RID_RETLO);
+      emit_movrr(as, irx, RID_RETHI, RID_TMP);
+      emit_movrr(as, irx, RID_RETLO, RID_RETHI);
+      emit_movrr(as, irx, RID_TMP, RID_RETLO);
 #endif
 #endif
     } else {
     } else {
-      emit_movrr(as, ir, RID_RETHI, RID_RETLO);
-      if (desthi != RID_RETHI) emit_movrr(as, ir, desthi, RID_RETHI);
+      emit_movrr(as, irx, RID_RETHI, RID_RETLO);
+      if (desthi != RID_RETHI) emit_movrr(as, irx, desthi, RID_RETHI);
     }
     }
   } else if (desthi == RID_RETLO) {
   } else if (desthi == RID_RETLO) {
-    emit_movrr(as, ir, RID_RETLO, RID_RETHI);
-    if (destlo != RID_RETLO) emit_movrr(as, ir, destlo, RID_RETLO);
+    emit_movrr(as, irx, RID_RETLO, RID_RETHI);
+    if (destlo != RID_RETLO) emit_movrr(as, irx, destlo, RID_RETLO);
   } else {
   } else {
-    if (desthi != RID_RETHI) emit_movrr(as, ir, desthi, RID_RETHI);
-    if (destlo != RID_RETLO) emit_movrr(as, ir, destlo, RID_RETLO);
+    if (desthi != RID_RETHI) emit_movrr(as, irx, desthi, RID_RETHI);
+    if (destlo != RID_RETLO) emit_movrr(as, irx, destlo, RID_RETLO);
   }
   }
   /* Restore spill slots (if any). */
   /* Restore spill slots (if any). */
   if (ra_hasspill((ir+1)->s)) ra_save(as, ir+1, RID_RETHI);
   if (ra_hasspill((ir+1)->s)) ra_save(as, ir+1, RID_RETHI);
   if (ra_hasspill(ir->s)) ra_save(as, ir, RID_RETLO);
   if (ra_hasspill(ir->s)) ra_save(as, ir, RID_RETLO);
 }
 }
-#endif
 
 
 /* -- Snapshot handling --------- ----------------------------------------- */
 /* -- Snapshot handling --------- ----------------------------------------- */
 
 
@@ -892,7 +902,10 @@ static int asm_sunk_store(ASMState *as, IRIns *ira, IRIns *irs)
 static void asm_snap_alloc1(ASMState *as, IRRef ref)
 static void asm_snap_alloc1(ASMState *as, IRRef ref)
 {
 {
   IRIns *ir = IR(ref);
   IRIns *ir = IR(ref);
-  if (!irref_isk(ref) && (!(ra_used(ir) || ir->r == RID_SUNK))) {
+  if (!irref_isk(ref) && ir->r != RID_SUNK) {
+    bloomset(as->snapfilt1, ref);
+    bloomset(as->snapfilt2, hashrot(ref, ref + HASH_BIAS));
+    if (ra_used(ir)) return;
     if (ir->r == RID_SINK) {
     if (ir->r == RID_SINK) {
       ir->r = RID_SUNK;
       ir->r = RID_SUNK;
 #if LJ_HASFFI
 #if LJ_HASFFI
@@ -947,11 +960,12 @@ static void asm_snap_alloc1(ASMState *as, IRRef ref)
 }
 }
 
 
 /* Allocate refs escaping to a snapshot. */
 /* Allocate refs escaping to a snapshot. */
-static void asm_snap_alloc(ASMState *as)
+static void asm_snap_alloc(ASMState *as, int snapno)
 {
 {
-  SnapShot *snap = &as->T->snap[as->snapno];
+  SnapShot *snap = &as->T->snap[snapno];
   SnapEntry *map = &as->T->snapmap[snap->mapofs];
   SnapEntry *map = &as->T->snapmap[snap->mapofs];
   MSize n, nent = snap->nent;
   MSize n, nent = snap->nent;
+  as->snapfilt1 = as->snapfilt2 = 0;
   for (n = 0; n < nent; n++) {
   for (n = 0; n < nent; n++) {
     SnapEntry sn = map[n];
     SnapEntry sn = map[n];
     IRRef ref = snap_ref(sn);
     IRRef ref = snap_ref(sn);
@@ -960,7 +974,7 @@ static void asm_snap_alloc(ASMState *as)
       if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) {
       if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) {
 	lj_assertA(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",
 		   "snap %d[%d] points to bad SOFTFP IR %04d",
-		   as->snapno, n, ref - REF_BIAS);
+		   snapno, n, ref - REF_BIAS);
 	asm_snap_alloc1(as, ref+1);
 	asm_snap_alloc1(as, ref+1);
       }
       }
     }
     }
@@ -976,35 +990,26 @@ static void asm_snap_alloc(ASMState *as)
 */
 */
 static int asm_snap_checkrename(ASMState *as, IRRef ren)
 static int asm_snap_checkrename(ASMState *as, IRRef ren)
 {
 {
-  SnapShot *snap = &as->T->snap[as->snapno];
-  SnapEntry *map = &as->T->snapmap[snap->mapofs];
-  MSize n, nent = snap->nent;
-  for (n = 0; n < nent; n++) {
-    SnapEntry sn = map[n];
-    IRRef ref = snap_ref(sn);
-    if (ref == ren || (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && ++ref == ren)) {
-      IRIns *ir = IR(ref);
-      ra_spill(as, ir);  /* Register renamed, so force a spill slot. */
-      RA_DBGX((as, "snaprensp $f $s", ref, ir->s));
-      return 1;  /* Found. */
-    }
+  if (bloomtest(as->snapfilt1, ren) &&
+      bloomtest(as->snapfilt2, hashrot(ren, ren + HASH_BIAS))) {
+    IRIns *ir = IR(ren);
+    ra_spill(as, ir);  /* Register renamed, so force a spill slot. */
+    RA_DBGX((as, "snaprensp $f $s", ren, ir->s));
+    return 1;  /* Found. */
   }
   }
   return 0;  /* Not found. */
   return 0;  /* Not found. */
 }
 }
 
 
-/* Prepare snapshot for next guard instruction. */
+/* Prepare snapshot for next guard or throwing instruction. */
 static void asm_snap_prep(ASMState *as)
 static void asm_snap_prep(ASMState *as)
 {
 {
-  if (as->curins < as->snapref) {
-    do {
-      if (as->snapno == 0) return;  /* Called by sunk stores before snap #0. */
-      as->snapno--;
-      as->snapref = as->T->snap[as->snapno].ref;
-    } while (as->curins < as->snapref);
-    asm_snap_alloc(as);
+  if (as->snapalloc) {
+    /* Alloc on first invocation for each snapshot. */
+    as->snapalloc = 0;
+    asm_snap_alloc(as, as->snapno);
     as->snaprename = as->T->nins;
     as->snaprename = as->T->nins;
   } else {
   } else {
-    /* Process any renames above the highwater mark. */
+    /* Check any renames above the highwater mark. */
     for (; as->snaprename < as->T->nins; as->snaprename++) {
     for (; as->snaprename < as->T->nins; as->snaprename++) {
       IRIns *ir = &as->T->ir[as->snaprename];
       IRIns *ir = &as->T->ir[as->snaprename];
       if (asm_snap_checkrename(as, ir->op1))
       if (asm_snap_checkrename(as, ir->op1))
@@ -1013,6 +1018,35 @@ static void asm_snap_prep(ASMState *as)
   }
   }
 }
 }
 
 
+/* Move to previous snapshot when we cross the current snapshot ref. */
+static void asm_snap_prev(ASMState *as)
+{
+  if (as->curins < as->snapref) {
+    uintptr_t ofs = (uintptr_t)(as->mctoporig - as->mcp);
+    if (ofs >= 0x10000) lj_trace_err(as->J, LJ_TRERR_MCODEOV);
+    do {
+      if (as->snapno == 0) return;
+      as->snapno--;
+      as->snapref = as->T->snap[as->snapno].ref;
+      as->T->snap[as->snapno].mcofs = (uint16_t)ofs;  /* Remember mcode ofs. */
+    } while (as->curins < as->snapref);  /* May have no ins inbetween. */
+    as->snapalloc = 1;
+  }
+}
+
+/* Fixup snapshot mcode offsetst. */
+static void asm_snap_fixup_mcofs(ASMState *as)
+{
+  uint32_t sz = (uint32_t)(as->mctoporig - as->mcp);
+  SnapShot *snap = as->T->snap;
+  SnapNo i;
+  for (i = as->T->nsnap-1; i > 0; i--) {
+    /* Compute offset from mcode start and store in correct snapshot. */
+    snap[i].mcofs = (uint16_t)(sz - snap[i-1].mcofs);
+  }
+  snap[0].mcofs = 0;
+}
+
 /* -- Miscellaneous helpers ----------------------------------------------- */
 /* -- Miscellaneous helpers ----------------------------------------------- */
 
 
 /* Calculate stack adjustment. */
 /* Calculate stack adjustment. */
@@ -1057,6 +1091,7 @@ static void asm_snew(ASMState *as, IRIns *ir)
 {
 {
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_new];
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_new];
   IRRef args[3];
   IRRef args[3];
+  asm_snap_prep(as);
   args[0] = ASMREF_L;  /* lua_State *L    */
   args[0] = ASMREF_L;  /* lua_State *L    */
   args[1] = ir->op1;   /* const char *str */
   args[1] = ir->op1;   /* const char *str */
   args[2] = ir->op2;   /* size_t len      */
   args[2] = ir->op2;   /* size_t len      */
@@ -1069,6 +1104,7 @@ static void asm_tnew(ASMState *as, IRIns *ir)
 {
 {
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_tab_new1];
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_tab_new1];
   IRRef args[2];
   IRRef args[2];
+  asm_snap_prep(as);
   args[0] = ASMREF_L;     /* lua_State *L    */
   args[0] = ASMREF_L;     /* lua_State *L    */
   args[1] = ASMREF_TMP1;  /* uint32_t ahsize */
   args[1] = ASMREF_TMP1;  /* uint32_t ahsize */
   as->gcsteps++;
   as->gcsteps++;
@@ -1081,6 +1117,7 @@ static void asm_tdup(ASMState *as, IRIns *ir)
 {
 {
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_tab_dup];
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_tab_dup];
   IRRef args[2];
   IRRef args[2];
+  asm_snap_prep(as);
   args[0] = ASMREF_L;  /* lua_State *L    */
   args[0] = ASMREF_L;  /* lua_State *L    */
   args[1] = ir->op1;   /* const GCtab *kt */
   args[1] = ir->op1;   /* const GCtab *kt */
   as->gcsteps++;
   as->gcsteps++;
@@ -1106,28 +1143,43 @@ static void asm_gcstep(ASMState *as, IRIns *ir)
 
 
 /* -- Buffer operations --------------------------------------------------- */
 /* -- Buffer operations --------------------------------------------------- */
 
 
-static void asm_tvptr(ASMState *as, Reg dest, IRRef ref);
+static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode);
+#if LJ_HASBUFFER
+static void asm_bufhdr_write(ASMState *as, Reg sb);
+#endif
 
 
 static void asm_bufhdr(ASMState *as, IRIns *ir)
 static void asm_bufhdr(ASMState *as, IRIns *ir)
 {
 {
   Reg sb = ra_dest(as, ir, RSET_GPR);
   Reg sb = ra_dest(as, ir, RSET_GPR);
-  if ((ir->op2 & IRBUFHDR_APPEND)) {
+  switch (ir->op2) {
+  case IRBUFHDR_RESET: {
+    Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb));
+    IRIns irbp;
+    irbp.ot = IRT(0, IRT_PTR);  /* Buffer data pointer type. */
+    emit_storeofs(as, &irbp, tmp, sb, offsetof(SBuf, w));
+    emit_loadofs(as, &irbp, tmp, sb, offsetof(SBuf, b));
+    break;
+    }
+  case IRBUFHDR_APPEND: {
     /* Rematerialize const buffer pointer instead of likely spill. */
     /* Rematerialize const buffer pointer instead of likely spill. */
     IRIns *irp = IR(ir->op1);
     IRIns *irp = IR(ir->op1);
     if (!(ra_hasreg(irp->r) || irp == ir-1 ||
     if (!(ra_hasreg(irp->r) || irp == ir-1 ||
 	  (irp == ir-2 && !ra_used(ir-1)))) {
 	  (irp == ir-2 && !ra_used(ir-1)))) {
-      while (!(irp->o == IR_BUFHDR && !(irp->op2 & IRBUFHDR_APPEND)))
+      while (!(irp->o == IR_BUFHDR && irp->op2 == IRBUFHDR_RESET))
 	irp = IR(irp->op1);
 	irp = IR(irp->op1);
       if (irref_isk(irp->op1)) {
       if (irref_isk(irp->op1)) {
 	ra_weak(as, ra_allocref(as, ir->op1, RSET_GPR));
 	ra_weak(as, ra_allocref(as, ir->op1, RSET_GPR));
 	ir = irp;
 	ir = irp;
       }
       }
     }
     }
-  } else {
-    Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb));
-    /* Passing ir isn't strictly correct, but it's an IRT_PGC, too. */
-    emit_storeofs(as, ir, tmp, sb, offsetof(SBuf, p));
-    emit_loadofs(as, ir, tmp, sb, offsetof(SBuf, b));
+    break;
+    }
+#if LJ_HASBUFFER
+  case IRBUFHDR_WRITE:
+    asm_bufhdr_write(as, sb);
+    break;
+#endif
+  default: lj_assertA(0, "bad BUFHDR op2 %d", ir->op2); break;
   }
   }
 #if LJ_TARGET_X86ORX64
 #if LJ_TARGET_X86ORX64
   ra_left(as, sb, ir->op1);
   ra_left(as, sb, ir->op1);
@@ -1179,7 +1231,7 @@ static void asm_bufput(ASMState *as, IRIns *ir)
   if (args[1] == ASMREF_TMP1) {
   if (args[1] == ASMREF_TMP1) {
     Reg tmp = ra_releasetmp(as, ASMREF_TMP1);
     Reg tmp = ra_releasetmp(as, ASMREF_TMP1);
     if (kchar == -129)
     if (kchar == -129)
-      asm_tvptr(as, tmp, irs->op1);
+      asm_tvptr(as, tmp, irs->op1, IRTMPREF_IN1);
     else
     else
       ra_allockreg(as, kchar, tmp);
       ra_allockreg(as, kchar, tmp);
   }
   }
@@ -1201,6 +1253,7 @@ static void asm_tostr(ASMState *as, IRIns *ir)
 {
 {
   const CCallInfo *ci;
   const CCallInfo *ci;
   IRRef args[2];
   IRRef args[2];
+  asm_snap_prep(as);
   args[0] = ASMREF_L;
   args[0] = ASMREF_L;
   as->gcsteps++;
   as->gcsteps++;
   if (ir->op2 == IRTOSTR_NUM) {
   if (ir->op2 == IRTOSTR_NUM) {
@@ -1216,7 +1269,7 @@ static void asm_tostr(ASMState *as, IRIns *ir)
   asm_setupresult(as, ir, ci);  /* GCstr * */
   asm_setupresult(as, ir, ci);  /* GCstr * */
   asm_gencall(as, ci, args);
   asm_gencall(as, ci, args);
   if (ir->op2 == IRTOSTR_NUM)
   if (ir->op2 == IRTOSTR_NUM)
-    asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1);
+    asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1, IRTMPREF_IN1);
 }
 }
 
 
 #if LJ_32 && LJ_HASFFI && !LJ_SOFTFP && !LJ_TARGET_X86
 #if LJ_32 && LJ_HASFFI && !LJ_SOFTFP && !LJ_TARGET_X86
@@ -1257,12 +1310,19 @@ static void asm_newref(ASMState *as, IRIns *ir)
   IRRef args[3];
   IRRef args[3];
   if (ir->r == RID_SINK)
   if (ir->r == RID_SINK)
     return;
     return;
+  asm_snap_prep(as);
   args[0] = ASMREF_L;     /* lua_State *L */
   args[0] = ASMREF_L;     /* lua_State *L */
   args[1] = ir->op1;      /* GCtab *t     */
   args[1] = ir->op1;      /* GCtab *t     */
   args[2] = ASMREF_TMP1;  /* cTValue *key */
   args[2] = ASMREF_TMP1;  /* cTValue *key */
   asm_setupresult(as, ir, ci);  /* TValue * */
   asm_setupresult(as, ir, ci);  /* TValue * */
   asm_gencall(as, ci, args);
   asm_gencall(as, ci, args);
-  asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op2);
+  asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op2, IRTMPREF_IN1);
+}
+
+static void asm_tmpref(ASMState *as, IRIns *ir)
+{
+  Reg r = ra_dest(as, ir, RSET_GPR);
+  asm_tvptr(as, r, ir->op1, ir->op2);
 }
 }
 
 
 static void asm_lref(ASMState *as, IRIns *ir)
 static void asm_lref(ASMState *as, IRIns *ir)
@@ -1744,6 +1804,7 @@ static void asm_ir(ASMState *as, IRIns *ir)
   case IR_NEWREF: asm_newref(as, ir); break;
   case IR_NEWREF: asm_newref(as, ir); break;
   case IR_UREFO: case IR_UREFC: asm_uref(as, ir); break;
   case IR_UREFO: case IR_UREFC: asm_uref(as, ir); break;
   case IR_FREF: asm_fref(as, ir); break;
   case IR_FREF: asm_fref(as, ir); break;
+  case IR_TMPREF: asm_tmpref(as, ir); break;
   case IR_STRREF: asm_strref(as, ir); break;
   case IR_STRREF: asm_strref(as, ir); break;
   case IR_LREF: asm_lref(as, ir); break;
   case IR_LREF: asm_lref(as, ir); break;
 
 
@@ -1838,8 +1899,7 @@ static void asm_head_side(ASMState *as)
 
 
   if (as->snapno && as->topslot > as->parent->topslot) {
   if (as->snapno && as->topslot > as->parent->topslot) {
     /* Force snap #0 alloc to prevent register overwrite in stack check. */
     /* Force snap #0 alloc to prevent register overwrite in stack check. */
-    as->snapno = 0;
-    asm_snap_alloc(as);
+    asm_snap_alloc(as, 0);
   }
   }
   allow = asm_head_side_base(as, irp, allow);
   allow = asm_head_side_base(as, irp, allow);
 
 
@@ -2078,6 +2138,9 @@ static void asm_setup_regsp(ASMState *as)
 #endif
 #endif
 
 
   ra_setup(as);
   ra_setup(as);
+#if LJ_TARGET_ARM64
+  ra_setkref(as, RID_GL, (intptr_t)J2G(as->J));
+#endif
 
 
   /* Clear reg/sp for constants. */
   /* Clear reg/sp for constants. */
   for (ir = IR(T->nk), lastir = IR(REF_BASE); ir < lastir; ir++) {
   for (ir = IR(T->nk), lastir = IR(REF_BASE); ir < lastir; ir++) {
@@ -2100,6 +2163,7 @@ static void asm_setup_regsp(ASMState *as)
   as->snaprename = nins;
   as->snaprename = nins;
   as->snapref = nins;
   as->snapref = nins;
   as->snapno = T->nsnap;
   as->snapno = T->nsnap;
+  as->snapalloc = 0;
 
 
   as->stopins = REF_BASE;
   as->stopins = REF_BASE;
   as->orignins = nins;
   as->orignins = nins;
@@ -2148,6 +2212,10 @@ static void asm_setup_regsp(ASMState *as)
       ir->prev = (uint16_t)REGSP_HINT((rload & 15));
       ir->prev = (uint16_t)REGSP_HINT((rload & 15));
       rload = lj_ror(rload, 4);
       rload = lj_ror(rload, 4);
       continue;
       continue;
+    case IR_TMPREF:
+      if ((ir->op2 & IRTMPREF_OUT2) && as->evenspill < 4)
+	as->evenspill = 4;  /* TMPREF OUT2 needs two TValues on the stack. */
+      break;
 #endif
 #endif
     case IR_CALLXS: {
     case IR_CALLXS: {
       CCallInfo ci;
       CCallInfo ci;
@@ -2157,7 +2225,17 @@ static void asm_setup_regsp(ASMState *as)
 	as->modset |= RSET_SCRATCH;
 	as->modset |= RSET_SCRATCH;
       continue;
       continue;
       }
       }
-    case IR_CALLN: case IR_CALLA: case IR_CALLL: case IR_CALLS: {
+    case IR_CALLL:
+      /* lj_vm_next needs two TValues on the stack. */
+#if LJ_TARGET_X64 && LJ_ABI_WIN
+      if (ir->op2 == IRCALL_lj_vm_next && as->evenspill < SPS_FIRST + 4)
+	as->evenspill = SPS_FIRST + 4;
+#else
+      if (SPS_FIRST < 4 && ir->op2 == IRCALL_lj_vm_next && as->evenspill < 4)
+	as->evenspill = 4;
+#endif
+      /* fallthrough */
+    case IR_CALLN: case IR_CALLA: case IR_CALLS: {
       const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
       const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
       ir->prev = asm_setup_call_slots(as, ir, ci);
       ir->prev = asm_setup_call_slots(as, ir, ci);
       if (inloop)
       if (inloop)
@@ -2165,7 +2243,6 @@ static void asm_setup_regsp(ASMState *as)
 		      (RSET_SCRATCH & ~RSET_FPR) : RSET_SCRATCH;
 		      (RSET_SCRATCH & ~RSET_FPR) : RSET_SCRATCH;
       continue;
       continue;
       }
       }
-#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
     case IR_HIOP:
     case IR_HIOP:
       switch ((ir-1)->o) {
       switch ((ir-1)->o) {
 #if LJ_SOFTFP && LJ_TARGET_ARM
 #if LJ_SOFTFP && LJ_TARGET_ARM
@@ -2176,7 +2253,7 @@ static void asm_setup_regsp(ASMState *as)
 	}
 	}
 	break;
 	break;
 #endif
 #endif
-#if !LJ_SOFTFP && LJ_NEED_FP64
+#if !LJ_SOFTFP && LJ_NEED_FP64 && LJ_32 && LJ_HASFFI
       case IR_CONV:
       case IR_CONV:
 	if (irt_isfp((ir-1)->t)) {
 	if (irt_isfp((ir-1)->t)) {
 	  ir->prev = REGSP_HINT(RID_FPRET);
 	  ir->prev = REGSP_HINT(RID_FPRET);
@@ -2184,7 +2261,7 @@ static void asm_setup_regsp(ASMState *as)
 	}
 	}
 #endif
 #endif
       /* fallthrough */
       /* fallthrough */
-      case IR_CALLN: case IR_CALLXS:
+      case IR_CALLN: case IR_CALLL: case IR_CALLS: case IR_CALLXS:
 #if LJ_SOFTFP
 #if LJ_SOFTFP
       case IR_MIN: case IR_MAX:
       case IR_MIN: case IR_MAX:
 #endif
 #endif
@@ -2195,7 +2272,6 @@ static void asm_setup_regsp(ASMState *as)
 	break;
 	break;
       }
       }
       break;
       break;
-#endif
 #if LJ_SOFTFP
 #if LJ_SOFTFP
     case IR_MIN: case IR_MAX:
     case IR_MIN: case IR_MAX:
       if ((ir+1)->o != IR_HIOP) break;
       if ((ir+1)->o != IR_HIOP) break;
@@ -2250,13 +2326,23 @@ static void asm_setup_regsp(ASMState *as)
       }
       }
       /* fallthrough */ /* for integer POW */
       /* fallthrough */ /* for integer POW */
     case IR_DIV: case IR_MOD:
     case IR_DIV: case IR_MOD:
-      if (!irt_isnum(ir->t)) {
+      if ((LJ_64 && LJ_SOFTFP) || !irt_isnum(ir->t)) {
 	ir->prev = REGSP_HINT(RID_RET);
 	ir->prev = REGSP_HINT(RID_RET);
 	if (inloop)
 	if (inloop)
 	  as->modset |= (RSET_SCRATCH & RSET_GPR);
 	  as->modset |= (RSET_SCRATCH & RSET_GPR);
 	continue;
 	continue;
       }
       }
       break;
       break;
+#if LJ_64 && LJ_SOFTFP
+    case IR_ADD: case IR_SUB: case IR_MUL:
+      if (irt_isnum(ir->t)) {
+	ir->prev = REGSP_HINT(RID_RET);
+	if (inloop)
+	  as->modset |= (RSET_SCRATCH & RSET_GPR);
+	continue;
+      }
+      break;
+#endif
     case IR_FPMATH:
     case IR_FPMATH:
 #if LJ_TARGET_X86ORX64
 #if LJ_TARGET_X86ORX64
       if (ir->op2 <= IRFPM_TRUNC) {
       if (ir->op2 <= IRFPM_TRUNC) {
@@ -2327,7 +2413,6 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
 {
 {
   ASMState as_;
   ASMState as_;
   ASMState *as = &as_;
   ASMState *as = &as_;
-  MCode *origtop;
 
 
   /* Remove nops/renames left over from ASM restart due to LJ_TRERR_MCODELM. */
   /* Remove nops/renames left over from ASM restart due to LJ_TRERR_MCODELM. */
   {
   {
@@ -2355,7 +2440,7 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
   as->parent = J->parent ? traceref(J, J->parent) : NULL;
   as->parent = J->parent ? traceref(J, J->parent) : NULL;
 
 
   /* Reserve MCode memory. */
   /* Reserve MCode memory. */
-  as->mctop = origtop = lj_mcode_reserve(J, &as->mcbot);
+  as->mctop = as->mctoporig = lj_mcode_reserve(J, &as->mcbot);
   as->mcp = as->mctop;
   as->mcp = as->mctop;
   as->mclim = as->mcbot + MCLIM_REDZONE;
   as->mclim = as->mcbot + MCLIM_REDZONE;
   asm_setup_target(as);
   asm_setup_target(as);
@@ -2417,6 +2502,7 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
       lj_assertA(!(LJ_32 && irt_isint64(ir->t)),
       lj_assertA(!(LJ_32 && irt_isint64(ir->t)),
 		 "IR %04d has unsplit 64 bit type",
 		 "IR %04d has unsplit 64 bit type",
 		 (int)(ir - as->ir) - REF_BIAS);
 		 (int)(ir - as->ir) - REF_BIAS);
+      asm_snap_prev(as);
       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))
@@ -2450,6 +2536,9 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
       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;
+      /* Fill mcofs of any unprocessed snapshots. */
+      as->curins = REF_FIRST;
+      asm_snap_prev(as);
       break;  /* Done. */
       break;  /* Done. */
     }
     }
 
 
@@ -2468,13 +2557,16 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
   /* Set trace entry point before fixing up tail to allow link to self. */
   /* Set trace entry point before fixing up tail to allow link to self. */
   T->mcode = as->mcp;
   T->mcode = as->mcp;
   T->mcloop = as->mcloop ? (MSize)((char *)as->mcloop - (char *)as->mcp) : 0;
   T->mcloop = as->mcloop ? (MSize)((char *)as->mcloop - (char *)as->mcp) : 0;
-  if (!as->loopref)
+  if (as->loopref)
+    asm_loop_tail_fixup(as);
+  else
     asm_tail_fixup(as, T->link);  /* Note: this may change as->mctop! */
     asm_tail_fixup(as, T->link);  /* Note: this may change as->mctop! */
   T->szmcode = (MSize)((char *)as->mctop - (char *)as->mcp);
   T->szmcode = (MSize)((char *)as->mctop - (char *)as->mcp);
+  asm_snap_fixup_mcofs(as);
 #if LJ_TARGET_MCODE_FIXUP
 #if LJ_TARGET_MCODE_FIXUP
   asm_mcode_fixup(T->mcode, T->szmcode);
   asm_mcode_fixup(T->mcode, T->szmcode);
 #endif
 #endif
-  lj_mcode_sync(T->mcode, origtop);
+  lj_mcode_sync(T->mcode, as->mctoporig);
 }
 }
 
 
 #undef IR
 #undef IR

+ 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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _LJ_ASM_H
 #ifndef _LJ_ASM_H

+ 90 - 39
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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 /* -- Register allocator extensions --------------------------------------- */
 /* -- Register allocator extensions --------------------------------------- */
@@ -185,6 +185,9 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow,
 	*ofsp = (ofs & 255);  /* Mask out less bits to allow LDRD. */
 	*ofsp = (ofs & 255);  /* Mask out less bits to allow LDRD. */
 	return ra_allock(as, (ofs & ~255), allow);
 	return ra_allock(as, (ofs & ~255), allow);
       }
       }
+    } else if (ir->o == IR_TMPREF) {
+      *ofsp = 0;
+      return RID_SP;
     }
     }
   }
   }
   *ofsp = 0;
   *ofsp = 0;
@@ -498,6 +501,30 @@ static void asm_retf(ASMState *as, IRIns *ir)
   emit_lso(as, ARMI_LDR, RID_TMP, base, -4);
   emit_lso(as, ARMI_LDR, RID_TMP, base, -4);
 }
 }
 
 
+/* -- Buffer operations --------------------------------------------------- */
+
+#if LJ_HASBUFFER
+static void asm_bufhdr_write(ASMState *as, Reg sb)
+{
+  Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb));
+  IRIns irgc;
+  int32_t addr = i32ptr((void *)&J2G(as->J)->cur_L);
+  irgc.ot = IRT(0, IRT_PGC);  /* GC type. */
+  emit_storeofs(as, &irgc, RID_TMP, sb, offsetof(SBuf, L));
+  if ((as->flags & JIT_F_ARMV6T2)) {
+    emit_dnm(as, ARMI_BFI, RID_TMP, lj_fls(SBUF_MASK_FLAG), tmp);
+  } else {
+    emit_dnm(as, ARMI_ORR, RID_TMP, RID_TMP, tmp);
+    emit_dn(as, ARMI_AND|ARMI_K12|SBUF_MASK_FLAG, tmp, tmp);
+  }
+  emit_lso(as, ARMI_LDR, RID_TMP,
+	   ra_allock(as, (addr & ~4095),
+		     rset_exclude(rset_exclude(RSET_GPR, sb), tmp)),
+	   (addr & 4095));
+  emit_loadofs(as, &irgc, tmp, sb, offsetof(SBuf, L));
+}
+#endif
+
 /* -- Type conversions ---------------------------------------------------- */
 /* -- Type conversions ---------------------------------------------------- */
 
 
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
@@ -666,35 +693,55 @@ static void asm_strto(ASMState *as, IRIns *ir)
 /* -- Memory references --------------------------------------------------- */
 /* -- Memory references --------------------------------------------------- */
 
 
 /* Get pointer to TValue. */
 /* Get pointer to TValue. */
-static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
+static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode)
 {
 {
-  IRIns *ir = IR(ref);
-  if (irt_isnum(ir->t)) {
-    if (irref_isk(ref)) {
-      /* Use the number constant itself as a TValue. */
-      ra_allockreg(as, i32ptr(ir_knum(ir)), dest);
-    } else {
+  if ((mode & IRTMPREF_IN1)) {
+    IRIns *ir = IR(ref);
+    if (irt_isnum(ir->t)) {
+      if ((mode & IRTMPREF_OUT1)) {
+#if LJ_SOFTFP
+	lj_assertA(irref_isk(ref), "unsplit FP op");
+	emit_dm(as, ARMI_MOV, dest, RID_SP);
+	emit_lso(as, ARMI_STR,
+		 ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, RSET_GPR),
+		 RID_SP, 0);
+	emit_lso(as, ARMI_STR,
+		 ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, RSET_GPR),
+		 RID_SP, 4);
+#else
+	Reg src = ra_alloc1(as, ref, RSET_FPR);
+	emit_dm(as, ARMI_MOV, dest, RID_SP);
+	emit_vlso(as, ARMI_VSTR_D, src, RID_SP, 0);
+#endif
+      } else if (irref_isk(ref)) {
+	/* Use the number constant itself as a TValue. */
+	ra_allockreg(as, i32ptr(ir_knum(ir)), dest);
+      } else {
 #if LJ_SOFTFP
 #if LJ_SOFTFP
-      lj_assertA(0, "unsplit FP op");
+	lj_assertA(0, "unsplit FP op");
 #else
 #else
-      /* Otherwise force a spill and use the spill slot. */
-      emit_opk(as, ARMI_ADD, dest, RID_SP, ra_spill(as, ir), RSET_GPR);
+	/* Otherwise force a spill and use the spill slot. */
+	emit_opk(as, ARMI_ADD, dest, RID_SP, ra_spill(as, ir), RSET_GPR);
 #endif
 #endif
+      }
+    } else {
+      /* Otherwise use [sp] and [sp+4] to hold the TValue.
+      ** This assumes the following call has max. 4 args.
+      */
+      Reg type;
+      emit_dm(as, ARMI_MOV, dest, RID_SP);
+      if (!irt_ispri(ir->t)) {
+	Reg src = ra_alloc1(as, ref, RSET_GPR);
+	emit_lso(as, ARMI_STR, src, RID_SP, 0);
+      }
+      if (LJ_SOFTFP && (ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t))
+	type = ra_alloc1(as, ref+1, RSET_GPR);
+      else
+	type = ra_allock(as, irt_toitype(ir->t), RSET_GPR);
+      emit_lso(as, ARMI_STR, type, RID_SP, 4);
     }
     }
   } else {
   } else {
-    /* Otherwise use [sp] and [sp+4] to hold the TValue. */
-    RegSet allow = rset_exclude(RSET_GPR, dest);
-    Reg type;
     emit_dm(as, ARMI_MOV, dest, RID_SP);
     emit_dm(as, ARMI_MOV, dest, RID_SP);
-    if (!irt_ispri(ir->t)) {
-      Reg src = ra_alloc1(as, ref, allow);
-      emit_lso(as, ARMI_STR, src, RID_SP, 0);
-    }
-    if (LJ_SOFTFP && (ir+1)->o == IR_HIOP)
-      type = ra_alloc1(as, ref+1, allow);
-    else
-      type = ra_allock(as, irt_toitype(ir->t), allow);
-    emit_lso(as, ARMI_STR, type, RID_SP, 4);
   }
   }
 }
 }
 
 
@@ -1086,6 +1133,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
   }
   }
   idx = asm_fuseahuref(as, ir->op1, &ofs, allow,
   idx = asm_fuseahuref(as, ir->op1, &ofs, allow,
 		       (!LJ_SOFTFP && t == IRT_NUM) ? 1024 : 4096);
 		       (!LJ_SOFTFP && t == IRT_NUM) ? 1024 : 4096);
+  if (ir->o == IR_VLOAD) ofs += 8 * ir->op2;
   if (!hiop || type == RID_NONE) {
   if (!hiop || type == RID_NONE) {
     rset_clear(allow, idx);
     rset_clear(allow, idx);
     if (ofs < 256 && ra_hasreg(dest) && (dest & 1) == 0 &&
     if (ofs < 256 && ra_hasreg(dest) && (dest & 1) == 0 &&
@@ -1837,15 +1885,15 @@ static void asm_int64comp(ASMState *as, IRIns *ir)
 }
 }
 #endif
 #endif
 
 
-/* -- Support for 64 bit ops in 32 bit mode ------------------------------- */
+/* -- Split register ops -------------------------------------------------- */
 
 
-/* Hiword op of a split 64 bit op. Previous op must be the loword op. */
+/* Hiword op of a split 32/32 bit op. Previous op is the loword op. */
 static void asm_hiop(ASMState *as, IRIns *ir)
 static void asm_hiop(ASMState *as, IRIns *ir)
 {
 {
-#if LJ_HASFFI || LJ_SOFTFP
   /* HIOP is marked as a store because it needs its own DCE logic. */
   /* HIOP is marked as a store because it needs its own DCE logic. */
   int uselo = ra_used(ir-1), usehi = ra_used(ir);  /* Loword/hiword used? */
   int uselo = ra_used(ir-1), usehi = ra_used(ir);  /* Loword/hiword used? */
   if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
   if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
+#if LJ_HASFFI || LJ_SOFTFP
   if ((ir-1)->o <= IR_NE) {  /* 64 bit integer or FP comparisons. ORDER IR. */
   if ((ir-1)->o <= IR_NE) {  /* 64 bit integer or FP comparisons. ORDER IR. */
     as->curins--;  /* Always skip the loword comparison. */
     as->curins--;  /* Always skip the loword comparison. */
 #if LJ_SOFTFP
 #if LJ_SOFTFP
@@ -1876,6 +1924,7 @@ static void asm_hiop(ASMState *as, IRIns *ir)
       asm_xstore_(as, ir, 4);
       asm_xstore_(as, ir, 4);
     return;
     return;
   }
   }
+#endif
   if (!usehi) return;  /* Skip unused hiword op for all remaining ops. */
   if (!usehi) return;  /* Skip unused hiword op for all remaining ops. */
   switch ((ir-1)->o) {
   switch ((ir-1)->o) {
 #if LJ_HASFFI
 #if LJ_HASFFI
@@ -1894,6 +1943,9 @@ static void asm_hiop(ASMState *as, IRIns *ir)
     asm_intneg(as, ir, ARMI_RSC);
     asm_intneg(as, ir, ARMI_RSC);
     asm_intneg(as, ir-1, ARMI_RSB|ARMI_S);
     asm_intneg(as, ir-1, ARMI_RSB|ARMI_S);
     break;
     break;
+  case IR_CNEWI:
+    /* Nothing to do here. Handled by lo op itself. */
+    break;
 #endif
 #endif
 #if LJ_SOFTFP
 #if LJ_SOFTFP
   case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
   case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
@@ -1901,25 +1953,16 @@ static void asm_hiop(ASMState *as, IRIns *ir)
     if (!uselo)
     if (!uselo)
       ra_allocref(as, ir->op1, RSET_GPR);  /* Mark lo op as used. */
       ra_allocref(as, ir->op1, RSET_GPR);  /* Mark lo op as used. */
     break;
     break;
+  case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: case IR_TMPREF:
+    /* Nothing to do here. Handled by lo op itself. */
+    break;
 #endif
 #endif
-  case IR_CALLN:
-  case IR_CALLS:
-  case IR_CALLXS:
+  case IR_CALLN: case IR_CALLL: case IR_CALLS: case IR_CALLXS:
     if (!uselo)
     if (!uselo)
       ra_allocref(as, ir->op1, RID2RSET(RID_RETLO));  /* Mark lo op as used. */
       ra_allocref(as, ir->op1, RID2RSET(RID_RETLO));  /* Mark lo op as used. */
     break;
     break;
-#if LJ_SOFTFP
-  case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR:
-#endif
-  case IR_CNEWI:
-    /* Nothing to do here. Handled by lo op itself. */
-    break;
   default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
   default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
   }
   }
-#else
-  /* Unused without SOFTFP or FFI. */
-  UNUSED(as); UNUSED(ir); lj_assertA(0, "unexpected HIOP");
-#endif
 }
 }
 
 
 /* -- Profiling ----------------------------------------------------------- */
 /* -- Profiling ----------------------------------------------------------- */
@@ -2021,6 +2064,8 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
       } else if ((sn & SNAP_SOFTFPNUM)) {
       } else if ((sn & SNAP_SOFTFPNUM)) {
 	type = ra_alloc1(as, ref+1, rset_exclude(RSET_GPRODD, RID_BASE));
 	type = ra_alloc1(as, ref+1, rset_exclude(RSET_GPRODD, RID_BASE));
 #endif
 #endif
+      } else if ((sn & SNAP_KEYINDEX)) {
+	type = ra_allock(as, (int32_t)LJ_KEYINDEX, odd);
       } else {
       } else {
 	type = ra_allock(as, (int32_t)irt_toitype(ir->t), odd);
 	type = ra_allock(as, (int32_t)irt_toitype(ir->t), odd);
       }
       }
@@ -2082,6 +2127,12 @@ static void asm_loop_fixup(ASMState *as)
   }
   }
 }
 }
 
 
+/* Fixup the tail of the loop. */
+static void asm_loop_tail_fixup(ASMState *as)
+{
+  UNUSED(as);  /* Nothing to do. */
+}
+
 /* -- Head of trace ------------------------------------------------------- */
 /* -- Head of trace ------------------------------------------------------- */
 
 
 /* Reload L register from g->cur_L. */
 /* Reload L register from g->cur_L. */

+ 79 - 36
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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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.
@@ -198,6 +198,9 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow,
 	  return RID_GL;
 	  return RID_GL;
 	}
 	}
       }
       }
+    } else if (ir->o == IR_TMPREF) {
+      *ofsp = (int32_t)glofs(as, &J2G(as->J)->tmptv);
+      return RID_GL;
     }
     }
   }
   }
   *ofsp = 0;
   *ofsp = 0;
@@ -457,8 +460,11 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
 static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
 static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
 {
 {
   RegSet drop = RSET_SCRATCH;
   RegSet drop = RSET_SCRATCH;
+  int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t));
   if (ra_hasreg(ir->r))
   if (ra_hasreg(ir->r))
     rset_clear(drop, ir->r); /* Dest reg handled below. */
     rset_clear(drop, ir->r); /* Dest reg handled below. */
+  if (hiop && ra_hasreg((ir+1)->r))
+    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)) {
     lj_assertA(!irt_ispri(ir->t), "PRI dest");
     lj_assertA(!irt_ispri(ir->t), "PRI dest");
@@ -470,6 +476,8 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
       } else {
       } else {
 	ra_destreg(as, ir, RID_FPRET);
 	ra_destreg(as, ir, RID_FPRET);
       }
       }
+    } else if (hiop) {
+      ra_destpair(as, ir);
     } else {
     } else {
       ra_destreg(as, ir, RID_RET);
       ra_destreg(as, ir, RID_RET);
     }
     }
@@ -519,6 +527,21 @@ static void asm_retf(ASMState *as, IRIns *ir)
   emit_lso(as, A64I_LDRx, RID_TMP, base, -8);
   emit_lso(as, A64I_LDRx, RID_TMP, base, -8);
 }
 }
 
 
+/* -- Buffer operations --------------------------------------------------- */
+
+#if LJ_HASBUFFER
+static void asm_bufhdr_write(ASMState *as, Reg sb)
+{
+  Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb));
+  IRIns irgc;
+  irgc.ot = IRT(0, IRT_PGC);  /* GC type. */
+  emit_storeofs(as, &irgc, RID_TMP, sb, offsetof(SBuf, L));
+  emit_dn(as, A64I_BFMx | A64F_IMMS(lj_fls(SBUF_MASK_FLAG)) | A64F_IMMR(0), RID_TMP, tmp);
+  emit_getgl(as, RID_TMP, cur_L);
+  emit_loadofs(as, &irgc, tmp, sb, offsetof(SBuf, L));
+}
+#endif
+
 /* -- Type conversions ---------------------------------------------------- */
 /* -- Type conversions ---------------------------------------------------- */
 
 
 static void asm_tointg(ASMState *as, IRIns *ir, Reg left)
 static void asm_tointg(ASMState *as, IRIns *ir, Reg left)
@@ -602,7 +625,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
 	emit_dn(as, A64I_SXTW, dest, left);
 	emit_dn(as, A64I_SXTW, dest, left);
       }
       }
     } else {
     } else {
-      if (st64) {
+      if (st64 && !(ir->op2 & IRCONV_NONE)) {
 	/* This is either a 32 bit reg/reg mov which zeroes the hiword
 	/* This is either a 32 bit reg/reg mov which zeroes the hiword
 	** or a load of the loword from a 64 bit address.
 	** or a load of the loword from a 64 bit address.
 	*/
 	*/
@@ -675,22 +698,23 @@ static void asm_tvstore64(ASMState *as, Reg base, int32_t ofs, IRRef ref)
 }
 }
 
 
 /* Get pointer to TValue. */
 /* Get pointer to TValue. */
-static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
+static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode)
 {
 {
-  IRIns *ir = IR(ref);
-  if (irt_isnum(ir->t)) {
-    if (irref_isk(ref)) {
-      /* Use the number constant itself as a TValue. */
-      ra_allockreg(as, i64ptr(ir_knum(ir)), dest);
+  if ((mode & IRTMPREF_IN1)) {
+    IRIns *ir = IR(ref);
+    if (irt_isnum(ir->t)) {
+      if (irref_isk(ref) && !(mode & IRTMPREF_OUT1)) {
+	/* Use the number constant itself as a TValue. */
+	ra_allockreg(as, i64ptr(ir_knum(ir)), dest);
+	return;
+      }
+      emit_lso(as, A64I_STRd, (ra_alloc1(as, ref, RSET_FPR) & 31), dest, 0);
     } else {
     } else {
-      /* Otherwise force a spill and use the spill slot. */
-      emit_opk(as, A64I_ADDx, dest, RID_SP, ra_spill(as, ir), RSET_GPR);
+      asm_tvstore64(as, dest, 0, ref);
     }
     }
-  } else {
-    /* Otherwise use g->tmptv to hold the TValue. */
-    asm_tvstore64(as, dest, 0, ref);
-    ra_allockreg(as, i64ptr(&J2G(as->J)->tmptv), dest);
   }
   }
+  /* g->tmptv holds the TValue(s). */
+  emit_dn(as, A64I_ADDx^emit_isk12(glofs(as, &J2G(as->J)->tmptv)), dest, RID_GL);
 }
 }
 
 
 static void asm_aref(ASMState *as, IRIns *ir)
 static void asm_aref(ASMState *as, IRIns *ir)
@@ -767,7 +791,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
     }
     }
   } else if (irt_isaddr(kt)) {
   } else if (irt_isaddr(kt)) {
     if (isk) {
     if (isk) {
-      int64_t kk = ((int64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64;
+      int64_t kk = ((int64_t)irt_toitype(kt) << 47) | irkey[1].tv.u64;
       scr = ra_allock(as, kk, allow);
       scr = ra_allock(as, kk, allow);
     } else {
     } else {
       scr = ra_scratch(as, allow);
       scr = ra_scratch(as, allow);
@@ -775,7 +799,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
     rset_clear(allow, scr);
     rset_clear(allow, scr);
   } else {
   } else {
     lj_assertA(irt_ispri(kt) && !irt_isnil(kt), "bad HREF key type");
     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(kt) << 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);
   }
   }
@@ -824,7 +848,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
       emit_lso(as, A64I_LDRx, scr, dest, offsetof(Node, key.u64));
       emit_lso(as, A64I_LDRx, scr, dest, offsetof(Node, key.u64));
     }
     }
   } else {
   } else {
-    emit_nm(as, A64I_CMPw, scr, type);
+    emit_nm(as, A64I_CMPx, scr, type);
     emit_lso(as, A64I_LDRx, scr, dest, offsetof(Node, key));
     emit_lso(as, A64I_LDRx, scr, dest, offsetof(Node, key));
   }
   }
 
 
@@ -1059,6 +1083,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
   }
   }
   type = ra_scratch(as, rset_clear(gpr, tmp));
   type = ra_scratch(as, rset_clear(gpr, tmp));
   idx = asm_fuseahuref(as, ir->op1, &ofs, rset_clear(gpr, type), A64I_LDRx);
   idx = asm_fuseahuref(as, ir->op1, &ofs, rset_clear(gpr, type), A64I_LDRx);
+  if (ir->o == IR_VLOAD) ofs += 8 * ir->op2;
   /* 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) {
@@ -1261,17 +1286,13 @@ static void asm_tbar(ASMState *as, IRIns *ir)
 {
 {
   Reg tab = ra_alloc1(as, ir->op1, RSET_GPR);
   Reg tab = ra_alloc1(as, ir->op1, RSET_GPR);
   Reg link = ra_scratch(as, rset_exclude(RSET_GPR, tab));
   Reg link = ra_scratch(as, rset_exclude(RSET_GPR, tab));
-  Reg gr = ra_allock(as, i64ptr(J2G(as->J)),
-		     rset_exclude(rset_exclude(RSET_GPR, tab), link));
   Reg mark = RID_TMP;
   Reg mark = RID_TMP;
   MCLabel l_end = emit_label(as);
   MCLabel l_end = emit_label(as);
   emit_lso(as, A64I_STRx, link, tab, (int32_t)offsetof(GCtab, gclist));
   emit_lso(as, A64I_STRx, link, tab, (int32_t)offsetof(GCtab, gclist));
   emit_lso(as, A64I_STRB, mark, tab, (int32_t)offsetof(GCtab, marked));
   emit_lso(as, A64I_STRB, mark, tab, (int32_t)offsetof(GCtab, marked));
-  emit_lso(as, A64I_STRx, tab, gr,
-	   (int32_t)offsetof(global_State, gc.grayagain));
+  emit_setgl(as, tab, gc.grayagain);
   emit_dn(as, A64I_ANDw^emit_isk13(~LJ_GC_BLACK, 0), mark, mark);
   emit_dn(as, A64I_ANDw^emit_isk13(~LJ_GC_BLACK, 0), mark, mark);
-  emit_lso(as, A64I_LDRx, link, gr,
-	   (int32_t)offsetof(global_State, gc.grayagain));
+  emit_getgl(as, link, gc.grayagain);
   emit_cond_branch(as, CC_EQ, l_end);
   emit_cond_branch(as, CC_EQ, l_end);
   emit_n(as, A64I_TSTw^emit_isk13(LJ_GC_BLACK, 0), mark);
   emit_n(as, A64I_TSTw^emit_isk13(LJ_GC_BLACK, 0), mark);
   emit_lso(as, A64I_LDRB, mark, tab, (int32_t)offsetof(GCtab, marked));
   emit_lso(as, A64I_LDRB, mark, tab, (int32_t)offsetof(GCtab, marked));
@@ -1291,7 +1312,7 @@ static void asm_obar(ASMState *as, IRIns *ir)
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[0] = ASMREF_TMP1;  /* global_State *g */
   args[1] = ir->op1;      /* TValue *tv      */
   args[1] = ir->op1;      /* TValue *tv      */
   asm_gencall(as, ci, args);
   asm_gencall(as, ci, args);
-  ra_allockreg(as, i64ptr(J2G(as->J)), ra_releasetmp(as, ASMREF_TMP1) );
+  emit_dm(as, A64I_MOVx, ra_releasetmp(as, ASMREF_TMP1), RID_GL);
   obj = IR(ir->op1)->r;
   obj = IR(ir->op1)->r;
   tmp = ra_scratch(as, rset_exclude(allow, obj));
   tmp = ra_scratch(as, rset_exclude(allow, obj));
   emit_cond_branch(as, CC_EQ, l_end);
   emit_cond_branch(as, CC_EQ, l_end);
@@ -1704,13 +1725,25 @@ static void asm_comp(ASMState *as, IRIns *ir)
 
 
 #define asm_equal(as, ir)	asm_comp(as, ir)
 #define asm_equal(as, ir)	asm_comp(as, ir)
 
 
-/* -- Support for 64 bit ops in 32 bit mode ------------------------------- */
+/* -- Split register ops -------------------------------------------------- */
 
 
-/* Hiword op of a split 64 bit op. Previous op must be the loword op. */
+/* Hiword op of a split 64/64 bit op. Previous op is the loword op. */
 static void asm_hiop(ASMState *as, IRIns *ir)
 static void asm_hiop(ASMState *as, IRIns *ir)
 {
 {
-  UNUSED(as); UNUSED(ir);
-  lj_assertA(0, "unexpected HIOP");  /* Unused on 64 bit. */
+  /* HIOP is marked as a store because it needs its own DCE logic. */
+  int uselo = ra_used(ir-1), usehi = ra_used(ir);  /* Loword/hiword used? */
+  if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
+  if (!usehi) return;  /* Skip unused hiword op for all remaining ops. */
+  switch ((ir-1)->o) {
+  case IR_CALLN:
+  case IR_CALLL:
+  case IR_CALLS:
+  case IR_CALLXS:
+    if (!uselo)
+      ra_allocref(as, ir->op1, RID2RSET(RID_RETLO));  /* Mark lo op as used. */
+    break;
+  default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
+  }
 }
 }
 
 
 /* -- Profiling ----------------------------------------------------------- */
 /* -- Profiling ----------------------------------------------------------- */
@@ -1781,7 +1814,14 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
     IRIns *ir = IR(ref);
     IRIns *ir = IR(ref);
     if ((sn & SNAP_NORESTORE))
     if ((sn & SNAP_NORESTORE))
       continue;
       continue;
-    if (irt_isnum(ir->t)) {
+    if ((sn & SNAP_KEYINDEX)) {
+      RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
+      Reg r = irref_isk(ref) ? ra_allock(as, ir->i, allow) :
+			       ra_alloc1(as, ref, allow);
+      rset_clear(allow, r);
+      emit_lso(as, A64I_STRw, r, RID_BASE, ofs);
+      emit_lso(as, A64I_STRw, ra_allock(as, LJ_KEYINDEX, allow), RID_BASE, ofs+4);
+    } else if (irt_isnum(ir->t)) {
       Reg src = ra_alloc1(as, ref, RSET_FPR);
       Reg src = ra_alloc1(as, ref, RSET_FPR);
       emit_lso(as, A64I_STRd, (src & 31), RID_BASE, ofs);
       emit_lso(as, A64I_STRd, (src & 31), RID_BASE, ofs);
     } else {
     } else {
@@ -1804,7 +1844,7 @@ static void asm_gc_check(ASMState *as)
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_gc_step_jit];
   const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_gc_step_jit];
   IRRef args[2];
   IRRef args[2];
   MCLabel l_end;
   MCLabel l_end;
-  Reg tmp1, tmp2;
+  Reg tmp2;
   ra_evictset(as, RSET_SCRATCH);
   ra_evictset(as, RSET_SCRATCH);
   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. */
@@ -1813,17 +1853,14 @@ 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);
-  tmp1 = ra_releasetmp(as, ASMREF_TMP1);
+  emit_dm(as, A64I_MOVx, ra_releasetmp(as, ASMREF_TMP1), RID_GL);
   tmp2 = ra_releasetmp(as, ASMREF_TMP2);
   tmp2 = ra_releasetmp(as, ASMREF_TMP2);
   emit_loadi(as, tmp2, as->gcsteps);
   emit_loadi(as, tmp2, as->gcsteps);
   /* Jump around GC step if GC total < GC threshold. */
   /* Jump around GC step if GC total < GC threshold. */
   emit_cond_branch(as, CC_LS, l_end);
   emit_cond_branch(as, CC_LS, l_end);
   emit_nm(as, A64I_CMPx, RID_TMP, tmp2);
   emit_nm(as, A64I_CMPx, RID_TMP, tmp2);
-  emit_lso(as, A64I_LDRx, tmp2, tmp1,
-	   (int32_t)offsetof(global_State, gc.threshold));
-  emit_lso(as, A64I_LDRx, RID_TMP, tmp1,
-	   (int32_t)offsetof(global_State, gc.total));
-  ra_allockreg(as, i64ptr(J2G(as->J)), tmp1);
+  emit_getgl(as, tmp2, gc.threshold);
+  emit_getgl(as, RID_TMP, gc.total);
   as->gcsteps = 0;
   as->gcsteps = 0;
   checkmclim(as);
   checkmclim(as);
 }
 }
@@ -1846,6 +1883,12 @@ static void asm_loop_fixup(ASMState *as)
   }
   }
 }
 }
 
 
+/* Fixup the tail of the loop. */
+static void asm_loop_tail_fixup(ASMState *as)
+{
+  UNUSED(as);  /* Nothing to do. */
+}
+
 /* -- Head of trace ------------------------------------------------------- */
 /* -- Head of trace ------------------------------------------------------- */
 
 
 /* Reload L register from g->cur_L. */
 /* Reload L register from g->cur_L. */

+ 142 - 92
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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 /* -- Register allocator extensions --------------------------------------- */
 /* -- Register allocator extensions --------------------------------------- */
@@ -64,17 +64,29 @@ static Reg ra_alloc2(ASMState *as, IRIns *ir, RegSet allow)
 /* Setup spare long-range jump slots per mcarea. */
 /* Setup spare long-range jump slots per mcarea. */
 static void asm_sparejump_setup(ASMState *as)
 static void asm_sparejump_setup(ASMState *as)
 {
 {
-  MCode *mxp = as->mcbot;
-  if (((uintptr_t)mxp & (LJ_PAGESIZE-1)) == sizeof(MCLink)) {
+  MCode *mxp = as->mctop;
+  if ((char *)mxp == (char *)as->J->mcarea + as->J->szmcarea) {
+    mxp -= MIPS_SPAREJUMP*2;
     lj_assertA(MIPSI_NOP == 0, "bad NOP");
     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;
-    lj_assertA(mxp < as->mctop, "MIPS_SPAREJUMP too big");
-    lj_mcode_sync(as->mcbot, mxp);
-    lj_mcode_commitbot(as->J, mxp);
-    as->mcbot = mxp;
-    as->mclim = as->mcbot + MCLIM_REDZONE;
+    as->mctop = mxp;
+  }
+}
+
+static MCode *asm_sparejump_use(MCode *mcarea, MCode tjump)
+{
+  MCode *mxp = (MCode *)((char *)mcarea + ((MCLink *)mcarea)->size);
+  int slot = MIPS_SPAREJUMP;
+  while (slot--) {
+    mxp -= 2;
+    if (*mxp == tjump) {
+      return mxp;
+    } else if (*mxp == MIPSI_NOP) {
+      *mxp = tjump;
+      return mxp;
+    }
   }
   }
+  return NULL;
 }
 }
 
 
 /* Setup exit stub after the end of each trace. */
 /* Setup exit stub after the end of each trace. */
@@ -181,6 +193,9 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow)
 	  return ra_allock(as, ofs-(int16_t)ofs, allow);
 	  return ra_allock(as, ofs-(int16_t)ofs, allow);
 	}
 	}
       }
       }
+    } else if (ir->o == IR_TMPREF) {
+      *ofsp = (int32_t)(offsetof(global_State, tmptv)-32768);
+      return RID_JGL;
     }
     }
   }
   }
   *ofsp = 0;
   *ofsp = 0;
@@ -336,19 +351,15 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
 static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
 static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
 {
 {
   RegSet drop = RSET_SCRATCH;
   RegSet drop = RSET_SCRATCH;
-#if LJ_32
   int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t));
   int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t));
-#endif
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
   if ((ci->flags & CCI_NOFPRCLOBBER))
   if ((ci->flags & CCI_NOFPRCLOBBER))
     drop &= ~RSET_FPR;
     drop &= ~RSET_FPR;
 #endif
 #endif
   if (ra_hasreg(ir->r))
   if (ra_hasreg(ir->r))
     rset_clear(drop, ir->r);  /* Dest reg handled below. */
     rset_clear(drop, ir->r);  /* Dest reg handled below. */
-#if LJ_32
   if (hiop && ra_hasreg((ir+1)->r))
   if (hiop && ra_hasreg((ir+1)->r))
     rset_clear(drop, (ir+1)->r);  /* Dest reg handled below. */
     rset_clear(drop, (ir+1)->r);  /* Dest reg handled below. */
-#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)) {
     lj_assertA(!irt_ispri(ir->t), "PRI dest");
     lj_assertA(!irt_ispri(ir->t), "PRI dest");
@@ -377,10 +388,8 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
       } else {
       } else {
 	ra_destreg(as, ir, RID_FPRET);
 	ra_destreg(as, ir, RID_FPRET);
       }
       }
-#if LJ_32
     } else if (hiop) {
     } else if (hiop) {
       ra_destpair(as, ir);
       ra_destpair(as, ir);
-#endif
     } else {
     } else {
       ra_destreg(as, ir, RID_RET);
       ra_destreg(as, ir, RID_RET);
     }
     }
@@ -450,6 +459,27 @@ static void asm_retf(ASMState *as, IRIns *ir)
   emit_tsi(as, MIPSI_AL, RID_TMP, base, -8);
   emit_tsi(as, MIPSI_AL, RID_TMP, base, -8);
 }
 }
 
 
+/* -- Buffer operations --------------------------------------------------- */
+
+#if LJ_HASBUFFER
+static void asm_bufhdr_write(ASMState *as, Reg sb)
+{
+  Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb));
+  IRIns irgc;
+  irgc.ot = IRT(0, IRT_PGC);  /* GC type. */
+  emit_storeofs(as, &irgc, RID_TMP, sb, offsetof(SBuf, L));
+  if ((as->flags & JIT_F_MIPSXXR2)) {
+    emit_tsml(as, LJ_64 ? MIPSI_DINS : MIPSI_INS, RID_TMP, tmp,
+	      lj_fls(SBUF_MASK_FLAG), 0);
+  } else {
+    emit_dst(as, MIPSI_OR, RID_TMP, RID_TMP, tmp);
+    emit_tsi(as, MIPSI_ANDI, tmp, tmp, SBUF_MASK_FLAG);
+  }
+  emit_getgl(as, RID_TMP, cur_L);
+  emit_loadofs(as, &irgc, tmp, sb, offsetof(SBuf, L));
+}
+#endif
+
 /* -- Type conversions ---------------------------------------------------- */
 /* -- Type conversions ---------------------------------------------------- */
 
 
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
@@ -739,7 +769,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
 	  }
 	  }
 	}
 	}
       } else {
       } else {
-	if (st64) {
+	if (st64 && !(ir->op2 & IRCONV_NONE)) {
 	  /* This is either a 32 bit reg/reg mov which zeroes the hiword
 	  /* This is either a 32 bit reg/reg mov which zeroes the hiword
 	  ** or a load of the loword from a 64 bit address.
 	  ** or a load of the loword from a 64 bit address.
 	  */
 	  */
@@ -827,34 +857,63 @@ static void asm_tvstore64(ASMState *as, Reg base, int32_t ofs, IRRef ref)
 #endif
 #endif
 
 
 /* Get pointer to TValue. */
 /* Get pointer to TValue. */
-static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
+static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode)
 {
 {
-  IRIns *ir = IR(ref);
-  if (irt_isnum(ir->t)) {
-    if (irref_isk(ref))  /* Use the number constant itself as a TValue. */
-      ra_allockreg(as, igcptr(ir_knum(ir)), dest);
-    else  /* Otherwise force a spill and use the spill slot. */
-      emit_tsi(as, MIPSI_AADDIU, dest, RID_SP, ra_spill(as, ir));
-  } else {
-    /* Otherwise use g->tmptv to hold the TValue. */
+  int32_t tmpofs = (int32_t)(offsetof(global_State, tmptv)-32768);
+  if ((mode & IRTMPREF_IN1)) {
+    IRIns *ir = IR(ref);
+    if (irt_isnum(ir->t)) {
+      if ((mode & IRTMPREF_OUT1)) {
+#if LJ_SOFTFP
+	emit_tsi(as, MIPSI_AADDIU, dest, RID_JGL, tmpofs);
+#if LJ_64
+	emit_setgl(as, ra_alloc1(as, ref, RSET_GPR), tmptv.u64);
+#else
+	lj_assertA(irref_isk(ref), "unsplit FP op");
+	emit_setgl(as,
+		   ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, RSET_GPR),
+		   tmptv.u32.lo);
+	emit_setgl(as,
+		   ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, RSET_GPR),
+		   tmptv.u32.hi);
+#endif
+#else
+	Reg src = ra_alloc1(as, ref, RSET_FPR);
+	emit_tsi(as, MIPSI_AADDIU, dest, RID_JGL, tmpofs);
+	emit_tsi(as, MIPSI_SDC1, (src & 31),  RID_JGL, tmpofs);
+#endif
+      } else if (irref_isk(ref)) {
+	/* Use the number constant itself as a TValue. */
+	ra_allockreg(as, igcptr(ir_knum(ir)), dest);
+      } else {
+#if LJ_SOFTFP32
+	lj_assertA(0, "unsplit FP op");
+#else
+	/* Otherwise force a spill and use the spill slot. */
+	emit_tsi(as, MIPSI_AADDIU, dest, RID_SP, ra_spill(as, ir));
+#endif
+      }
+    } else {
+      /* Otherwise use g->tmptv to hold the TValue. */
 #if LJ_32
 #if LJ_32
-    RegSet allow = rset_exclude(RSET_GPR, dest);
-    Reg type;
-    emit_tsi(as, MIPSI_ADDIU, dest, RID_JGL, (int32_t)(offsetof(global_State, tmptv)-32768));
-    if (!irt_ispri(ir->t)) {
-      Reg src = ra_alloc1(as, ref, allow);
-      emit_setgl(as, src, tmptv.gcr);
-    }
-    if (LJ_SOFTFP && (ir+1)->o == IR_HIOP)
-      type = ra_alloc1(as, ref+1, allow);
-    else
-      type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
-    emit_setgl(as, type, tmptv.it);
+      Reg type;
+      emit_tsi(as, MIPSI_ADDIU, dest, RID_JGL, tmpofs);
+      if (!irt_ispri(ir->t)) {
+	Reg src = ra_alloc1(as, ref, RSET_GPR);
+	emit_setgl(as, src, tmptv.gcr);
+      }
+      if (LJ_SOFTFP && (ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t))
+	type = ra_alloc1(as, ref+1, RSET_GPR);
+      else
+	type = ra_allock(as, (int32_t)irt_toitype(ir->t), RSET_GPR);
+      emit_setgl(as, type, tmptv.it);
 #else
 #else
-    asm_tvstore64(as, dest, 0, ref);
-    emit_tsi(as, MIPSI_DADDIU, dest, RID_JGL,
-	     (int32_t)(offsetof(global_State, tmptv)-32768));
+      asm_tvstore64(as, dest, 0, ref);
+      emit_tsi(as, MIPSI_DADDIU, dest, RID_JGL, tmpofs);
 #endif
 #endif
+    }
+  } else {
+    emit_tsi(as, MIPSI_AADDIU, dest, RID_JGL, tmpofs);
   }
   }
 }
 }
 
 
@@ -909,11 +968,16 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
   MCLabel l_end, l_loop, l_next;
   MCLabel l_end, l_loop, l_next;
 
 
   rset_clear(allow, tab);
   rset_clear(allow, tab);
-#if LJ_SOFTFP32
-  if (!isk) {
-    key = ra_alloc1(as, refkey, allow);
-    rset_clear(allow, key);
-    if (irkey[1].o == IR_HIOP) {
+  if (!LJ_SOFTFP && irt_isnum(kt)) {
+    key = ra_alloc1(as, refkey, RSET_FPR);
+    tmpnum = ra_scratch(as, rset_exclude(RSET_FPR, key));
+  } else {
+    if (!irt_ispri(kt)) {
+      key = ra_alloc1(as, refkey, allow);
+      rset_clear(allow, key);
+    }
+#if LJ_32
+    if (LJ_SOFTFP && irkey[1].o == IR_HIOP) {
       if (ra_hasreg((irkey+1)->r)) {
       if (ra_hasreg((irkey+1)->r)) {
 	type = tmpnum = (irkey+1)->r;
 	type = tmpnum = (irkey+1)->r;
 	tmp1 = ra_scratch(as, allow);
 	tmp1 = ra_scratch(as, allow);
@@ -924,23 +988,11 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
       }
       }
       rset_clear(allow, tmpnum);
       rset_clear(allow, tmpnum);
     } else {
     } else {
-      type = ra_allock(as, (int32_t)irt_toitype(irkey->t), allow);
+      type = ra_allock(as, (int32_t)irt_toitype(kt), allow);
       rset_clear(allow, type);
       rset_clear(allow, type);
     }
     }
-  }
-#else
-  if (!LJ_SOFTFP && irt_isnum(kt)) {
-    key = ra_alloc1(as, refkey, RSET_FPR);
-    tmpnum = ra_scratch(as, rset_exclude(RSET_FPR, key));
-  } else if (!irt_ispri(kt)) {
-    key = ra_alloc1(as, refkey, allow);
-    rset_clear(allow, key);
-#if LJ_32
-    type = ra_allock(as, (int32_t)irt_toitype(irkey->t), allow);
-    rset_clear(allow, type);
 #endif
 #endif
   }
   }
-#endif
   tmp2 = ra_scratch(as, allow);
   tmp2 = ra_scratch(as, allow);
   rset_clear(allow, tmp2);
   rset_clear(allow, tmp2);
 #if LJ_64
 #if LJ_64
@@ -953,10 +1005,10 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
     } else {
     } else {
       int64_t k;
       int64_t k;
       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(kt) << 47) | irkey[1].tv.u64;
       } else {
       } else {
 	lj_assertA(irt_ispri(kt) && !irt_isnil(kt), "bad HREF key type");
 	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(kt) << 47);
       }
       }
       cmp64 = ra_allock(as, k, allow);
       cmp64 = ra_allock(as, k, allow);
       rset_clear(allow, cmp64);
       rset_clear(allow, cmp64);
@@ -1352,6 +1404,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
 #endif
 #endif
   }
   }
   idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
   idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
+  if (ir->o == IR_VLOAD) ofs += 8 * ir->op2;
   rset_clear(allow, idx);
   rset_clear(allow, idx);
   if (irt_isnum(t)) {
   if (irt_isnum(t)) {
     asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO);
     asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO);
@@ -2327,15 +2380,15 @@ static void asm_comp64eq(ASMState *as, IRIns *ir)
 }
 }
 #endif
 #endif
 
 
-/* -- Support for 64 bit ops in 32 bit mode ------------------------------- */
+/* -- Split register ops -------------------------------------------------- */
 
 
-/* Hiword op of a split 64 bit op. Previous op must be the loword op. */
+/* Hiword op of a split 32/32 or 64/64 bit op. Previous op is the loword op. */
 static void asm_hiop(ASMState *as, IRIns *ir)
 static void asm_hiop(ASMState *as, IRIns *ir)
 {
 {
-#if LJ_32 && (LJ_HASFFI || LJ_SOFTFP)
   /* HIOP is marked as a store because it needs its own DCE logic. */
   /* HIOP is marked as a store because it needs its own DCE logic. */
   int uselo = ra_used(ir-1), usehi = ra_used(ir);  /* Loword/hiword used? */
   int uselo = ra_used(ir-1), usehi = ra_used(ir);  /* Loword/hiword used? */
   if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
   if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
+#if LJ_32 && (LJ_HASFFI || LJ_SOFTFP)
   if ((ir-1)->o == IR_CONV) {  /* Conversions to/from 64 bit. */
   if ((ir-1)->o == IR_CONV) {  /* Conversions to/from 64 bit. */
     as->curins--;  /* Always skip the CONV. */
     as->curins--;  /* Always skip the CONV. */
 #if LJ_HASFFI && !LJ_SOFTFP
 #if LJ_HASFFI && !LJ_SOFTFP
@@ -2382,38 +2435,33 @@ static void asm_hiop(ASMState *as, IRIns *ir)
     }
     }
     return;
     return;
   }
   }
+#endif
   if (!usehi) return;  /* Skip unused hiword op for all remaining ops. */
   if (!usehi) return;  /* Skip unused hiword op for all remaining ops. */
   switch ((ir-1)->o) {
   switch ((ir-1)->o) {
-#if LJ_HASFFI
+#if LJ_32 && LJ_HASFFI
   case IR_ADD: as->curins--; asm_add64(as, ir); break;
   case IR_ADD: as->curins--; asm_add64(as, ir); break;
   case IR_SUB: as->curins--; asm_sub64(as, ir); break;
   case IR_SUB: as->curins--; asm_sub64(as, ir); break;
   case IR_NEG: as->curins--; asm_neg64(as, ir); break;
   case IR_NEG: as->curins--; asm_neg64(as, ir); break;
+  case IR_CNEWI:
+    /* Nothing to do here. Handled by lo op itself. */
+    break;
 #endif
 #endif
-#if LJ_SOFTFP
+#if LJ_32 && LJ_SOFTFP
   case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
   case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
   case IR_STRTO:
   case IR_STRTO:
     if (!uselo)
     if (!uselo)
       ra_allocref(as, ir->op1, RSET_GPR);  /* Mark lo op as used. */
       ra_allocref(as, ir->op1, RSET_GPR);  /* Mark lo op as used. */
     break;
     break;
+  case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: case IR_TMPREF:
+    /* Nothing to do here. Handled by lo op itself. */
+    break;
 #endif
 #endif
-  case IR_CALLN:
-  case IR_CALLS:
-  case IR_CALLXS:
+  case IR_CALLN: case IR_CALLL: case IR_CALLS: case IR_CALLXS:
     if (!uselo)
     if (!uselo)
       ra_allocref(as, ir->op1, RID2RSET(RID_RETLO));  /* Mark lo op as used. */
       ra_allocref(as, ir->op1, RID2RSET(RID_RETLO));  /* Mark lo op as used. */
     break;
     break;
-#if LJ_SOFTFP
-  case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR:
-#endif
-  case IR_CNEWI:
-    /* Nothing to do here. Handled by lo op itself. */
-    break;
   default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
   default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
   }
   }
-#else
-  /* Unused on MIPS64 or without SOFTFP or FFI. */
-  UNUSED(as); UNUSED(ir); lj_assertA(0, "unexpected HIOP");
-#endif
 }
 }
 
 
 /* -- Profiling ----------------------------------------------------------- */
 /* -- Profiling ----------------------------------------------------------- */
@@ -2513,6 +2561,8 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
       } else if ((sn & SNAP_SOFTFPNUM)) {
       } else if ((sn & SNAP_SOFTFPNUM)) {
 	type = ra_alloc1(as, ref+1, rset_exclude(RSET_GPR, RID_BASE));
 	type = ra_alloc1(as, ref+1, rset_exclude(RSET_GPR, RID_BASE));
 #endif
 #endif
+      } else if ((sn & SNAP_KEYINDEX)) {
+	type = ra_allock(as, (int32_t)LJ_KEYINDEX, allow);
       } else {
       } else {
 	type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
 	type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
       }
       }
@@ -2575,6 +2625,12 @@ static void asm_loop_fixup(ASMState *as)
   }
   }
 }
 }
 
 
+/* Fixup the tail of the loop. */
+static void asm_loop_tail_fixup(ASMState *as)
+{
+  if (as->loopinv) as->mctop--;
+}
+
 /* -- Head of trace ------------------------------------------------------- */
 /* -- Head of trace ------------------------------------------------------- */
 
 
 /* Coalesce BASE register for a root trace. */
 /* Coalesce BASE register for a root trace. */
@@ -2582,7 +2638,6 @@ static void asm_head_root_base(ASMState *as)
 {
 {
   IRIns *ir = IR(REF_BASE);
   IRIns *ir = IR(REF_BASE);
   Reg r = ir->r;
   Reg r = ir->r;
-  if (as->loopinv) as->mctop--;
   if (ra_hasreg(r)) {
   if (ra_hasreg(r)) {
     ra_free(as, r);
     ra_free(as, r);
     if (rset_test(as->modset, r) || irt_ismarked(ir->t))
     if (rset_test(as->modset, r) || irt_ismarked(ir->t))
@@ -2597,7 +2652,6 @@ static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
 {
 {
   IRIns *ir = IR(REF_BASE);
   IRIns *ir = IR(REF_BASE);
   Reg r = ir->r;
   Reg r = ir->r;
-  if (as->loopinv) as->mctop--;
   if (ra_hasreg(r)) {
   if (ra_hasreg(r)) {
     ra_free(as, r);
     ra_free(as, r);
     if (rset_test(as->modset, r) || irt_ismarked(ir->t))
     if (rset_test(as->modset, r) || irt_ismarked(ir->t))
@@ -2704,21 +2758,17 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
 	patchbranch:
 	patchbranch:
 	  p[-1] = (p[-1] & 0xffff0000u) | (delta & 0xffffu);
 	  p[-1] = (p[-1] & 0xffff0000u) | (delta & 0xffffu);
 	  *p = MIPSI_NOP;  /* Replace the load of the exit number. */
 	  *p = MIPSI_NOP;  /* Replace the load of the exit number. */
-	  cstop = p;
+	  cstop = p+1;
 	  if (!cstart) cstart = p-1;
 	  if (!cstart) cstart = p-1;
 	} else {  /* Branch out of range. Use spare jump slot in mcarea. */
 	} else {  /* Branch out of range. Use spare jump slot in mcarea. */
-	  int i;
-	  for (i = (int)(sizeof(MCLink)/sizeof(MCode));
-	       i < (int)(sizeof(MCLink)/sizeof(MCode)+MIPS_SPAREJUMP*2);
-	       i += 2) {
-	    if (mcarea[i] == tjump) {
-	      delta = mcarea+i - p;
-	      goto patchbranch;
-	    } else if (mcarea[i] == MIPSI_NOP) {
-	      mcarea[i] = tjump;
-	      cstart = mcarea+i;
-	      delta = mcarea+i - p;
+	  MCode *mcjump = asm_sparejump_use(mcarea, tjump);
+	  if (mcjump) {
+	    lj_mcode_sync(mcjump, mcjump+1);
+	    delta = mcjump - p;
+	    if (((delta + 0x8000) >> 16) == 0) {
 	      goto patchbranch;
 	      goto patchbranch;
+	    } else {
+	      lj_assertJ(0, "spare jump out of range: -Osizemcode too big");
 	    }
 	    }
 	  }
 	  }
 	  /* Ignore jump slot overflow. Child trace is simply not attached. */
 	  /* Ignore jump slot overflow. Child trace is simply not attached. */

+ 91 - 41
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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 /* -- Register allocator extensions --------------------------------------- */
 /* -- Register allocator extensions --------------------------------------- */
@@ -156,6 +156,9 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow)
 	  return ra_allock(as, ofs-(int16_t)ofs, allow);
 	  return ra_allock(as, ofs-(int16_t)ofs, allow);
 	}
 	}
       }
       }
+    } else if (ir->o == IR_TMPREF) {
+      *ofsp = (int32_t)(offsetof(global_State, tmptv)-32768);
+      return RID_JGL;
     }
     }
   }
   }
   *ofsp = 0;
   *ofsp = 0;
@@ -337,10 +340,8 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
       } else {
       } else {
 	ra_destreg(as, ir, RID_FPRET);
 	ra_destreg(as, ir, RID_FPRET);
       }
       }
-#if LJ_32
     } else if (hiop) {
     } else if (hiop) {
       ra_destpair(as, ir);
       ra_destpair(as, ir);
-#endif
     } else {
     } else {
       ra_destreg(as, ir, RID_RET);
       ra_destreg(as, ir, RID_RET);
     }
     }
@@ -389,6 +390,21 @@ static void asm_retf(ASMState *as, IRIns *ir)
   emit_tai(as, PPCI_LWZ, RID_TMP, base, -8);
   emit_tai(as, PPCI_LWZ, RID_TMP, base, -8);
 }
 }
 
 
+/* -- Buffer operations --------------------------------------------------- */
+
+#if LJ_HASBUFFER
+static void asm_bufhdr_write(ASMState *as, Reg sb)
+{
+  Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb));
+  IRIns irgc;
+  irgc.ot = IRT(0, IRT_PGC);  /* GC type. */
+  emit_storeofs(as, &irgc, RID_TMP, sb, offsetof(SBuf, L));
+  emit_rot(as, PPCI_RLWIMI, RID_TMP, tmp, 0, 31-lj_fls(SBUF_MASK_FLAG), 31);
+  emit_getgl(as, RID_TMP, cur_L);
+  emit_loadofs(as, &irgc, tmp, sb, offsetof(SBuf, L));
+}
+#endif
+
 /* -- Type conversions ---------------------------------------------------- */
 /* -- Type conversions ---------------------------------------------------- */
 
 
 #if !LJ_SOFTFP
 #if !LJ_SOFTFP
@@ -567,28 +583,54 @@ static void asm_strto(ASMState *as, IRIns *ir)
 /* -- Memory references --------------------------------------------------- */
 /* -- Memory references --------------------------------------------------- */
 
 
 /* Get pointer to TValue. */
 /* Get pointer to TValue. */
-static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
+static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode)
 {
 {
-  IRIns *ir = IR(ref);
-  if (irt_isnum(ir->t)) {
-    if (irref_isk(ref))  /* Use the number constant itself as a TValue. */
-      ra_allockreg(as, i32ptr(ir_knum(ir)), dest);
-    else  /* Otherwise force a spill and use the spill slot. */
-      emit_tai(as, PPCI_ADDI, dest, RID_SP, ra_spill(as, ir));
-  } else {
-    /* Otherwise use g->tmptv to hold the TValue. */
-    RegSet allow = rset_exclude(RSET_GPR, dest);
-    Reg type;
-    emit_tai(as, PPCI_ADDI, dest, RID_JGL, (int32_t)offsetof(global_State, tmptv)-32768);
-    if (!irt_ispri(ir->t)) {
-      Reg src = ra_alloc1(as, ref, allow);
-      emit_setgl(as, src, tmptv.gcr);
+  int32_t tmpofs = (int32_t)(offsetof(global_State, tmptv)-32768);
+  if ((mode & IRTMPREF_IN1)) {
+    IRIns *ir = IR(ref);
+    if (irt_isnum(ir->t)) {
+      if ((mode & IRTMPREF_OUT1)) {
+#if LJ_SOFTFP
+	lj_assertA(irref_isk(ref), "unsplit FP op");
+	emit_tai(as, PPCI_ADDI, dest, RID_JGL, tmpofs);
+	emit_setgl(as,
+		   ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, RSET_GPR),
+		   tmptv.u32.lo);
+	emit_setgl(as,
+		   ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, RSET_GPR),
+		   tmptv.u32.hi);
+#else
+	Reg src = ra_alloc1(as, ref, RSET_FPR);
+	emit_tai(as, PPCI_ADDI, dest, RID_JGL, tmpofs);
+	emit_fai(as, PPCI_STFD, src, RID_JGL, tmpofs);
+#endif
+      } else if (irref_isk(ref)) {
+	/* Use the number constant itself as a TValue. */
+	ra_allockreg(as, i32ptr(ir_knum(ir)), dest);
+      } else {
+#if LJ_SOFTFP
+	lj_assertA(0, "unsplit FP op");
+#else
+	/* Otherwise force a spill and use the spill slot. */
+	emit_tai(as, PPCI_ADDI, dest, RID_SP, ra_spill(as, ir));
+#endif
+      }
+    } else {
+      /* Otherwise use g->tmptv to hold the TValue. */
+      Reg type;
+      emit_tai(as, PPCI_ADDI, dest, RID_JGL, tmpofs);
+      if (!irt_ispri(ir->t)) {
+	Reg src = ra_alloc1(as, ref, RSET_GPR);
+	emit_setgl(as, src, tmptv.gcr);
+      }
+      if (LJ_SOFTFP && (ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t))
+	type = ra_alloc1(as, ref+1, RSET_GPR);
+      else
+	type = ra_allock(as, irt_toitype(ir->t), RSET_GPR);
+      emit_setgl(as, type, tmptv.it);
     }
     }
-    if (LJ_SOFTFP && (ir+1)->o == IR_HIOP)
-      type = ra_alloc1(as, ref+1, allow);
-    else
-      type = ra_allock(as, irt_toitype(ir->t), allow);
-    emit_setgl(as, type, tmptv.it);
+  } else {
+    emit_tai(as, PPCI_ADDI, dest, RID_JGL, tmpofs);
   }
   }
 }
 }
 
 
@@ -894,7 +936,7 @@ static void asm_fload(ASMState *as, IRIns *ir)
   int32_t ofs;
   int32_t ofs;
   if (ir->op1 == REF_NIL) {  /* FLOAD from GG_State with offset. */
   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 - GG_OFS(g);
   } else {
   } else {
     idx = ra_alloc1(as, ir->op1, RSET_GPR);
     idx = ra_alloc1(as, ir->op1, RSET_GPR);
     if (ir->op2 == IRFL_TAB_ARRAY) {
     if (ir->op2 == IRFL_TAB_ARRAY) {
@@ -975,6 +1017,10 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
     rset_clear(allow, dest);
     rset_clear(allow, dest);
   }
   }
   idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
   idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
+  if (ir->o == IR_VLOAD) {
+    ofs = ofs != AHUREF_LSX ? ofs + 8 * ir->op2 :
+	  ir->op2 ? 8 * ir->op2 : AHUREF_LSX;
+  }
   if (irt_isnum(t)) {
   if (irt_isnum(t)) {
     Reg tisnum = ra_allock(as, (int32_t)LJ_TISNUM, rset_exclude(allow, idx));
     Reg tisnum = ra_allock(as, (int32_t)LJ_TISNUM, rset_exclude(allow, idx));
     asm_guardcc(as, CC_GE);
     asm_guardcc(as, CC_GE);
@@ -1057,7 +1103,8 @@ static void asm_sload(ASMState *as, IRIns *ir)
   lj_assertA(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK),
   lj_assertA(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK),
 	     "inconsistent SLOAD variant");
 	     "inconsistent SLOAD variant");
   lj_assertA(LJ_DUALNUM ||
   lj_assertA(LJ_DUALNUM ||
-	     !irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)),
+	     !irt_isint(t) ||
+	     (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME|IRSLOAD_KEYINDEX)),
 	     "bad SLOAD type");
 	     "bad SLOAD type");
 #if LJ_SOFTFP
 #if LJ_SOFTFP
   lj_assertA(!(ir->op2 & IRSLOAD_CONVERT),
   lj_assertA(!(ir->op2 & IRSLOAD_CONVERT),
@@ -1894,15 +1941,15 @@ static void asm_comp64(ASMState *as, IRIns *ir)
 }
 }
 #endif
 #endif
 
 
-/* -- Support for 64 bit ops in 32 bit mode ------------------------------- */
+/* -- Split register ops -------------------------------------------------- */
 
 
-/* Hiword op of a split 64 bit op. Previous op must be the loword op. */
+/* Hiword op of a split 32/32 bit op. Previous op is be the loword op. */
 static void asm_hiop(ASMState *as, IRIns *ir)
 static void asm_hiop(ASMState *as, IRIns *ir)
 {
 {
-#if LJ_HASFFI || LJ_SOFTFP
   /* HIOP is marked as a store because it needs its own DCE logic. */
   /* HIOP is marked as a store because it needs its own DCE logic. */
   int uselo = ra_used(ir-1), usehi = ra_used(ir);  /* Loword/hiword used? */
   int uselo = ra_used(ir-1), usehi = ra_used(ir);  /* Loword/hiword used? */
   if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
   if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
+#if LJ_HASFFI || LJ_SOFTFP
   if ((ir-1)->o == IR_CONV) {  /* Conversions to/from 64 bit. */
   if ((ir-1)->o == IR_CONV) {  /* Conversions to/from 64 bit. */
     as->curins--;  /* Always skip the CONV. */
     as->curins--;  /* Always skip the CONV. */
 #if LJ_HASFFI && !LJ_SOFTFP
 #if LJ_HASFFI && !LJ_SOFTFP
@@ -1937,12 +1984,16 @@ static void asm_hiop(ASMState *as, IRIns *ir)
     }
     }
     return;
     return;
   }
   }
+#endif
   if (!usehi) return;  /* Skip unused hiword op for all remaining ops. */
   if (!usehi) return;  /* Skip unused hiword op for all remaining ops. */
   switch ((ir-1)->o) {
   switch ((ir-1)->o) {
 #if LJ_HASFFI
 #if LJ_HASFFI
   case IR_ADD: as->curins--; asm_add64(as, ir); break;
   case IR_ADD: as->curins--; asm_add64(as, ir); break;
   case IR_SUB: as->curins--; asm_sub64(as, ir); break;
   case IR_SUB: as->curins--; asm_sub64(as, ir); break;
   case IR_NEG: as->curins--; asm_neg64(as, ir); break;
   case IR_NEG: as->curins--; asm_neg64(as, ir); break;
+  case IR_CNEWI:
+    /* Nothing to do here. Handled by lo op itself. */
+    break;
 #endif
 #endif
 #if LJ_SOFTFP
 #if LJ_SOFTFP
   case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
   case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
@@ -1950,25 +2001,16 @@ static void asm_hiop(ASMState *as, IRIns *ir)
     if (!uselo)
     if (!uselo)
       ra_allocref(as, ir->op1, RSET_GPR);  /* Mark lo op as used. */
       ra_allocref(as, ir->op1, RSET_GPR);  /* Mark lo op as used. */
     break;
     break;
+  case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: case IR_TMPREF:
+    /* Nothing to do here. Handled by lo op itself. */
+    break;
 #endif
 #endif
-  case IR_CALLN:
-  case IR_CALLS:
-  case IR_CALLXS:
+  case IR_CALLN: case IR_CALLL: case IR_CALLS: case IR_CALLXS:
     if (!uselo)
     if (!uselo)
       ra_allocref(as, ir->op1, RID2RSET(RID_RETLO));  /* Mark lo op as used. */
       ra_allocref(as, ir->op1, RID2RSET(RID_RETLO));  /* Mark lo op as used. */
     break;
     break;
-#if LJ_SOFTFP
-  case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR:
-#endif
-  case IR_CNEWI:
-    /* Nothing to do here. Handled by lo op itself. */
-    break;
   default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
   default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
   }
   }
-#else
-  /* Unused without SOFTFP or FFI. */
-  UNUSED(as); UNUSED(ir); lj_assertA(0, "unexpected HIOP");
-#endif
 }
 }
 
 
 /* -- Profiling ----------------------------------------------------------- */
 /* -- Profiling ----------------------------------------------------------- */
@@ -2055,6 +2097,8 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
       } else if ((sn & SNAP_SOFTFPNUM)) {
       } else if ((sn & SNAP_SOFTFPNUM)) {
 	type = ra_alloc1(as, ref+1, rset_exclude(RSET_GPR, RID_BASE));
 	type = ra_alloc1(as, ref+1, rset_exclude(RSET_GPR, RID_BASE));
 #endif
 #endif
+      } else if ((sn & SNAP_KEYINDEX)) {
+	type = ra_allock(as, (int32_t)LJ_KEYINDEX, allow);
       } else {
       } else {
 	type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
 	type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
       }
       }
@@ -2113,6 +2157,12 @@ static void asm_loop_fixup(ASMState *as)
   }
   }
 }
 }
 
 
+/* Fixup the tail of the loop. */
+static void asm_loop_tail_fixup(ASMState *as)
+{
+  UNUSED(as);  /* Nothing to do. */
+}
+
 /* -- Head of trace ------------------------------------------------------- */
 /* -- Head of trace ------------------------------------------------------- */
 
 
 /* Coalesce BASE register for a root trace. */
 /* Coalesce BASE register for a root trace. */

+ 94 - 56
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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 /* -- Guard handling ------------------------------------------------------ */
 /* -- Guard handling ------------------------------------------------------ */
@@ -216,10 +216,17 @@ static void asm_fuseahuref(ASMState *as, IRRef ref, RegSet allow)
 #endif
 #endif
       }
       }
       break;
       break;
+    case IR_TMPREF:
+#if LJ_GC64
+      as->mrm.ofs = (int32_t)dispofs(as, &J2G(as->J)->tmptv);
+      as->mrm.base = RID_DISPATCH;
+      as->mrm.idx = RID_NONE;
+#else
+      as->mrm.ofs = igcptr(&J2G(as->J)->tmptv);
+      as->mrm.base = as->mrm.idx = RID_NONE;
+#endif
+      return;
     default:
     default:
-      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;
     }
     }
   }
   }
@@ -480,6 +487,7 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
       }
       }
     } else if (ir->o == IR_VLOAD && !(LJ_GC64 && irt_isaddr(ir->t))) {
     } else if (ir->o == IR_VLOAD && !(LJ_GC64 && irt_isaddr(ir->t))) {
       asm_fuseahuref(as, ir->op1, xallow);
       asm_fuseahuref(as, ir->op1, xallow);
+      as->mrm.ofs += 8 * ir->op2;
       return RID_MRM;
       return RID_MRM;
     }
     }
   }
   }
@@ -651,7 +659,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
 static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
 static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
 {
 {
   RegSet drop = RSET_SCRATCH;
   RegSet drop = RSET_SCRATCH;
-  int hiop = (LJ_32 && (ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t));
+  int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t));
   if ((ci->flags & CCI_NOFPRCLOBBER))
   if ((ci->flags & CCI_NOFPRCLOBBER))
     drop &= ~RSET_FPR;
     drop &= ~RSET_FPR;
   if (ra_hasreg(ir->r))
   if (ra_hasreg(ir->r))
@@ -691,10 +699,8 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
 		  irt_isnum(ir->t) ? XOg_FSTPq : XOg_FSTPd, RID_ESP, ofs);
 		  irt_isnum(ir->t) ? XOg_FSTPq : XOg_FSTPd, RID_ESP, ofs);
       }
       }
 #endif
 #endif
-#if LJ_32
     } else if (hiop) {
     } else if (hiop) {
       ra_destpair(as, ir);
       ra_destpair(as, ir);
-#endif
     } else {
     } else {
       lj_assertA(!irt_ispri(ir->t), "PRI dest");
       lj_assertA(!irt_ispri(ir->t), "PRI dest");
       ra_destreg(as, ir, RID_RET);
       ra_destreg(as, ir, RID_RET);
@@ -781,6 +787,21 @@ static void asm_retf(ASMState *as, IRIns *ir)
 #endif
 #endif
 }
 }
 
 
+/* -- Buffer operations --------------------------------------------------- */
+
+#if LJ_HASBUFFER
+static void asm_bufhdr_write(ASMState *as, Reg sb)
+{
+  Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb));
+  IRIns irgc;
+  irgc.ot = IRT(0, IRT_PGC);  /* GC type. */
+  emit_storeofs(as, &irgc, tmp, sb, offsetof(SBuf, L));
+  emit_opgl(as, XO_ARITH(XOg_OR), tmp|REX_GC64, cur_L);
+  emit_gri(as, XG_ARITHi(XOg_AND), tmp, SBUF_MASK_FLAG);
+  emit_loadofs(as, &irgc, tmp, sb, offsetof(SBuf, L));
+}
+#endif
+
 /* -- Type conversions ---------------------------------------------------- */
 /* -- Type conversions ---------------------------------------------------- */
 
 
 static void asm_tointg(ASMState *as, IRIns *ir, Reg left)
 static void asm_tointg(ASMState *as, IRIns *ir, Reg left)
@@ -924,7 +945,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
       }
       }
     } else {
     } else {
       Reg dest = ra_dest(as, ir, RSET_GPR);
       Reg dest = ra_dest(as, ir, RSET_GPR);
-      if (st64) {
+      if (st64 && !(ir->op2 & IRCONV_NONE)) {
 	Reg left = asm_fuseload(as, lref, RSET_GPR);
 	Reg left = asm_fuseload(as, lref, RSET_GPR);
 	/* This is either a 32 bit reg/reg mov which zeroes the hiword
 	/* This is either a 32 bit reg/reg mov which zeroes the hiword
 	** or a load of the loword from a 64 bit address.
 	** or a load of the loword from a 64 bit address.
@@ -1050,47 +1071,48 @@ static void asm_strto(ASMState *as, IRIns *ir)
 /* -- Memory references --------------------------------------------------- */
 /* -- Memory references --------------------------------------------------- */
 
 
 /* Get pointer to TValue. */
 /* Get pointer to TValue. */
-static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
+static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode)
 {
 {
-  IRIns *ir = IR(ref);
-  if (irt_isnum(ir->t)) {
-    /* For numbers use the constant itself or a spill slot as a TValue. */
-    if (irref_isk(ref))
-      emit_loada(as, dest, ir_knum(ir));
-    else
-      emit_rmro(as, XO_LEA, dest|REX_64, RID_ESP, ra_spill(as, ir));
-  } else {
-    /* Otherwise use g->tmptv to hold the TValue. */
-#if LJ_GC64
-    if (irref_isk(ref)) {
-      TValue k;
-      lj_ir_kvalue(as->J->L, &k, ir);
-      emit_movmroi(as, dest, 4, k.u32.hi);
-      emit_movmroi(as, dest, 0, k.u32.lo);
+  if ((mode & IRTMPREF_IN1)) {
+    IRIns *ir = IR(ref);
+    if (irt_isnum(ir->t)) {
+      if (irref_isk(ref) && !(mode & IRTMPREF_OUT1)) {
+	/* Use the number constant itself as a TValue. */
+	emit_loada(as, dest, ir_knum(ir));
+	return;
+      }
+      emit_rmro(as, XO_MOVSDto, ra_alloc1(as, ref, RSET_FPR), dest, 0);
     } else {
     } else {
-      /* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */
-      Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest));
-      if (irt_is64(ir->t)) {
-	emit_u32(as, irt_toitype(ir->t) << 15);
-	emit_rmro(as, XO_ARITHi, XOg_OR, dest, 4);
+#if LJ_GC64
+      if (irref_isk(ref)) {
+	TValue k;
+	lj_ir_kvalue(as->J->L, &k, ir);
+	emit_movmroi(as, dest, 4, k.u32.hi);
+	emit_movmroi(as, dest, 0, k.u32.lo);
       } else {
       } else {
-	/* Currently, no caller passes integers that might end up here. */
-	emit_movmroi(as, dest, 4, (irt_toitype(ir->t) << 15));
+	/* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */
+	Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest));
+	if (irt_is64(ir->t)) {
+	  emit_u32(as, irt_toitype(ir->t) << 15);
+	  emit_rmro(as, XO_ARITHi, XOg_OR, dest, 4);
+	} else {
+	  emit_movmroi(as, dest, 4, (irt_toitype(ir->t) << 15));
+	}
+	emit_movtomro(as, REX_64IR(ir, src), dest, 0);
       }
       }
-      emit_movtomro(as, REX_64IR(ir, src), dest, 0);
-    }
 #else
 #else
-    if (!irref_isk(ref)) {
-      Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest));
-      emit_movtomro(as, REX_64IR(ir, src), dest, 0);
-    } else if (!irt_ispri(ir->t)) {
-      emit_movmroi(as, dest, 0, ir->i);
-    }
-    if (!(LJ_64 && irt_islightud(ir->t)))
-      emit_movmroi(as, dest, 4, irt_toitype(ir->t));
+      if (!irref_isk(ref)) {
+	Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest));
+	emit_movtomro(as, REX_64IR(ir, src), dest, 0);
+      } else if (!irt_ispri(ir->t)) {
+	emit_movmroi(as, dest, 0, ir->i);
+      }
+      if (!(LJ_64 && irt_islightud(ir->t)))
+	emit_movmroi(as, dest, 4, irt_toitype(ir->t));
 #endif
 #endif
-    emit_loada(as, dest, &J2G(as->J)->tmptv);
+    }
   }
   }
+  emit_loada(as, dest, &J2G(as->J)->tmptv); /* g->tmptv holds the TValue(s). */
 }
 }
 
 
 static void asm_aref(ASMState *as, IRIns *ir)
 static void asm_aref(ASMState *as, IRIns *ir)
@@ -1524,6 +1546,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
     Reg dest = asm_load_lightud64(as, ir, 1);
     Reg dest = asm_load_lightud64(as, ir, 1);
     if (ra_hasreg(dest)) {
     if (ra_hasreg(dest)) {
       asm_fuseahuref(as, ir->op1, RSET_GPR);
       asm_fuseahuref(as, ir->op1, RSET_GPR);
+      if (ir->o == IR_VLOAD) as->mrm.ofs += 8 * ir->op2;
       emit_mrm(as, XO_MOV, dest|REX_64, RID_MRM);
       emit_mrm(as, XO_MOV, dest|REX_64, RID_MRM);
     }
     }
     return;
     return;
@@ -1533,6 +1556,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
     RegSet allow = irt_isnum(ir->t) ? RSET_FPR : RSET_GPR;
     RegSet allow = irt_isnum(ir->t) ? RSET_FPR : RSET_GPR;
     Reg dest = ra_dest(as, ir, allow);
     Reg dest = ra_dest(as, ir, allow);
     asm_fuseahuref(as, ir->op1, RSET_GPR);
     asm_fuseahuref(as, ir->op1, RSET_GPR);
+    if (ir->o == IR_VLOAD) as->mrm.ofs += 8 * ir->op2;
 #if LJ_GC64
 #if LJ_GC64
     if (irt_isaddr(ir->t)) {
     if (irt_isaddr(ir->t)) {
       emit_shifti(as, XOg_SHR|REX_64, dest, 17);
       emit_shifti(as, XOg_SHR|REX_64, dest, 17);
@@ -1560,6 +1584,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
     }
     }
 #endif
 #endif
     asm_fuseahuref(as, ir->op1, gpr);
     asm_fuseahuref(as, ir->op1, gpr);
+    if (ir->o == IR_VLOAD) as->mrm.ofs += 8 * ir->op2;
   }
   }
   /* Always do the type check, even if the load result is unused. */
   /* Always do the type check, even if the load result is unused. */
   as->mrm.ofs += 4;
   as->mrm.ofs += 4;
@@ -1675,7 +1700,8 @@ static void asm_sload(ASMState *as, IRIns *ir)
   lj_assertA(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK),
   lj_assertA(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK),
 	     "inconsistent SLOAD variant");
 	     "inconsistent SLOAD variant");
   lj_assertA(LJ_DUALNUM ||
   lj_assertA(LJ_DUALNUM ||
-	     !irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)),
+	     !irt_isint(t) ||
+	     (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME|IRSLOAD_KEYINDEX)),
 	     "bad SLOAD type");
 	     "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);
@@ -2584,15 +2610,15 @@ static void asm_comp_int64(ASMState *as, IRIns *ir)
 }
 }
 #endif
 #endif
 
 
-/* -- Support for 64 bit ops in 32 bit mode ------------------------------- */
+/* -- Split register ops -------------------------------------------------- */
 
 
-/* Hiword op of a split 64 bit op. Previous op must be the loword op. */
+/* Hiword op of a split 32/32 or 64/64 bit op. Previous op is the loword op. */
 static void asm_hiop(ASMState *as, IRIns *ir)
 static void asm_hiop(ASMState *as, IRIns *ir)
 {
 {
-#if LJ_32 && LJ_HASFFI
   /* HIOP is marked as a store because it needs its own DCE logic. */
   /* HIOP is marked as a store because it needs its own DCE logic. */
   int uselo = ra_used(ir-1), usehi = ra_used(ir);  /* Loword/hiword used? */
   int uselo = ra_used(ir-1), usehi = ra_used(ir);  /* Loword/hiword used? */
   if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
   if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
+#if LJ_32 && LJ_HASFFI
   if ((ir-1)->o == IR_CONV) {  /* Conversions to/from 64 bit. */
   if ((ir-1)->o == IR_CONV) {  /* Conversions to/from 64 bit. */
     as->curins--;  /* Always skip the CONV. */
     as->curins--;  /* Always skip the CONV. */
     if (usehi || uselo)
     if (usehi || uselo)
@@ -2606,8 +2632,10 @@ static void asm_hiop(ASMState *as, IRIns *ir)
       asm_fxstore(as, ir);
       asm_fxstore(as, ir);
     return;
     return;
   }
   }
+#endif
   if (!usehi) return;  /* Skip unused hiword op for all remaining ops. */
   if (!usehi) return;  /* Skip unused hiword op for all remaining ops. */
   switch ((ir-1)->o) {
   switch ((ir-1)->o) {
+#if LJ_32 && LJ_HASFFI
   case IR_ADD:
   case IR_ADD:
     as->flagmcp = NULL;
     as->flagmcp = NULL;
     as->curins--;
     as->curins--;
@@ -2630,20 +2658,16 @@ static void asm_hiop(ASMState *as, IRIns *ir)
     asm_neg_not(as, ir-1, XOg_NEG);
     asm_neg_not(as, ir-1, XOg_NEG);
     break;
     break;
     }
     }
-  case IR_CALLN:
-  case IR_CALLXS:
-    if (!uselo)
-      ra_allocref(as, ir->op1, RID2RSET(RID_RETLO));  /* Mark lo op as used. */
-    break;
   case IR_CNEWI:
   case IR_CNEWI:
     /* Nothing to do here. Handled by CNEWI itself. */
     /* Nothing to do here. Handled by CNEWI itself. */
     break;
     break;
+#endif
+  case IR_CALLN: case IR_CALLL: case IR_CALLS: case IR_CALLXS:
+    if (!uselo)
+      ra_allocref(as, ir->op1, RID2RSET(RID_RETLO));  /* Mark lo op as used. */
+    break;
   default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
   default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break;
   }
   }
-#else
-  /* Unused on x64 or without FFI. */
-  UNUSED(as); UNUSED(ir); lj_assertA(0, "unexpected HIOP");
-#endif
 }
 }
 
 
 /* -- Profiling ----------------------------------------------------------- */
 /* -- Profiling ----------------------------------------------------------- */
@@ -2704,7 +2728,15 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
     IRIns *ir = IR(ref);
     IRIns *ir = IR(ref);
     if ((sn & SNAP_NORESTORE))
     if ((sn & SNAP_NORESTORE))
       continue;
       continue;
-    if (irt_isnum(ir->t)) {
+    if ((sn & SNAP_KEYINDEX)) {
+      emit_movmroi(as, RID_BASE, ofs+4, LJ_KEYINDEX);
+      if (irref_isk(ref)) {
+	emit_movmroi(as, RID_BASE, ofs, ir->i);
+      } else {
+	Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE));
+	emit_movtomro(as, src, RID_BASE, ofs);
+      }
+    } else if (irt_isnum(ir->t)) {
       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 {
@@ -2837,6 +2869,12 @@ static void asm_loop_fixup(ASMState *as)
   }
   }
 }
 }
 
 
+/* Fixup the tail of the loop. */
+static void asm_loop_tail_fixup(ASMState *as)
+{
+  UNUSED(as);  /* Nothing to do. */
+}
+
 /* -- Head of trace ------------------------------------------------------- */
 /* -- Head of trace ------------------------------------------------------- */
 
 
 /* Coalesce BASE register for a root trace. */
 /* Coalesce BASE register for a root trace. */

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** Internal assertions.
 ** Internal assertions.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lj_assert_c
 #define lj_assert_c

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** Bytecode instruction modes.
 ** Bytecode instruction modes.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 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-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _LJ_BCDUMP_H
 #ifndef _LJ_BCDUMP_H

+ 7 - 11
libs/LuaJIT/src/lj_bcread.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Bytecode reader.
 ** Bytecode reader.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lj_bcread_c
 #define lj_bcread_c
@@ -53,11 +53,11 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
   do {
   do {
     const char *buf;
     const char *buf;
     size_t sz;
     size_t sz;
-    char *p = sbufB(&ls->sb);
+    char *p = ls->sb.b;
     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. */
-	lj_assertLS(ls->pe == sbufP(&ls->sb), "bad buffer pointer");
+	lj_assertLS(ls->pe == ls->sb.w, "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);
@@ -66,7 +66,7 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
       ls->p = p;
       ls->p = p;
       ls->pe = p + n;
       ls->pe = p + n;
     }
     }
-    setsbufP(&ls->sb, p + n);
+    ls->sb.w = p + n;
     buf = ls->rfunc(ls->L, ls->rdata, &sz);  /* Get more data from reader. */
     buf = ls->rfunc(ls->L, ls->rdata, &sz);  /* Get more data from reader. */
     if (buf == NULL || sz == 0) {  /* EOF? */
     if (buf == NULL || sz == 0) {  /* EOF? */
       if (need) bcread_error(ls, LJ_ERR_BCBAD);
       if (need) bcread_error(ls, LJ_ERR_BCBAD);
@@ -77,8 +77,8 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need)
     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);
-      memcpy(sbufP(&ls->sb), buf, sz);
-      setsbufP(&ls->sb, p + n);
+      memcpy(ls->sb.w, buf, sz);
+      ls->sb.w = p + n;
       ls->p = p;
       ls->p = p;
       ls->pe = p + n;
       ls->pe = p + n;
     } else {  /* Return buffer provided by reader. */
     } else {  /* Return buffer provided by reader. */
@@ -399,11 +399,7 @@ static int bcread_header(LexState *ls)
   if ((flags & BCDUMP_F_FFI)) {
   if ((flags & BCDUMP_F_FFI)) {
 #if LJ_HASFFI
 #if LJ_HASFFI
     lua_State *L = ls->L;
     lua_State *L = ls->L;
-    if (!ctype_ctsG(G(L))) {
-      ptrdiff_t oldtop = savestack(L, L->top);
-      luaopen_ffi(L);  /* Load FFI library on-demand. */
-      L->top = restorestack(L, oldtop);
-    }
+    ctype_loadffi(L);
 #else
 #else
     return 0;
     return 0;
 #endif
 #endif

+ 12 - 12
libs/LuaJIT/src/lj_bcwrite.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Bytecode writer.
 ** Bytecode writer.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lj_bcwrite_c
 #define lj_bcwrite_c
@@ -62,7 +62,7 @@ static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
       if (num == (lua_Number)k) {  /* -0 is never a constant. */
       if (num == (lua_Number)k) {  /* -0 is never a constant. */
 	*p++ = BCDUMP_KTAB_INT;
 	*p++ = BCDUMP_KTAB_INT;
 	p = lj_strfmt_wuleb128(p, k);
 	p = lj_strfmt_wuleb128(p, k);
-	setsbufP(&ctx->sb, p);
+	ctx->sb.w = p;
 	return;
 	return;
       }
       }
     }
     }
@@ -73,7 +73,7 @@ static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
     lj_assertBCW(tvispri(o), "unhandled type %d", itype(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);
+  ctx->sb.w = p;
 }
 }
 
 
 /* Write a template table. */
 /* Write a template table. */
@@ -97,7 +97,7 @@ static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
   /* Write number of array slots and hash slots. */
   /* Write number of array slots and hash slots. */
   p = lj_strfmt_wuleb128(p, narray);
   p = lj_strfmt_wuleb128(p, narray);
   p = lj_strfmt_wuleb128(p, nhash);
   p = lj_strfmt_wuleb128(p, nhash);
-  setsbufP(&ctx->sb, p);
+  ctx->sb.w = p;
   if (narray) {  /* Write array entries (may contain nil). */
   if (narray) {  /* Write array entries (may contain nil). */
     MSize i;
     MSize i;
     TValue *o = tvref(t->array);
     TValue *o = tvref(t->array);
@@ -172,7 +172,7 @@ static void bcwrite_kgc(BCWriteCtx *ctx, GCproto *pt)
       }
       }
 #endif
 #endif
     }
     }
-    setsbufP(&ctx->sb, p);
+    ctx->sb.w = p;
   }
   }
 }
 }
 
 
@@ -206,7 +206,7 @@ static void bcwrite_knum(BCWriteCtx *ctx, GCproto *pt)
       p = lj_strfmt_wuleb128(p, o->u32.hi);
       p = lj_strfmt_wuleb128(p, o->u32.hi);
     }
     }
   }
   }
-  setsbufP(&ctx->sb, p);
+  ctx->sb.w = p;
 }
 }
 
 
 /* Write bytecode instructions. */
 /* Write bytecode instructions. */
@@ -281,7 +281,7 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
   /* Write bytecode instructions and upvalue refs. */
   /* Write bytecode instructions and upvalue refs. */
   p = bcwrite_bytecode(ctx, p, pt);
   p = bcwrite_bytecode(ctx, p, pt);
   p = lj_buf_wmem(p, proto_uv(pt), pt->sizeuv*2);
   p = lj_buf_wmem(p, proto_uv(pt), pt->sizeuv*2);
-  setsbufP(&ctx->sb, p);
+  ctx->sb.w = p;
 
 
   /* Write constants. */
   /* Write constants. */
   bcwrite_kgc(ctx, pt);
   bcwrite_kgc(ctx, pt);
@@ -291,16 +291,16 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt)
   if (sizedbg) {
   if (sizedbg) {
     p = lj_buf_more(&ctx->sb, sizedbg);
     p = lj_buf_more(&ctx->sb, sizedbg);
     p = lj_buf_wmem(p, proto_lineinfo(pt), sizedbg);
     p = lj_buf_wmem(p, proto_lineinfo(pt), sizedbg);
-    setsbufP(&ctx->sb, p);
+    ctx->sb.w = p;
   }
   }
 
 
   /* Pass buffer to writer function. */
   /* Pass buffer to writer function. */
   if (ctx->status == 0) {
   if (ctx->status == 0) {
     MSize n = sbuflen(&ctx->sb) - 5;
     MSize n = sbuflen(&ctx->sb) - 5;
     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 = ctx->sb.b + (5 - nn);
     p = lj_strfmt_wuleb128(q, n);  /* Fill in final size. */
     p = lj_strfmt_wuleb128(q, n);  /* Fill in final size. */
-    lj_assertBCW(p == sbufB(&ctx->sb) + 5, "bad ULEB128 write");
+    lj_assertBCW(p == ctx->sb.b + 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);
   }
   }
 }
 }
@@ -324,8 +324,8 @@ static void bcwrite_header(BCWriteCtx *ctx)
     p = lj_strfmt_wuleb128(p, len);
     p = lj_strfmt_wuleb128(p, len);
     p = lj_buf_wmem(p, name, len);
     p = lj_buf_wmem(p, name, len);
   }
   }
-  ctx->status = ctx->wfunc(sbufL(&ctx->sb), sbufB(&ctx->sb),
-			   (MSize)(p - sbufB(&ctx->sb)), ctx->wdata);
+  ctx->status = ctx->wfunc(sbufL(&ctx->sb), ctx->sb.b,
+			   (MSize)(p - ctx->sb.b), ctx->wdata);
 }
 }
 
 
 /* Write footer of bytecode dump. */
 /* Write footer of bytecode dump. */

+ 133 - 60
libs/LuaJIT/src/lj_buf.c

@@ -1,6 +1,6 @@
 /*
 /*
 ** Buffer handling.
 ** Buffer handling.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #define lj_buf_c
 #define lj_buf_c
@@ -20,12 +20,32 @@ static void buf_grow(SBuf *sb, MSize sz)
 {
 {
   MSize osz = sbufsz(sb), len = sbuflen(sb), nsz = osz;
   MSize osz = sbufsz(sb), len = sbuflen(sb), nsz = osz;
   char *b;
   char *b;
+  GCSize flag;
   if (nsz < LJ_MIN_SBUF) nsz = LJ_MIN_SBUF;
   if (nsz < LJ_MIN_SBUF) nsz = LJ_MIN_SBUF;
   while (nsz < sz) nsz += nsz;
   while (nsz < sz) nsz += nsz;
-  b = (char *)lj_mem_realloc(sbufL(sb), sbufB(sb), osz, nsz);
-  setmref(sb->b, b);
-  setmref(sb->p, b + len);
-  setmref(sb->e, b + nsz);
+  flag = sbufflag(sb);
+  if ((flag & SBUF_FLAG_COW)) {  /* Copy-on-write semantics. */
+    lj_assertG_(G(sbufL(sb)), sb->w == sb->e, "bad SBuf COW");
+    b = (char *)lj_mem_new(sbufL(sb), nsz);
+    setsbufflag(sb, flag & ~(GCSize)SBUF_FLAG_COW);
+    setgcrefnull(sbufX(sb)->cowref);
+    memcpy(b, sb->b, osz);
+  } else {
+    b = (char *)lj_mem_realloc(sbufL(sb), sb->b, osz, nsz);
+  }
+  if ((flag & SBUF_FLAG_EXT)) {
+    sbufX(sb)->r = sbufX(sb)->r - sb->b + b;  /* Adjust read pointer, too. */
+  }
+  /* Adjust buffer pointers. */
+  sb->b = b;
+  sb->w = b + len;
+  sb->e = b + nsz;
+  if ((flag & SBUF_FLAG_BORROW)) {  /* Adjust borrowed buffer pointers. */
+    SBuf *bsb = mref(sbufX(sb)->bsb, SBuf);
+    bsb->b = b;
+    bsb->w = b + len;
+    bsb->e = b + nsz;
+  }
 }
 }
 
 
 LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz)
 LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz)
@@ -34,30 +54,51 @@ LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz)
   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);
-  return sbufB(sb);
+  return sb->b;
 }
 }
 
 
 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);
-  lj_assertG_(G(sbufL(sb)), sz > sbufleft(sb), "SBuf overflow");
-  if (LJ_UNLIKELY(sz > LJ_MAX_BUF || len + sz > LJ_MAX_BUF))
-    lj_err_mem(sbufL(sb));
-  buf_grow(sb, len + sz);
-  return sbufP(sb);
+  if (sbufisext(sb)) {
+    SBufExt *sbx = (SBufExt *)sb;
+    MSize len = sbufxlen(sbx);
+    if (LJ_UNLIKELY(sz > LJ_MAX_BUF || len + sz > LJ_MAX_BUF))
+      lj_err_mem(sbufL(sbx));
+    if (len + sz > sbufsz(sbx)) {  /* Must grow. */
+      buf_grow((SBuf *)sbx, len + sz);
+    } else if (sbufxslack(sbx) < (sbufsz(sbx) >> 3)) {
+      /* Also grow to avoid excessive compactions, if slack < size/8. */
+      buf_grow((SBuf *)sbx, sbuflen(sbx) + sz);  /* Not sbufxlen! */
+      return sbx->w;
+    }
+    if (sbx->r != sbx->b) {  /* Compact by moving down. */
+      memmove(sbx->b, sbx->r, len);
+      sbx->r = sbx->b;
+      sbx->w = sbx->b + len;
+      lj_assertG_(G(sbufL(sbx)), len + sz <= sbufsz(sbx), "bad SBuf compact");
+    }
+  } else {
+    MSize len = sbuflen(sb);
+    lj_assertG_(G(sbufL(sb)), sz > sbufleft(sb), "SBuf overflow");
+    if (LJ_UNLIKELY(sz > LJ_MAX_BUF || len + sz > LJ_MAX_BUF))
+      lj_err_mem(sbufL(sb));
+    buf_grow(sb, len + sz);
+  }
+  return sb->w;
 }
 }
 
 
 void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb)
 void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb)
 {
 {
-  char *b = sbufB(sb);
-  MSize osz = (MSize)(sbufE(sb) - b);
+  char *b = sb->b;
+  MSize osz = (MSize)(sb->e - b);
   if (osz > 2*LJ_MIN_SBUF) {
   if (osz > 2*LJ_MIN_SBUF) {
-    MSize n = (MSize)(sbufP(sb) - b);
+    MSize n = (MSize)(sb->w - b);
     b = lj_mem_realloc(L, b, osz, (osz >> 1));
     b = lj_mem_realloc(L, b, osz, (osz >> 1));
-    setmref(sb->b, b);
-    setmref(sb->p, b + n);
-    setmref(sb->e, b + (osz >> 1));
+    sb->b = b;
+    sb->w = b + n;
+    sb->e = b + (osz >> 1);
   }
   }
+  lj_assertG_(G(sbufL(sb)), !sbufisext(sb), "YAGNI shrink SBufExt");
 }
 }
 
 
 char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz)
 char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz)
@@ -67,30 +108,62 @@ char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz)
   return lj_buf_need(sb, sz);
   return lj_buf_need(sb, sz);
 }
 }
 
 
+#if LJ_HASBUFFER && LJ_HASJIT
+void lj_bufx_set(SBufExt *sbx, const char *p, MSize len, GCobj *ref)
+{
+  lua_State *L = sbufL(sbx);
+  lj_bufx_free(L, sbx);
+  lj_bufx_set_cow(L, sbx, p, len);
+  setgcref(sbx->cowref, ref);
+  lj_gc_objbarrier(L, (GCudata *)sbx - 1, ref);
+}
+
+#if LJ_HASFFI
+MSize LJ_FASTCALL lj_bufx_more(SBufExt *sbx, MSize sz)
+{
+  lj_buf_more((SBuf *)sbx, sz);
+  return sbufleft(sbx);
+}
+#endif
+#endif
+
 /* -- Low-level buffer put operations ------------------------------------- */
 /* -- Low-level buffer put operations ------------------------------------- */
 
 
 SBuf *lj_buf_putmem(SBuf *sb, const void *q, MSize len)
 SBuf *lj_buf_putmem(SBuf *sb, const void *q, MSize len)
 {
 {
-  char *p = lj_buf_more(sb, len);
-  p = lj_buf_wmem(p, q, len);
-  setsbufP(sb, p);
+  char *w = lj_buf_more(sb, len);
+  w = lj_buf_wmem(w, q, len);
+  sb->w = w;
   return sb;
   return sb;
 }
 }
 
 
-SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c)
+#if LJ_HASJIT || LJ_HASFFI
+static LJ_NOINLINE SBuf * LJ_FASTCALL lj_buf_putchar2(SBuf *sb, int c)
 {
 {
-  char *p = lj_buf_more(sb, 1);
-  *p++ = (char)c;
-  setsbufP(sb, p);
+  char *w = lj_buf_more2(sb, 1);
+  *w++ = (char)c;
+  sb->w = w;
   return sb;
   return sb;
 }
 }
 
 
+SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c)
+{
+  char *w = sb->w;
+  if (LJ_LIKELY(w < sb->e)) {
+    *w++ = (char)c;
+    sb->w = w;
+    return sb;
+  }
+  return lj_buf_putchar2(sb, c);
+}
+#endif
+
 SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s)
 SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s)
 {
 {
   MSize len = s->len;
   MSize len = s->len;
-  char *p = lj_buf_more(sb, len);
-  p = lj_buf_wmem(p, strdata(s), len);
-  setsbufP(sb, p);
+  char *w = lj_buf_more(sb, len);
+  w = lj_buf_wmem(w, strdata(s), len);
+  sb->w = w;
   return sb;
   return sb;
 }
 }
 
 
@@ -99,47 +172,47 @@ SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s)
 SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s)
 SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s)
 {
 {
   MSize len = s->len;
   MSize len = s->len;
-  char *p = lj_buf_more(sb, len), *e = p+len;
+  char *w = lj_buf_more(sb, len), *e = w+len;
   const char *q = strdata(s)+len-1;
   const char *q = strdata(s)+len-1;
-  while (p < e)
-    *p++ = *q--;
-  setsbufP(sb, p);
+  while (w < e)
+    *w++ = *q--;
+  sb->w = w;
   return sb;
   return sb;
 }
 }
 
 
 SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s)
 SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s)
 {
 {
   MSize len = s->len;
   MSize len = s->len;
-  char *p = lj_buf_more(sb, len), *e = p+len;
+  char *w = lj_buf_more(sb, len), *e = w+len;
   const char *q = strdata(s);
   const char *q = strdata(s);
-  for (; p < e; p++, q++) {
+  for (; w < e; w++, q++) {
     uint32_t c = *(unsigned char *)q;
     uint32_t c = *(unsigned char *)q;
 #if LJ_TARGET_PPC
 #if LJ_TARGET_PPC
-    *p = c + ((c >= 'A' && c <= 'Z') << 5);
+    *w = c + ((c >= 'A' && c <= 'Z') << 5);
 #else
 #else
     if (c >= 'A' && c <= 'Z') c += 0x20;
     if (c >= 'A' && c <= 'Z') c += 0x20;
-    *p = c;
+    *w = c;
 #endif
 #endif
   }
   }
-  setsbufP(sb, p);
+  sb->w = w;
   return sb;
   return sb;
 }
 }
 
 
 SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s)
 SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s)
 {
 {
   MSize len = s->len;
   MSize len = s->len;
-  char *p = lj_buf_more(sb, len), *e = p+len;
+  char *w = lj_buf_more(sb, len), *e = w+len;
   const char *q = strdata(s);
   const char *q = strdata(s);
-  for (; p < e; p++, q++) {
+  for (; w < e; w++, q++) {
     uint32_t c = *(unsigned char *)q;
     uint32_t c = *(unsigned char *)q;
 #if LJ_TARGET_PPC
 #if LJ_TARGET_PPC
-    *p = c - ((c >= 'a' && c <= 'z') << 5);
+    *w = c - ((c >= 'a' && c <= 'z') << 5);
 #else
 #else
     if (c >= 'a' && c <= 'z') c -= 0x20;
     if (c >= 'a' && c <= 'z') c -= 0x20;
-    *p = c;
+    *w = c;
 #endif
 #endif
   }
   }
-  setsbufP(sb, p);
+  sb->w = w;
   return sb;
   return sb;
 }
 }
 
 
@@ -148,21 +221,21 @@ SBuf *lj_buf_putstr_rep(SBuf *sb, GCstr *s, int32_t rep)
   MSize len = s->len;
   MSize len = s->len;
   if (rep > 0 && len) {
   if (rep > 0 && len) {
     uint64_t tlen = (uint64_t)rep * len;
     uint64_t tlen = (uint64_t)rep * len;
-    char *p;
+    char *w;
     if (LJ_UNLIKELY(tlen > LJ_MAX_STR))
     if (LJ_UNLIKELY(tlen > LJ_MAX_STR))
       lj_err_mem(sbufL(sb));
       lj_err_mem(sbufL(sb));
-    p = lj_buf_more(sb, (MSize)tlen);
+    w = lj_buf_more(sb, (MSize)tlen);
     if (len == 1) {  /* Optimize a common case. */
     if (len == 1) {  /* Optimize a common case. */
       uint32_t c = strdata(s)[0];
       uint32_t c = strdata(s)[0];
-      do { *p++ = c; } while (--rep > 0);
+      do { *w++ = c; } while (--rep > 0);
     } else {
     } else {
       const char *e = strdata(s) + len;
       const char *e = strdata(s) + len;
       do {
       do {
 	const char *q = strdata(s);
 	const char *q = strdata(s);
-	do { *p++ = *q++; } while (q < e);
+	do { *w++ = *q++; } while (q < e);
       } while (--rep > 0);
       } while (--rep > 0);
     }
     }
-    setsbufP(sb, p);
+    sb->w = w;
   }
   }
   return sb;
   return sb;
 }
 }
@@ -173,27 +246,27 @@ SBuf *lj_buf_puttab(SBuf *sb, GCtab *t, GCstr *sep, int32_t i, int32_t e)
   if (i <= e) {
   if (i <= e) {
     for (;;) {
     for (;;) {
       cTValue *o = lj_tab_getint(t, i);
       cTValue *o = lj_tab_getint(t, i);
-      char *p;
+      char *w;
       if (!o) {
       if (!o) {
       badtype:  /* Error: bad element type. */
       badtype:  /* Error: bad element type. */
-	setsbufP(sb, (void *)(intptr_t)i);  /* Store failing index. */
+	sb->w = (char *)(intptr_t)i;  /* Store failing index. */
 	return NULL;
 	return NULL;
       } else if (tvisstr(o)) {
       } else if (tvisstr(o)) {
 	MSize len = strV(o)->len;
 	MSize len = strV(o)->len;
-	p = lj_buf_wmem(lj_buf_more(sb, len + seplen), strVdata(o), len);
+	w = lj_buf_wmem(lj_buf_more(sb, len + seplen), strVdata(o), len);
       } else if (tvisint(o)) {
       } else if (tvisint(o)) {
-	p = lj_strfmt_wint(lj_buf_more(sb, STRFMT_MAXBUF_INT+seplen), intV(o));
+	w = lj_strfmt_wint(lj_buf_more(sb, STRFMT_MAXBUF_INT+seplen), intV(o));
       } else if (tvisnum(o)) {
       } else if (tvisnum(o)) {
-	p = lj_buf_more(lj_strfmt_putfnum(sb, STRFMT_G14, numV(o)), seplen);
+	w = lj_buf_more(lj_strfmt_putfnum(sb, STRFMT_G14, numV(o)), seplen);
       } else {
       } else {
 	goto badtype;
 	goto badtype;
       }
       }
       if (i++ == e) {
       if (i++ == e) {
-	setsbufP(sb, p);
+	sb->w = w;
 	break;
 	break;
       }
       }
-      if (seplen) p = lj_buf_wmem(p, strdata(sep), seplen);
-      setsbufP(sb, p);
+      if (seplen) w = lj_buf_wmem(w, strdata(sep), seplen);
+      sb->w = w;
     }
     }
   }
   }
   return sb;
   return sb;
@@ -203,7 +276,7 @@ SBuf *lj_buf_puttab(SBuf *sb, GCtab *t, GCstr *sep, int32_t i, int32_t e)
 
 
 GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb)
 GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb)
 {
 {
-  return lj_str_new(sbufL(sb), sbufB(sb), sbuflen(sb));
+  return lj_str_new(sbufL(sb), sb->b, sbuflen(sb));
 }
 }
 
 
 /* Concatenate two strings. */
 /* Concatenate two strings. */
@@ -219,14 +292,14 @@ GCstr *lj_buf_cat2str(lua_State *L, GCstr *s1, GCstr *s2)
 /* Read ULEB128 from buffer. */
 /* Read ULEB128 from buffer. */
 uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp)
 uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp)
 {
 {
-  const uint8_t *p = (const uint8_t *)*pp;
-  uint32_t v = *p++;
+  const uint8_t *w = (const uint8_t *)*pp;
+  uint32_t v = *w++;
   if (LJ_UNLIKELY(v >= 0x80)) {
   if (LJ_UNLIKELY(v >= 0x80)) {
     int sh = 0;
     int sh = 0;
     v &= 0x7f;
     v &= 0x7f;
-    do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80);
+    do { v |= ((*w & 0x7f) << (sh += 7)); } while (*w++ >= 0x80);
   }
   }
-  *pp = (const char *)p;
+  *pp = (const char *)w;
   return v;
   return v;
 }
 }
 
 

+ 115 - 20
libs/LuaJIT/src/lj_buf.h

@@ -1,6 +1,6 @@
 /*
 /*
 ** Buffer handling.
 ** Buffer handling.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _LJ_BUF_H
 #ifndef _LJ_BUF_H
@@ -10,16 +10,60 @@
 #include "lj_gc.h"
 #include "lj_gc.h"
 #include "lj_str.h"
 #include "lj_str.h"
 
 
-/* Resizable string buffers. Struct definition in lj_obj.h. */
-#define sbufB(sb)	(mref((sb)->b, char))
-#define sbufP(sb)	(mref((sb)->p, char))
-#define sbufE(sb)	(mref((sb)->e, char))
-#define sbufL(sb)	(mref((sb)->L, lua_State))
-#define sbufsz(sb)	((MSize)(sbufE((sb)) - sbufB((sb))))
-#define sbuflen(sb)	((MSize)(sbufP((sb)) - sbufB((sb))))
-#define sbufleft(sb)	((MSize)(sbufE((sb)) - sbufP((sb))))
-#define setsbufP(sb, q)	(setmref((sb)->p, (q)))
-#define setsbufL(sb, l)	(setmref((sb)->L, (l)))
+/* Resizable string buffers. */
+
+/* The SBuf struct definition is in lj_obj.h:
+**   char *w;	Write pointer.
+**   char *e;	End pointer.
+**   char *b;	Base pointer.
+**   MRef L;	lua_State, used for buffer resizing. Extension bits in 3 LSB.
+*/
+
+/* Extended string buffer. */
+typedef struct SBufExt {
+  SBufHeader;
+  union {
+    GCRef cowref;	/* Copy-on-write object reference. */
+    MRef bsb;		/* Borrowed string buffer. */
+  };
+  char *r;		/* Read pointer. */
+  GCRef dict_str;	/* Serialization string dictionary table. */
+  GCRef dict_mt;	/* Serialization metatable dictionary table. */
+  int depth;		/* Remaining recursion depth. */
+} SBufExt;
+
+#define sbufsz(sb)		((MSize)((sb)->e - (sb)->b))
+#define sbuflen(sb)		((MSize)((sb)->w - (sb)->b))
+#define sbufleft(sb)		((MSize)((sb)->e - (sb)->w))
+#define sbufxlen(sbx)		((MSize)((sbx)->w - (sbx)->r))
+#define sbufxslack(sbx)		((MSize)((sbx)->r - (sbx)->b))
+
+#define SBUF_MASK_FLAG		(7)
+#define SBUF_MASK_L		(~(GCSize)SBUF_MASK_FLAG)
+#define SBUF_FLAG_EXT		1	/* Extended string buffer. */
+#define SBUF_FLAG_COW		2	/* Copy-on-write buffer. */
+#define SBUF_FLAG_BORROW	4	/* Borrowed string buffer. */
+
+#define sbufL(sb) \
+  ((lua_State *)(void *)(uintptr_t)(mrefu((sb)->L) & SBUF_MASK_L))
+#define setsbufL(sb, l)		(setmref((sb)->L, (l)))
+#define setsbufXL(sb, l, flag) \
+  (setmrefu((sb)->L, (GCSize)(uintptr_t)(void *)(l) + (flag)))
+#define setsbufXL_(sb, l) \
+  (setmrefu((sb)->L, (GCSize)(uintptr_t)(void *)(l) | (mrefu((sb)->L) & SBUF_MASK_FLAG)))
+
+#define sbufflag(sb)		(mrefu((sb)->L))
+#define sbufisext(sb)		(sbufflag((sb)) & SBUF_FLAG_EXT)
+#define sbufiscow(sb)		(sbufflag((sb)) & SBUF_FLAG_COW)
+#define sbufisborrow(sb)	(sbufflag((sb)) & SBUF_FLAG_BORROW)
+#define sbufiscoworborrow(sb)	(sbufflag((sb)) & (SBUF_FLAG_COW|SBUF_FLAG_BORROW))
+#define sbufX(sb) \
+  (lj_assertG_(G(sbufL(sb)), sbufisext(sb), "not an SBufExt"), (SBufExt *)(sb))
+#define setsbufflag(sb, flag)	(setmrefu((sb)->L, (flag)))
+
+#define tvisbuf(o) \
+  (LJ_HASBUFFER && tvisudata(o) && udataV(o)->udtype == UDTYPE_BUFFER)
+#define bufV(o)		check_exp(tvisbuf(o), ((SBufExt *)uddata(udataV(o))))
 
 
 /* Buffer management */
 /* Buffer management */
 LJ_FUNC char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz);
 LJ_FUNC char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz);
@@ -30,12 +74,12 @@ LJ_FUNC char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz);
 static LJ_AINLINE void lj_buf_init(lua_State *L, SBuf *sb)
 static LJ_AINLINE void lj_buf_init(lua_State *L, SBuf *sb)
 {
 {
   setsbufL(sb, L);
   setsbufL(sb, L);
-  setmref(sb->p, NULL); setmref(sb->e, NULL); setmref(sb->b, NULL);
+  sb->w = sb->e = sb->b = NULL;
 }
 }
 
 
 static LJ_AINLINE void lj_buf_reset(SBuf *sb)
 static LJ_AINLINE void lj_buf_reset(SBuf *sb)
 {
 {
-  setmrefr(sb->p, sb->b);
+  sb->w = sb->b;
 }
 }
 
 
 static LJ_AINLINE SBuf *lj_buf_tmp_(lua_State *L)
 static LJ_AINLINE SBuf *lj_buf_tmp_(lua_State *L)
@@ -48,26 +92,77 @@ static LJ_AINLINE SBuf *lj_buf_tmp_(lua_State *L)
 
 
 static LJ_AINLINE void lj_buf_free(global_State *g, SBuf *sb)
 static LJ_AINLINE void lj_buf_free(global_State *g, SBuf *sb)
 {
 {
-  lj_mem_free(g, sbufB(sb), sbufsz(sb));
+  lj_assertG(!sbufisext(sb), "bad free of SBufExt");
+  lj_mem_free(g, sb->b, sbufsz(sb));
 }
 }
 
 
 static LJ_AINLINE char *lj_buf_need(SBuf *sb, MSize sz)
 static LJ_AINLINE char *lj_buf_need(SBuf *sb, MSize sz)
 {
 {
   if (LJ_UNLIKELY(sz > sbufsz(sb)))
   if (LJ_UNLIKELY(sz > sbufsz(sb)))
     return lj_buf_need2(sb, sz);
     return lj_buf_need2(sb, sz);
-  return sbufB(sb);
+  return sb->b;
 }
 }
 
 
 static LJ_AINLINE char *lj_buf_more(SBuf *sb, MSize sz)
 static LJ_AINLINE char *lj_buf_more(SBuf *sb, MSize sz)
 {
 {
   if (LJ_UNLIKELY(sz > sbufleft(sb)))
   if (LJ_UNLIKELY(sz > sbufleft(sb)))
     return lj_buf_more2(sb, sz);
     return lj_buf_more2(sb, sz);
-  return sbufP(sb);
+  return sb->w;
+}
+
+/* Extended buffer management */
+static LJ_AINLINE void lj_bufx_init(lua_State *L, SBufExt *sbx)
+{
+  memset(sbx, 0, sizeof(SBufExt));
+  setsbufXL(sbx, L, SBUF_FLAG_EXT);
+}
+
+static LJ_AINLINE void lj_bufx_set_borrow(lua_State *L, SBufExt *sbx, SBuf *sb)
+{
+  setsbufXL(sbx, L, SBUF_FLAG_EXT | SBUF_FLAG_BORROW);
+  setmref(sbx->bsb, sb);
+  sbx->r = sbx->w = sbx->b = sb->b;
+  sbx->e = sb->e;
+}
+
+static LJ_AINLINE void lj_bufx_set_cow(lua_State *L, SBufExt *sbx,
+				       const char *p, MSize len)
+{
+  setsbufXL(sbx, L, SBUF_FLAG_EXT | SBUF_FLAG_COW);
+  sbx->r = sbx->b = (char *)p;
+  sbx->w = sbx->e = (char *)p + len;
+}
+
+static LJ_AINLINE void lj_bufx_reset(SBufExt *sbx)
+{
+  if (sbufiscow(sbx)) {
+    setmrefu(sbx->L, (mrefu(sbx->L) & ~(GCSize)SBUF_FLAG_COW));
+    setgcrefnull(sbx->cowref);
+    sbx->b = sbx->e = NULL;
+  }
+  sbx->r = sbx->w = sbx->b;
 }
 }
 
 
+static LJ_AINLINE void lj_bufx_free(lua_State *L, SBufExt *sbx)
+{
+  if (!sbufiscoworborrow(sbx)) lj_mem_free(G(L), sbx->b, sbufsz(sbx));
+  setsbufXL(sbx, L, SBUF_FLAG_EXT);
+  setgcrefnull(sbx->cowref);
+  sbx->r = sbx->w = sbx->b = sbx->e = NULL;
+}
+
+#if LJ_HASBUFFER && LJ_HASJIT
+LJ_FUNC void lj_bufx_set(SBufExt *sbx, const char *p, MSize len, GCobj *o);
+#if LJ_HASFFI
+LJ_FUNC MSize LJ_FASTCALL lj_bufx_more(SBufExt *sbx, MSize sz);
+#endif
+#endif
+
 /* Low-level buffer put operations */
 /* Low-level buffer put operations */
 LJ_FUNC SBuf *lj_buf_putmem(SBuf *sb, const void *q, MSize len);
 LJ_FUNC SBuf *lj_buf_putmem(SBuf *sb, const void *q, MSize len);
+#if LJ_HASJIT || LJ_HASFFI
 LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c);
 LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c);
+#endif
 LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s);
 LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s);
 
 
 static LJ_AINLINE char *lj_buf_wmem(char *p, const void *q, MSize len)
 static LJ_AINLINE char *lj_buf_wmem(char *p, const void *q, MSize len)
@@ -77,9 +172,9 @@ static LJ_AINLINE char *lj_buf_wmem(char *p, const void *q, MSize len)
 
 
 static LJ_AINLINE void lj_buf_putb(SBuf *sb, int c)
 static LJ_AINLINE void lj_buf_putb(SBuf *sb, int c)
 {
 {
-  char *p = lj_buf_more(sb, 1);
-  *p++ = (char)c;
-  setsbufP(sb, p);
+  char *w = lj_buf_more(sb, 1);
+  *w++ = (char)c;
+  sb->w = w;
 }
 }
 
 
 /* High-level buffer put operations */
 /* High-level buffer put operations */
@@ -97,7 +192,7 @@ LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp);
 
 
 static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb)
 static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb)
 {
 {
-  return lj_str_new(L, sbufB(sb), sbuflen(sb));
+  return lj_str_new(L, sb->b, sbuflen(sb));
 }
 }
 
 
 #endif
 #endif

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** C data arithmetic.
 ** C data arithmetic.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #include "lj_obj.h"
 #include "lj_obj.h"

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** C data arithmetic.
 ** C data arithmetic.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #ifndef _LJ_CARITH_H
 #ifndef _LJ_CARITH_H

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

@@ -1,6 +1,6 @@
 /*
 /*
 ** FFI C call handling.
 ** FFI C call handling.
-** Copyright (C) 2005-2020 Mike Pall. See Copyright Notice in luajit.h
+** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h
 */
 */
 
 
 #include "lj_obj.h"
 #include "lj_obj.h"
@@ -334,7 +334,7 @@
   isfp = sz == 2*sizeof(float) ? 2 : 1;
   isfp = sz == 2*sizeof(float) ? 2 : 1;
 
 
 #define CCALL_HANDLE_REGARG \
 #define CCALL_HANDLE_REGARG \
-  if (LJ_TARGET_IOS && isva) { \
+  if (LJ_TARGET_OSX && isva) { \
     /* IOS: All variadic arguments are on the stack. */ \
     /* IOS: All variadic arguments are on the stack. */ \
   } else if (isfp) {  /* Try to pass argument in FPRs. */ \
   } else if (isfp) {  /* Try to pass argument in FPRs. */ \
     int n2 = ctype_isvector(d->info) ? 1 : \
     int n2 = ctype_isvector(d->info) ? 1 : \
@@ -345,10 +345,10 @@
       goto done; \
       goto done; \
     } else { \
     } else { \
       nfpr = CCALL_NARG_FPR;  /* Prevent reordering. */ \
       nfpr = CCALL_NARG_FPR;  /* Prevent reordering. */ \
-      if (LJ_TARGET_IOS && d->size < 8) goto err_nyi; \
+      if (LJ_TARGET_OSX && d->size < 8) goto err_nyi; \
     } \
     } \
   } else {  /* Try to pass argument in GPRs. */ \
   } else {  /* Try to pass argument in GPRs. */ \
-    if (!LJ_TARGET_IOS && (d->info & CTF_ALIGN) > CTALIGN_PTR) \
+    if (!LJ_TARGET_OSX && (d->info & CTF_ALIGN) > CTALIGN_PTR) \
       ngpr = (ngpr + 1u) & ~1u;  /* Align to regpair. */ \
       ngpr = (ngpr + 1u) & ~1u;  /* Align to regpair. */ \
     if (ngpr + n <= maxgpr) { \
     if (ngpr + n <= maxgpr) { \
       dp = &cc->gpr[ngpr]; \
       dp = &cc->gpr[ngpr]; \
@@ -356,7 +356,7 @@
       goto done; \
       goto done; \
     } else { \
     } else { \
       ngpr = maxgpr;  /* Prevent reordering. */ \
       ngpr = maxgpr;  /* Prevent reordering. */ \
-      if (LJ_TARGET_IOS && d->size < 8) goto err_nyi; \
+      if (LJ_TARGET_OSX && d->size < 8) goto err_nyi; \
     } \
     } \
   }
   }
 
 

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