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 {
|
if _, ok := typ.Underlying().(*types.Interface); ok {
|
||||||
hasMethodSet = false
|
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)
|
typeCodeName, isLocal := getTypeCodeName(typ)
|
||||||
globalName := "reflect/types.type:" + typeCodeName
|
globalName := "reflect/types.type:" + typeCodeName
|
||||||
var global llvm.Value
|
var global llvm.Value
|
||||||
|
@ -391,6 +403,9 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
||||||
}, typeFields...)
|
}, typeFields...)
|
||||||
}
|
}
|
||||||
alignment := c.targetData.TypeAllocSize(c.i8ptrType)
|
alignment := c.targetData.TypeAllocSize(c.i8ptrType)
|
||||||
|
if alignment < 4 {
|
||||||
|
alignment = 4
|
||||||
|
}
|
||||||
globalValue := c.ctx.ConstStruct(typeFields, false)
|
globalValue := c.ctx.ConstStruct(typeFields, false)
|
||||||
global.SetInitializer(globalValue)
|
global.SetInitializer(globalValue)
|
||||||
if isLocal {
|
if isLocal {
|
||||||
|
|
|
@ -477,7 +477,15 @@ func (t *rawType) underlying() *rawType {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *rawType) ptrtag() uintptr {
|
||||||
|
return uintptr(unsafe.Pointer(t)) & 0b11
|
||||||
|
}
|
||||||
|
|
||||||
func (t *rawType) isNamed() bool {
|
func (t *rawType) isNamed() bool {
|
||||||
|
if tag := t.ptrtag(); tag != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return t.meta&flagNamed != 0
|
return t.meta&flagNamed != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,9 +510,13 @@ func pointerTo(t *rawType) *rawType {
|
||||||
|
|
||||||
switch t.Kind() {
|
switch t.Kind() {
|
||||||
case Pointer:
|
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
|
// 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.
|
// 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:
|
case Struct:
|
||||||
return (*structType)(unsafe.Pointer(t)).ptrTo
|
return (*structType)(unsafe.Pointer(t)).ptrTo
|
||||||
default:
|
default:
|
||||||
|
@ -581,6 +593,11 @@ func (t *rawType) Kind() Kind {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
return Invalid
|
return Invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tag := t.ptrtag(); tag != 0 {
|
||||||
|
return Pointer
|
||||||
|
}
|
||||||
|
|
||||||
return Kind(t.meta & kindMask)
|
return Kind(t.meta & kindMask)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,6 +608,10 @@ func (t *rawType) Elem() Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *rawType) elem() *rawType {
|
func (t *rawType) elem() *rawType {
|
||||||
|
if tag := t.ptrtag(); tag != 0 {
|
||||||
|
return (*rawType)(unsafe.Add(unsafe.Pointer(t), -1))
|
||||||
|
}
|
||||||
|
|
||||||
underlying := t.underlying()
|
underlying := t.underlying()
|
||||||
switch underlying.Kind() {
|
switch underlying.Kind() {
|
||||||
case Pointer:
|
case Pointer:
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче