mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-03 02:27:48 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 73dc9963ed |
@@ -225,6 +225,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
|||||||
)
|
)
|
||||||
case *types.Map:
|
case *types.Map:
|
||||||
typeFieldTypes = append(typeFieldTypes,
|
typeFieldTypes = append(typeFieldTypes,
|
||||||
|
types.NewVar(token.NoPos, nil, "extraFlags", types.Typ[types.Uint8]),
|
||||||
types.NewVar(token.NoPos, nil, "numMethods", types.Typ[types.Uint16]),
|
types.NewVar(token.NoPos, nil, "numMethods", types.Typ[types.Uint16]),
|
||||||
types.NewVar(token.NoPos, nil, "ptrTo", types.Typ[types.UnsafePointer]),
|
types.NewVar(token.NoPos, nil, "ptrTo", types.Typ[types.UnsafePointer]),
|
||||||
types.NewVar(token.NoPos, nil, "elementType", types.Typ[types.UnsafePointer]),
|
types.NewVar(token.NoPos, nil, "elementType", types.Typ[types.UnsafePointer]),
|
||||||
@@ -273,10 +274,6 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
|||||||
metabyte |= 1 << 6
|
metabyte |= 1 << 6
|
||||||
}
|
}
|
||||||
|
|
||||||
if hashmapIsBinaryKey(typ) {
|
|
||||||
metabyte |= 1 << 7
|
|
||||||
}
|
|
||||||
|
|
||||||
switch typ := typ.(type) {
|
switch typ := typ.(type) {
|
||||||
case *types.Basic:
|
case *types.Basic:
|
||||||
typeFields = []llvm.Value{c.getTypeCode(types.NewPointer(typ))}
|
typeFields = []llvm.Value{c.getTypeCode(types.NewPointer(typ))}
|
||||||
@@ -333,7 +330,12 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
|||||||
c.getTypeCode(types.NewSlice(typ.Elem())), // slicePtr
|
c.getTypeCode(types.NewSlice(typ.Elem())), // slicePtr
|
||||||
}
|
}
|
||||||
case *types.Map:
|
case *types.Map:
|
||||||
|
var extraFlags uint8
|
||||||
|
if hashmapIsBinaryKey(typ.Key()) {
|
||||||
|
extraFlags |= 1 // extraFlagIsBinaryKey
|
||||||
|
}
|
||||||
typeFields = []llvm.Value{
|
typeFields = []llvm.Value{
|
||||||
|
llvm.ConstInt(c.ctx.Int8Type(), uint64(extraFlags), false),
|
||||||
llvm.ConstInt(c.ctx.Int16Type(), 0, false), // numMethods
|
llvm.ConstInt(c.ctx.Int16Type(), 0, false), // numMethods
|
||||||
c.getTypeCode(types.NewPointer(typ)), // ptrTo
|
c.getTypeCode(types.NewPointer(typ)), // ptrTo
|
||||||
c.getTypeCode(typ.Elem()), // elem
|
c.getTypeCode(typ.Elem()), // elem
|
||||||
|
|||||||
Vendored
+1
-1
@@ -22,7 +22,7 @@ target triple = "wasm32-unknown-wasi"
|
|||||||
@"runtime/gc.layout:62-2000000000000001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00 " }
|
@"runtime/gc.layout:62-2000000000000001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00 " }
|
||||||
@"runtime/gc.layout:62-0001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00\00" }
|
@"runtime/gc.layout:62-0001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00\00" }
|
||||||
@"reflect/types.type:basic:complex128" = linkonce_odr constant { i8, ptr } { i8 80, ptr @"reflect/types.type:pointer:basic:complex128" }, align 4
|
@"reflect/types.type:basic:complex128" = linkonce_odr constant { i8, ptr } { i8 80, ptr @"reflect/types.type:pointer:basic:complex128" }, align 4
|
||||||
@"reflect/types.type:pointer:basic:complex128" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:basic:complex128" }, align 4
|
@"reflect/types.type:pointer:basic:complex128" = linkonce_odr constant { i8, i16, ptr } { i8 85, i16 0, ptr @"reflect/types.type:basic:complex128" }, align 4
|
||||||
|
|
||||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|||||||
Vendored
+5
-5
@@ -6,14 +6,14 @@ target triple = "wasm32-unknown-wasi"
|
|||||||
%runtime._interface = type { ptr, ptr }
|
%runtime._interface = type { ptr, ptr }
|
||||||
%runtime._string = type { ptr, i32 }
|
%runtime._string = type { ptr, i32 }
|
||||||
|
|
||||||
@"reflect/types.type:basic:int" = linkonce_odr constant { i8, ptr } { i8 -62, ptr @"reflect/types.type:pointer:basic:int" }, align 4
|
@"reflect/types.type:basic:int" = linkonce_odr constant { i8, ptr } { i8 66, ptr @"reflect/types.type:pointer:basic:int" }, align 4
|
||||||
@"reflect/types.type:pointer:basic:int" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:basic:int" }, align 4
|
@"reflect/types.type:pointer:basic:int" = linkonce_odr constant { i8, i16, ptr } { i8 85, i16 0, ptr @"reflect/types.type:basic:int" }, align 4
|
||||||
@"reflect/types.type:pointer:named:error" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:named:error" }, align 4
|
@"reflect/types.type:pointer:named:error" = linkonce_odr constant { i8, i16, ptr } { i8 85, i16 0, ptr @"reflect/types.type:named:error" }, align 4
|
||||||
@"reflect/types.type:named:error" = linkonce_odr constant { i8, i16, ptr, ptr, ptr, [7 x i8] } { i8 116, i16 1, ptr @"reflect/types.type:pointer:named:error", ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", ptr @"reflect/types.type.pkgpath.empty", [7 x i8] c".error\00" }, align 4
|
@"reflect/types.type:named:error" = linkonce_odr constant { i8, i16, ptr, ptr, ptr, [7 x i8] } { i8 116, i16 1, ptr @"reflect/types.type:pointer:named:error", ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", ptr @"reflect/types.type.pkgpath.empty", [7 x i8] c".error\00" }, align 4
|
||||||
@"reflect/types.type.pkgpath.empty" = linkonce_odr unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
@"reflect/types.type.pkgpath.empty" = linkonce_odr unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
||||||
@"reflect/types.type:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr } { i8 84, ptr @"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" }, align 4
|
@"reflect/types.type:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr } { i8 84, ptr @"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" }, align 4
|
||||||
@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}" }, align 4
|
@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, i16, ptr } { i8 85, i16 0, ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}" }, align 4
|
||||||
@"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:interface:{String:func:{}{basic:string}}" }, align 4
|
@"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" = linkonce_odr constant { i8, i16, ptr } { i8 85, i16 0, ptr @"reflect/types.type:interface:{String:func:{}{basic:string}}" }, align 4
|
||||||
@"reflect/types.type:interface:{String:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr } { i8 84, ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" }, align 4
|
@"reflect/types.type:interface:{String:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr } { i8 84, ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" }, align 4
|
||||||
@"reflect/types.typeid:basic:int" = external constant i8
|
@"reflect/types.typeid:basic:int" = external constant i8
|
||||||
|
|
||||||
|
|||||||
+19
-12
@@ -30,8 +30,9 @@
|
|||||||
// elem *typeStruct // element type of the array
|
// elem *typeStruct // element type of the array
|
||||||
// arrayLen uintptr // length of the array (this is part of the type)
|
// arrayLen uintptr // length of the array (this is part of the type)
|
||||||
// slicePtr *typeStruct // pointer to []T type
|
// slicePtr *typeStruct // pointer to []T type
|
||||||
// - map types (this is still missing the key and element types)
|
// - map types
|
||||||
// meta uint8
|
// meta uint8
|
||||||
|
// extraMeta uint8
|
||||||
// nmethods uint16 (0)
|
// nmethods uint16 (0)
|
||||||
// ptrTo *typeStruct
|
// ptrTo *typeStruct
|
||||||
// elem *typeStruct
|
// elem *typeStruct
|
||||||
@@ -396,10 +397,14 @@ type Type interface {
|
|||||||
|
|
||||||
// Constants for the 'meta' byte.
|
// Constants for the 'meta' byte.
|
||||||
const (
|
const (
|
||||||
kindMask = 31 // mask to apply to the meta byte to get the Kind value
|
kindMask = 31 // mask to apply to the meta byte to get the Kind value
|
||||||
flagNamed = 32 // flag that is set if this is a named type
|
flagNamed = 32 // flag that is set if this is a named type
|
||||||
flagComparable = 64 // flag that is set if this type is comparable
|
flagComparable = 64 // flag that is set if this type is comparable
|
||||||
flagIsBinary = 128 // flag that is set if this type uses the hashmap binary algorithm
|
)
|
||||||
|
|
||||||
|
// Constants for the 'extraFlags' byte in the map type.
|
||||||
|
const (
|
||||||
|
extraFlagIsBinaryKey = 1 // flag that is set if this type uses the hashmap binary algorithm
|
||||||
)
|
)
|
||||||
|
|
||||||
// The base type struct. All type structs start with this.
|
// The base type struct. All type structs start with this.
|
||||||
@@ -433,10 +438,11 @@ type arrayType struct {
|
|||||||
|
|
||||||
type mapType struct {
|
type mapType struct {
|
||||||
rawType
|
rawType
|
||||||
numMethod uint16
|
extraFlags uint8
|
||||||
ptrTo *rawType
|
numMethod uint16
|
||||||
elem *rawType
|
ptrTo *rawType
|
||||||
key *rawType
|
elem *rawType
|
||||||
|
key *rawType
|
||||||
}
|
}
|
||||||
|
|
||||||
type namedType struct {
|
type namedType struct {
|
||||||
@@ -980,9 +986,10 @@ func (t *rawType) Comparable() bool {
|
|||||||
return (t.meta & flagComparable) == flagComparable
|
return (t.meta & flagComparable) == flagComparable
|
||||||
}
|
}
|
||||||
|
|
||||||
// isBinary returns if the hashmapAlgorithmBinary functions can be used on this type
|
// isBinaryKey returns if the hashmapAlgorithmBinary functions can be used on
|
||||||
func (t *rawType) isBinary() bool {
|
// the key type of this map.
|
||||||
return (t.meta & flagIsBinary) == flagIsBinary
|
func (t *mapType) isBinaryKey() bool {
|
||||||
|
return t.extraFlags&extraFlagIsBinaryKey != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *rawType) ChanDir() ChanDir {
|
func (t *rawType) ChanDir() ChanDir {
|
||||||
|
|||||||
+12
-7
@@ -947,9 +947,10 @@ func (v Value) MapKeys() []Value {
|
|||||||
k := New(v.typecode.Key())
|
k := New(v.typecode.Key())
|
||||||
e := New(v.typecode.Elem())
|
e := New(v.typecode.Elem())
|
||||||
|
|
||||||
|
typecode := (*mapType)(unsafe.Pointer((v.typecode.underlying())))
|
||||||
keyType := v.typecode.key()
|
keyType := v.typecode.key()
|
||||||
keyTypeIsEmptyInterface := keyType.Kind() == Interface && keyType.NumMethod() == 0
|
keyTypeIsEmptyInterface := keyType.Kind() == Interface && keyType.NumMethod() == 0
|
||||||
shouldUnpackInterface := !keyTypeIsEmptyInterface && keyType.Kind() != String && !keyType.isBinary()
|
shouldUnpackInterface := !keyTypeIsEmptyInterface && keyType.Kind() != String && !typecode.isBinaryKey()
|
||||||
|
|
||||||
for hashmapNext(v.pointer(), it, k.value, e.value) {
|
for hashmapNext(v.pointer(), it, k.value, e.value) {
|
||||||
if shouldUnpackInterface {
|
if shouldUnpackInterface {
|
||||||
@@ -979,6 +980,7 @@ func (v Value) MapIndex(key Value) Value {
|
|||||||
panic(&ValueError{Method: "MapIndex", Kind: v.Kind()})
|
panic(&ValueError{Method: "MapIndex", Kind: v.Kind()})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typecode := (*mapType)(unsafe.Pointer(v.typecode.underlying()))
|
||||||
vkey := v.typecode.key()
|
vkey := v.typecode.key()
|
||||||
|
|
||||||
// compare key type with actual key type of map
|
// compare key type with actual key type of map
|
||||||
@@ -997,7 +999,7 @@ func (v Value) MapIndex(key Value) Value {
|
|||||||
return Value{}
|
return Value{}
|
||||||
}
|
}
|
||||||
return elem.Elem()
|
return elem.Elem()
|
||||||
} else if vkey.isBinary() {
|
} else if typecode.isBinaryKey() {
|
||||||
var keyptr unsafe.Pointer
|
var keyptr unsafe.Pointer
|
||||||
if key.isIndirect() || key.typecode.Size() > unsafe.Sizeof(uintptr(0)) {
|
if key.isIndirect() || key.typecode.Size() > unsafe.Sizeof(uintptr(0)) {
|
||||||
keyptr = key.value
|
keyptr = key.value
|
||||||
@@ -1028,10 +1030,11 @@ func (v Value) MapRange() *MapIter {
|
|||||||
panic(&ValueError{Method: "MapRange", Kind: v.Kind()})
|
panic(&ValueError{Method: "MapRange", Kind: v.Kind()})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typecode := (*mapType)(unsafe.Pointer(v.typecode.underlying()))
|
||||||
keyType := v.typecode.key()
|
keyType := v.typecode.key()
|
||||||
|
|
||||||
keyTypeIsEmptyInterface := keyType.Kind() == Interface && keyType.NumMethod() == 0
|
keyTypeIsEmptyInterface := keyType.Kind() == Interface && keyType.NumMethod() == 0
|
||||||
shouldUnpackInterface := !keyTypeIsEmptyInterface && keyType.Kind() != String && !keyType.isBinary()
|
shouldUnpackInterface := !keyTypeIsEmptyInterface && keyType.Kind() != String && !typecode.isBinaryKey()
|
||||||
|
|
||||||
return &MapIter{
|
return &MapIter{
|
||||||
m: v,
|
m: v,
|
||||||
@@ -1824,6 +1827,7 @@ func (v Value) SetMapIndex(key, elem Value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vkey := v.typecode.key()
|
vkey := v.typecode.key()
|
||||||
|
typecode := (*mapType)(unsafe.Pointer(v.typecode.underlying()))
|
||||||
|
|
||||||
// compare key type with actual key type of map
|
// compare key type with actual key type of map
|
||||||
if !key.typecode.AssignableTo(vkey) {
|
if !key.typecode.AssignableTo(vkey) {
|
||||||
@@ -1859,7 +1863,7 @@ func (v Value) SetMapIndex(key, elem Value) {
|
|||||||
hashmapStringSet(v.pointer(), *(*string)(key.value), elemptr)
|
hashmapStringSet(v.pointer(), *(*string)(key.value), elemptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if key.typecode.isBinary() {
|
} else if typecode.isBinaryKey() {
|
||||||
var keyptr unsafe.Pointer
|
var keyptr unsafe.Pointer
|
||||||
if key.isIndirect() || key.typecode.Size() > unsafe.Sizeof(uintptr(0)) {
|
if key.isIndirect() || key.typecode.Size() > unsafe.Sizeof(uintptr(0)) {
|
||||||
keyptr = key.value
|
keyptr = key.value
|
||||||
@@ -1965,14 +1969,15 @@ func MakeMapWithSize(typ Type, n int) Value {
|
|||||||
panic("reflect.MakeMapWithSize: negative size hint")
|
panic("reflect.MakeMapWithSize: negative size hint")
|
||||||
}
|
}
|
||||||
|
|
||||||
key := typ.Key().(*rawType)
|
typecode := (*mapType)(unsafe.Pointer(typ.(*rawType).underlying()))
|
||||||
val := typ.Elem().(*rawType)
|
key := typecode.rawType.key()
|
||||||
|
val := typecode.rawType.elem()
|
||||||
|
|
||||||
var alg uint8
|
var alg uint8
|
||||||
|
|
||||||
if key.Kind() == String {
|
if key.Kind() == String {
|
||||||
alg = hashmapAlgorithmString
|
alg = hashmapAlgorithmString
|
||||||
} else if key.isBinary() {
|
} else if typecode.isBinaryKey() {
|
||||||
alg = hashmapAlgorithmBinary
|
alg = hashmapAlgorithmBinary
|
||||||
} else {
|
} else {
|
||||||
alg = hashmapAlgorithmInterface
|
alg = hashmapAlgorithmInterface
|
||||||
|
|||||||
Reference in New Issue
Block a user