diff --git a/compiler.go b/compiler.go index 2c2f5ade0..50bc0d69d 100644 --- a/compiler.go +++ b/compiler.go @@ -755,6 +755,16 @@ func (c *Compiler) getInterpretedValue(value Value) (llvm.Value, error) { case *ConstValue: return c.parseConst(value.Expr) + case *FunctionValue: + if value.Elem == nil { + llvmType, err := c.getLLVMType(value.Type) + if err != nil { + return llvm.Value{}, err + } + return getZeroValue(llvmType) + } + return c.ir.GetFunction(value.Elem).llvmFn, nil + case *GlobalValue: zero := llvm.ConstInt(llvm.Int32Type(), 0, false) ptr := llvm.ConstInBoundsGEP(value.Global.llvmGlobal, []llvm.Value{zero}) diff --git a/interpreter.go b/interpreter.go index dfa44d4b1..d4135e8bc 100644 --- a/interpreter.go +++ b/interpreter.go @@ -188,6 +188,8 @@ func (p *Program) getValue(value ssa.Value, locals map[ssa.Value]Value) (Value, switch value := value.(type) { case *ssa.Const: return &ConstValue{value}, nil + case *ssa.Function: + return &FunctionValue{value.Type(), value}, nil case *ssa.Global: if strings.HasPrefix(value.Name(), "__cgofn__cgo_") || strings.HasPrefix(value.Name(), "_cgo_") { // Ignore CGo global variables which we don't use. @@ -202,7 +204,6 @@ func (p *Program) getValue(value ssa.Value, locals map[ssa.Value]Value) (Value, g.initializer = value } return &GlobalValue{g}, nil - //return &PointerValue{&g.initializer}, nil default: if local, ok := locals[value]; ok { return local, nil @@ -226,6 +227,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.Signature: + return &FunctionValue{typ, nil}, nil case *types.Interface: return &InterfaceValue{typ, nil}, nil case *types.Map: @@ -265,6 +268,11 @@ type PointerValue struct { Elem *Value } +type FunctionValue struct { + Type types.Type + Elem *ssa.Function +} + type InterfaceValue struct { Type types.Type Elem Value