diff options
| author | Pieter Droogendijk <pieter@binky.org.uk> | 2013-07-29 19:43:08 +0400 |
|---|---|---|
| committer | Dmitriy Vyukov <dvyukov@google.com> | 2013-07-29 19:43:08 +0400 |
| commit | 6350e45892b5b0189fe3461ba1e7f530da23ff8f (patch) | |
| tree | fe90ee9ca61e20117ea8e420d3df9fac029e7f5d /src/pkg/runtime/malloc.goc | |
| parent | 3398322d5ebaf7b870f07aebae92fc2fd047704c (diff) | |
| download | go-6350e45892b5b0189fe3461ba1e7f530da23ff8f.tar.xz | |
runtime: allow SetFinalizer with a func(interface{})
Fixes #5368.
R=golang-dev, dvyukov
CC=golang-dev, rsc
https://golang.org/cl/11858043
Diffstat (limited to 'src/pkg/runtime/malloc.goc')
| -rw-r--r-- | src/pkg/runtime/malloc.goc | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc index f31f119082..67da7ed846 100644 --- a/src/pkg/runtime/malloc.goc +++ b/src/pkg/runtime/malloc.goc @@ -799,6 +799,8 @@ func SetFinalizer(obj Eface, finalizer Eface) { int32 i; uintptr nret; Type *t; + Type *fint; + PtrType *ot; if(obj.type == nil) { runtime·printf("runtime.SetFinalizer: first argument is nil interface\n"); @@ -813,11 +815,17 @@ func SetFinalizer(obj Eface, finalizer Eface) { goto throw; } nret = 0; + ot = nil; if(finalizer.type != nil) { if(finalizer.type->kind != KindFunc) goto badfunc; ft = (FuncType*)finalizer.type; - if(ft->dotdotdot || ft->in.len != 1 || *(Type**)ft->in.array != obj.type) + if(ft->dotdotdot || ft->in.len != 1) + goto badfunc; + fint = *(Type**)ft->in.array; + if(fint->kind == KindInterface && ((InterfaceType*)fint)->mhdr.len == 0) + ot = (PtrType*)obj.type; + else if(fint != obj.type) goto badfunc; // compute size needed for return parameters @@ -828,14 +836,14 @@ func SetFinalizer(obj Eface, finalizer Eface) { nret = ROUND(nret, sizeof(void*)); } - if(!runtime·addfinalizer(obj.data, finalizer.data, nret)) { + if(!runtime·addfinalizer(obj.data, finalizer.data, nret, ot)) { runtime·printf("runtime.SetFinalizer: finalizer already set\n"); goto throw; } return; badfunc: - runtime·printf("runtime.SetFinalizer: second argument is %S, not func(%S)\n", *finalizer.type->string, *obj.type->string); + runtime·printf("runtime.SetFinalizer: second argument is %S, not func(%S) or func(interface{})\n", *finalizer.type->string, *obj.type->string); throw: runtime·throw("runtime.SetFinalizer"); } |
