わらばんし仄聞記

南の国で引きこもってるWeb屋さん

pythonでJIT(64bit版Linux環境) part1

池袋バイナリ勉強会(4)にて、pythonJITを行うコードを書いてみました。
基本的にこちらを参考として、64bit版Linux環境下にて。

とりあえずはほぼ写経で、ちょこちょこっと環境に応じて変えてみて動作することを確認する。

  • part1.py
from ctypes import *

libc = cdll.LoadLibrary("libc.so.6")

mmap = libc.mmap
mmap.restype = c_void_p
munmap = libc.munmap
munmap.argtype = [c_void_p, c_size_t]

PROT_READ       = 1
PROT_WRITE      = 2
PROT_EXEC       = 4
MAP_PRIVATE     = 2
MAP_ANONYMOUS   = 0x20

codes = (c_ubyte * 32) (
    0x48, 0x89, 0xf8,   # mov rax, rdi
    0x48, 0x01, 0xf0,   # add rax, rsi
    0xc3,               # ret
)

buflen = len(codes)
p = mmap(
    0, buflen,
    PROT_READ | PROT_WRITE | PROT_EXEC,
    MAP_PRIVATE | MAP_ANONYMOUS,
    -1, 0
)

memmove(p, addressof(codes), buflen)
f = CFUNCTYPE(c_int, c_int, c_int)(p)

print("f(1, 2) = %s" % f(1, 2))
munmap(p, buflen)

違っている箇所は

  • libc = cdll.LoadLibrary("libc.so.6")
  • MAP_ANONYMOUS = 0x20

くらいで他はほぼ同じ。