summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/malloc.cgo
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/malloc.cgo')
-rw-r--r--src/pkg/runtime/malloc.cgo18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/pkg/runtime/malloc.cgo b/src/pkg/runtime/malloc.cgo
index 286aa2bf3..c6d5c6e33 100644
--- a/src/pkg/runtime/malloc.cgo
+++ b/src/pkg/runtime/malloc.cgo
@@ -289,6 +289,8 @@ func SetFinalizer(obj Eface, finalizer Eface) {
byte *base;
uintptr size;
FuncType *ft;
+ int32 i, nret;
+ Type *t;
if(obj.type == nil) {
printf("runtime.SetFinalizer: first argument is nil interface\n");
@@ -303,6 +305,7 @@ func SetFinalizer(obj Eface, finalizer Eface) {
printf("runtime.SetFinalizer: pointer not at beginning of allocated block\n");
goto throw;
}
+ nret = 0;
if(finalizer.type != nil) {
if(finalizer.type->kind != KindFunc) {
badfunc:
@@ -310,12 +313,21 @@ func SetFinalizer(obj Eface, finalizer Eface) {
goto throw;
}
ft = (FuncType*)finalizer.type;
- if(ft->dotdotdot || ft->out.len != 0 || ft->in.len != 1 || *(Type**)ft->in.array != obj.type)
+ if(ft->dotdotdot || ft->in.len != 1 || *(Type**)ft->in.array != obj.type)
goto badfunc;
- if(getfinalizer(obj.data, 0)) {
+
+ // compute size needed for return parameters
+ for(i=0; i<ft->out.len; i++) {
+ t = ((Type**)ft->out.array)[i];
+ nret = (nret + t->align - 1) & ~(t->align - 1);
+ nret += t->size;
+ }
+ nret = (nret + sizeof(void*)-1) & ~(sizeof(void*)-1);
+
+ if(getfinalizer(obj.data, 0, nil)) {
printf("runtime.SetFinalizer: finalizer already set");
goto throw;
}
}
- addfinalizer(obj.data, finalizer.data);
+ addfinalizer(obj.data, finalizer.data, nret);
}