1. Си / Говнокод #21932

    +3

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>
    #include <sys/mman.h>
    
    typedef intptr_t binaryfunc(intptr_t, intptr_t);
    typedef intptr_t unaryfunc(intptr_t);
    
    #define evalsiz ((intptr_t)eval_end - (intptr_t)eval)
    #define clossiz (evalsiz+sizeof(intptr_t)+sizeof(int))
    void eval_end();
    intptr_t eval(intptr_t rem) {
    #define argsize ((intptr_t)&&argend - (intptr_t)eval)
    #define leasize ((intptr_t)&&leaaft - (intptr_t)&&leabef)
    #define eoffset (argsize+leasize)
        argend:;
        register void *ptr asm("r10");
        leabef: asm("lea (%rip),%r10"); leaaft:;
        void *off = (ptr - eoffset + evalsiz);
        binaryfunc *bin = *(binaryfunc**)off;
        return bin(*(intptr_t *)(off+sizeof(intptr_t)),rem);
    }
    void eval_end() { }
    
    unaryfunc* apply(binaryfunc *bin, intptr_t arg) {
        void *data = mmap(0, clossiz, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
        memmove(data, &eval, evalsiz);
        intptr_t ptr = (intptr_t)bin;
        memmove(data+evalsiz, &ptr, sizeof(intptr_t));
        memmove(data+evalsiz+sizeof(intptr_t), &arg, sizeof(intptr_t));
        return data;
    }
    
    intptr_t add(intptr_t a, intptr_t b) {
        return a+b;
    }
    
    int main() {
        printf("%ld\n", apply(add, 1)(2));
        return 0;
    }

    Simple x86_64 closure implementation attempt

    https://gist.github.com/iamtakingiteasy/c80112437ebc1f8d73eecf8df27caa24

    Запостил: j123123, 01 Января 2017

    Комментарии (5) RSS

    • А не использовать ли нам bbcode?
      Ответить
    • А разве не должно быть

      typedef intptr_t (*binaryfunc)(intptr_t, intptr_t);
      typedef intptr_t (*unaryfunc)(intptr_t);
      Ответить
      • И так сойдёт, если звёздочки при каждом использовании хочется порисовать.
        Ответить
    • Царский код... Кстати, гццшники, когда просовывали "лямбду" в указатель на функцию, требовали (о ужас!) RWX стек. Но там "лямбда" была как в паскале - жила только до конца скопа, в котором она описана.
      Ответить
    • Пиздить надо по рукам за такие названия переменных (и меток и макросов).
      Ответить

    Добавить комментарий