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.
ALU instructions like add imm %rax can be encoded in multiple ways.
- the add imm32 r64 way
- the add imm32 %rax way
- or the add imm8 r64 way.
Previousely libjit preferred the second way even if the immediate was between -128 and 127.
The third way makes the operation, even when not using the rax specific opcode, two bytes shorter.