On Fri, Sep 27, 2013 at 10:54 AM, Ian Lance Taylor <i...@google.com> wrote: > The Go standard library has an interesting function named > reflect.MakeFunc. It takes a Go function F that accepts and returns a > slice of reflect.Value, and a function type T, and returns a pointer to > a function of type T that converts its arguments to reflect.Value, calls > F, and converts the returned reflect.Value into the appropriate return > types. In effect this is the reverse of libffi: instead of describing a > function and calling it, we describe a function and permit it to be > called. > > For gccgo I tried to implement this generically using the builtin > varargs functions, but that failed because I had no way to handle the > return type. Many Go functions return multiple values, which in gccgo > is represented as returning a struct, and, of course, in some cases a > struct is returned by passing a hidden pointer as the first argument, > and in other cases is handled by splitting up the struct into different > register classes. So handling this generically is essentially > impossible, at least without adding some more builtin functions to > somehow handle the return value, builtin functions that I couldn't > figure out how to even represent. > > So I gave up and went for a processor-specific approach. The idea is > that processor-specific assembly code will save all the relevant > registers into a struct, and pass them to processor-specific Go code > which will implement the calling convention. This has the advantage > that I only need to deal with Go types, which in particular means no > worries about vector types. > > This patch implements this approach for x86_64. Bootstrapped and ran Go > testsuite on x86_64-unknown-linux-gnu. Committed to mainline and 4.8 > branch. >
Hi Ian, TestMakeFunc failed on x32: FAIL: TestMakeFunc (0.00 seconds) all_test.go:1457: Call returned 10, 20, 30, [40 0], 60, 70, 80; want 10, 20, 30, [40, 50], 60, 70, 80 The difference in x32 is x32 puts 2 pointers (32-bit) in one 64-git register. Somehow, the second pointer in type two [2]uintptr isn't returned properly.. Do you know what I should check for x32? Thanks. -- H.J.