謎's キッチン

謎のひとりごと。Amazon欲しい物リストはこちら: https://www.amazon.co.jp/hz/wishlist/ls/CCPOV7C6JTD2

C呼び出し規則のcallbackにdelegateを渡したい

ヒープに関数置けばあまり良い方法で無いにせよできるはず。
ってことで、以下のようなの作った。x86 + cdecl(おまけでD呼び出し規則) + ヒープでコードが実行できる環境向け。

alias extern(C)void function() CFunc;

invariant ubyte[] ret = [0xc3];
invariant ubyte[] nop = [0x90];
invariant ubyte[] pushEBX = [0x53];
invariant ubyte[] popEBX = [0x5b];
invariant ubyte[] callpEDX = [0xff, 0xd2];
ubyte[] mov(uint i)(void* x){
  return cast(ubyte[])[i] ~ (cast(ubyte*)&x)[0..4];
}
alias mov!(0xb8) movEAX;
alias mov!(0xbb) movEBX;
alias mov!(0xba) movEDX;

void function() toFunction(void delegate() x){
  ubyte[] f = pushEBX ~ movEAX(x.ptr) ~ movEBX(x.ptr) ~ movEDX(x.funcptr) ~ (callpEDX ~ popEBX ~ ret ~ nop ~ nop ~ nop);
  return cast(void function())f.ptr;
}

CFunc toCFunction(void delegate() x){
  return cast(CFunc)toFunction(x);
}

引数を渡せるようにしたいけどEBX退避のせいで面倒だなぁ。