diff options
author | Damian Gryski <[email protected]> | 2024-09-18 12:07:33 -0700 |
---|---|---|
committer | Ayke <[email protected]> | 2024-10-02 12:40:07 +0200 |
commit | b3e1974c304bb5b676bfdb0e193f40658495d61f (patch) | |
tree | 4420e9745cf20be9d4efffd158e12c05c6643d8b /src/runtime | |
parent | fa12450552884e0c37a03d943d97193488c9f527 (diff) | |
download | tinygo-b3e1974c304bb5b676bfdb0e193f40658495d61f.tar.gz tinygo-b3e1974c304bb5b676bfdb0e193f40658495d61f.zip |
runtime: add maps.clone
Fixes #4382
Diffstat (limited to 'src/runtime')
-rw-r--r-- | src/runtime/hashmap.go | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go index 93bbb2f41..7b46b42be 100644 --- a/src/runtime/hashmap.go +++ b/src/runtime/hashmap.go @@ -281,13 +281,26 @@ func hashmapInsertIntoNewBucket(m *hashmap, key, value unsafe.Pointer, tophash u } func hashmapGrow(m *hashmap) { + // allocate our new buckets twice as big + n := hashmapCopy(m, m.bucketBits+1) + *m = n +} + +//go:linkname hashmapClone maps.clone +func hashmapClone(intf _interface) _interface { + typ, val := decomposeInterface(intf) + m := (*hashmap)(val) + n := hashmapCopy(m, m.bucketBits) + return composeInterface(typ, unsafe.Pointer(&n)) +} + +func hashmapCopy(m *hashmap, sizeBits uint8) hashmap { // clone map as empty n := *m n.count = 0 n.seed = uintptr(fastrand()) - // allocate our new buckets twice as big - n.bucketBits = m.bucketBits + 1 + n.bucketBits = sizeBits numBuckets := uintptr(1) << n.bucketBits bucketBufSize := hashmapBucketSize(m) n.buckets = alloc(bucketBufSize*numBuckets, nil) @@ -303,7 +316,7 @@ func hashmapGrow(m *hashmap) { hashmapSet(&n, key, value, h) } - *m = n + return n } // Get the value of a specified key, or zero the value if not found. |