diff options
Diffstat (limited to 'libgo/go/reflect/makefunc.go')
-rw-r--r-- | libgo/go/reflect/makefunc.go | 66 |
1 files changed, 32 insertions, 34 deletions
diff --git a/libgo/go/reflect/makefunc.go b/libgo/go/reflect/makefunc.go index d30bf63aae3..f03beb34483 100644 --- a/libgo/go/reflect/makefunc.go +++ b/libgo/go/reflect/makefunc.go @@ -10,6 +10,14 @@ import ( "unsafe" ) +// makeFuncImpl is the closure value implementing the function +// returned by MakeFunc. +type makeFuncImpl struct { + code uintptr + typ *funcType + fn func([]Value) []Value +} + // MakeFunc returns a new function of the given Type // that wraps the function fn. When called, that new function // does the following: @@ -37,45 +45,35 @@ func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value { panic("reflect: call of MakeFunc with non-Func type") } - ft := (*funcType)(unsafe.Pointer(typ.common())) + t := typ.common() + ftyp := (*funcType)(unsafe.Pointer(t)) - // 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. + _, _ = t, ftyp - // 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. + panic("reflect MakeFunc not implemented") +} - 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 +// makeMethodValue converts v from the rcvr+method index representation +// of a method value to an actual method func value, which is +// basically the receiver value with a special bit set, into a true +// func value - a value holding an actual func. The output is +// semantically equivalent to the input as far as the user of package +// reflect can tell, but the true func representation can be handled +// by code like Convert and Interface and Assign. +func makeMethodValue(op string, v Value) Value { + if v.flag&flagMethod == 0 { + panic("reflect: internal error: invalid use of makePartialFunc") } - panic("reflect MakeFunc not implemented") + // Ignoring the flagMethod bit, v describes the receiver, not the method type. + fl := v.flag & (flagRO | flagAddr | flagIndir) + fl |= flag(v.typ.Kind()) << flagKindShift + rcvr := Value{v.typ, v.val, fl} - // 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) - // } + // Cause panic if method is not appropriate. + // The panic would still happen during the call if we omit this, + // but we want Interface() and other operations to fail early. + methodReceiver(op, rcvr, int(v.flag)>>flagMethodShift) - // return Value{t, unsafe.Pointer(&impl.code[0]), flag(Func) << flagKindShift} + panic("reflect makeMethodValue not implemented") } |