Merge remote-tracking branch 'suokko/ruby_memory_return_calling_convention' into develop

develop
lethosor 2018-07-12 14:46:23 -04:00
commit c82532fd4b
3 changed files with 27 additions and 1 deletions

@ -43,6 +43,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- Fixed special characters in `command-prompt` and other non-console in-game outputs on Linux/macOS (in tools using ``df2console``)
- `die`: fixed windows crash in exit handling
- `dwarfmonitor`, `manipulator`: fixed stress cutoffs
- `ruby`: fixed calling conventions for vmethods that return strings (currently ``enabler.GetKeyDisplay()``)
- `startdwarf`: fixed on 64-bit Linux
## Misc Improvements

@ -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