Skip to content

Commit 62fb386

Browse files
dgryskideadprogram
authored andcommitted
compiler,reflect: add tagged pointers for **T etc
1 parent a59f92d commit 62fb386

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

compiler/interface.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,18 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
127127
if _, ok := typ.Underlying().(*types.Interface); ok {
128128
hasMethodSet = false
129129
}
130+
131+
// Short-circuit all the global pointer logic here for pointers to pointers.
132+
if typ, ok := typ.(*types.Pointer); ok {
133+
if _, ok := typ.Elem().(*types.Pointer); ok {
134+
// For a pointer to a pointer, we just increase the pointer by 1
135+
ptr := c.getTypeCode(typ.Elem())
136+
return llvm.ConstGEP(c.ctx.Int8Type(), ptr, []llvm.Value{
137+
llvm.ConstInt(llvm.Int32Type(), 1, false),
138+
})
139+
}
140+
}
141+
130142
typeCodeName, isLocal := getTypeCodeName(typ)
131143
globalName := "reflect/types.type:" + typeCodeName
132144
var global llvm.Value
@@ -391,6 +403,9 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
391403
}, typeFields...)
392404
}
393405
alignment := c.targetData.TypeAllocSize(c.i8ptrType)
406+
if alignment < 4 {
407+
alignment = 4
408+
}
394409
globalValue := c.ctx.ConstStruct(typeFields, false)
395410
global.SetInitializer(globalValue)
396411
if isLocal {

src/reflect/type.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,15 @@ func (t *rawType) underlying() *rawType {
477477
return t
478478
}
479479

480+
func (t *rawType) ptrtag() uintptr {
481+
return uintptr(unsafe.Pointer(t)) & 0b11
482+
}
483+
480484
func (t *rawType) isNamed() bool {
485+
if tag := t.ptrtag(); tag != 0 {
486+
return false
487+
}
488+
481489
return t.meta&flagNamed != 0
482490
}
483491

@@ -502,9 +510,13 @@ func pointerTo(t *rawType) *rawType {
502510

503511
switch t.Kind() {
504512
case Pointer:
513+
if tag := t.ptrtag(); tag < 3 {
514+
return (*rawType)(unsafe.Add(unsafe.Pointer(t), 1))
515+
}
516+
505517
// TODO(dgryski): This is blocking https://github.com/tinygo-org/tinygo/issues/3131
506518
// We need to be able to create types that match existing types to prevent typecode equality.
507-
panic("reflect: cannot make **T type")
519+
panic("reflect: cannot make *****T type")
508520
case Struct:
509521
return (*structType)(unsafe.Pointer(t)).ptrTo
510522
default:
@@ -581,6 +593,11 @@ func (t *rawType) Kind() Kind {
581593
if t == nil {
582594
return Invalid
583595
}
596+
597+
if tag := t.ptrtag(); tag != 0 {
598+
return Pointer
599+
}
600+
584601
return Kind(t.meta & kindMask)
585602
}
586603

@@ -591,6 +608,10 @@ func (t *rawType) Elem() Type {
591608
}
592609

593610
func (t *rawType) elem() *rawType {
611+
if tag := t.ptrtag(); tag != 0 {
612+
return (*rawType)(unsafe.Add(unsafe.Pointer(t), -1))
613+
}
614+
594615
underlying := t.underlying()
595616
switch underlying.Kind() {
596617
case Pointer:

0 commit comments

Comments
 (0)