From ad1ba9bf6b55251f54366d3b679737d169336870 Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 24 Jun 2012 02:59:56 +0200 Subject: [PATCH] ruby: try msvc workaround for __thiscall --- plugins/ruby/ruby.cpp | 51 +++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/plugins/ruby/ruby.cpp b/plugins/ruby/ruby.cpp index 06f033d2f..630cca0e6 100644 --- a/plugins/ruby/ruby.cpp +++ b/plugins/ruby/ruby.cpp @@ -761,22 +761,49 @@ static VALUE rb_dfmemory_bitarray_set(VALUE self, VALUE addr, VALUE idx, VALUE v /* call an arbitrary object virtual method */ -static VALUE rb_dfvcall(VALUE self, VALUE cppobj, VALUE cppvoff, VALUE a0, VALUE a1, VALUE a2, VALUE a3) -{ #ifdef WIN32 - int (__fastcall *fptr)(char **me, int dummy_edx, int, int, int, int); +__declspec(naked) static int raw_vcall(char **that, unsigned long voff, unsigned long a0, + unsigned long a1, unsigned long a2, unsigned long a3) +{ + // __thiscall requires that the callee cleans up the stack + // here we dont know how many arguments it will take, so + // we simply fix esp across the funcall + __asm { + push ebp + mov ebp, esp + + push a3 + push a2 + push a1 + push a0 + + mov ecx, that + + mov eax, [ecx] + add eax, voff + call [eax] + + mov esp, ebp + pop ebp + ret + } +} #else +static int raw_vcall(char **that, unsigned long voff, unsigned long a0, + unsigned long a1, unsigned long a2, unsigned long a3) +{ int (*fptr)(char **me, int, int, int, int); + fptr = (decltype(fptr))*(void**)(*that + voff); + return fptr(that, a0, a1, a2, a3); +} #endif - char **that = (char**)rb_num2ulong(cppobj); - int ret; - fptr = (decltype(fptr))*(void**)(*that + rb_num2ulong(cppvoff)); - ret = fptr(that, -#ifdef WIN32 - 0, -#endif - rb_num2ulong(a0), rb_num2ulong(a1), rb_num2ulong(a2), rb_num2ulong(a3)); - return rb_int2inum(ret); + +// call an arbitrary vmethod, convert args/ret to native values for raw_vcall +static VALUE rb_dfvcall(VALUE self, VALUE cppobj, VALUE cppvoff, VALUE a0, VALUE a1, VALUE a2, VALUE a3) +{ + return rb_int2inum(raw_vcall((char**)rb_num2ulong(cppobj), rb_num2ulong(cppvoff), + rb_num2ulong(a0), rb_num2ulong(a1), + rb_num2ulong(a2), rb_num2ulong(a3))); }