compiler,reflect: add tagged pointers for **T etc
Этот коммит содержится в:
родитель
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:
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче