2015年4月21日

js-ctypes で JIT

Hello, JIT World: The Joy of Simple JITs の記事を参考に js-ctypes の上で JIT してみようの巻(ジョークです)。

とりあえず最初のコードをそれっぽくなんとなく JavaScript + js-ctypes で書き直す。

let libc = ctypes.open(ctypes.libraryName("c"));

let memcpy = libc.declare("memcpy", ctypes.default_abi,
                          ctypes.voidptr_t,
                          ctypes.voidptr_t, ctypes.voidptr_t, ctypes.size_t);

const PROT_WRITE = 0x02;
const PROT_EXEC = 0x04;
const MAP_ANON = 0x1000;
const MAP_PRIVATE = 0x0002;
let mmap = libc.declare("mmap", ctypes.default_abi,
                        ctypes.voidptr_t,
                        ctypes.voidptr_t, ctypes.size_t, ctypes.int, ctypes.int,
                        ctypes.int, ctypes.off_t);
let munmap = libc.declare("munmap", ctypes.default_abi,
                          ctypes.int,
                          ctypes.voidptr_t, ctypes.size_t);

let code = ctypes.uint8_t.array()([
  0xb8, 0x00, 0x00, 0x00, 0x00, // mov eax, 0
  0xc3                          // ret
]);

let num = ctypes.int32_t(0x12345678);
memcpy(code.addressOfElement(1), num.address(), num.constructor.size);

let mem = mmap(null, code.length,
               PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE,
               -1, 0);

memcpy(mem, code, code.length);

let funcType = ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t);
let func = ctypes.cast(mem, funcType.ptr);

print(func().toString(16));

munmap(mem, code.length);

libc.close();

で、実行するとこうなる。

$ js jit.js
12345678

やったね。

0 件のコメント:

コメントを投稿