summaryrefslogtreecommitdiff
path: root/libgo/go/reflect/makefunc.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/reflect/makefunc.go')
-rw-r--r--libgo/go/reflect/makefunc.go81
1 files changed, 81 insertions, 0 deletions
diff --git a/libgo/go/reflect/makefunc.go b/libgo/go/reflect/makefunc.go
new file mode 100644
index 00000000000..d30bf63aae3
--- /dev/null
+++ b/libgo/go/reflect/makefunc.go
@@ -0,0 +1,81 @@
+// 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}
+}