From 6d4dfcf72fb5dd4cc9130c3b883fd313a5b8dac3 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 15 Nov 2024 09:09:04 +0100 Subject: [PATCH] compiler, runtime: move constants into shared package Use a single package for certain constants that must be the same between the compiler and the runtime. While just using the same values in both places works, this is much more obvious and harder to mess up. It also avoids the need for comments pointing to the other location the constant is defined. And having it in code makes it possible for IDEs to analyze the source. In the future, more such constants and maybe algorithms can be added. --- compiler/compiler.go | 6 +++--- compiler/map.go | 16 +++++----------- loader/goroot.go | 1 + src/runtime/hashmap.go | 29 +++++++++++------------------ src/runtime/panic.go | 10 +++------- src/runtime/runtime_unix.go | 3 ++- src/tinygo/runtime.go | 17 +++++++++++++++++ 7 files changed, 42 insertions(+), 40 deletions(-) create mode 100644 src/tinygo/runtime.go diff --git a/compiler/compiler.go b/compiler/compiler.go index 981993fe76..8b5f0d1cb2 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -17,6 +17,7 @@ import ( "github.com/tinygo-org/tinygo/compiler/llvmutil" "github.com/tinygo-org/tinygo/loader" + "github.com/tinygo-org/tinygo/src/tinygo" "golang.org/x/tools/go/ssa" "golang.org/x/tools/go/types/typeutil" "tinygo.org/x/go-llvm" @@ -1869,10 +1870,9 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) } return llvm.ConstInt(b.ctx.Int1Type(), supportsRecover, false), nil case name == "runtime.panicStrategy": - // These constants are defined in src/runtime/panic.go. panicStrategy := map[string]uint64{ - "print": 1, // panicStrategyPrint - "trap": 2, // panicStrategyTrap + "print": tinygo.PanicStrategyPrint, + "trap": tinygo.PanicStrategyTrap, }[b.Config.PanicStrategy] return llvm.ConstInt(b.ctx.Int8Type(), panicStrategy, false), nil case name == "runtime/interrupt.New": diff --git a/compiler/map.go b/compiler/map.go index b4c5267233..71fb3f0da8 100644 --- a/compiler/map.go +++ b/compiler/map.go @@ -6,17 +6,11 @@ import ( "go/token" "go/types" + "github.com/tinygo-org/tinygo/src/tinygo" "golang.org/x/tools/go/ssa" "tinygo.org/x/go-llvm" ) -// constants for hashmap algorithms; must match src/runtime/hashmap.go -const ( - hashmapAlgorithmBinary = iota - hashmapAlgorithmString - hashmapAlgorithmInterface -) - // createMakeMap creates a new map object (runtime.hashmap) by allocating and // initializing an appropriately sized object. func (b *builder) createMakeMap(expr *ssa.MakeMap) (llvm.Value, error) { @@ -24,20 +18,20 @@ func (b *builder) createMakeMap(expr *ssa.MakeMap) (llvm.Value, error) { keyType := mapType.Key().Underlying() llvmValueType := b.getLLVMType(mapType.Elem().Underlying()) var llvmKeyType llvm.Type - var alg uint64 // must match values in src/runtime/hashmap.go + var alg uint64 if t, ok := keyType.(*types.Basic); ok && t.Info()&types.IsString != 0 { // String keys. llvmKeyType = b.getLLVMType(keyType) - alg = hashmapAlgorithmString + alg = uint64(tinygo.HashmapAlgorithmString) } else if hashmapIsBinaryKey(keyType) { // Trivially comparable keys. llvmKeyType = b.getLLVMType(keyType) - alg = hashmapAlgorithmBinary + alg = uint64(tinygo.HashmapAlgorithmBinary) } else { // All other keys. Implemented as map[interface{}]valueType for ease of // implementation. llvmKeyType = b.getLLVMRuntimeType("_interface") - alg = hashmapAlgorithmInterface + alg = uint64(tinygo.HashmapAlgorithmInterface) } keySize := b.targetData.TypeAllocSize(llvmKeyType) valueSize := b.targetData.TypeAllocSize(llvmValueType) diff --git a/loader/goroot.go b/loader/goroot.go index 20fee016bf..631cc6e7e6 100644 --- a/loader/goroot.go +++ b/loader/goroot.go @@ -256,6 +256,7 @@ func pathsToOverride(goMinor int, needsSyscallPackage bool) map[string]bool { "runtime/": false, "sync/": true, "testing/": true, + "tinygo/": false, "unique/": false, } diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go index 7b46b42bef..ad42fda753 100644 --- a/src/runtime/hashmap.go +++ b/src/runtime/hashmap.go @@ -7,6 +7,7 @@ package runtime import ( "reflect" + "tinygo" "unsafe" ) @@ -22,14 +23,6 @@ type hashmap struct { keyHash func(key unsafe.Pointer, size, seed uintptr) uint32 } -type hashmapAlgorithm uint8 - -const ( - hashmapAlgorithmBinary hashmapAlgorithm = iota - hashmapAlgorithmString - hashmapAlgorithmInterface -) - // A hashmap bucket. A bucket is a container of 8 key/value pairs: first the // following two entries, then the 8 keys, then the 8 values. This somewhat odd // ordering is to make sure the keys and values are well aligned when one of @@ -76,8 +69,8 @@ func hashmapMake(keySize, valueSize uintptr, sizeHint uintptr, alg uint8) *hashm bucketBufSize := unsafe.Sizeof(hashmapBucket{}) + keySize*8 + valueSize*8 buckets := alloc(bucketBufSize*(1<