#make a function on the fly to simulate closures

4 messages · Page 1 of 1 (latest)

supple violetBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

supple violetBOT
#

@near glade

Please Do Not Delete Posts!

Please don't delete forum posts. They can be helpful to refer to later and other members can learn from them. In the future you can use !solved to close a post and mark a post as solved.

delicate marlin
near glade
# delicate marlin Oh, the post is gone. <@241962659505766402>, if you're still interested, have a ...

i eventually got it to work, i think

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>

#define i32 int32_t
#define u64 uint64_t 
#define u8 uint8_t 

typedef i32(*closure)(void *, i32);
typedef i32(*total)(i32);

total from_closure(closure f, void *state) {
    u64 f_adr = (u64)f;
    u64 state_adr = (u64)state;
    u8 code[] = {
        0x48, 0xb8, f_adr & 0xFF,(f_adr >> 8) & 0xFF,(f_adr >> 16) & 0xFF,(f_adr >> 24) & 0xFF,(f_adr >> 32) & 0xFF,(f_adr >> 40) & 0xFF,(f_adr >> 48) & 0xFF,(f_adr >> 56) & 0xFF, // movabs rax, closure adress
        0x89, 0xfe, // mov esi, edi
        0x48, 0xbf, state_adr & 0xFF,(state_adr >> 8) & 0xFF,(state_adr >> 16) & 0xFF,(state_adr >> 24) & 0xFF,(state_adr >> 32) & 0xFF,(state_adr >> 40) & 0xFF,(state_adr >> 48) & 0xFF,(state_adr >> 56) & 0xFF, // movabs rdi, state
        0xff, 0xe0, // jmp rax
    };
    total funptr = mmap(NULL, sizeof(code), PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
    memcpy(funptr, code, sizeof(code));
    return funptr;
}

i32 closure_example(void *state, i32 y) {
    return (*(int*)state)*y;
}

i32 main() {
    i32 *state = malloc(sizeof(i32));
    *state = 42;
    total test = from_closure(&closure_example, state);
    printf("%d\n", test(2));
}

i was interested in making it myself, but yeah, for a practical usecase that libffcall/callback seems useful