From b5efc654daa9bfd404d722fe30ad19af127dcabb Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Tue, 20 Jun 2023 14:54:30 +0900 Subject: [PATCH] Use less hacky finalizer key and ignore rather than panic on unsupported finalizer (#17) --- finalizer.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/finalizer.go b/finalizer.go index b71b18d..82ef4dd 100644 --- a/finalizer.go +++ b/finalizer.go @@ -14,11 +14,21 @@ void free(void* ptr); import "C" import "unsafe" -var finalizers = map[uintptr]interface{}{} +var finalizers = map[uint64]interface{}{} + +var finalizersIdx = uint64(0) //go:linkname SetFinalizer runtime.SetFinalizer func SetFinalizer(obj interface{}, finalizer interface{}) { - finKey := uintptr((*_interface)(unsafe.Pointer(&finalizer)).value) + if _, ok := finalizer.(func(interface{})); !ok { + // Until function invocation with reflection is supported by TinyGo, we cannot support arbitrary finalizers. + // We make a best-effort attempt to support the generic func(interface{}). For other finalizers, we silently + // ignore, which would be the behavior for all finalizers with the default allocator. + return + } + + finalizersIdx++ + finKey := finalizersIdx finalizers[finKey] = finalizer in := (*_interface)(unsafe.Pointer(&obj)) @@ -47,7 +57,7 @@ func onFinalizer(obj unsafe.Pointer, data unsafe.Pointer) { case func(interface{}): f(in) default: - panic("currently only finalizers of the form func(interface{}) are supported") + panic("BUG: SetFinalizer should have filtered out non-supported finalizer interface") } } @@ -58,5 +68,5 @@ type _interface struct { type registeredFinalizer struct { typecode uintptr - finKey uintptr + finKey uint64 }