Source File
makefunc.go
Belonging Package
reflect
// 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 reflectimport ()// makeFuncImpl is the closure value implementing the function// returned by MakeFunc.// The first three words of this type must be kept in sync with// methodValue and runtime.reflectMethodValue.// Any changes should be reflected in all three.type makeFuncImpl struct {code uintptrstack *bitVector // ptrmap for both args and resultsargLen uintptr // just argsftyp *funcTypefn 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://// - converts its arguments to a slice of Values.// - 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 ( Type, func( []Value) ( []Value)) Value {if .Kind() != Func {panic("reflect: call of MakeFunc with non-Func type")}:= .common():= (*funcType)(unsafe.Pointer())// Indirect Go func value (dummy) to obtain// actual code address. (A Go func value is a pointer// to a C function pointer. https://golang.org/s/go11func.):= makeFuncStub:= **(**uintptr)(unsafe.Pointer(&))// makeFuncImpl contains a stack map for use by the runtime, , , , := funcLayout(, nil):= &makeFuncImpl{code: , stack: , argLen: , ftyp: , fn: }return Value{, unsafe.Pointer(), flag(Func)}}// makeFuncStub is an assembly function that is the code half of// the function returned from MakeFunc. It expects a *callReflectFunc// as its context register, and its job is to invoke callReflect(ctxt, frame)// where ctxt is the context register and frame is a pointer to the first// word in the passed-in argument frame.func ()// The first 3 words of this type must be kept in sync with// makeFuncImpl and runtime.reflectMethodValue.// Any changes should be reflected in all three.type methodValue struct {fn uintptrstack *bitVector // ptrmap for both args and resultsargLen uintptr // just argsmethod intrcvr Value}// 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 ( string, Value) Value {if .flag&flagMethod == 0 {panic("reflect: internal error: invalid use of makeMethodValue")}// Ignoring the flagMethod bit, v describes the receiver, not the method type.:= .flag & (flagRO | flagAddr | flagIndir)|= flag(.typ.Kind()):= Value{.typ, .ptr, }// v.Type returns the actual type of the method value.:= (*funcType)(unsafe.Pointer(.Type().(*rtype)))// Indirect Go func value (dummy) to obtain// actual code address. (A Go func value is a pointer// to a C function pointer. https://golang.org/s/go11func.):= methodValueCall:= **(**uintptr)(unsafe.Pointer(&))// methodValue contains a stack map for use by the runtime, , , , := funcLayout(, nil):= &methodValue{fn: ,stack: ,argLen: ,method: int(.flag) >> flagMethodShift,rcvr: ,}// 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(, .rcvr, .method)return Value{&.rtype, unsafe.Pointer(), .flag&flagRO | flag(Func)}}// methodValueCall is an assembly function that is the code half of// the function returned from makeMethodValue. It expects a *methodValue// as its context register, and its job is to invoke callMethod(ctxt, frame)// where ctxt is the context register and frame is a pointer to the first// word in the passed-in argument frame.func ()