Kinx ライブラリ - JIT ライブラリ(番外編)
はじめに
「見た目は JavaScript、頭脳(中身)は Ruby、(安定感は AC/DC)」 でお届けしているスクリプト言語 Kinx。今回は JIT ライブラリ番外編です。
- 参考
- 最初の動機 ... スクリプト言語 KINX(ご紹介)
- 個別記事へのリンクは全てここに集約してあります。
- リポジトリ ... https://github.com/Kray-G/kinx
- Pull Request 等お待ちしております。
- Pull Request 等お待ちしております。
- 最初の動機 ... スクリプト言語 KINX(ご紹介)
ここ で紹介した JIT ライブラリに新規追加した機能です。
JIT ライブラリ に任意のバイナリコードを実行できる機能を追加してみました。本気で細かく制御したい人向けです。こちらはがっつりアーキテクチャ依存です。そして、クラッシュさせるのも簡単です。
サンプル
まずはサンプルです。
using Jit;
var code
= System.PLATFORM == "X86_64-WIN" ? <0x48, 0x89, 0xc8, 0xc3> // mov rax, rcx | ret
: System.PLATFORM == "X86_64" ? <0x48, 0x89, 0xf8, 0xc3> // mov rax, rdi | ret
: null;
if (code.isBinary) {
Jit.dump(code);
var runner = new Jit.Runner(code);
System.println(runner.run(100));
}
$ ./kinx okay.kx
0: 48 89 f8 mov rax, rdi
3: c3 ret
100
さて、引数で与えた数値を単に返すだけの関数で、破壊するレジスタも無いのでプロローグもエピローグもなく、第一引数に来た値を復帰値(rax
)に設定して ret
するだけのものです。
System.PLATFORM
System.PLATFORM
で x64 でかつ Windows か Windows ではないかを切り分けてます。生のアセンブラだとこうやって切り分けないといけないのが面倒ですね。しかし、何でもできる という危険で甘い香りのするメリットを存分に享受できます。
Windows だと Microsoft 呼び出し規約に基づくので第一引数は rcx
レジスタに入ってきます。それに対し、ほぼほぼマイクロソフト以外が採用している System V 呼び出し規約では rdi
レジスタに第一引数が入ってきます。
System.PLATFORM
で具体的には何が返るかというと...
Value | Window? |
---|---|
"X86_32-WIN" |
O |
"X86_64-WIN" |
O |
"ARM_THUMB2-WIN" |
O |
"ARM_V7-WIN" |
O |
"ARM_V5-WIN" |
O |
"ARM_64-WIN" |
O |
"X86_32" |
|
"X86_64" |
|
"ARM_THUMB2" |
|
"ARM_V7" |
|
"ARM_V5" |
|
"ARM_64" |
|
"PPC_64" |
|
"PPC_32" |
|
"MIPS_32" |
|
"MIPS_64" |
|
"SPARC_32" |
|
"TILEGX" |
|
"UNSUPPORTED" |
です。
やってはいけないこと
using Jit;
var code = <0x48, 0x31, 0xc0, // xor rax, rax
0x48, 0x8b, 0x00> // mov rax, [rax]
;
Jit.dump(code);
var runner = new Jit.Runner(code);
System.println(runner.run());
$ ./kinx crash.kx
0: 48 31 c0 xor rax, rax
3: 48 8b 00 mov rax, [rax]
Segmentation fault (core dumped)
ふふふ...。危ないなぁ。
おわりに
一言でいうと、"Take your own risk." といったところですね。しかし、こういうところに踏み込むスクリプト言語はなかなか無いと思うので、それなりの価値はあるのではないでしょうか。例えば、このライブラリがあれば Xbyak なんかも移植できそうですね! Kinx には演算子オーバーライド(オーバーロードとは呼ばない)もありますし。
ますます JIT が身近になりますね。
ではまた。