Implement global interface variable constant

Этот коммит содержится в:
Ayke van Laethem 2018-08-25 02:58:00 +02:00
родитель c25b448758
коммит 9f2bcfe5e3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E97FF5335DFDFDED
3 изменённых файлов: 39 добавлений и 3 удалений

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

@ -748,6 +748,18 @@ func (c *Compiler) getInterpretedValue(value Value) (llvm.Value, error) {
ptr := llvm.ConstInBoundsGEP(value.Global.llvmGlobal, []llvm.Value{zero})
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:
// Create initial bucket.
firstBucketGlobal, keySize, valueSize, err := c.initMapNewBucket(value.Type)
@ -1929,14 +1941,31 @@ func (c *Compiler) parseConst(expr *ssa.Const) (llvm.Value, error) {
} else {
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:
if expr.Value != nil {
return llvm.Value{}, errors.New("non-nil pointer constant")
}
llvmType, err := c.getLLVMType(typ)
if err != nil {
return llvm.Value{}, err
}
return llvm.ConstPointerNull(llvmType), nil
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
case *types.Basic:
return &ZeroBasicValue{typ}, nil
case *types.Interface:
return &InterfaceValue{typ}, nil
case *types.Pointer:
return &PointerValue{nil}, nil
case *types.Struct:
@ -259,6 +261,11 @@ type PointerValue struct {
Elem *Value
}
type InterfaceValue struct {
Type *types.Interface
//Elem Value
}
type PointerBitCastValue struct {
Type types.Type
Elem Value

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

@ -90,8 +90,8 @@ func (p *Program) AnalyseCallgraph() {
// Find all types that are put in an interface.
func (p *Program) AnalyseInterfaceConversions() {
// Clear, if AnalyseTypes has been called before.
p.typesWithMethods = make(map[string]*InterfaceType)
p.typesWithoutMethods = make(map[string]int)
p.typesWithoutMethods = map[string]int{"interface{}": 0}
p.typesWithMethods = map[string]*InterfaceType{}
for _, f := range p.Functions {
for _, block := range f.fn.Blocks {