Fix memory return calling convention in ruby bindings

Calling convention for memory return is that caller allocates (in stack)
memory to hold returned object. Then caller passes the pointer to callee
as implicit first parameter.

references:
https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI
https://msdn.microsoft.com/en-us/library/7572ztz4.aspx

Fixes #1209
develop
Pauli 2018-07-04 23:35:07 +03:00
parent d1a3f1a738
commit ff6d0c4e7d
2 changed files with 26 additions and 1 deletions

@ -462,8 +462,13 @@ sub render_class_vmethods {
push @lines_rb, "def $name(" . join(', ', @argnames) . ')';
indent_rb {
my $args = join('', map { ", $_" } @argargs);
my $call = "DFHack.vmethod_call(self, $voff$args)";
my $ret = $meth->findnodes('child::ret-type')->[0];
my $call;
if (!$ret or $ret->getAttribute('ld:meta') ne 'primitive') {
$call = "DFHack.vmethod_call(self, $voff$args)";
} else {
$call = "DFHack.vmethod_call_mem_return(self, $voff, rv$args)";
}
render_class_vmethod_ret($call, $ret);
};
push @lines_rb, 'end';
@ -534,6 +539,18 @@ sub render_class_vmethod_ret {
};
push @lines_rb, "end._at(ptr) if ptr != 0";
}
elsif ($retmeta eq 'primitive')
{
my $subtype = $ret->getAttribute('ld:subtype');
if ($subtype eq 'stl-string') {
push @lines_rb, "rv = DFHack::StlString.cpp_new";
push @lines_rb, $call;
push @lines_rb, "rv";
} else {
print "Unknown return subtype for $call\n";
push @lines_rb, "nil";
}
}
else
{
print "vmethod unkret $call\n";

@ -994,6 +994,14 @@ module DFHack
vmethod_arg(a3), vmethod_arg(a4), vmethod_arg(a5))
end
def self.vmethod_call_mem_return(obj, voff, r0=0, a0=0, a1=0, a2=0, a3=0, a4=0)
this = obj._memaddr
vt = df.get_vtable_ptr(this)
fptr = df.memory_read_ptr(vt + voff)
vmethod_do_call(vmethod_arg(r0), fptr, this, vmethod_arg(a0), vmethod_arg(a1), vmethod_arg(a2),
vmethod_arg(a3), vmethod_arg(a4))
end
def self.vmethod_arg(arg)
case arg
when nil, false; 0