aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/runtime
diff options
context:
space:
mode:
authorDamian Gryski <[email protected]>2024-09-18 12:07:33 -0700
committerAyke <[email protected]>2024-10-02 12:40:07 +0200
commitb3e1974c304bb5b676bfdb0e193f40658495d61f (patch)
tree4420e9745cf20be9d4efffd158e12c05c6643d8b /src/runtime
parentfa12450552884e0c37a03d943d97193488c9f527 (diff)
downloadtinygo-b3e1974c304bb5b676bfdb0e193f40658495d61f.tar.gz
tinygo-b3e1974c304bb5b676bfdb0e193f40658495d61f.zip
runtime: add maps.clone
Fixes #4382
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/hashmap.go19
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.