aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDamian Gryski <[email protected]>2023-04-28 23:01:51 -0700
committerRon Evans <[email protected]>2023-06-09 17:30:02 +0200
commit62fb386d57a0080881c756000e42a2c873372eb8 (patch)
treeef4e399b665c6bed69f83389567a8cf0221be62d
parenta59f92daf8cc279eb5252ca08fc72604b8c956e1 (diff)
downloadtinygo-62fb386d57a0080881c756000e42a2c873372eb8.tar.gz
tinygo-62fb386d57a0080881c756000e42a2c873372eb8.zip
compiler,reflect: add tagged pointers for **T etc
-rw-r--r--compiler/interface.go15
-rw-r--r--src/reflect/type.go23
2 files changed, 37 insertions, 1 deletions
diff --git a/compiler/interface.go b/compiler/interface.go
index 6a9e638b5..7b49a81d4 100644
--- a/compiler/interface.go
+++ b/compiler/interface.go
@@ -127,6 +127,18 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
if _, ok := typ.Underlying().(*types.Interface); ok {
hasMethodSet = false
}
+
+ // Short-circuit all the global pointer logic here for pointers to pointers.
+ if typ, ok := typ.(*types.Pointer); ok {
+ if _, ok := typ.Elem().(*types.Pointer); ok {
+ // For a pointer to a pointer, we just increase the pointer by 1
+ ptr := c.getTypeCode(typ.Elem())
+ return llvm.ConstGEP(c.ctx.Int8Type(), ptr, []llvm.Value{
+ llvm.ConstInt(llvm.Int32Type(), 1, false),
+ })
+ }
+ }
+
typeCodeName, isLocal := getTypeCodeName(typ)
globalName := "reflect/types.type:" + typeCodeName
var global llvm.Value
@@ -391,6 +403,9 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
}, typeFields...)
}
alignment := c.targetData.TypeAllocSize(c.i8ptrType)
+ if alignment < 4 {
+ alignment = 4
+ }
globalValue := c.ctx.ConstStruct(typeFields, false)
global.SetInitializer(globalValue)
if isLocal {
diff --git a/src/reflect/type.go b/src/reflect/type.go
index 00b47a7e1..220179003 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -477,7 +477,15 @@ func (t *rawType) underlying() *rawType {
return t
}
+func (t *rawType) ptrtag() uintptr {
+ return uintptr(unsafe.Pointer(t)) & 0b11
+}
+
func (t *rawType) isNamed() bool {
+ if tag := t.ptrtag(); tag != 0 {
+ return false
+ }
+
return t.meta&flagNamed != 0
}
@@ -502,9 +510,13 @@ func pointerTo(t *rawType) *rawType {
switch t.Kind() {
case Pointer:
+ if tag := t.ptrtag(); tag < 3 {
+ return (*rawType)(unsafe.Add(unsafe.Pointer(t), 1))
+ }
+
// TODO(dgryski): This is blocking https://github.com/tinygo-org/tinygo/issues/3131
// We need to be able to create types that match existing types to prevent typecode equality.
- panic("reflect: cannot make **T type")
+ panic("reflect: cannot make *****T type")
case Struct:
return (*structType)(unsafe.Pointer(t)).ptrTo
default:
@@ -581,6 +593,11 @@ func (t *rawType) Kind() Kind {
if t == nil {
return Invalid
}
+
+ if tag := t.ptrtag(); tag != 0 {
+ return Pointer
+ }
+
return Kind(t.meta & kindMask)
}
@@ -591,6 +608,10 @@ func (t *rawType) Elem() Type {
}
func (t *rawType) elem() *rawType {
+ if tag := t.ptrtag(); tag != 0 {
+ return (*rawType)(unsafe.Add(unsafe.Pointer(t), -1))
+ }
+
underlying := t.underlying()
switch underlying.Kind() {
case Pointer: