From 504c82a0e7edab55d2c9b326309151a9d7f32750 Mon Sep 17 00:00:00 2001 From: Konstantin Yegupov Date: Thu, 31 Jan 2019 01:12:57 +1000 Subject: [PATCH] compiler: support for byte arrays as keys in maps --- compiler/map.go | 4 ++++ interp/values.go | 7 +++++++ testdata/map.go | 12 ++++++++++++ testdata/map.txt | 2 ++ 4 files changed, 25 insertions(+) diff --git a/compiler/map.go b/compiler/map.go index 88547b1f..dc5ddead 100644 --- a/compiler/map.go +++ b/compiler/map.go @@ -120,6 +120,10 @@ func hashmapIsBinaryKey(keyType types.Type) bool { } } return true + case *types.Array: + return hashmapIsBinaryKey(keyType.Elem()) + case *types.Named: + return hashmapIsBinaryKey(keyType.Underlying()) default: return false } diff --git a/interp/values.go b/interp/values.go index c4f6e302..a6b5336a 100644 --- a/interp/values.go +++ b/interp/values.go @@ -451,6 +451,13 @@ func (v *MapValue) Value() llvm.Value { keyBuf[i] = byte(n) n >>= 8 } + } else if key.Type().TypeKind() == llvm.ArrayTypeKind && + key.Type().ElementType().TypeKind() == llvm.IntegerTypeKind && + key.Type().ElementType().IntTypeWidth() == 8 { + keyBuf = make([]byte, v.Eval.TargetData.TypeAllocSize(key.Type())) + for i := range keyBuf { + keyBuf[i] = byte(llvm.ConstExtractValue(llvmKey, []uint32{uint32(i)}).ZExtValue()) + } } else { panic("interp: map key type not implemented: " + key.Type().String()) } diff --git a/testdata/map.go b/testdata/map.go index 5b97bf5d..fdf61502 100644 --- a/testdata/map.go +++ b/testdata/map.go @@ -15,6 +15,13 @@ var testmap2 = map[string]int{ "eleven": 11, "twelve": 12, } + +type ArrayKey [4]byte + +var testMapArrayKey = map[ArrayKey]int{ + ArrayKey([4]byte{1, 2, 3, 4}): 1234, + ArrayKey([4]byte{4, 3, 2, 1}): 4321, +} var testmapIntInt = map[int]int{1: 1, 2: 4, 3: 9} func main() { @@ -35,6 +42,11 @@ func main() { println(testmapIntInt[2]) testmapIntInt[2] = 42 println(testmapIntInt[2]) + + arrKey := ArrayKey([4]byte{4, 3, 2, 1}) + println(testMapArrayKey[arrKey]) + testMapArrayKey[arrKey] = 5555 + println(testMapArrayKey[arrKey]) } func readMap(m map[string]int, key string) { diff --git a/testdata/map.txt b/testdata/map.txt index a11e421c..a41522f7 100644 --- a/testdata/map.txt +++ b/testdata/map.txt @@ -52,3 +52,5 @@ false true 2 true false 0 4 42 +4321 +5555