diff --git a/engine/references.go b/engine/references.go index 3bb5c80..0f8594a 100644 --- a/engine/references.go +++ b/engine/references.go @@ -1,12 +1,14 @@ package engine -import "unsafe" +import ( + "math/rand" + "unsafe" +) // ExternalReferences manages external references to be used by the Interpreter // to store references that can be passed to guest modules. type ExternalReferences struct { - nextid int32 - refs map[int32]uintptr + refs map[int32]uintptr } // NewReferences creates a new ExternalReferences store. @@ -18,7 +20,7 @@ func NewReferences() *ExternalReferences { // Add adds a reference to the ExternalReferences store and returns the new reference id. func (r *ExternalReferences) Add(thing unsafe.Pointer) int32 { - id := r.referenceid() + id := r.newReferenceId() r.refs[id] = uintptr(thing) return id } @@ -33,8 +35,17 @@ func (r *ExternalReferences) Remove(id int32) { delete(r.refs, id) } -// TODO: generate a safe reference id -func (r *ExternalReferences) referenceid() int32 { - r.nextid++ - return r.nextid +// generates a random reference id that is not already in use. +func (r *ExternalReferences) newReferenceId() int32 { + for { + id := int32(randomInt(1, 0x7FFFFFFF)) + if _, ok := r.refs[id]; !ok { + return id + } + } +} + +// Returns an int >= min, < max +func randomInt(min, max int) int { + return min + rand.Intn(max-min) }