今までPythonやC#やNode.jsでJITを実装しました。
- PythonでJIT (Windows 32bit)
- PythonでJIT (Mac OS X 64bit)
- C#でJIT
- Node.jsでJIT
今回はF#版です。C#版をほとんどそのまま焼き直しただけですが、それだけでは面白くないので、環境を判定して64bitにも対応しました。
open System.Runtime.InteropServices [<DllImport("kernel32.dll", SetLastError = true)>] extern nativeint VirtualAlloc( nativeint lpAddress, int dwSize, int flAllocationType, int flProtect) [<DllImport("kernel32.dll", SetLastError = true)>] extern bool VirtualFree( nativeint lpAddress, int dwSize, int dwFreeType) let MEM_COMMIT = 0x1000 let MEM_RELEASE = 0x8000 let PAGE_EXECUTE_READWRITE = 0x40 let codes = Array.map (fun x -> byte x) <| if Marshal.SizeOf typeof<nativeint> = 4 then // 32bit i386 [| 0x8b; 0x44; 0x24; 0x04; // mov eax, [esp+4] 0x03; 0x44; 0x24; 0x08; // add eax, [esp+8] 0xc3 |] // ret else // 64bit x86-64 [| 0x89; 0xc8; // mov eax, ecx 0x01; 0xd0; // add eax, edx 0xc3 |] // ret let buflen = codes.Length let p = VirtualAlloc(nativeint 0, buflen, MEM_COMMIT, PAGE_EXECUTE_READWRITE) Marshal.Copy(codes, 0, p, buflen) [<UnmanagedFunctionPointer(CallingConvention.Cdecl)>] type Delg = delegate of int * int -> int let f = Marshal.GetDelegateForFunctionPointer( p, typeof<Delg>) :?> Delg printfn "f(1, 2) = %d" (f.Invoke(1, 2)) VirtualFree(p, 0, MEM_RELEASE)