aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/malloc.goc
diff options
context:
space:
mode:
authorPieter Droogendijk <pieter@binky.org.uk>2013-07-29 19:43:08 +0400
committerDmitriy Vyukov <dvyukov@google.com>2013-07-29 19:43:08 +0400
commit6350e45892b5b0189fe3461ba1e7f530da23ff8f (patch)
treefe90ee9ca61e20117ea8e420d3df9fac029e7f5d /src/pkg/runtime/malloc.goc
parent3398322d5ebaf7b870f07aebae92fc2fd047704c (diff)
downloadgo-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.goc14
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");
}