mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-12 15:03:41 +00:00
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.
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
|||||||
|
|
||||||
"github.com/tinygo-org/tinygo/compiler/llvmutil"
|
"github.com/tinygo-org/tinygo/compiler/llvmutil"
|
||||||
"github.com/tinygo-org/tinygo/loader"
|
"github.com/tinygo-org/tinygo/loader"
|
||||||
|
"github.com/tinygo-org/tinygo/src/tinygo"
|
||||||
"golang.org/x/tools/go/ssa"
|
"golang.org/x/tools/go/ssa"
|
||||||
"golang.org/x/tools/go/types/typeutil"
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
"tinygo.org/x/go-llvm"
|
"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
|
return llvm.ConstInt(b.ctx.Int1Type(), supportsRecover, false), nil
|
||||||
case name == "runtime.panicStrategy":
|
case name == "runtime.panicStrategy":
|
||||||
// These constants are defined in src/runtime/panic.go.
|
|
||||||
panicStrategy := map[string]uint64{
|
panicStrategy := map[string]uint64{
|
||||||
"print": 1, // panicStrategyPrint
|
"print": tinygo.PanicStrategyPrint,
|
||||||
"trap": 2, // panicStrategyTrap
|
"trap": tinygo.PanicStrategyTrap,
|
||||||
}[b.Config.PanicStrategy]
|
}[b.Config.PanicStrategy]
|
||||||
return llvm.ConstInt(b.ctx.Int8Type(), panicStrategy, false), nil
|
return llvm.ConstInt(b.ctx.Int8Type(), panicStrategy, false), nil
|
||||||
case name == "runtime/interrupt.New":
|
case name == "runtime/interrupt.New":
|
||||||
|
|||||||
+5
-11
@@ -6,17 +6,11 @@ import (
|
|||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
|
|
||||||
|
"github.com/tinygo-org/tinygo/src/tinygo"
|
||||||
"golang.org/x/tools/go/ssa"
|
"golang.org/x/tools/go/ssa"
|
||||||
"tinygo.org/x/go-llvm"
|
"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
|
// createMakeMap creates a new map object (runtime.hashmap) by allocating and
|
||||||
// initializing an appropriately sized object.
|
// initializing an appropriately sized object.
|
||||||
func (b *builder) createMakeMap(expr *ssa.MakeMap) (llvm.Value, error) {
|
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()
|
keyType := mapType.Key().Underlying()
|
||||||
llvmValueType := b.getLLVMType(mapType.Elem().Underlying())
|
llvmValueType := b.getLLVMType(mapType.Elem().Underlying())
|
||||||
var llvmKeyType llvm.Type
|
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 {
|
if t, ok := keyType.(*types.Basic); ok && t.Info()&types.IsString != 0 {
|
||||||
// String keys.
|
// String keys.
|
||||||
llvmKeyType = b.getLLVMType(keyType)
|
llvmKeyType = b.getLLVMType(keyType)
|
||||||
alg = hashmapAlgorithmString
|
alg = uint64(tinygo.HashmapAlgorithmString)
|
||||||
} else if hashmapIsBinaryKey(keyType) {
|
} else if hashmapIsBinaryKey(keyType) {
|
||||||
// Trivially comparable keys.
|
// Trivially comparable keys.
|
||||||
llvmKeyType = b.getLLVMType(keyType)
|
llvmKeyType = b.getLLVMType(keyType)
|
||||||
alg = hashmapAlgorithmBinary
|
alg = uint64(tinygo.HashmapAlgorithmBinary)
|
||||||
} else {
|
} else {
|
||||||
// All other keys. Implemented as map[interface{}]valueType for ease of
|
// All other keys. Implemented as map[interface{}]valueType for ease of
|
||||||
// implementation.
|
// implementation.
|
||||||
llvmKeyType = b.getLLVMRuntimeType("_interface")
|
llvmKeyType = b.getLLVMRuntimeType("_interface")
|
||||||
alg = hashmapAlgorithmInterface
|
alg = uint64(tinygo.HashmapAlgorithmInterface)
|
||||||
}
|
}
|
||||||
keySize := b.targetData.TypeAllocSize(llvmKeyType)
|
keySize := b.targetData.TypeAllocSize(llvmKeyType)
|
||||||
valueSize := b.targetData.TypeAllocSize(llvmValueType)
|
valueSize := b.targetData.TypeAllocSize(llvmValueType)
|
||||||
|
|||||||
@@ -256,6 +256,7 @@ func pathsToOverride(goMinor int, needsSyscallPackage bool) map[string]bool {
|
|||||||
"runtime/": false,
|
"runtime/": false,
|
||||||
"sync/": true,
|
"sync/": true,
|
||||||
"testing/": true,
|
"testing/": true,
|
||||||
|
"tinygo/": false,
|
||||||
"unique/": false,
|
"unique/": false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-18
@@ -7,6 +7,7 @@ package runtime
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"tinygo"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,14 +23,6 @@ type hashmap struct {
|
|||||||
keyHash func(key unsafe.Pointer, size, seed uintptr) uint32
|
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
|
// 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
|
// 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
|
// 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
|
bucketBufSize := unsafe.Sizeof(hashmapBucket{}) + keySize*8 + valueSize*8
|
||||||
buckets := alloc(bucketBufSize*(1<<bucketBits), nil)
|
buckets := alloc(bucketBufSize*(1<<bucketBits), nil)
|
||||||
|
|
||||||
keyHash := hashmapKeyHashAlg(hashmapAlgorithm(alg))
|
keyHash := hashmapKeyHashAlg(tinygo.HashmapAlgorithm(alg))
|
||||||
keyEqual := hashmapKeyEqualAlg(hashmapAlgorithm(alg))
|
keyEqual := hashmapKeyEqualAlg(tinygo.HashmapAlgorithm(alg))
|
||||||
|
|
||||||
return &hashmap{
|
return &hashmap{
|
||||||
buckets: buckets,
|
buckets: buckets,
|
||||||
@@ -119,13 +112,13 @@ 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 {
|
switch alg {
|
||||||
case hashmapAlgorithmBinary:
|
case tinygo.HashmapAlgorithmBinary:
|
||||||
return memequal
|
return memequal
|
||||||
case hashmapAlgorithmString:
|
case tinygo.HashmapAlgorithmString:
|
||||||
return hashmapStringEqual
|
return hashmapStringEqual
|
||||||
case hashmapAlgorithmInterface:
|
case tinygo.HashmapAlgorithmInterface:
|
||||||
return hashmapInterfaceEqual
|
return hashmapInterfaceEqual
|
||||||
default:
|
default:
|
||||||
// compiler bug :(
|
// compiler bug :(
|
||||||
@@ -133,13 +126,13 @@ func hashmapKeyEqualAlg(alg hashmapAlgorithm) func(x, y unsafe.Pointer, n uintpt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
switch alg {
|
||||||
case hashmapAlgorithmBinary:
|
case tinygo.HashmapAlgorithmBinary:
|
||||||
return hash32
|
return hash32
|
||||||
case hashmapAlgorithmString:
|
case tinygo.HashmapAlgorithmString:
|
||||||
return hashmapStringPtrHash
|
return hashmapStringPtrHash
|
||||||
case hashmapAlgorithmInterface:
|
case tinygo.HashmapAlgorithmInterface:
|
||||||
return hashmapInterfacePtrHash
|
return hashmapInterfacePtrHash
|
||||||
default:
|
default:
|
||||||
// compiler bug :(
|
// compiler bug :(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package runtime
|
|||||||
import (
|
import (
|
||||||
"internal/task"
|
"internal/task"
|
||||||
"runtime/interrupt"
|
"runtime/interrupt"
|
||||||
|
"tinygo"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,11 +23,6 @@ func tinygo_longjmp(frame *deferFrame)
|
|||||||
// Returns whether recover is supported on the current architecture.
|
// Returns whether recover is supported on the current architecture.
|
||||||
func supportsRecover() bool
|
func supportsRecover() bool
|
||||||
|
|
||||||
const (
|
|
||||||
panicStrategyPrint = 1
|
|
||||||
panicStrategyTrap = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
// Compile intrinsic.
|
// Compile intrinsic.
|
||||||
// Returns which strategy is used. This is usually "print" but can be changed
|
// Returns which strategy is used. This is usually "print" but can be changed
|
||||||
// using the -panic= compiler flag.
|
// using the -panic= compiler flag.
|
||||||
@@ -48,7 +44,7 @@ type deferFrame struct {
|
|||||||
|
|
||||||
// Builtin function panic(msg), used as a compiler intrinsic.
|
// Builtin function panic(msg), used as a compiler intrinsic.
|
||||||
func _panic(message interface{}) {
|
func _panic(message interface{}) {
|
||||||
if panicStrategy() == panicStrategyTrap {
|
if panicStrategy() == tinygo.PanicStrategyTrap {
|
||||||
trap()
|
trap()
|
||||||
}
|
}
|
||||||
// Note: recover is not supported inside interrupts.
|
// Note: recover is not supported inside interrupts.
|
||||||
@@ -76,7 +72,7 @@ func runtimePanic(msg string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runtimePanicAt(addr unsafe.Pointer, msg string) {
|
func runtimePanicAt(addr unsafe.Pointer, msg string) {
|
||||||
if panicStrategy() == panicStrategyTrap {
|
if panicStrategy() == tinygo.PanicStrategyTrap {
|
||||||
trap()
|
trap()
|
||||||
}
|
}
|
||||||
if hasReturnAddr {
|
if hasReturnAddr {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package runtime
|
|||||||
import (
|
import (
|
||||||
"math/bits"
|
"math/bits"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"tinygo"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -141,7 +142,7 @@ func tinygo_register_fatal_signals()
|
|||||||
//
|
//
|
||||||
//export tinygo_handle_fatal_signal
|
//export tinygo_handle_fatal_signal
|
||||||
func tinygo_handle_fatal_signal(sig int32, addr uintptr) {
|
func tinygo_handle_fatal_signal(sig int32, addr uintptr) {
|
||||||
if panicStrategy() == panicStrategyTrap {
|
if panicStrategy() == tinygo.PanicStrategyTrap {
|
||||||
trap()
|
trap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user