Rubyからマシン語を直接呼ぶ
Ruby1.9のDLで。
require 'DL' str = "\xb8\xff\x7f\x00\x00\xc3" # mov eax, 0x7fff : ret i = [str].pack("P").unpack("l!")[0] cfunc = DL::CFunc.new(i, DL::TYPE_INT) p cfunc.call([]) #=> 32767
文字列としてバイナリを直接生成して、そのポインタをDLに渡して呼び出せば、マシン語のコードを呼ぶことができる。
WindowsにはDEPというデータ領域実行保護機能があるが、とりあえずXPのSP2以降はシステムしか保護されていないので動く。Linuxとかの場合はなんかフラグをいじったりする必要があるらしいがよくわからない。
こういうプログラムが動くかどうかはRubyの実装に強く依存する。たとえばStringオブジェクトの文字列が独自領域に取られてGCの際にコンパクションされたりするとアドレスが変わるので怪しいことになる。つまりこのような改善提案が受け入れられるとはじめは動くがGCが走るとアドレスを取得しなおさない限りコケることになる。→http://www.is.titech.ac.jp/~sassa/lab/papers-written/08M37090-oota.pdf
なんしかバイナリ直接生成で呼び出すことができるのなら、Ruby用インラインアセンブラが作れる可能性が出てくる。Rubyで書けば外部にアセンブラもコンパイラもいらない。といっても別に目新しいものではなくて、ytljitとかが既にある。→https://github.com/miura1729/ytljit/wiki/
これで何かをしようと言う話ではなくて、できるかな?と思ってやってみたらできた。という話。でした。