■
なんもないところに鼻水垂らして死んでしまいました。もうちょい行けた気がするのに。
C で curry 化 @x86
http://nicosia.is.s.u-tokyo.ac.jp/pub/essay/hagiya/h/curry
を Sun から x86 に。
C言語は便利で楽しいなあ、と思わざる得ないのである。
に激しく同意なのです。
#include <stdio.h> #include <stdlib.h> #include <sys/mman.h> int (*curry(int (*F)(), int A))() { char *code = (char*)malloc(18); *(char*)code = 0x55; *(short int*)(code+1) = 0xe589; *(short int*)(code+3) = 0x75ff; *(char*)(code+5) = 0x08; *(char*)(code+6) = 0x6a; *(char*)(code+7) = (char)A; *(char*)(code+8) = 0xe8; *(int*)(code+9) = (int)F-((int)code+9+4); *(short int*)(code+13) = 0xc483; *(short int*)(code+15) = 0x08; *(short int*)(code+16) = 0xc9; *(short int*)(code+17) = 0xc3; mprotect((void*)(((int)code+4095) & ~4095 - 4096), 4096, PROT_READ | PROT_EXEC); return((int (*)())code); } int add(int x, int y) { return(x + y); } int main() { int (*c)(); c = curry(add, 100); printf("%d\n", (*c)(10)); }
C で curry 化 @lightning
さて上記をポータブルに。 GNU lightning の出番。
http://www.gnu.org/software/lightning/lightning.html
下記コードは i386-linux と ppc-macosx と sparc-solaris で動きました。
#include <stdio.h> #include "lightning.h" typedef int (*pifi)(int); static jit_insn buf[1024]; int (*curry(int (*F)(), int A))() { pifi code = (pifi)(jit_set_ip(buf).iptr); int i; jit_prolog(1); i = jit_arg_ui(); jit_getarg_ui(JIT_V0, i); jit_movi_i(JIT_V1, A); jit_prepare(2); jit_pusharg_ui(JIT_V1); jit_pusharg_ui(JIT_V0); jit_finish(F); jit_retval(JIT_RET); jit_ret(); jit_flush_code(buf, jit_get_ip().ptr); return code; } int add(int x, int y) { return(x + y); } int main() { int (*c)(); c = curry(add, 100); printf("%d\n", (*c)(10)); }
あら簡単。