Skip to content

Commit

Permalink
compiler, runtime: move constants into shared package
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
aykevl committed Nov 15, 2024
1 parent ac9f72b commit 6d4dfcf
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 40 deletions.
6 changes: 3 additions & 3 deletions compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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":
Expand Down
16 changes: 5 additions & 11 deletions compiler/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,32 @@ 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) {
mapType := expr.Type().Underlying().(*types.Map)
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)
Expand Down
1 change: 1 addition & 0 deletions loader/goroot.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ func pathsToOverride(goMinor int, needsSyscallPackage bool) map[string]bool {
"runtime/": false,
"sync/": true,
"testing/": true,
"tinygo/": false,
"unique/": false,
}

Expand Down
29 changes: 11 additions & 18 deletions src/runtime/hashmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package runtime

import (
"reflect"
"tinygo"
"unsafe"
)

Expand All @@ -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
Expand Down Expand Up @@ -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<<bucketBits), nil)

keyHash := hashmapKeyHashAlg(hashmapAlgorithm(alg))
keyEqual := hashmapKeyEqualAlg(hashmapAlgorithm(alg))
keyHash := hashmapKeyHashAlg(tinygo.HashmapAlgorithm(alg))
keyEqual := hashmapKeyEqualAlg(tinygo.HashmapAlgorithm(alg))

return &hashmap{
buckets: buckets,
Expand Down Expand Up @@ -119,27 +112,27 @@ func hashmapClear(m *hashmap) {
}
}

func hashmapKeyEqualAlg(alg hashmapAlgorithm) func(x, y unsafe.Pointer, n uintptr) bool {
func hashmapKeyEqualAlg(alg tinygo.HashmapAlgorithm) func(x, y unsafe.Pointer, n uintptr) bool {
switch alg {
case hashmapAlgorithmBinary:
case tinygo.HashmapAlgorithmBinary:
return memequal
case hashmapAlgorithmString:
case tinygo.HashmapAlgorithmString:
return hashmapStringEqual
case hashmapAlgorithmInterface:
case tinygo.HashmapAlgorithmInterface:
return hashmapInterfaceEqual
default:
// compiler bug :(
return nil
}
}

func hashmapKeyHashAlg(alg hashmapAlgorithm) func(key unsafe.Pointer, n, seed uintptr) uint32 {
func hashmapKeyHashAlg(alg tinygo.HashmapAlgorithm) func(key unsafe.Pointer, n, seed uintptr) uint32 {
switch alg {
case hashmapAlgorithmBinary:
case tinygo.HashmapAlgorithmBinary:
return hash32
case hashmapAlgorithmString:
case tinygo.HashmapAlgorithmString:
return hashmapStringPtrHash
case hashmapAlgorithmInterface:
case tinygo.HashmapAlgorithmInterface:
return hashmapInterfacePtrHash
default:
// compiler bug :(
Expand Down
10 changes: 3 additions & 7 deletions src/runtime/panic.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package runtime
import (
"internal/task"
"runtime/interrupt"
"tinygo"
"unsafe"
)

Expand All @@ -22,11 +23,6 @@ func tinygo_longjmp(frame *deferFrame)
// Returns whether recover is supported on the current architecture.
func supportsRecover() bool

const (
panicStrategyPrint = 1
panicStrategyTrap = 2
)

// Compile intrinsic.
// Returns which strategy is used. This is usually "print" but can be changed
// using the -panic= compiler flag.
Expand All @@ -48,7 +44,7 @@ type deferFrame struct {

// Builtin function panic(msg), used as a compiler intrinsic.
func _panic(message interface{}) {
if panicStrategy() == panicStrategyTrap {
if panicStrategy() == tinygo.PanicStrategyTrap {
trap()
}
// Note: recover is not supported inside interrupts.
Expand Down Expand Up @@ -76,7 +72,7 @@ func runtimePanic(msg string) {
}

func runtimePanicAt(addr unsafe.Pointer, msg string) {
if panicStrategy() == panicStrategyTrap {
if panicStrategy() == tinygo.PanicStrategyTrap {
trap()
}
if hasReturnAddr {
Expand Down
3 changes: 2 additions & 1 deletion src/runtime/runtime_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package runtime
import (
"math/bits"
"sync/atomic"
"tinygo"
"unsafe"
)

Expand Down Expand Up @@ -141,7 +142,7 @@ func tinygo_register_fatal_signals()
//
//export tinygo_handle_fatal_signal
func tinygo_handle_fatal_signal(sig int32, addr uintptr) {
if panicStrategy() == panicStrategyTrap {
if panicStrategy() == tinygo.PanicStrategyTrap {
trap()
}

Expand Down
17 changes: 17 additions & 0 deletions src/tinygo/runtime.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Package tinygo contains constants used between the TinyGo compiler and
// runtime.
package tinygo

const (
PanicStrategyPrint = iota + 1
PanicStrategyTrap
)

type HashmapAlgorithm uint8

// Constants for hashmap algorithms.
const (
HashmapAlgorithmBinary HashmapAlgorithm = iota
HashmapAlgorithmString
HashmapAlgorithmInterface
)

0 comments on commit 6d4dfcf

Please sign in to comment.