diff options
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/mfinal.go | 11 | ||||
| -rw-r--r-- | src/runtime/syscall_windows.go | 6 | ||||
| -rw-r--r-- | src/runtime/type.go | 30 |
3 files changed, 36 insertions, 11 deletions
diff --git a/src/runtime/mfinal.go b/src/runtime/mfinal.go index 6d5378200e..1238d4a053 100644 --- a/src/runtime/mfinal.go +++ b/src/runtime/mfinal.go @@ -331,10 +331,13 @@ func SetFinalizer(obj interface{}, finalizer interface{}) { throw("runtime.SetFinalizer: second argument is " + ftyp._string + ", not a function") } ft := (*functype)(unsafe.Pointer(ftyp)) - if ft.dotdotdot || len(ft.in) != 1 { + if ft.dotdotdot() { + throw("runtime.SetFinalizer: cannot pass " + etyp._string + " to finalizer " + ftyp._string + " because dotdotdot") + } + if ft.dotdotdot() || ft.inCount != 1 { throw("runtime.SetFinalizer: cannot pass " + etyp._string + " to finalizer " + ftyp._string) } - fint := ft.in[0] + fint := ft.in()[0] switch { case fint == etyp: // ok - same type @@ -359,8 +362,8 @@ func SetFinalizer(obj interface{}, finalizer interface{}) { okarg: // compute size needed for return parameters nret := uintptr(0) - for _, t := range ft.out { - nret = round(nret, uintptr(t.align)) + t.size + for _, t := range ft.out() { + nret = round(nret, uintptr(t.align)) + uintptr(t.size) } nret = round(nret, sys.PtrSize) diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go index 081516c70a..ebfa32ff8c 100644 --- a/src/runtime/syscall_windows.go +++ b/src/runtime/syscall_windows.go @@ -45,15 +45,15 @@ func compileCallback(fn eface, cleanstack bool) (code uintptr) { panic("compileCallback: not a function") } ft := (*functype)(unsafe.Pointer(fn._type)) - if len(ft.out) != 1 { + if len(ft.out()) != 1 { panic("compileCallback: function must have one output parameter") } uintptrSize := unsafe.Sizeof(uintptr(0)) - if ft.out[0].size != uintptrSize { + if ft.out()[0].size != uintptrSize { panic("compileCallback: output parameter size is wrong") } argsize := uintptr(0) - for _, t := range ft.in { + for _, t := range ft.in() { if t.size > uintptrSize { panic("compileCallback: input parameter size is wrong") } diff --git a/src/runtime/type.go b/src/runtime/type.go index 9c9b5fb8cc..c504e2d294 100644 --- a/src/runtime/type.go +++ b/src/runtime/type.go @@ -128,6 +128,29 @@ func (t *_type) name() string { return t._string[i+1:] } +func (t *functype) in() []*_type { + // See funcType in reflect/type.go for details on data layout. + uadd := uintptr(unsafe.Sizeof(functype{})) + if t.typ.tflag&tflagUncommon != 0 { + uadd += unsafe.Sizeof(uncommontype{}) + } + return (*[1 << 20]*_type)(add(unsafe.Pointer(t), uadd))[:t.inCount] +} + +func (t *functype) out() []*_type { + // See funcType in reflect/type.go for details on data layout. + uadd := uintptr(unsafe.Sizeof(functype{})) + if t.typ.tflag&tflagUncommon != 0 { + uadd += unsafe.Sizeof(uncommontype{}) + } + outCount := t.outCount & (1<<15 - 1) + return (*[1 << 20]*_type)(add(unsafe.Pointer(t), uadd))[t.inCount : t.inCount+outCount] +} + +func (t *functype) dotdotdot() bool { + return t.outCount&(1<<15) != 0 +} + type method struct { name *string pkgpath *string @@ -187,10 +210,9 @@ type slicetype struct { } type functype struct { - typ _type - dotdotdot bool - in []*_type - out []*_type + typ _type + inCount uint16 + outCount uint16 } type ptrtype struct { |
