Create  Edit  Diff  FrontPage  Index  Search  Changes  Login

The Backyard - DlPatch Diff

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

ruby-win32@moonwolf.comに投げたもの(に多少の語句追加―特に注記なし―と、修正―追記あり―したもの)

artonです。

ZnZさんのところで、http://www.tietew.jp/beckrb/msg00113.html
を見かけたので、VC6版(ASR)で、msgbox.rbがなぜ動くか調べてみました。
[[StdDeclCDecl]]ですが、とりあえず動くが、まずいでしょう、という結論です。
で、__cdecl、__stdcall両方を呼べれば良いのですから、呼び出し前の引数をス
タックへ積む直前と、呼出し後のコンパイラが生成したスタック調整直後でesp
を保存/復帰させれば良いだろうということで、以下のパッチを作ってみました。

diff -c sym.c.original sym.c
*** sym.c.original Sat Mar 29 11:56:18 2003
--- sym.c Sun Oct 19 16:56:43 2003
***************
*** 329,334 ****
--- 329,337 ----
     int i;
     long ftype;
     void *func;
+ #if defined(_MSC_VER)
+   void *spsave;
+ #endif
  
     rb_secure_update(self);
     Data_Get_Struct(self, struct sym_data, sym);
***************
*** 607,612 ****
--- 610,618 ----
     DLSTACK_END(sym->type);
  
     {
+ #if defined(_MSC_VER)
+     __asm mov spsave, esp
+ #endif
       switch( sym->type[0] ){
       case '0':
         {
***************
*** 675,680 ****
--- 681,689 ----
         rb_raise(rb_eDLTypeError, "unknown type `%c'", sym->type[0]);
       }
     }
+ #if defined(_MSC_VER)
+     __asm mov esp, spsave
+ #endif
     }
   #else /* defined(DLSTACK) */
     switch(ftype){
------------------------
VC++6SP5であれば、これは

; 613  : #if defined(_MSC_VER)
; 614  :     __asm mov spsave, esp

   010e4 89 65 d0 mov DWORD PTR _spsave$[ebp], esp

; 615  : #endif
; 616  :     switch( sym->type[0] ){

−−−−−−−−−−−−
(ここにはペーストミスしたコードが貼り付けてあった。以下が正しい)

$L56554:

; 684  : #if defined(_MSC_VER)
; 685  :     __asm mov esp, spsave

   015fc 8b 65 d0 mov esp, DWORD PTR _spsave$[ebp]

; 688  : #else /* defined(DLSTACK) */
; 689  :   switch(ftype){

で、おそらくうまく動きます(msgbox.rbを使った、__stdcallの呼び出しについ
ては正常に動作し、パッチの前後のespが正しい値になります(MessageBoxは4引
数=16バイトのずれが解消)

ただ、mingw、cygwin、bccについてはこちらに環境がないこともあって、どのよ
うなコードになるかわかりません。
また、上記のような強制的な方法でespを調整することが本当に望ましいか
(__stdcallと__cdeclの区別をdlの利用者がつけなくて良いという意味では望ま
しいと思います)、また、よりスマートな解決方法があるかも知れない、など議
論の余地が大きいので、こちらへ投稿します。