Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //let (^) x y = pown y x
- //
- //let fs = List.map
- //let f1 = (*) 2
- //let f2 = (^) 2
- //let fsf1 = fs f1
- //let fsf2 = fs f2
- //
- //printfn "%A" (fsf1 [0; 1; 2; 3])
- //printfn "%A" (fsf1 [2; 4; 6; 8])
- //printfn "%A" (fsf2 [0; 1; 2; 3])
- //printfn "%A" (fsf2 [2; 4; 6; 8])
- #include <stdio.h>
- #include <stdint.h>
- #include <stdarg.h>
- #include <string.h>
- #include <sys/mman.h>
- #include <unistd.h>
- void __end();
- void __call(uintptr_t addr, size_t size, size_t nmemb, const void* in, void* out)
- {
- uintptr_t offs = ((uintptr_t) &__end) - ((uintptr_t) &__call);
- uintptr_t func = *((uintptr_t*) (addr + offs));
- uintptr_t data = *((uintptr_t*) (addr + offs + sizeof(uintptr_t)));
- ((void (*)(void*, size_t, size_t, const void*, void*)) func) ((void*) data, size, nmemb, in, out);
- }
- void __end() {}
- void* bind(uintptr_t func, void* data)
- {
- size_t page_size = getpagesize(); // assumes that the size of __call is less than a page
- char* ptr = mmap(NULL, page_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
- if (ptr == NULL)
- {
- perror("mmap");
- return NULL;
- }
- size_t func_size = ((uintptr_t) &__end) - ((uintptr_t) &__call);
- uintptr_t func_addr = (uintptr_t) &__call;
- memcpy(ptr, (const void*) func_addr, func_size);
- *((uintptr_t*) (ptr + func_size)) = func;
- *((uintptr_t*) (ptr + func_size + sizeof(uintptr_t))) = (uintptr_t) data;
- return ptr;
- }
- void unbind(void* bound)
- {
- munmap(bound, getpagesize());
- }
- void call(void* bound, size_t size, size_t nmemb, const void* in, void* out)
- {
- uintptr_t func = (uintptr_t) bound;
- ((void (*)(uintptr_t, size_t, size_t, const void*, void*)) func) (func, size, nmemb, in, out);
- }
- void map(uintptr_t func, size_t size, size_t nmemb, const void* in, void* out)
- {
- if (nmemb > 0)
- {
- ((void (*)(size_t, const void*, void*)) func)(size, in, out);
- map(func, size, nmemb - 1, ((const char*) in) + size, ((char*) out) + size);
- }
- }
- void f1(size_t size, const void* in, void* out)
- {
- int* x = (int*) out;
- *x = *((const int*) in) * 2;
- }
- void f2(size_t size, const void* in, void* out)
- {
- const int* x = (const int*) in;
- *((int*) out) = *x * *x;
- }
- void print(int* list)
- {
- // HACK: pass 4 to function somehow, maybe as an additional arg to bind
- printf("[%d", list[0]);
- for (int i = 1; i < 4; ++i)
- {
- printf("; %d", list[i]);
- }
- printf("]\n");
- }
- int main()
- {
- int list_lo[] = {0, 1, 2, 3};
- int list_hi[] = {2, 4, 6, 8};
- int result[4];
- void* print_result = bind((uintptr_t) &print, result);
- uintptr_t fs = (uintptr_t) ↦
- void* fsf1 = bind(fs, (void*) &f1);
- void* fsf2 = bind(fs, (void*) &f2);
- call(fsf1, sizeof(int), 4, list_lo, result);
- call(print_result, 0, 0, NULL, NULL);
- call(fsf1, sizeof(int), 4, list_hi, result);
- call(print_result, 0, 0, NULL, NULL);
- call(fsf2, sizeof(int), 4, list_lo, result);
- call(print_result, 0, 0, NULL, NULL);
- call(fsf2, sizeof(int), 4, list_hi, result);
- call(print_result, 0, 0, NULL, NULL);
- unbind(print_result);
- unbind(fsf1);
- unbind(fsf2);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement