Skip to content

Commit aef9cec

Browse files
committed
WIP: Get rid of intern.BoxedType
1 parent fac0f35 commit aef9cec

File tree

2 files changed

+16
-64
lines changed

2 files changed

+16
-64
lines changed

pkg/core/closure/closure.go

-6
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,8 @@ package closure
33
import (
44
"sync"
55
"unsafe"
6-
7-
"github.com/diamondburned/gotk4/pkg/core/intern"
86
)
97

10-
var RegistryType = intern.RegisterType[Registry](func(*intern.Box) *Registry {
11-
return NewRegistry()
12-
})
13-
148
// Registry describes the local closure registry of each object.
159
type Registry struct {
1610
reg sync.Map // unsafe.Pointer(*C.GClosure) -> *FuncStack

pkg/core/intern/intern.go

+16-58
Original file line numberDiff line numberDiff line change
@@ -18,73 +18,19 @@ import (
1818
"sync/atomic"
1919
"unsafe"
2020

21+
"github.com/diamondburned/gotk4/pkg/core/closure"
2122
"github.com/diamondburned/gotk4/pkg/core/gdebug"
2223

2324
// Require a non-moving GC for heap pointers. Current GC is moving only by
2425
// the stack. See https://github.com/go4org/intern.
2526
_ "go4.org/unsafe/assume-no-moving-gc"
2627
)
2728

28-
const maxTypesAllowed = 2
29-
30-
var knownTypes uint32 = 0
31-
32-
type BoxedType[T any] struct {
33-
ctor func(*Box) *T
34-
id uint32
35-
}
36-
37-
func RegisterType[T any](ctor func(*Box) *T) BoxedType[T] {
38-
t := BoxedType[T]{
39-
ctor: ctor,
40-
id: atomic.AddUint32(&knownTypes, 1) - 1,
41-
}
42-
if t.id > maxTypesAllowed {
43-
panic("BoxedType ID overflow")
44-
}
45-
return t
46-
}
47-
48-
func (t *BoxedType[T]) Get(box *Box) *T {
49-
old := atomic.LoadPointer(&box.data[t.id])
50-
if old != nil {
51-
return (*T)(old)
52-
}
53-
54-
if t.ctor == nil {
55-
return nil
56-
}
57-
58-
new := t.ctor(box)
59-
60-
if atomic.CompareAndSwapPointer(&box.data[t.id], nil, unsafe.Pointer(new)) {
61-
return new
62-
}
63-
64-
ptr := atomic.LoadPointer(&box.data[t.id])
65-
if ptr != nil {
66-
return (*T)(ptr)
67-
}
68-
69-
panic("Load returned nil after CompareAndSwap(old = nil) failed")
70-
}
71-
72-
func (t *BoxedType[T]) Set(box *Box, v *T) {
73-
if t.ctor != nil {
74-
panic("bug: Set not permitted if t.ctor != nil")
75-
}
76-
atomic.StorePointer(&box.data[t.id], unsafe.Pointer(v))
77-
}
78-
79-
func (t *BoxedType[T]) Delete(box *Box) {
80-
atomic.StorePointer(&box.data[t.id], nil)
81-
}
82-
8329
// Box is an opaque type holding extra data.
8430
type Box struct {
85-
gobject unsafe.Pointer
86-
dummy *boxDummy
87-
data [maxTypesAllowed]unsafe.Pointer
31+
gobject unsafe.Pointer
32+
closures atomic.Pointer[closure.Registry]
33+
dummy *boxDummy
8834
}
8935

9036
type boxDummy struct {
@@ -96,6 +42,18 @@ func (b *Box) GObject() unsafe.Pointer {
9642
return b.gobject
9743
}
9844

45+
// Closures returns the closure registry for this Box.
46+
func (b *Box) Closures() *closure.Registry {
47+
closures := b.closures.Load()
48+
if closures == nil {
49+
closures = closure.NewRegistry()
50+
if !b.closures.CompareAndSwap(nil, closures) {
51+
closures = b.closures.Load()
52+
}
53+
}
54+
return closures
55+
}
56+
9957
// Hack to force an object on the heap.
10058
var never bool
10159
var sink_ interface{}

0 commit comments

Comments
 (0)