[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Libjit] Call to child through function pointer?

From: Jakob Löw
Subject: Re: [Libjit] Call to child through function pointer?
Date: Sun, 05 Aug 2018 11:30:26 +0200


in theory a nested function needs to be called a special way, as it
requires a pointer to the parent frame in order to import values. This
makes sense when thinking about calling parent functions multiple
times: Multiple parent frames exist but the child code does not know
where they are and which one they should access. This is why in all
programming languages a nested function (sometimes called lambda,
delegate) requires two pointers, the pointer to the code of the
function and the pointer to the parent's frame. 
I hope this is not too complicated, I find it hard to explain,
especially as it requires knowledge on how nested functions work in
general. Walter Bright (the creator of D) has a nice explanation
Theory aside nesting is mostly unimplemented in libjit. Afaik only the
x86 (32-bit Intel) backend implements it.
As i needed nesting for my projects myself I implemented nesting in the
frontend (so nesting does not have to be implemented for each backend).
 You can find it here[0], maybe I'll find time to merge this int libjit
master one day. It uses jit_insn_incoming_reg to retrieve the frame
pointer, passes it to child functions and uses jit_insn_load_relative
with the frame pointer and the values frame offset to import values. It
leaves passing around the frame pointer to the user (except when using
Anyways the above is just how it works internally, if you want to know
how to use it, it adds four new functions:

/* Retrieves the frame pointer of the current function */
jit_value_t jit_insn_get_frame_pointer(jit_function_t func);

/* Retrieves the frame pointer of @var{target}
jit_value_t jit_insn_get_parent_frame_pointer_of
        (jit_function_t func, jit_function_t target);

/* similar to jit_insn_call_indirect but allows to call nested functions
   @var{parent_frame} has to be retrieved from one of the above two
   functions and somehow passed here (global variable, function
   parameter, etc.)
jit_value_t jit_insn_call_nested_indirect
        (jit_function_t func, jit_value_t value, jit_value_t parent_frame,
         jit_type_t signature, jit_value_t *args, unsigned int num_args,
         int flags);

/* Sets the frame pointer of @var{func}. This is useful when childs can
   somehow obtain the parent pointer (e.g. via a global variable).
   You could then call the child like any other function (without
   special nesting care) as it can find the parent frame itself.  */
void jit_function_set_parent_frame(jit_function_t func,
        jit_value_t parent_frame);

Calling nested functions using only the function pointer was one my
needs too. That's why I added the jit_insn_call_nested_indirect
function. Together with the first two functions it allows you to use
your own way to pass the parent frame. jit_insn_call_native is just the
constant version of jit_insn_call_indirect.

- Jakob


On Sun, 2018-08-05 at 02:25 +0200, Aritz Erkiaga wrote:
> Hi,
> Sorry for bothering again :) I was just about to run into this stuff
> when I realised that the docs didn't even mention it, so I'm afraid I
> will have to ask so as to prevent uncomfortable surprises...
> Is it safe to call a child of a certain function from its parent by
> using jit_insn_call_native with a pointer to the child, obtained via
> jit_function_from_closure? The documentation does not recommend using
> the later on a nested function, but neither does it prohibit it.
> After that, the child function should be able to use jit_insn_import.
> Sorry, and thanks for all the help! Using LibJIT is a real challenge,
> but is also very rewarding.
> Aritz

reply via email to

[Prev in Thread] Current Thread [Next in Thread]