compiler,reflect: add tagged pointers for **T etc

Этот коммит содержится в:
Damian Gryski 2023-04-28 23:01:51 -07:00 коммит произвёл Ron Evans
родитель a59f92daf8
коммит 62fb386d57
2 изменённых файлов: 37 добавлений и 1 удалений

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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: