• callable object to function-pointer

    From Bonita Montero@21:1/5 to All on Sun Sep 12 16:45:57 2021
    I've got an idea how a compiler could convert a callable object to a
    plain C function-pointer at runtime, i.e. each callable object would
    get an individually runtime-"compiled" C-function.
    The compiler would have to generate a skeleton of a stub-function which
    will be called as a normal C-fuction and call the individual object's calling-operator with the same parameters the C-function is called with
    but of course with the implicit this or context-pointer (if it is a
    lamda). This skeleton has an unassigned pointer to the called function
    -object (with a function object I don't mean necessarily a function<>
    object but all objects with a calling-operator). Then there's some
    additional code that would be called at runtime when a stub would be
    copyied to some memory that's writable as well as executable; this "adjustment-code" will relocate the individually adjusted stub for an
    object to its address and relocate the this or context-pointer. So if
    you would create such a stub the readjustment-code would be called with
    the address of the called object, allocate executable storage for the
    copied stub, readjust all the pointers within it, adjust the pointer
    to the called object and everything is fine.
    It would be best that the callable object's parameters are all native
    types or references so that there wouldn't be any additional object
    -copying inside the stub.
    I came to this idea because with Windows there are some APIs with
    callbacks where you can't pass a context-pointer to the API which
    will be handed to the callback. Normaly I use a lambda without a
    capture here and this lambda accesses a thread-local variable defined
    outside that lambda as a context. But that fits only when the callback
    won't be called again after the API-call has finished. So in this
    cases such a conversion if a callable object to a bare function-pointer
    would be nice.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paavo Helde@21:1/5 to All on Sun Sep 12 18:44:27 2021
    12.09.2021 17:45 Bonita Montero kirjutas:
    I've got an idea how a compiler could convert a callable object to a
    plain C function-pointer at runtime, i.e. each callable object would
    get an individually runtime-"compiled" C-function.
    The compiler would have to generate a skeleton of a stub-function which
    will be called as a normal C-fuction and call the individual object's calling-operator with the same parameters the C-function is called with
    but of course with the implicit this or context-pointer (if it is a
    lamda). This skeleton has an unassigned pointer to the called function -object (with a function object I don't mean necessarily a function<>
    object but all objects with a calling-operator). Then there's some
    additional code that would be called at runtime when a stub would be
    copyied to some memory that's writable as well as executable; this "adjustment-code" will relocate the individually adjusted stub for an
    object to its address and relocate the this or context-pointer. So if
    you would create such a stub the readjustment-code would be called with
    the address of the called object, allocate executable storage for the
    copied stub, readjust all the pointers within it, adjust the pointer
    to the called object and everything is fine.
    It would be best that the callable object's parameters are all native
    types or references so that there wouldn't be any additional object
    -copying inside the stub.
    I came to this idea because with Windows there are some APIs with
    callbacks where you can't pass a context-pointer to the API which
    will be handed to the callback. Normaly I use a lambda without a
    capture here and this lambda accesses a thread-local variable defined
    outside that lambda as a context. But that fits only when the callback
    won't be called again after the API-call has finished. So in this
    cases such a conversion if a callable object to a bare function-pointer
    would be nice.

    This looks like a trampoline. The wikipedia page https://en.wikipedia.org/wiki/Trampoline_(computing) also mentions
    trampolines generated at run time (for implementing nested function
    pointers), but those live on the stack, so the memory management is a
    bit easier.

    The general security considerations about having writable+executable
    memory segments are probably the most serious hindrance against such techniques.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alf P. Steinbach@21:1/5 to Bonita Montero on Mon Sep 13 19:05:47 2021
    On 12 Sep 2021 16:45, Bonita Montero wrote:
    I've got an idea how a compiler could convert a callable object to a
    plain C function-pointer at runtime, i.e. each callable object would
    get an individually runtime-"compiled" C-function.
    The compiler would have to generate a skeleton of a stub-function which
    will be called as a normal C-fuction and call the individual object's calling-operator with the same parameters the C-function is called with
    but of course with the implicit this or context-pointer (if it is a
    lamda). This skeleton has an unassigned pointer to the called function -object (with a function object I don't mean necessarily a function<>
    object but all objects with a calling-operator). Then there's some
    additional code that would be called at runtime when a stub would be
    copyied to some memory that's writable as well as executable; this "adjustment-code" will relocate the individually adjusted stub for an
    object to its address and relocate the this or context-pointer. So if
    you would create such a stub the readjustment-code would be called with
    the address of the called object, allocate executable storage for the
    copied stub, readjust all the pointers within it, adjust the pointer
    to the called object and everything is fine.
    It would be best that the callable object's parameters are all native
    types or references so that there wouldn't be any additional object
    -copying inside the stub.
    I came to this idea because with Windows there are some APIs with
    callbacks where you can't pass a context-pointer to the API which
    will be handed to the callback. Normaly I use a lambda without a
    capture here and this lambda accesses a thread-local variable defined
    outside that lambda as a context. But that fits only when the callback
    won't be called again after the API-call has finished. So in this
    cases such a conversion if a callable object to a bare function-pointer
    would be nice.

    As Paavo Helde notes in his reply it's called a trampoline.

    Trampolines were used in Borland Pascal's windowing library, and I guess
    they did the same in Borland C++.

    One C++ expert that's done some work on trampolines: Andrei
    Alexandrescu. Andrei is or was much like Bjarne. One could e-mail him
    and he'd answer to the best of his ability. As I recall I've only
    ┬╣intersected his path five times, but I think it's enough to say that
    the opinion that you can mail him and will probably get help with this
    is an informed one.

    One C++ programmer who's submitted or at least started on a proposal for standardization of C++ trampoline generation: the good Puppy (I don't
    recall his real name) in the C++ Lounge at Stack Overflow.

    You could visit the Lounge and air the question. Chances are that the
    puppy wrote some implementation for his proposal. As I recall he
    attended one committee meeting for this.


    - Alf

    Notes:
    ┬╣ I provided some feedback on the first ScopeGuard implementation
    (Andrei helped the original inventor Petru Marginean publish a DDJ
    article about it and provided some helper functionality), namely that
    their use of `__LINE__` at that time didn't work with a special option
    in Visual C++, and that they swallowed exceptions; I was one of the
    reviewers of his "Mojo" framework for C++03 move semantics, where I
    failed to see the big problem that someone else noticed, and Andrei then corrected, and I even at first failed to compile it, but Andrei helped
    me out; I fixed the failure/succeess return code of `WinMain` for the D language, where Andrei and Walter Bright somehow, very perplexingly, got
    that wrong; as a clc++m contributor I engaged in an escalating debate
    with Andrei about SESE versus SEME, where I used so strong words that a
    posting was rejected and I had to apologize, and the moderators
    explained that they had accepted the posting without looking because it
    was two experts debating (that was the first time I was ever called a
    C++ expert); and, but I'm not sure I remember this correctly, but
    something like this, later as clc++m moderator I accepted a posting that included a link to an illegal PDF of Andrei's "Modern C++ Design" book,
    and he was absolutely not pleased about that.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)