blob: 433534756b795067842a81b0221d676701a8aced (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
package mem
type Mem struct {
cells []cell
free []int
}
func New() Mem {
return Mem{
cells: make([]cell, 0),
free: make([]int, 0),
}
}
func (m *Mem) Allocate(kind CellKind) Ptr {
if len(m.free) > 0 {
idx := m.free[len(m.free)-1]
m.free = m.free[:len(m.free)-1]
if m.cells[idx].kind != CellKindEmpty {
panic("invalid free cell")
}
m.cells[idx].kind = kind
return Ptr(idx)
} else {
idx := len(m.cells)
m.cells = append(m.cells, cell{kind: kind})
return Ptr(idx)
}
}
func (m *Mem) Set(ptr Ptr, v any) {
if ptr >= Ptr(len(m.cells)) {
panic("out of bounds")
}
m.cells[ptr].data = v
}
func (m *Mem) Get(ptr Ptr) any {
if ptr >= Ptr(len(m.cells)) {
panic("out of bounds")
}
return m.cells[ptr].data
}
func (m *Mem) Retain(ptr Ptr) {
if ptr >= Ptr(len(m.cells)) {
panic("out of bounds")
}
m.cells[ptr].refs++
}
func (m *Mem) Release(ptr Ptr) {
if ptr >= Ptr(len(m.cells)) {
panic("out of bounds")
}
m.cells[ptr].refs--
if m.cells[ptr].refs == 0 {
m.cells[ptr].kind = CellKindEmpty
m.free = append(m.free, int(ptr))
}
}
|