aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/mfinal.go11
-rw-r--r--src/runtime/syscall_windows.go6
-rw-r--r--src/runtime/type.go30
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 {