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})
|
||||
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 {
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче