libjit
[Top][All Lists]
Advanced

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

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


From: Aritz Erkiaga
Subject: Re: [Libjit] Call to child through function pointer?
Date: Sun, 5 Aug 2018 15:25:51 +0200

Thanks!
Your help is absolutely invaluable. I'm not the kind that is constantly asking online; in fact, I can't recall having asked about anything before LibJIT! But, well, you know, I'm using a JIT because I want some performance-critical code to run much, much faster, and fast code (at least mine) ends up not being very clean and fancy... So, as always, I can't be grateful enough for helping me find my way through the realm of hackiness and bad programming practices ;), and for contributing to LibJIT too! I'm not releasing my bunch of weird code anytime soon, but if I ever do, who knows, maybe it wouldn't have been possible without you.
Seriously considering some "special thanks" stuff or sort of,
Aritz

On Sun, Aug 5, 2018 at 11:30 AM Jakob Löw <address@hidden> wrote:
Hey,

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
here[1]
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
jit_insn_call).
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
  address@hidden 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

[0] https://github.com/M4GNV5/libjit/tree/nesting
[1] http://www.drdobbs.com/cpp/how-nested-functions-work-part-1/2287014
76

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]