| // 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" | 
 | ) | 
 |  | 
 | // makeFuncImpl is the closure value implementing the function | 
 | // returned by MakeFunc. | 
 | type makeFuncImpl struct { | 
 | 	code  uintptr | 
 | 	stack *bitVector // stack bitmap for args - offset known to runtime | 
 | 	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: | 
 | // | 
 | //	- 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 MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value { | 
 | 	if typ.Kind() != Func { | 
 | 		panic("reflect: call of MakeFunc with non-Func type") | 
 | 	} | 
 |  | 
 | 	t := typ.common() | 
 | 	ftyp := (*funcType)(unsafe.Pointer(t)) | 
 |  | 
 | 	// 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.) | 
 | 	dummy := makeFuncStub | 
 | 	code := **(**uintptr)(unsafe.Pointer(&dummy)) | 
 |  | 
 | 	// makeFuncImpl contains a stack map for use by the runtime | 
 | 	_, _, _, stack, _ := funcLayout(t, nil) | 
 |  | 
 | 	impl := &makeFuncImpl{code: code, stack: stack, typ: ftyp, fn: fn} | 
 |  | 
 | 	return Value{t, unsafe.Pointer(impl), 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 makeFuncStub() | 
 |  | 
 | type methodValue struct { | 
 | 	fn     uintptr | 
 | 	stack  *bitVector // stack bitmap for args - offset known to runtime | 
 | 	method int | 
 | 	rcvr   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 makeMethodValue(op string, v Value) Value { | 
 | 	if v.flag&flagMethod == 0 { | 
 | 		panic("reflect: internal error: invalid use of makeMethodValue") | 
 | 	} | 
 |  | 
 | 	// Ignoring the flagMethod bit, v describes the receiver, not the method type. | 
 | 	fl := v.flag & (flagRO | flagAddr | flagIndir) | 
 | 	fl |= flag(v.typ.Kind()) | 
 | 	rcvr := Value{v.typ, v.ptr, fl} | 
 |  | 
 | 	// v.Type returns the actual type of the method value. | 
 | 	funcType := v.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.) | 
 | 	dummy := methodValueCall | 
 | 	code := **(**uintptr)(unsafe.Pointer(&dummy)) | 
 |  | 
 | 	// methodValue contains a stack map for use by the runtime | 
 | 	_, _, _, stack, _ := funcLayout(funcType, nil) | 
 |  | 
 | 	fv := &methodValue{ | 
 | 		fn:     code, | 
 | 		stack:  stack, | 
 | 		method: int(v.flag) >> flagMethodShift, | 
 | 		rcvr:   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(op, fv.rcvr, fv.method) | 
 |  | 
 | 	return Value{funcType, unsafe.Pointer(fv), v.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 methodValueCall() |