gcc/libgo/go/reflect/makefunc.go
Ian Lance Taylor 4ccad563d2 libgo: Update to current sources.
From-SVN: r192704
2012-10-23 04:31:11 +00:00

82 lines
2.6 KiB
Go

// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// MakeFunc implementation.
package reflect
import (
"unsafe"
)
// MakeFunc returns a new function of the given Type
// that wraps the function fn. When called, that new function
// does the following:
//
// - converts its arguments to a list of Values args.
// - runs results := fn(args).
// - returns the results as a slice of Values, one per formal result.
//
// The implementation fn can assume that the argument Value slice
// has the number and type of arguments given by typ.
// If typ describes a variadic function, the final Value is itself
// a slice representing the variadic arguments, as in the
// body of a variadic function. The result Value slice returned by fn
// must have the number and type of results given by typ.
//
// The Value.Call method allows the caller to invoke a typed function
// in terms of Values; in contrast, MakeFunc allows the caller to implement
// a typed function in terms of Values.
//
// The Examples section of the documentation includes an illustration
// of how to use MakeFunc to build a swap function for different types.
//
func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value {
if typ.Kind() != Func {
panic("reflect: call of MakeFunc with non-Func type")
}
ft := (*funcType)(unsafe.Pointer(typ.common()))
// We will build a function that uses the C stdarg routines to
// pull out the arguments. Since the stdarg routines require
// the first parameter to be available, we need to switch on
// the possible first parameter types. Note that this assumes
// that the calling ABI for a stdarg function is the same as
// that for a non-stdarg function. The C standard does not
// require this, but it is true for most implementations in
// practice.
// Handling result types is a different problem. There are a
// few cases to handle:
// * No results.
// * One result.
// * More than one result, which is returned in a struct.
// + Struct returned in registers.
// + Struct returned in memory.
var result Kind
var resultSize uintptr
switch len(ft.out) {
case 0:
result = Invalid
case 1:
result = Kind(ft.out[0].kind)
resultSize = ft.out[0].size
default:
result = Struct
}
panic("reflect MakeFunc not implemented")
// stub := func(i int) {
// var args __gnuc_va_list
// __builtin_va_start(args, i)
// v := makeInt(0, uint64(i), ft.in[0])
// return callReflect(ft, fn, v, args)
// }
// return Value{t, unsafe.Pointer(&impl.code[0]), flag(Func) << flagKindShift}
}