...
1 package values
2
3 import (
4 "fmt"
5
6 "github.com/tetratelabs/wazero/internal/gojs/goos"
7 )
8
9 func NewValues() *Values {
10 ret := &Values{}
11 ret.Reset()
12 return ret
13 }
14
15 type Values struct {
16
17
18
19 values []interface{}
20 goRefCounts []uint32
21 ids map[interface{}]uint32
22 idPool []uint32
23 }
24
25 func (j *Values) Get(id uint32) interface{} {
26 index := id - goos.NextID
27 if index >= uint32(len(j.values)) {
28 panic(fmt.Errorf("id %d is out of range %d", id, len(j.values)))
29 }
30 if v := j.values[index]; v == nil {
31 panic(fmt.Errorf("value for %d was nil", id))
32 } else {
33 return v
34 }
35 }
36
37 func (j *Values) Increment(v interface{}) uint32 {
38 id, ok := j.ids[v]
39 if !ok {
40 if len(j.idPool) == 0 {
41 id, j.values, j.goRefCounts = uint32(len(j.values)), append(j.values, v), append(j.goRefCounts, 0)
42 } else {
43 id, j.idPool = j.idPool[len(j.idPool)-1], j.idPool[:len(j.idPool)-1]
44 j.values[id], j.goRefCounts[id] = v, 0
45 }
46 j.ids[v] = id
47 }
48 j.goRefCounts[id]++
49
50 return id + goos.NextID
51 }
52
53 func (j *Values) Decrement(id uint32) {
54
55 if id < goos.NextID {
56 return
57 }
58 id -= goos.NextID
59 j.goRefCounts[id]--
60 if j.goRefCounts[id] == 0 {
61 v := j.values[id]
62 j.values[id] = nil
63 delete(j.ids, v)
64 j.idPool = append(j.idPool, id)
65 }
66 }
67
68 func (j *Values) Reset() {
69 j.values = nil
70 j.goRefCounts = nil
71 j.ids = map[interface{}]uint32{}
72 j.idPool = nil
73 }
74
View as plain text