This adds some code to "make check" to look for functions that are
documented but not declared in a public header. This found a few such
missing functions; this is also fixed in this patch.
Fixes#20
In my Emacs JIT I noticed that sometimes libjit would emit a
conditional jump to branch around an unconditional jump, like:
7ffff7fe5160: 0f 85 05 00 00 00 jne 0x7ffff7fe516b
7ffff7fe5166: e9 0e 00 00 00 jmpq 0x7ffff7fe5179
7ffff7fe516b: 41 bf 17 00 00 00 mov $0x17,%r15d
While this can be worked around by constructing the IL a bit
differently, I was curious about the difficulty of fixing this in the
libjit optimizer.
This patch notices the specific case where a conditional branch simply
jumps around an unconditional branch. In this case, the condition is
inverted and the extra jump is eliminated.
when converting byte and short values to larger values the conversion becomes
a simple copy opcode. The copy opcode however isn't included in the conversion
instrinsics array, causing an out of bounds read.
the current implementations of incoming_frame_posn and outgoing_frame_posn
tend to break addressable variables, as they simply change a values
frame_offset.
For incoming_frame_posn this is fine, as it is only used at the start
of a function.
This commit changes the implementation of outgoing_frame_posn to store
the value at the target frame offset.
this commit also makes sure that the frame offset of parameters is available
when the function is built, so they dont get assigned a different offset
when being imported.
previousely this was handeled by incoming_reg however the register allocator
doesn't allow to move registers from different reg classes.
Nesting is tested on x86-86, x86 and the interpreter.
currently nested functions can only be called using jit_insn_call. This requires
the caller to have the jit_function_t object available. The new function
jit_insn_call_nested_indirect is similar to jit_insn_call_indirect - allowing
to call a function using a jit_value_t - but it has an additional parameter for
passing a pointer to the parent frame of the callee. Using
jit_insn_get_parent_frame_pointer_of and jit_function_to_closure one can now
create both the closure and the parent frame and pass it around together as
jit values, calling them does not require the caller to know the actual
jit_function_t he is calling. This makes it possible to implement what C#
calls delegates.
when calling a nested function the function needs a pointer to the parent frame
to import values. With the new nested importing system the work of importing
values was taken away from the backends, so this commit takes away setting up
calls to nested functions from the backend. Instead this is done in
jit-rules.c (and architecture specific versions of jit-rule.c).
The previous commit intrduced a couple of bugs.
While importing values from the parent worked importing
values from a higher ancestor or calling siblings was broken.
This commit fixes these issues
The current way on how importing values from ancestors works mainly aims at
hiding how it works from the outside. The main problem was that it required
a complex implementation in each backend which only one of the backends (x86)
implemented.
This commit changes accessing nested values, making it completely frontend
based. Furthermore it allows the library users to retrieve the frame pointer
of a parent and pass it in any way they like instead of forcing them to use
jit_insn_call. This means the new way allows implementing things such as lambdas
as function pointer (closure) together with a pointer to the parent frame and
then call this lambda using jit_insn_call_indirect.