LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // MakeFunc implementation. | 5 // MakeFunc implementation. |
6 | 6 |
7 package reflect | 7 package reflect |
8 | 8 |
9 import ( | 9 import ( |
10 "unsafe" | 10 "unsafe" |
11 ) | 11 ) |
12 | 12 |
13 // makeFuncImpl is the closure value implementing the function | 13 // makeFuncImpl is the closure value implementing the function |
14 // returned by MakeFunc. | 14 // returned by MakeFunc. |
15 type makeFuncImpl struct { | 15 type makeFuncImpl struct { |
16 » code uintptr | 16 » code uintptr |
17 » typ *funcType | 17 » stack *bitVector // stack bitmap for args - offset known to runtime |
18 » fn func([]Value) []Value | 18 » typ *funcType |
| 19 » fn func([]Value) []Value |
19 } | 20 } |
20 | 21 |
21 // MakeFunc returns a new function of the given Type | 22 // MakeFunc returns a new function of the given Type |
22 // that wraps the function fn. When called, that new function | 23 // that wraps the function fn. When called, that new function |
23 // does the following: | 24 // does the following: |
24 // | 25 // |
25 // - converts its arguments to a slice of Values. | 26 // - converts its arguments to a slice of Values. |
26 // - runs results := fn(args). | 27 // - runs results := fn(args). |
27 // - returns the results as a slice of Values, one per formal result. | 28 // - returns the results as a slice of Values, one per formal result. |
28 // | 29 // |
(...skipping 18 matching lines...) Expand all Loading... |
47 | 48 |
48 t := typ.common() | 49 t := typ.common() |
49 ftyp := (*funcType)(unsafe.Pointer(t)) | 50 ftyp := (*funcType)(unsafe.Pointer(t)) |
50 | 51 |
51 // Indirect Go func value (dummy) to obtain | 52 // Indirect Go func value (dummy) to obtain |
52 // actual code address. (A Go func value is a pointer | 53 // actual code address. (A Go func value is a pointer |
53 // to a C function pointer. http://golang.org/s/go11func.) | 54 // to a C function pointer. http://golang.org/s/go11func.) |
54 dummy := makeFuncStub | 55 dummy := makeFuncStub |
55 code := **(**uintptr)(unsafe.Pointer(&dummy)) | 56 code := **(**uintptr)(unsafe.Pointer(&dummy)) |
56 | 57 |
57 » impl := &makeFuncImpl{code: code, typ: ftyp, fn: fn} | 58 » // makeFuncImpl contains a stack map for use by the runtime |
| 59 » _, _, _, stack := funcLayout(t, nil) |
58 | 60 |
59 » return Value{t, unsafe.Pointer(impl), 0, flag(Func) << flagKindShift} | 61 » impl := &makeFuncImpl{code: code, stack: stack, typ: ftyp, fn: fn} |
| 62 |
| 63 » return Value{t, unsafe.Pointer(impl), flag(Func)} |
60 } | 64 } |
61 | 65 |
62 // makeFuncStub is an assembly function that is the code half of | 66 // makeFuncStub is an assembly function that is the code half of |
63 // the function returned from MakeFunc. It expects a *callReflectFunc | 67 // the function returned from MakeFunc. It expects a *callReflectFunc |
64 // as its context register, and its job is to invoke callReflect(ctxt, frame) | 68 // as its context register, and its job is to invoke callReflect(ctxt, frame) |
65 // where ctxt is the context register and frame is a pointer to the first | 69 // where ctxt is the context register and frame is a pointer to the first |
66 // word in the passed-in argument frame. | 70 // word in the passed-in argument frame. |
67 func makeFuncStub() | 71 func makeFuncStub() |
68 | 72 |
69 type methodValue struct { | 73 type methodValue struct { |
70 fn uintptr | 74 fn uintptr |
| 75 stack *bitVector // stack bitmap for args - offset known to runtime |
71 method int | 76 method int |
72 rcvr Value | 77 rcvr Value |
73 } | 78 } |
74 | 79 |
75 // makeMethodValue converts v from the rcvr+method index representation | 80 // makeMethodValue converts v from the rcvr+method index representation |
76 // of a method value to an actual method func value, which is | 81 // of a method value to an actual method func value, which is |
77 // basically the receiver value with a special bit set, into a true | 82 // basically the receiver value with a special bit set, into a true |
78 // func value - a value holding an actual func. The output is | 83 // func value - a value holding an actual func. The output is |
79 // semantically equivalent to the input as far as the user of package | 84 // semantically equivalent to the input as far as the user of package |
80 // reflect can tell, but the true func representation can be handled | 85 // reflect can tell, but the true func representation can be handled |
81 // by code like Convert and Interface and Assign. | 86 // by code like Convert and Interface and Assign. |
82 func makeMethodValue(op string, v Value) Value { | 87 func makeMethodValue(op string, v Value) Value { |
83 if v.flag&flagMethod == 0 { | 88 if v.flag&flagMethod == 0 { |
84 panic("reflect: internal error: invalid use of makeMethodValue") | 89 panic("reflect: internal error: invalid use of makeMethodValue") |
85 } | 90 } |
86 | 91 |
87 // Ignoring the flagMethod bit, v describes the receiver, not the method
type. | 92 // Ignoring the flagMethod bit, v describes the receiver, not the method
type. |
88 fl := v.flag & (flagRO | flagAddr | flagIndir) | 93 fl := v.flag & (flagRO | flagAddr | flagIndir) |
89 » fl |= flag(v.typ.Kind()) << flagKindShift | 94 » fl |= flag(v.typ.Kind()) |
90 » rcvr := Value{v.typ, v.ptr, v.scalar, fl} | 95 » rcvr := Value{v.typ, v.ptr, fl} |
91 | 96 |
92 // v.Type returns the actual type of the method value. | 97 // v.Type returns the actual type of the method value. |
93 funcType := v.Type().(*rtype) | 98 funcType := v.Type().(*rtype) |
94 | 99 |
95 // Indirect Go func value (dummy) to obtain | 100 // Indirect Go func value (dummy) to obtain |
96 // actual code address. (A Go func value is a pointer | 101 // actual code address. (A Go func value is a pointer |
97 // to a C function pointer. http://golang.org/s/go11func.) | 102 // to a C function pointer. http://golang.org/s/go11func.) |
98 dummy := methodValueCall | 103 dummy := methodValueCall |
99 code := **(**uintptr)(unsafe.Pointer(&dummy)) | 104 code := **(**uintptr)(unsafe.Pointer(&dummy)) |
100 | 105 |
| 106 // methodValue contains a stack map for use by the runtime |
| 107 _, _, _, stack := funcLayout(funcType, nil) |
| 108 |
101 fv := &methodValue{ | 109 fv := &methodValue{ |
102 fn: code, | 110 fn: code, |
| 111 stack: stack, |
103 method: int(v.flag) >> flagMethodShift, | 112 method: int(v.flag) >> flagMethodShift, |
104 rcvr: rcvr, | 113 rcvr: rcvr, |
105 } | 114 } |
106 | 115 |
107 // Cause panic if method is not appropriate. | 116 // Cause panic if method is not appropriate. |
108 // The panic would still happen during the call if we omit this, | 117 // The panic would still happen during the call if we omit this, |
109 // but we want Interface() and other operations to fail early. | 118 // but we want Interface() and other operations to fail early. |
110 methodReceiver(op, fv.rcvr, fv.method) | 119 methodReceiver(op, fv.rcvr, fv.method) |
111 | 120 |
112 » return Value{funcType, unsafe.Pointer(fv), 0, v.flag&flagRO | flag(Func)
<<flagKindShift} | 121 » return Value{funcType, unsafe.Pointer(fv), v.flag&flagRO | flag(Func)} |
113 } | 122 } |
114 | 123 |
115 // methodValueCall is an assembly function that is the code half of | 124 // methodValueCall is an assembly function that is the code half of |
116 // the function returned from makeMethodValue. It expects a *methodValue | 125 // the function returned from makeMethodValue. It expects a *methodValue |
117 // as its context register, and its job is to invoke callMethod(ctxt, frame) | 126 // as its context register, and its job is to invoke callMethod(ctxt, frame) |
118 // where ctxt is the context register and frame is a pointer to the first | 127 // where ctxt is the context register and frame is a pointer to the first |
119 // word in the passed-in argument frame. | 128 // word in the passed-in argument frame. |
120 func methodValueCall() | 129 func methodValueCall() |
LEFT | RIGHT |