Implement global interface variable constant
Этот коммит содержится в:
родитель
c25b448758
коммит
9f2bcfe5e3
3 изменённых файлов: 39 добавлений и 3 удалений
31
compiler.go
31
compiler.go
|
@ -748,6 +748,18 @@ func (c *Compiler) getInterpretedValue(value Value) (llvm.Value, error) {
|
||||||
ptr := llvm.ConstInBoundsGEP(value.Global.llvmGlobal, []llvm.Value{zero})
|
ptr := llvm.ConstInBoundsGEP(value.Global.llvmGlobal, []llvm.Value{zero})
|
||||||
return ptr, nil
|
return ptr, nil
|
||||||
|
|
||||||
|
case *InterfaceValue:
|
||||||
|
itfTypeNum, ok := c.ir.TypeNum(value.Type)
|
||||||
|
if !ok {
|
||||||
|
panic("interface number is unknown")
|
||||||
|
}
|
||||||
|
fields := []llvm.Value{
|
||||||
|
llvm.ConstInt(llvm.Int32Type(), uint64(itfTypeNum), false),
|
||||||
|
llvm.Undef(c.i8ptrType),
|
||||||
|
}
|
||||||
|
itf := llvm.ConstNamedStruct(c.mod.GetTypeByName("interface"), fields)
|
||||||
|
return itf, nil
|
||||||
|
|
||||||
case *MapValue:
|
case *MapValue:
|
||||||
// Create initial bucket.
|
// Create initial bucket.
|
||||||
firstBucketGlobal, keySize, valueSize, err := c.initMapNewBucket(value.Type)
|
firstBucketGlobal, keySize, valueSize, err := c.initMapNewBucket(value.Type)
|
||||||
|
@ -1929,14 +1941,31 @@ func (c *Compiler) parseConst(expr *ssa.Const) (llvm.Value, error) {
|
||||||
} else {
|
} else {
|
||||||
return llvm.Value{}, errors.New("todo: unknown constant: " + typ.String())
|
return llvm.Value{}, errors.New("todo: unknown constant: " + typ.String())
|
||||||
}
|
}
|
||||||
|
case *types.Interface:
|
||||||
|
if expr.Value != nil {
|
||||||
|
return llvm.Value{}, errors.New("non-nil interface constant")
|
||||||
|
}
|
||||||
|
itfTypeNum, ok := c.ir.TypeNum(expr.Type())
|
||||||
|
if !ok {
|
||||||
|
panic("interface number is unknown")
|
||||||
|
}
|
||||||
|
fields := []llvm.Value{
|
||||||
|
llvm.ConstInt(llvm.Int32Type(), uint64(itfTypeNum), false),
|
||||||
|
llvm.Undef(c.i8ptrType),
|
||||||
|
}
|
||||||
|
itf := llvm.ConstNamedStruct(c.mod.GetTypeByName("interface"), fields)
|
||||||
|
return itf, nil
|
||||||
case *types.Pointer:
|
case *types.Pointer:
|
||||||
|
if expr.Value != nil {
|
||||||
|
return llvm.Value{}, errors.New("non-nil pointer constant")
|
||||||
|
}
|
||||||
llvmType, err := c.getLLVMType(typ)
|
llvmType, err := c.getLLVMType(typ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return llvm.Value{}, err
|
return llvm.Value{}, err
|
||||||
}
|
}
|
||||||
return llvm.ConstPointerNull(llvmType), nil
|
return llvm.ConstPointerNull(llvmType), nil
|
||||||
default:
|
default:
|
||||||
return llvm.Value{}, errors.New("todo: unknown constant: " + typ.String())
|
return llvm.Value{}, errors.New("todo: unknown constant: " + expr.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -224,6 +224,8 @@ func (p *Program) getZeroValue(t types.Type) (Value, error) {
|
||||||
return &ArrayValue{typ.Elem(), elems}, nil
|
return &ArrayValue{typ.Elem(), elems}, nil
|
||||||
case *types.Basic:
|
case *types.Basic:
|
||||||
return &ZeroBasicValue{typ}, nil
|
return &ZeroBasicValue{typ}, nil
|
||||||
|
case *types.Interface:
|
||||||
|
return &InterfaceValue{typ}, nil
|
||||||
case *types.Pointer:
|
case *types.Pointer:
|
||||||
return &PointerValue{nil}, nil
|
return &PointerValue{nil}, nil
|
||||||
case *types.Struct:
|
case *types.Struct:
|
||||||
|
@ -259,6 +261,11 @@ type PointerValue struct {
|
||||||
Elem *Value
|
Elem *Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InterfaceValue struct {
|
||||||
|
Type *types.Interface
|
||||||
|
//Elem Value
|
||||||
|
}
|
||||||
|
|
||||||
type PointerBitCastValue struct {
|
type PointerBitCastValue struct {
|
||||||
Type types.Type
|
Type types.Type
|
||||||
Elem Value
|
Elem Value
|
||||||
|
|
|
@ -90,8 +90,8 @@ func (p *Program) AnalyseCallgraph() {
|
||||||
// Find all types that are put in an interface.
|
// Find all types that are put in an interface.
|
||||||
func (p *Program) AnalyseInterfaceConversions() {
|
func (p *Program) AnalyseInterfaceConversions() {
|
||||||
// Clear, if AnalyseTypes has been called before.
|
// Clear, if AnalyseTypes has been called before.
|
||||||
p.typesWithMethods = make(map[string]*InterfaceType)
|
p.typesWithoutMethods = map[string]int{"interface{}": 0}
|
||||||
p.typesWithoutMethods = make(map[string]int)
|
p.typesWithMethods = map[string]*InterfaceType{}
|
||||||
|
|
||||||
for _, f := range p.Functions {
|
for _, f := range p.Functions {
|
||||||
for _, block := range f.fn.Blocks {
|
for _, block := range f.fn.Blocks {
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче