mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Merge branch 'v2.1' into luajit-s390x
This commit is contained in:
commit
3c878599b1
6
Makefile
6
Makefile
@ -33,7 +33,8 @@ DPREFIX= $(DESTDIR)$(PREFIX)
|
||||
INSTALL_BIN= $(DPREFIX)/bin
|
||||
INSTALL_LIB= $(DPREFIX)/$(MULTILIB)
|
||||
INSTALL_SHARE= $(DPREFIX)/share
|
||||
INSTALL_INC= $(DPREFIX)/include/luajit-$(MAJVER).$(MINVER)
|
||||
INSTALL_DEFINC= $(DPREFIX)/include/luajit-$(MAJVER).$(MINVER)
|
||||
INSTALL_INC= $(INSTALL_DEFINC)
|
||||
|
||||
INSTALL_LJLIBD= $(INSTALL_SHARE)/luajit-$(VERSION)
|
||||
INSTALL_JITLIB= $(INSTALL_LJLIBD)/jit
|
||||
@ -78,6 +79,9 @@ UNINSTALL= $(RM)
|
||||
LDCONFIG= ldconfig -n 2>/dev/null
|
||||
SED_PC= sed -e "s|^prefix=.*|prefix=$(PREFIX)|" \
|
||||
-e "s|^multilib=.*|multilib=$(MULTILIB)|"
|
||||
ifneq ($(INSTALL_DEFINC),$(INSTALL_INC))
|
||||
SED_PC+= -e "s|^includedir=.*|includedir=$(INSTALL_INC)|"
|
||||
endif
|
||||
|
||||
FILE_T= luajit
|
||||
FILE_A= libluajit.a
|
||||
|
@ -86,7 +86,7 @@ overhead. In conjunction with the FFI library, they allow zero-copy
|
||||
operations.
|
||||
</p>
|
||||
<p>
|
||||
The string buffer libary also includes a high-performance
|
||||
The string buffer library also includes a high-performance
|
||||
<a href="serialize">serializer</a> for Lua objects.
|
||||
</p>
|
||||
|
||||
@ -434,8 +434,8 @@ unsupported object types, circular references or deeply nested tables.
|
||||
<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
|
||||
The stand-alone function deserializes (decodes) the string
|
||||
<tt>str</tt>, the buffer method deserializes one object from the
|
||||
buffer. Both return a Lua object <tt>obj</tt>.
|
||||
</p>
|
||||
<p>
|
||||
@ -449,7 +449,7 @@ data after decoding a single top-level object. The buffer method leaves
|
||||
any left-over data in the buffer.
|
||||
</p>
|
||||
<p>
|
||||
Attempting to de-serialize an FFI type will throw an error, if the FFI
|
||||
Attempting to deserialize an FFI type will throw an error, if the FFI
|
||||
library is not built-in or has not been loaded, yet.
|
||||
</p>
|
||||
|
||||
@ -462,7 +462,7 @@ the following members (all optional):
|
||||
<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
|
||||
are compactly encoded as indexes during serialization. A well-chosen
|
||||
dictionary saves space and improves serialization performance.
|
||||
</li>
|
||||
<li>
|
||||
@ -473,7 +473,7 @@ for the table objects you are serializing.
|
||||
<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
|
||||
<tt>nil</tt> in between). 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>.
|
||||
@ -624,7 +624,7 @@ 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
|
||||
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:
|
||||
|
@ -107,7 +107,7 @@ Turn the whole JIT compiler on or off or flush the whole cache of compiled code.
|
||||
This sets the mode for the function at the stack index <tt>idx</tt> or
|
||||
the parent of the calling function (<tt>idx = 0</tt>). It either
|
||||
enables JIT compilation for a function, disables it and flushes any
|
||||
already compiled code or only flushes already compiled code. This
|
||||
already compiled code, or only flushes already compiled code. This
|
||||
applies recursively to all sub-functions of the function with
|
||||
<tt>LUAJIT_MODE_ALLFUNC</tt> or only to the sub-functions with
|
||||
<tt>LUAJIT_MODE_ALLSUBFUNC</tt>.
|
||||
@ -126,7 +126,7 @@ traces which link to it.
|
||||
This mode defines a wrapper function for calls to C functions. If
|
||||
called with <tt>LUAJIT_MODE_ON</tt>, the stack index at <tt>idx</tt>
|
||||
must be a <tt>lightuserdata</tt> object holding a pointer to the wrapper
|
||||
function. From now on all C functions are called through the wrapper
|
||||
function. From now on, all C functions are called through the wrapper
|
||||
function. If called with <tt>LUAJIT_MODE_OFF</tt> this mode is turned
|
||||
off and all C functions are directly called.
|
||||
</p>
|
||||
|
@ -157,7 +157,7 @@ call the binding function. Phew!
|
||||
<h2 id="cdata">Motivating Example: Using C Data Structures</h2>
|
||||
<p>
|
||||
The FFI library allows you to create and access C data
|
||||
structures. Of course the main use for this is for interfacing with
|
||||
structures. Of course, the main use for this is for interfacing with
|
||||
C functions. But they can be used stand-alone, too.
|
||||
</p>
|
||||
<p>
|
||||
@ -169,7 +169,7 @@ implemented with a big table holding lots of tiny tables. This imposes
|
||||
both a substantial memory overhead as well as a performance overhead.
|
||||
</p>
|
||||
<p>
|
||||
Here's a sketch of a library that operates on color images plus a
|
||||
Here's a sketch of a library that operates on color images, plus a
|
||||
simple benchmark. First, the plain Lua version:
|
||||
</p>
|
||||
<pre class="code">
|
||||
@ -184,7 +184,7 @@ local function image_ramp_green(n)
|
||||
return img
|
||||
end
|
||||
|
||||
local function image_to_grey(img, n)
|
||||
local function image_to_gray(img, n)
|
||||
for i=1,n do
|
||||
local y = floor(0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue)
|
||||
img[i].red = y; img[i].green = y; img[i].blue = y
|
||||
@ -194,14 +194,14 @@ end
|
||||
local N = 400*400
|
||||
local img = image_ramp_green(N)
|
||||
for i=1,1000 do
|
||||
image_to_grey(img, N)
|
||||
image_to_gray(img, N)
|
||||
end
|
||||
</pre>
|
||||
<p>
|
||||
This creates a table with 160.000 pixels, each of which is a table
|
||||
holding four number values in the range of 0-255. First an image with
|
||||
holding four number values in the range of 0-255. First, an image with
|
||||
a green ramp is created (1D for simplicity), then the image is
|
||||
converted to greyscale 1000 times. Yes, that's silly, but I was in
|
||||
converted to grayscale 1000 times. Yes, that's silly, but I was in
|
||||
need of a simple example ...
|
||||
</p>
|
||||
<p>
|
||||
@ -308,7 +308,7 @@ be more compact and faster. This is certainly true (by a factor of
|
||||
~1.7x). Switching to a struct-of-arrays would help, too.
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
However the resulting code would be less idiomatic and rather
|
||||
However, the resulting code would be less idiomatic and rather
|
||||
error-prone. And it still doesn't get even close to the performance of
|
||||
the FFI version of the code. Also, high-level data structures cannot
|
||||
be easily passed to other C functions, especially I/O functions,
|
||||
|
@ -121,7 +121,7 @@ separated by semicolons. The trailing semicolon for a single
|
||||
declaration may be omitted.
|
||||
</p>
|
||||
<p>
|
||||
Please note that external symbols are only <em>declared</em>, but they
|
||||
Please note, that external symbols are only <em>declared</em>, but they
|
||||
are <em>not bound</em> to any specific address, yet. Binding is
|
||||
achieved with C library namespaces (see below).
|
||||
</p>
|
||||
@ -209,7 +209,7 @@ parse the cdecl only once and get its ctype with
|
||||
<tt>ffi.typeof()</tt>. Then use the ctype as a constructor repeatedly.
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
Please note that an anonymous <tt>struct</tt> declaration implicitly
|
||||
Please note, that an anonymous <tt>struct</tt> declaration implicitly
|
||||
creates a new and distinguished ctype every time you use it for
|
||||
<tt>ffi.new()</tt>. This is probably <b>not</b> what you want,
|
||||
especially if you create more than one cdata object. Different anonymous
|
||||
@ -256,12 +256,12 @@ afterwards. Neither the contents of the <tt>metatable</tt> nor the
|
||||
contents of an <tt>__index</tt> table (if any) may be modified
|
||||
afterwards. The associated metatable automatically applies to all uses
|
||||
of this type, no matter how the objects are created or where they
|
||||
originate from. Note that pre-defined operations on types have
|
||||
originate from. Note that predefined operations on types have
|
||||
precedence (e.g. declared field names cannot be overridden).
|
||||
</p>
|
||||
<p>
|
||||
All standard Lua metamethods are implemented. These are called directly,
|
||||
without shortcuts and on any mix of types. For binary operations, the
|
||||
without shortcuts, and on any mix of types. For binary operations, the
|
||||
left operand is checked first for a valid ctype metamethod. The
|
||||
<tt>__gc</tt> metamethod only applies to <tt>struct</tt>/<tt>union</tt>
|
||||
types and performs an implicit <a href="#ffi_gc"><tt>ffi.gc()</tt></a>
|
||||
@ -492,7 +492,7 @@ have some extra methods:
|
||||
<p>
|
||||
Free the resources associated with a callback. The associated Lua
|
||||
function is unanchored and may be garbage collected. The callback
|
||||
function pointer is no longer valid and must not be called anymore
|
||||
function pointer is no longer valid and must not be called again
|
||||
(it may be reused by a subsequently created callback).
|
||||
</p>
|
||||
|
||||
|
@ -88,7 +88,7 @@ footprint. It's used by the <a href="ext_ffi_api.html">ffi.* library
|
||||
functions</a> to declare C types or external symbols.
|
||||
</p>
|
||||
<p>
|
||||
It's only purpose is to parse C declarations, as found e.g. in
|
||||
Its only purpose is to parse C declarations, as found e.g. in
|
||||
C header files. Although it does evaluate constant expressions,
|
||||
it's <em>not</em> a C compiler. The body of <tt>inline</tt>
|
||||
C function definitions is simply ignored.
|
||||
@ -165,7 +165,7 @@ function declarations.</li>
|
||||
|
||||
</ul>
|
||||
<p>
|
||||
The following C types are pre-defined by the C parser (like
|
||||
The following C types are predefined by the C parser (like
|
||||
a <tt>typedef</tt>, except re-declarations will be ignored):
|
||||
</p>
|
||||
<ul>
|
||||
@ -583,9 +583,9 @@ ffi.new("struct nested", {x=1,y={2,3}}) --> x = 1, y.a = 2, y.b = 3
|
||||
|
||||
<h2 id="cdata_ops">Operations on cdata Objects</h2>
|
||||
<p>
|
||||
All of the standard Lua operators can be applied to cdata objects or a
|
||||
All standard Lua operators can be applied to cdata objects or a
|
||||
mix of a cdata object and another Lua object. The following list shows
|
||||
the pre-defined operations.
|
||||
the predefined operations.
|
||||
</p>
|
||||
<p>
|
||||
Reference types are dereferenced <em>before</em> performing each of
|
||||
@ -593,7 +593,7 @@ the operations below — the operation is applied to the
|
||||
C type pointed to by the reference.
|
||||
</p>
|
||||
<p>
|
||||
The pre-defined operations are always tried first before deferring to a
|
||||
The predefined operations are always tried first before deferring to a
|
||||
metamethod or index table (if any) for the corresponding ctype (except
|
||||
for <tt>__new</tt>). An error is raised if the metamethod lookup or
|
||||
index table lookup fails.
|
||||
@ -643,7 +643,7 @@ assigning to an index of a vector raises an error.</li>
|
||||
</ul>
|
||||
<p>
|
||||
A ctype object can be indexed with a string key, too. The only
|
||||
pre-defined operation is reading scoped constants of
|
||||
predefined operation is reading scoped constants of
|
||||
<tt>struct</tt>/<tt>union</tt> types. All other accesses defer
|
||||
to the corresponding metamethods or index tables (if any).
|
||||
</p>
|
||||
@ -656,7 +656,7 @@ certain optimizations.
|
||||
<p>
|
||||
As a consequence, the <em>elements</em> of complex numbers and
|
||||
vectors are immutable. But the elements of an aggregate holding these
|
||||
types <em>may</em> be modified of course. I.e. you cannot assign to
|
||||
types <em>may</em> be modified, of course. I.e. you cannot assign to
|
||||
<tt>foo.c.im</tt>, but you can assign a (newly created) complex number
|
||||
to <tt>foo.c</tt>.
|
||||
</p>
|
||||
@ -675,8 +675,8 @@ through unions is explicitly detected and allowed.
|
||||
to <tt>ffi.new(ct, ...)</tt>, unless a <tt>__new</tt> metamethod is
|
||||
defined. The <tt>__new</tt> metamethod is called with the ctype object
|
||||
plus any other arguments passed to the constructor. Note that you have to
|
||||
use <tt>ffi.new</tt> inside of it, since calling <tt>ct(...)</tt> would
|
||||
cause infinite recursion.</li>
|
||||
use <tt>ffi.new</tt> inside the metamethod, since calling <tt>ct(...)</tt>
|
||||
would cause infinite recursion.</li>
|
||||
|
||||
<li><b>C function call</b>: a cdata function or cdata function
|
||||
pointer can be called. The passed arguments are
|
||||
@ -687,7 +687,7 @@ variable argument part of vararg C function use
|
||||
C function is called and the return value (if any) is
|
||||
<a href="#convert_tolua">converted to a Lua object</a>.<br>
|
||||
On Windows/x86 systems, <tt>__stdcall</tt> functions are automatically
|
||||
detected and a function declared as <tt>__cdecl</tt> (the default) is
|
||||
detected, and a function declared as <tt>__cdecl</tt> (the default) is
|
||||
silently fixed up after the first call.</li>
|
||||
|
||||
</ul>
|
||||
@ -697,7 +697,7 @@ silently fixed up after the first call.</li>
|
||||
|
||||
<li><b>Pointer arithmetic</b>: a cdata pointer/array and a cdata
|
||||
number or a Lua number can be added or subtracted. The number must be
|
||||
on the right hand side for a subtraction. The result is a pointer of
|
||||
on the right-hand side for a subtraction. The result is a pointer of
|
||||
the same type with an address plus or minus the number value
|
||||
multiplied by the element size in bytes. An error is raised if the
|
||||
element size is undefined.</li>
|
||||
@ -712,7 +712,7 @@ operators (<tt>+ - * / % ^</tt> and unary
|
||||
minus) can be applied to two cdata numbers, or a cdata number and a
|
||||
Lua number. If one of them is an <tt>uint64_t</tt>, the other side is
|
||||
converted to an <tt>uint64_t</tt> and an unsigned arithmetic operation
|
||||
is performed. Otherwise both sides are converted to an
|
||||
is performed. Otherwise, both sides are converted to an
|
||||
<tt>int64_t</tt> and a signed arithmetic operation is performed. The
|
||||
result is a boxed 64 bit cdata object.<br>
|
||||
|
||||
@ -759,7 +759,7 @@ which is compatible with any other pointer type.</li>
|
||||
<li><b>64 bit integer comparison</b>: two cdata numbers, or a
|
||||
cdata number and a Lua number can be compared with each other. If one
|
||||
of them is an <tt>uint64_t</tt>, the other side is converted to an
|
||||
<tt>uint64_t</tt> and an unsigned comparison is performed. Otherwise
|
||||
<tt>uint64_t</tt> and an unsigned comparison is performed. Otherwise,
|
||||
both sides are converted to an <tt>int64_t</tt> and a signed
|
||||
comparison is performed.<br>
|
||||
|
||||
@ -784,9 +784,9 @@ keys!</b>
|
||||
A cdata object is treated like any other garbage-collected object and
|
||||
is hashed and compared by its address for table indexing. Since
|
||||
there's no interning for cdata value types, the same value may be
|
||||
boxed in different cdata objects with different addresses. Thus
|
||||
boxed in different cdata objects with different addresses. Thus,
|
||||
<tt>t[1LL+1LL]</tt> and <tt>t[2LL]</tt> usually <b>do not</b> point to
|
||||
the same hash slot and they certainly <b>do not</b> point to the same
|
||||
the same hash slot, and they certainly <b>do not</b> point to the same
|
||||
hash slot as <tt>t[2]</tt>.
|
||||
</p>
|
||||
<p>
|
||||
@ -808,7 +808,7 @@ the resulting Lua number as a key when indexing tables.<br>
|
||||
One obvious benefit: <tt>t[tonumber(2LL)]</tt> <b>does</b> point to
|
||||
the same slot as <tt>t[2]</tt>.</li>
|
||||
|
||||
<li>Otherwise use either <tt>tostring()</tt> on 64 bit integers
|
||||
<li>Otherwise, use either <tt>tostring()</tt> on 64 bit integers
|
||||
or complex numbers or combine multiple fields of a cdata aggregate to
|
||||
a Lua string (e.g. with
|
||||
<a href="ext_ffi_api.html#ffi_string"><tt>ffi.string()</tt></a>). Then
|
||||
@ -816,7 +816,7 @@ use the resulting Lua string as a key when indexing tables.</li>
|
||||
|
||||
<li>Create your own specialized hash table implementation using the
|
||||
C types provided by the FFI library, just like you would in
|
||||
C code. Ultimately this may give much better performance than the
|
||||
C code. Ultimately, this may give much better performance than the
|
||||
other alternatives or what a generic by-value hash table could
|
||||
possibly provide.</li>
|
||||
|
||||
@ -882,7 +882,7 @@ garbage collector will automatically free the memory used by it (at
|
||||
the end of the next GC cycle).
|
||||
</p>
|
||||
<p>
|
||||
Please note that pointers themselves are cdata objects, however they
|
||||
Please note, that pointers themselves are cdata objects, however they
|
||||
are <b>not</b> followed by the garbage collector. So e.g. if you
|
||||
assign a cdata array to a pointer, you must keep the cdata object
|
||||
holding the array alive as long as the pointer is still in use:
|
||||
@ -931,18 +931,18 @@ of the function pointer and the Lua function object (closure).
|
||||
</p>
|
||||
<p>
|
||||
This can happen implicitly due to the usual conversions, e.g. when
|
||||
passing a Lua function to a function pointer argument. Or you can use
|
||||
passing a Lua function to a function pointer argument. Or, you can use
|
||||
<tt>ffi.cast()</tt> to explicitly cast a Lua function to a
|
||||
C function pointer.
|
||||
</p>
|
||||
<p>
|
||||
Currently only certain C function types can be used as callback
|
||||
Currently, only certain C function types can be used as callback
|
||||
functions. Neither C vararg functions nor functions with
|
||||
pass-by-value aggregate argument or result types are supported. There
|
||||
are no restrictions for the kind of Lua functions that can be called
|
||||
are no restrictions on the kind of Lua functions that can be called
|
||||
from the callback — no checks for the proper number of arguments
|
||||
are made. The return value of the Lua function will be converted to the
|
||||
result type and an error will be thrown for invalid conversions.
|
||||
result type, and an error will be thrown for invalid conversions.
|
||||
</p>
|
||||
<p>
|
||||
It's allowed to throw errors across a callback invocation, but it's not
|
||||
@ -1003,7 +1003,7 @@ convention cannot be automatically detected, unlike for
|
||||
<tt>__stdcall</tt> calls <em>to</em> Windows functions.
|
||||
</p>
|
||||
<p>
|
||||
For some use cases it's necessary to free up the resources or to
|
||||
For some use cases, it's necessary to free up the resources or to
|
||||
dynamically redirect callbacks. Use an explicit cast to a
|
||||
C function pointer and keep the resulting cdata object. Then use
|
||||
the <a href="ext_ffi_api.html#callback_free"><tt>cb:free()</tt></a>
|
||||
@ -1056,7 +1056,7 @@ GUI application, which waits for user input most of the time, anyway.
|
||||
</p>
|
||||
<p>
|
||||
For new designs <b>avoid push-style APIs</b>: a C function repeatedly
|
||||
calling a callback for each result. Instead <b>use pull-style APIs</b>:
|
||||
calling a callback for each result. Instead, <b>use pull-style APIs</b>:
|
||||
call a C function repeatedly to get a new result. Calls from Lua
|
||||
to C via the FFI are much faster than the other way round. Most well-designed
|
||||
libraries already use pull-style APIs (read/write, get/put).
|
||||
@ -1075,7 +1075,7 @@ function.
|
||||
</p>
|
||||
<p>
|
||||
Indexing a C library namespace object with a symbol name (a Lua
|
||||
string) automatically binds it to the library. First the symbol type
|
||||
string) automatically binds it to the library. First, the symbol type
|
||||
is resolved — it must have been declared with
|
||||
<a href="ext_ffi_api.html#ffi_cdef"><tt>ffi.cdef</tt></a>. Then the
|
||||
symbol address is resolved by searching for the symbol name in the
|
||||
@ -1130,7 +1130,7 @@ Performance notice: the JIT compiler specializes to the identity of
|
||||
namespace objects and to the strings used to index it. This
|
||||
effectively turns function cdata objects into constants. It's not
|
||||
useful and actually counter-productive to explicitly cache these
|
||||
function objects, e.g. <tt>local strlen = ffi.C.strlen</tt>. OTOH it
|
||||
function objects, e.g. <tt>local strlen = ffi.C.strlen</tt>. OTOH, it
|
||||
<em>is</em> useful to cache the namespace itself, e.g. <tt>local C =
|
||||
ffi.C</tt>.
|
||||
</p>
|
||||
@ -1155,14 +1155,14 @@ This behavior is inevitable, since the goal is to provide full
|
||||
interoperability with C code. Adding extra safety measures, like
|
||||
bounds checks, would be futile. There's no way to detect
|
||||
misdeclarations of C functions, since shared libraries only
|
||||
provide symbol names, but no type information. Likewise there's no way
|
||||
provide symbol names, but no type information. Likewise, there's no way
|
||||
to infer the valid range of indexes for a returned pointer.
|
||||
</p>
|
||||
<p>
|
||||
Again: the FFI library is a low-level library. This implies it needs
|
||||
to be used with care, but it's flexibility and performance often
|
||||
outweigh this concern. If you're a C or C++ developer, it'll be easy
|
||||
to apply your existing knowledge. OTOH writing code for the FFI
|
||||
to apply your existing knowledge. OTOH, writing code for the FFI
|
||||
library is not for the faint of heart and probably shouldn't be the
|
||||
first exercise for someone with little experience in Lua, C or C++.
|
||||
</p>
|
||||
@ -1190,7 +1190,7 @@ currently incomplete:
|
||||
<li>C declarations are not passed through a C pre-processor,
|
||||
yet.</li>
|
||||
<li>The C parser is able to evaluate most constant expressions
|
||||
commonly found in C header files. However it doesn't handle the
|
||||
commonly found in C header files. However, it doesn't handle the
|
||||
full range of C expression semantics and may fail for some
|
||||
obscure constructs.</li>
|
||||
<li><tt>static const</tt> declarations only work for integer types
|
||||
|
@ -85,7 +85,7 @@ of its functions:
|
||||
local ffi = require("ffi")
|
||||
</pre>
|
||||
<p>
|
||||
Please note this doesn't define an <tt>ffi</tt> variable in the table
|
||||
Please note, this doesn't define an <tt>ffi</tt> variable in the table
|
||||
of globals — you really need to use the local variable. The
|
||||
<tt>require</tt> function ensures the library is only loaded once.
|
||||
</p>
|
||||
@ -194,7 +194,7 @@ don't need to declare them as such.
|
||||
<span class="mark">⑤</span> The <tt>poll()</tt>
|
||||
function takes a couple more arguments we're not going to use. You can
|
||||
simply use <tt>nil</tt> to pass a <tt>NULL</tt> pointer and <tt>0</tt>
|
||||
for the <tt>nfds</tt> parameter. Please note that the
|
||||
for the <tt>nfds</tt> parameter. Please note, that the
|
||||
number <tt>0</tt> <em>does not convert to a pointer value</em>,
|
||||
unlike in C++. You really have to pass pointers to pointer arguments
|
||||
and numbers to number arguments.
|
||||
@ -291,12 +291,12 @@ Here's the step-by-step explanation:
|
||||
<p>
|
||||
<span class="mark">①</span> This defines some of the
|
||||
C functions provided by zlib. For the sake of this example, some
|
||||
type indirections have been reduced and it uses the pre-defined
|
||||
type indirections have been reduced and it uses the predefined
|
||||
fixed-size integer types, while still adhering to the zlib API/ABI.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">②</span> This loads the zlib shared
|
||||
library. On POSIX systems it's named <tt>libz.so</tt> and usually
|
||||
library. On POSIX systems, it's named <tt>libz.so</tt> and usually
|
||||
comes pre-installed. Since <tt>ffi.load()</tt> automatically adds any
|
||||
missing standard prefixes/suffixes, we can simply load the
|
||||
<tt>"z"</tt> library. On Windows it's named <tt>zlib1.dll</tt> and
|
||||
@ -324,7 +324,7 @@ actual length that was used.
|
||||
<p>
|
||||
In C you'd pass in the address of a local variable
|
||||
(<tt>&buflen</tt>). But since there's no address-of operator in
|
||||
Lua, we'll just pass in a one-element array. Conveniently it can be
|
||||
Lua, we'll just pass in a one-element array. Conveniently, it can be
|
||||
initialized with the maximum buffer size in one step. Calling the
|
||||
actual <tt>zlib.compress2</tt> function is then straightforward.
|
||||
</p>
|
||||
@ -348,7 +348,7 @@ for garbage collection and string interning.
|
||||
<span class="mark">⑥</span> The <tt>uncompress</tt>
|
||||
functions does the exact opposite of the <tt>compress</tt> function.
|
||||
The compressed data doesn't include the size of the original string,
|
||||
so this needs to be passed in. Otherwise no surprises here.
|
||||
so this needs to be passed in. Otherwise, no surprises here.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">⑦</span> The code, that makes use
|
||||
@ -382,7 +382,7 @@ Ok, so the <tt>ffi.*</tt> functions generally accept cdata objects
|
||||
wherever you'd want to use a number. That's why we get a away with
|
||||
passing <tt>n</tt> to <tt>ffi.string()</tt> above. But other Lua
|
||||
library functions or modules don't know how to deal with this. So for
|
||||
maximum portability one needs to use <tt>tonumber()</tt> on returned
|
||||
maximum portability, one needs to use <tt>tonumber()</tt> on returned
|
||||
<tt>long</tt> results before passing them on. Otherwise the
|
||||
application might work on some systems, but would fail in a POSIX/x64
|
||||
environment.
|
||||
@ -454,7 +454,7 @@ the origin.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">④</span> If we run out of operators, we can
|
||||
define named methods, too. Here the <tt>__index</tt> table defines an
|
||||
define named methods, too. Here, the <tt>__index</tt> table defines an
|
||||
<tt>area</tt> function. For custom indexing needs, one might want to
|
||||
define <tt>__index</tt> and <tt>__newindex</tt> <em>functions</em> instead.
|
||||
</p>
|
||||
@ -468,13 +468,13 @@ be used e.g. to create an array of points. The metamethods automatically
|
||||
apply to any and all uses of this type.
|
||||
</p>
|
||||
<p>
|
||||
Please note that the association with a metatable is permanent and
|
||||
Please note, that the association with a metatable is permanent and
|
||||
<b>the metatable must not be modified afterwards!</b> Ditto for the
|
||||
<tt>__index</tt> table.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">⑥</span> Here are some simple usage examples
|
||||
for the point type and their expected results. The pre-defined
|
||||
for the point type and their expected results. The predefined
|
||||
operations (such as <tt>a.x</tt>) can be freely mixed with the newly
|
||||
defined metamethods. Note that <tt>area</tt> is a method and must be
|
||||
called with the Lua syntax for methods: <tt>a:area()</tt>, not
|
||||
@ -483,7 +483,7 @@ called with the Lua syntax for methods: <tt>a:area()</tt>, not
|
||||
<p>
|
||||
The C type metamethod mechanism is most useful when used in
|
||||
conjunction with C libraries that are written in an object-oriented
|
||||
style. Creators return a pointer to a new instance and methods take an
|
||||
style. Creators return a pointer to a new instance, and methods take an
|
||||
instance pointer as the first argument. Sometimes you can just point
|
||||
<tt>__index</tt> to the library namespace and <tt>__gc</tt> to the
|
||||
destructor and you're done. But often enough you'll want to add
|
||||
@ -569,7 +569,7 @@ end
|
||||
</pre>
|
||||
<p>
|
||||
This turns them into indirect calls and generates bigger and slower
|
||||
machine code. Instead you'll want to cache the namespace itself and
|
||||
machine code. Instead, you'll want to cache the namespace itself and
|
||||
rely on the JIT compiler to eliminate the lookups:
|
||||
</p>
|
||||
<pre class="code">
|
||||
|
@ -154,7 +154,7 @@ Contains the target architecture name:
|
||||
|
||||
<h2 id="jit_opt"><tt>jit.opt.*</tt> — JIT compiler optimization control</h2>
|
||||
<p>
|
||||
This sub-module provides the backend for the <tt>-O</tt> command line
|
||||
This submodule provides the backend for the <tt>-O</tt> command line
|
||||
option.
|
||||
</p>
|
||||
<p>
|
||||
@ -174,7 +174,7 @@ which was one of the ways to enable optimization.
|
||||
|
||||
<h2 id="jit_util"><tt>jit.util.*</tt> — JIT compiler introspection</h2>
|
||||
<p>
|
||||
This sub-module holds functions to introspect the bytecode, generated
|
||||
This submodule holds functions to introspect the bytecode, generated
|
||||
traces, the IR and the generated machine code. The functionality
|
||||
provided by this module is still in flux and therefore undocumented.
|
||||
</p>
|
||||
|
@ -158,7 +158,7 @@ To see how much time is spent in different VM states or
|
||||
Combinations of <tt>v/z</tt> with <tt>f/F/l</tt> produce two-level
|
||||
views, e.g. <tt>-jp=vf</tt> or <tt>-jp=fv</tt>. This shows the time
|
||||
spent in a VM state or zone vs. hotspots. This can be used to answer
|
||||
questions like "Which time consuming functions are only interpreted?" or
|
||||
questions like "Which time-consuming functions are only interpreted?" or
|
||||
"What's the garbage collector overhead for a specific function?".
|
||||
</p>
|
||||
<p>
|
||||
@ -217,7 +217,7 @@ local profile = require("jit.profile")
|
||||
This module can be used to implement your own higher-level profiler.
|
||||
A typical profiling run starts the profiler, captures stack dumps in
|
||||
the profiler callback, adds them to a hash table to aggregate the number
|
||||
of samples, stops the profiler and then analyzes all of the captured
|
||||
of samples, stops the profiler and then analyzes all captured
|
||||
stack dumps. Other parameters can be sampled in the profiler callback,
|
||||
too. But it's important not to spend too much time in the callback,
|
||||
since this may skew the statistics.
|
||||
@ -271,9 +271,9 @@ returns a string with a stack dump for the <tt>thread</tt> (coroutine),
|
||||
formatted according to the <tt>fmt</tt> argument:
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>p</tt> — Preserve the full path for module names. Otherwise
|
||||
<li><tt>p</tt> — Preserve the full path for module names. Otherwise,
|
||||
only the file name is used.</li>
|
||||
<li><tt>f</tt> — Dump the function name if it can be derived. Otherwise
|
||||
<li><tt>f</tt> — Dump the function name if it can be derived. Otherwise,
|
||||
use module:line.</li>
|
||||
<li><tt>F</tt> — Ditto, but dump module:name.</li>
|
||||
<li><tt>l</tt> — Dump module:line.</li>
|
||||
|
@ -88,7 +88,7 @@ or LuaJIT.
|
||||
</p>
|
||||
<p>
|
||||
LuaJIT extends the standard Lua VM with new functionality and adds
|
||||
several extension modules. Please note this page is only about
|
||||
several extension modules. Please note, this page is only about
|
||||
<em>functional</em> enhancements and not about performance enhancements,
|
||||
such as the optimized VM, the faster interpreter or the JIT compiler.
|
||||
</p>
|
||||
@ -197,7 +197,7 @@ usage. See also the
|
||||
</p>
|
||||
<p>
|
||||
The generated bytecode is portable and can be loaded on any architecture
|
||||
that LuaJIT supports, independent of word size or endianess. However the
|
||||
that LuaJIT supports, independent of word size or endianess. However, the
|
||||
bytecode compatibility versions must match. Bytecode stays compatible
|
||||
for dot releases (x.y.0 → x.y.1), but may change with major or
|
||||
minor releases (2.0 → 2.1) or between any beta release. Foreign
|
||||
@ -229,7 +229,7 @@ avoids managing backlinks, saves an allocation and the overhead of
|
||||
incremental array/hash part growth.
|
||||
</p>
|
||||
<p>
|
||||
Please note this function is meant for very specific situations. In most
|
||||
Please note, this function is meant for very specific situations. In most
|
||||
cases it's better to replace the (usually single) link with a new table
|
||||
and let the GC do its work.
|
||||
</p>
|
||||
@ -239,7 +239,7 @@ and let the GC do its work.
|
||||
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
|
||||
<tt>math.random()</tt> and <tt>math.randomseed()</tt>. The quality of
|
||||
the PRNG results is much superior compared to the standard Lua
|
||||
implementation which uses the platform-specific ANSI rand().
|
||||
implementation, which uses the platform-specific ANSI rand().
|
||||
</p>
|
||||
<p>
|
||||
The PRNG generates the same sequences from the same seeds on all
|
||||
@ -257,7 +257,7 @@ Important: Neither this nor any other PRNG based on the simplistic
|
||||
<h3 id="io"><tt>io.*</tt> functions handle 64 bit file offsets</h3>
|
||||
<p>
|
||||
The file I/O functions in the standard <tt>io.*</tt> library handle
|
||||
64 bit file offsets. In particular this means it's possible
|
||||
64 bit file offsets. In particular, this means it's possible
|
||||
to open files larger than 2 Gigabytes and to reposition or obtain
|
||||
the current file position for offsets beyond 2 GB
|
||||
(<tt>fp:seek()</tt> method).
|
||||
|
@ -120,7 +120,7 @@ Direct3D version 10 or higher do not show this behavior anymore.
|
||||
Consider testing your application with older versions, too.<br>
|
||||
|
||||
Similarly, the Borland/Delphi runtime modifies the FPU control word and
|
||||
enables FP exceptions. Of course this violates the Windows ABI, too.
|
||||
enables FP exceptions. Of course, this violates the Windows ABI, too.
|
||||
Please check the Delphi docs for the Set8087CW method.</dd>
|
||||
</dl>
|
||||
|
||||
@ -130,7 +130,7 @@ Please check the Delphi docs for the Set8087CW method.</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
|
||||
You have to press Ctrl-C twice to stop your program. That's similar
|
||||
to when it's stuck running inside a C function under the Lua interpreter.</dd>
|
||||
</dl>
|
||||
|
||||
@ -150,7 +150,7 @@ so it doesn't rely on the key order. Or sort the table keys, if you must.</dd>
|
||||
<dl id="sandbox">
|
||||
<dt>Q: Can Lua code be safely sandboxed?</dt>
|
||||
<dd>
|
||||
Maybe for an extremly restricted subset of Lua and if you relentlessly
|
||||
Maybe for an extremely restricted subset of Lua and if you relentlessly
|
||||
scrutinize every single interface function you offer to the untrusted code.<br>
|
||||
|
||||
Although Lua provides some sandboxing functionality (<tt>setfenv()</tt>, hooks),
|
||||
|
@ -328,7 +328,7 @@ 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).
|
||||
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):
|
||||
@ -697,7 +697,7 @@ allocator from your system (no support for this on 64 bit architectures).</
|
||||
of calling <tt>luaopen_base</tt> etc. directly.</li>
|
||||
<li>To change or extend the list of standard libraries to load, copy
|
||||
<tt>src/lib_init.c</tt> to your project and modify it accordingly.
|
||||
Make sure the <tt>jit</tt> library is loaded or the JIT compiler
|
||||
Make sure the <tt>jit</tt> library is loaded, or the JIT compiler
|
||||
will not be activated.</li>
|
||||
<li>The <tt>bit.*</tt> module for bitwise operations
|
||||
is already built-in. There's no need to statically link
|
||||
@ -716,7 +716,7 @@ in unspeakable ways.
|
||||
There should be absolutely no need to patch <tt>luaconf.h</tt> or any
|
||||
of the Makefiles. And please do not hand-pick files for your packages —
|
||||
simply use whatever <tt>make install</tt> creates. There's a reason
|
||||
for all of the files <em>and</em> directories it creates.
|
||||
for all the files <em>and</em> directories it creates.
|
||||
</p>
|
||||
<p>
|
||||
The build system uses GNU make and auto-detects most settings based on
|
||||
|
@ -111,6 +111,7 @@ are accepted:
|
||||
<li><tt>-t type</tt> — Set output file type (default: auto-detect from output name).</li>
|
||||
<li><tt>-a arch</tt> — Override architecture for object files (default: native).</li>
|
||||
<li><tt>-o os</tt> — Override OS for object files (default: native).</li>
|
||||
<li><tt>-F name</tt> — Override filename (default: input filename).</li>
|
||||
<li><tt>-e chunk</tt> — Use chunk string as input.</li>
|
||||
<li><tt>-</tt> (a single minus sign) — Use stdin as input and/or stdout as output.</li>
|
||||
</ul>
|
||||
@ -184,7 +185,7 @@ written in Lua. They are mainly used for debugging the JIT compiler
|
||||
itself. For a description of their options and output format, please
|
||||
read the comment block at the start of their source.
|
||||
They can be found in the <tt>lib</tt> directory of the source
|
||||
distribution or installed under the <tt>jit</tt> directory. By default
|
||||
distribution or installed under the <tt>jit</tt> directory. By default,
|
||||
this is <tt>/usr/local/share/luajit-XX.YY.ZZ>/jit</tt> on POSIX
|
||||
systems (replace XX.YY.ZZ by the installed version).
|
||||
</p>
|
||||
@ -216,7 +217,7 @@ to a specific value.
|
||||
You can either use this option multiple times (like <tt>-Ocse
|
||||
-O-dce -Ohotloop=10</tt>) or separate several settings with a comma
|
||||
(like <tt>-O+cse,-dce,hotloop=10</tt>). The settings are applied from
|
||||
left to right and later settings override earlier ones. You can freely
|
||||
left to right, and later settings override earlier ones. You can freely
|
||||
mix the three forms, but note that setting an optimization level
|
||||
overrides all earlier flags.
|
||||
</p>
|
||||
|
@ -83,7 +83,7 @@ Known incompatibilities and issues in LuaJIT 2.0:
|
||||
<ul>
|
||||
<li>
|
||||
There are some differences in <b>implementation-defined</b> behavior.
|
||||
These either have a good reason, are arbitrary design choices
|
||||
These either have a good reason, are arbitrary design choices,
|
||||
or are due to quirks in the VM. The latter cases may get fixed if a
|
||||
demonstrable need is shown.
|
||||
</li>
|
||||
|
@ -34,6 +34,7 @@ Save LuaJIT bytecode: luajit -b[options] input output
|
||||
-t type Set output file type (default: auto-detect from output name).
|
||||
-a arch Override architecture for object files (default: native).
|
||||
-o os Override OS for object files (default: native).
|
||||
-F name Override filename (default: input filename).
|
||||
-e chunk Use chunk string as input.
|
||||
-- Stop handling options.
|
||||
- Use stdin as input and/or stdout as output.
|
||||
@ -50,10 +51,22 @@ local function check(ok, ...)
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
local function readfile(input)
|
||||
local function readfile(ctx, input)
|
||||
if type(input) == "function" then return input end
|
||||
if input == "-" then input = nil end
|
||||
return check(loadfile(input))
|
||||
if ctx.filename then
|
||||
local data
|
||||
if input == "-" then
|
||||
data = io.stdin:read("*a")
|
||||
else
|
||||
local fp = assert(io.open(input, "rb"))
|
||||
data = assert(fp:read("*a"))
|
||||
assert(fp:close())
|
||||
end
|
||||
return check(load(data, ctx.filename))
|
||||
else
|
||||
if input == "-" then input = nil end
|
||||
return check(loadfile(input))
|
||||
end
|
||||
end
|
||||
|
||||
local function savefile(name, mode)
|
||||
@ -457,18 +470,18 @@ typedef struct {
|
||||
uint32_t value;
|
||||
} mach_nlist;
|
||||
typedef struct {
|
||||
uint32_t strx;
|
||||
int32_t strx;
|
||||
uint8_t type, sect;
|
||||
uint16_t desc;
|
||||
uint64_t value;
|
||||
} mach_nlist_64;
|
||||
typedef struct
|
||||
{
|
||||
uint32_t magic, nfat_arch;
|
||||
int32_t magic, nfat_arch;
|
||||
} mach_fat_header;
|
||||
typedef struct
|
||||
{
|
||||
uint32_t cputype, cpusubtype, offset, size, align;
|
||||
int32_t cputype, cpusubtype, offset, size, align;
|
||||
} mach_fat_arch;
|
||||
typedef struct {
|
||||
struct {
|
||||
@ -502,6 +515,18 @@ typedef struct {
|
||||
mach_nlist sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj;
|
||||
typedef struct {
|
||||
mach_fat_header fat;
|
||||
mach_fat_arch fat_arch[2];
|
||||
struct {
|
||||
mach_header_64 hdr;
|
||||
mach_segment_command_64 seg;
|
||||
mach_section_64 sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[2];
|
||||
mach_nlist_64 sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj_64;
|
||||
]]
|
||||
local symname = '_'..LJBC_PREFIX..ctx.modname
|
||||
local isfat, is64, align, mobj = false, false, 4, "mach_obj"
|
||||
@ -510,7 +535,7 @@ typedef struct {
|
||||
elseif ctx.arch == "arm" then
|
||||
isfat, mobj = true, "mach_fat_obj"
|
||||
elseif ctx.arch == "arm64" then
|
||||
is64, align, isfat, mobj = true, 8, true, "mach_fat_obj"
|
||||
is64, align, isfat, mobj = true, 8, true, "mach_fat_obj_64"
|
||||
else
|
||||
check(ctx.arch == "x86", "unsupported architecture for OSX")
|
||||
end
|
||||
@ -599,7 +624,7 @@ local function bclist(input, output, lineinfo)
|
||||
end
|
||||
|
||||
local function bcsave(ctx, input, output)
|
||||
local f = readfile(input)
|
||||
local f = readfile(ctx, input)
|
||||
local s = string.dump(f, ctx.strip)
|
||||
local t = ctx.type
|
||||
if not t then
|
||||
@ -656,6 +681,8 @@ local function docmd(...)
|
||||
ctx.arch = checkarg(tremove(arg, n), map_arch, "architecture")
|
||||
elseif opt == "o" then
|
||||
ctx.os = checkarg(tremove(arg, n), map_os, "OS name")
|
||||
elseif opt == "F" then
|
||||
ctx.filename = "@"..tremove(arg, n)
|
||||
else
|
||||
usage()
|
||||
end
|
||||
|
@ -323,6 +323,7 @@ LJLIB_CF(buffer_new)
|
||||
setgcref(sbx->dict_str, obj2gco(dict_str));
|
||||
setgcref(sbx->dict_mt, obj2gco(dict_mt));
|
||||
if (sz > 0) lj_buf_need2((SBuf *)sbx, sz);
|
||||
lj_gc_check(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -339,6 +340,7 @@ LJLIB_CF(buffer_decode) LJLIB_REC(.)
|
||||
GCstr *str = lj_lib_checkstrx(L, 1);
|
||||
setnilV(L->top++);
|
||||
lj_serialize_decode(L, L->top-1, str);
|
||||
lj_gc_check(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -639,7 +639,7 @@ LJLIB_CF(ffi_alignof) LJLIB_REC(ffi_xof FF_ffi_alignof)
|
||||
CTState *cts = ctype_cts(L);
|
||||
CTypeID id = ffi_checkctype(L, cts, NULL);
|
||||
CTSize sz = 0;
|
||||
CTInfo info = lj_ctype_info(cts, id, &sz);
|
||||
CTInfo info = lj_ctype_info_raw(cts, id, &sz);
|
||||
setintV(L->top-1, 1 << ctype_align(info));
|
||||
return 1;
|
||||
}
|
||||
@ -770,7 +770,7 @@ LJLIB_CF(ffi_metatype)
|
||||
CTypeID id = ffi_checkctype(L, cts, NULL);
|
||||
GCtab *mt = lj_lib_checktab(L, 2);
|
||||
GCtab *t = cts->miscmap;
|
||||
CType *ct = ctype_get(cts, id); /* Only allow raw types. */
|
||||
CType *ct = ctype_raw(cts, id);
|
||||
TValue *tv;
|
||||
GCcdata *cd;
|
||||
if (!(ctype_isstruct(ct->info) || ctype_iscomplex(ct->info) ||
|
||||
|
@ -57,7 +57,7 @@ static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
|
||||
|
||||
static const char *ll_bcsym(void *lib, const char *sym)
|
||||
{
|
||||
#if defined(RTLD_DEFAULT)
|
||||
#if defined(RTLD_DEFAULT) && !defined(NO_RTLD_DEFAULT)
|
||||
if (lib == NULL) lib = RTLD_DEFAULT;
|
||||
#elif LJ_TARGET_OSX || LJ_TARGET_BSD
|
||||
if (lib == NULL) lib = (void *)(intptr_t)-2;
|
||||
|
@ -779,7 +779,7 @@ LUA_API void lua_concat(lua_State *L, int n)
|
||||
L->top -= n;
|
||||
break;
|
||||
}
|
||||
n -= (int)(L->top - top);
|
||||
n -= (int)(L->top - (top - 2*LJ_FR2));
|
||||
L->top = top+2;
|
||||
lj_vm_call(L, top, 1+1);
|
||||
L->top -= 1+LJ_FR2;
|
||||
|
@ -485,7 +485,8 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
|
||||
asm_fusexref(as, ir->op1, xallow);
|
||||
return RID_MRM;
|
||||
}
|
||||
} else if (ir->o == IR_VLOAD && !(LJ_GC64 && irt_isaddr(ir->t))) {
|
||||
} else if (ir->o == IR_VLOAD && IR(ir->op1)->o == IR_AREF &&
|
||||
!(LJ_GC64 && irt_isaddr(ir->t))) {
|
||||
asm_fuseahuref(as, ir->op1, xallow);
|
||||
as->mrm.ofs += 8 * ir->op2;
|
||||
return RID_MRM;
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(RTLD_DEFAULT)
|
||||
#if defined(RTLD_DEFAULT) && !defined(NO_RTLD_DEFAULT)
|
||||
#define CLIB_DEFHANDLE RTLD_DEFAULT
|
||||
#elif LJ_TARGET_OSX || LJ_TARGET_BSD
|
||||
#define CLIB_DEFHANDLE ((void *)(intptr_t)-2)
|
||||
|
@ -468,7 +468,7 @@ static void cp_expr_sizeof(CPState *cp, CPValue *k, int wantsz)
|
||||
} else {
|
||||
cp_expr_unary(cp, k);
|
||||
}
|
||||
info = lj_ctype_info(cp->cts, k->id, &sz);
|
||||
info = lj_ctype_info_raw(cp->cts, k->id, &sz);
|
||||
if (wantsz) {
|
||||
if (sz != CTSIZE_INVALID)
|
||||
k->u32 = sz;
|
||||
|
@ -333,6 +333,14 @@ CTInfo lj_ctype_info(CTState *cts, CTypeID id, CTSize *szp)
|
||||
return qual;
|
||||
}
|
||||
|
||||
/* Ditto, but follow a reference. */
|
||||
CTInfo lj_ctype_info_raw(CTState *cts, CTypeID id, CTSize *szp)
|
||||
{
|
||||
CType *ct = ctype_get(cts, id);
|
||||
if (ctype_isref(ct->info)) id = ctype_cid(ct->info);
|
||||
return lj_ctype_info(cts, id, szp);
|
||||
}
|
||||
|
||||
/* Get ctype metamethod. */
|
||||
cTValue *lj_ctype_meta(CTState *cts, CTypeID id, MMS mm)
|
||||
{
|
||||
|
@ -468,6 +468,7 @@ LJ_FUNC CType *lj_ctype_rawref(CTState *cts, CTypeID id);
|
||||
LJ_FUNC CTSize lj_ctype_size(CTState *cts, CTypeID id);
|
||||
LJ_FUNC CTSize lj_ctype_vlsize(CTState *cts, CType *ct, CTSize nelem);
|
||||
LJ_FUNC CTInfo lj_ctype_info(CTState *cts, CTypeID id, CTSize *szp);
|
||||
LJ_FUNC CTInfo lj_ctype_info_raw(CTState *cts, CTypeID id, CTSize *szp);
|
||||
LJ_FUNC cTValue *lj_ctype_meta(CTState *cts, CTypeID id, MMS mm);
|
||||
LJ_FUNC GCstr *lj_ctype_repr(lua_State *L, CTypeID id, GCstr *name);
|
||||
LJ_FUNC GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned);
|
||||
|
@ -700,9 +700,12 @@ static size_t gc_onestep(lua_State *L)
|
||||
}
|
||||
case GCSfinalize:
|
||||
if (gcref(g->gc.mmudata) != NULL) {
|
||||
GCSize old = g->gc.total;
|
||||
if (tvref(g->jit_base)) /* Don't call finalizers on trace. */
|
||||
return LJ_MAX_MEM;
|
||||
gc_finalize(L); /* Finalize one userdata object. */
|
||||
if (old >= g->gc.total && g->gc.estimate > old - g->gc.total)
|
||||
g->gc.estimate -= old - g->gc.total;
|
||||
if (g->gc.estimate > GCFINALIZECOST)
|
||||
g->gc.estimate -= GCFINALIZECOST;
|
||||
return GCFINALIZECOST;
|
||||
|
@ -1956,7 +1956,7 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults)
|
||||
emitir(IRTGI(IR_EQ), fr,
|
||||
lj_ir_kint(J, (int32_t)frame_ftsz(J->L->base-1)));
|
||||
vbase = emitir(IRT(IR_SUB, IRT_IGC), REF_BASE, fr);
|
||||
vbase = emitir(IRT(IR_ADD, IRT_PGC), vbase, lj_ir_kint(J, frofs-8));
|
||||
vbase = emitir(IRT(IR_ADD, IRT_PGC), vbase, lj_ir_kint(J, frofs-8*(1+LJ_FR2)));
|
||||
for (i = 0; i < nload; i++) {
|
||||
IRType t = itype2irt(&J->L->base[i-1-LJ_FR2-nvararg]);
|
||||
J->base[dst+i] = lj_record_vload(J, vbase, i, t);
|
||||
@ -2660,6 +2660,8 @@ static const BCIns *rec_setup_root(jit_State *J)
|
||||
J->bc_min = pc;
|
||||
break;
|
||||
case BC_ITERL:
|
||||
if (bc_op(pc[-1]) == BC_JLOOP)
|
||||
lj_trace_err(J, LJ_TRERR_LINNER);
|
||||
lj_assertJ(bc_op(pc[-1]) == BC_ITERC, "no ITERC before ITERL");
|
||||
J->maxslot = ra + bc_b(pc[-1]) - 1;
|
||||
J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
|
||||
|
@ -3988,6 +3988,7 @@ static void emit_asm_debug(BuildCtx *ctx)
|
||||
"\t.align 3\n"
|
||||
".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
|
||||
#endif
|
||||
#if !LJ_NO_UNWIND
|
||||
fprintf(ctx->fp, "\t.section .eh_frame,\"a\",%%progbits\n");
|
||||
fprintf(ctx->fp,
|
||||
".Lframe1:\n"
|
||||
@ -4055,6 +4056,7 @@ static void emit_asm_debug(BuildCtx *ctx)
|
||||
"\t.byte 0x94\n\t.uleb128 4\n" /* offset x20 */
|
||||
"\t.align 3\n"
|
||||
".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
#if !LJ_NO_UNWIND
|
||||
|
@ -359,9 +359,6 @@
|
||||
|.macro sseconst_1, reg, tmp // Synthesize 1.0.
|
||||
| sseconst_hi reg, tmp, 3ff00000
|
||||
|.endmacro
|
||||
|.macro sseconst_m1, reg, tmp // Synthesize -1.0.
|
||||
| sseconst_hi reg, tmp, bff00000
|
||||
|.endmacro
|
||||
|.macro sseconst_2p52, reg, tmp // Synthesize 2^52.
|
||||
| sseconst_hi reg, tmp, 43300000
|
||||
|.endmacro
|
||||
@ -2543,15 +2540,17 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| addsd xmm1, xmm3 // (|x| + 2^52) - 2^52
|
||||
| subsd xmm1, xmm3
|
||||
| orpd xmm1, xmm2 // Merge sign bit back in.
|
||||
| sseconst_1 xmm3, RD
|
||||
| .if mode == 1 // ceil(x)?
|
||||
| sseconst_m1 xmm2, RD // Must subtract -1 to preserve -0.
|
||||
| cmpsd xmm0, xmm1, 6 // x > result?
|
||||
| andpd xmm0, xmm3
|
||||
| addsd xmm1, xmm0 // If yes, add 1.
|
||||
| orpd xmm1, xmm2 // Merge sign bit back in (again).
|
||||
| .else // floor(x)?
|
||||
| sseconst_1 xmm2, RD
|
||||
| cmpsd xmm0, xmm1, 1 // x < result?
|
||||
| andpd xmm0, xmm3
|
||||
| subsd xmm1, xmm0 // If yes, subtract 1.
|
||||
| .endif
|
||||
| andpd xmm0, xmm2
|
||||
| subsd xmm1, xmm0 // If yes, subtract +-1.
|
||||
|.endif
|
||||
| movaps xmm0, xmm1
|
||||
|1:
|
||||
|
@ -464,9 +464,6 @@
|
||||
|.macro sseconst_1, reg, tmp // Synthesize 1.0.
|
||||
| sseconst_hi reg, tmp, 3ff00000
|
||||
|.endmacro
|
||||
|.macro sseconst_m1, reg, tmp // Synthesize -1.0.
|
||||
| sseconst_hi reg, tmp, bff00000
|
||||
|.endmacro
|
||||
|.macro sseconst_2p52, reg, tmp // Synthesize 2^52.
|
||||
| sseconst_hi reg, tmp, 43300000
|
||||
|.endmacro
|
||||
@ -3004,15 +3001,17 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| addsd xmm1, xmm3 // (|x| + 2^52) - 2^52
|
||||
| subsd xmm1, xmm3
|
||||
| orpd xmm1, xmm2 // Merge sign bit back in.
|
||||
| sseconst_1 xmm3, RDa
|
||||
| .if mode == 1 // ceil(x)?
|
||||
| sseconst_m1 xmm2, RDa // Must subtract -1 to preserve -0.
|
||||
| cmpsd xmm0, xmm1, 6 // x > result?
|
||||
| andpd xmm0, xmm3
|
||||
| addsd xmm1, xmm0 // If yes, add 1.
|
||||
| orpd xmm1, xmm2 // Merge sign bit back in (again).
|
||||
| .else // floor(x)?
|
||||
| sseconst_1 xmm2, RDa
|
||||
| cmpsd xmm0, xmm1, 1 // x < result?
|
||||
| andpd xmm0, xmm3
|
||||
| subsd xmm1, xmm0 // If yes, subtract 1.
|
||||
| .endif
|
||||
| andpd xmm0, xmm2
|
||||
| subsd xmm1, xmm0 // If yes, subtract +-1.
|
||||
|.endif
|
||||
| movaps xmm0, xmm1
|
||||
|1:
|
||||
|
Loading…
Reference in New Issue
Block a user