// Returns the textual version of Value, possibly emmitting an error // can't merge with indirectValue, as this is used by emit-func-setup to get register names func (l langType) Value(v interface{}, errorInfo string) string { val, ok := v.(ssa.Value) if !ok { return "" // if it is not a value, an empty string will be returned } switch v.(type) { case *ssa.Global: return "Go." + l.LangName(v.(*ssa.Global).Pkg.Object.Name(), v.(*ssa.Global).Name()) case *ssa.Alloc, *ssa.MakeSlice: return pogo.RegisterName(v.(ssa.Value)) case *ssa.FieldAddr, *ssa.IndexAddr: return pogo.RegisterName(v.(ssa.Value)) case *ssa.Const: ci := v.(*ssa.Const) _, c := l.Const(*ci, errorInfo) return c case *ssa.Parameter: return "p_" + pogo.MakeId(v.(*ssa.Parameter).Name()) case *ssa.Capture: for b := range v.(*ssa.Capture).Parent().FreeVars { if v.(*ssa.Capture) == v.(*ssa.Capture).Parent().FreeVars[b] { // comparing the name gives the wrong result return `_bds[` + fmt.Sprintf("%d", b) + `]` } } pogo.LogError(errorInfo, "Haxe", fmt.Errorf("haxe.Value(): *ssa.Capture name not found: %s", v.(*ssa.Capture).Name())) return `_bds["_b` + "ERROR: Captured bound variable name not found" + `"]` // TODO proper error case *ssa.Function: pk := "unknown" if v.(*ssa.Function).Signature.Recv() != nil { // it's a method pk = v.(*ssa.Function).Signature.Recv().Pkg().Name() + "." + v.(*ssa.Function).Signature.Recv().Name() } else { if v.(*ssa.Function).Pkg != nil { if v.(*ssa.Function).Pkg.Object != nil { pk = v.(*ssa.Function).Pkg.Object.Name() } } } if len(v.(*ssa.Function).Blocks) > 0 { //the function actually exists return "new Closure(Go_" + l.LangName(pk, v.(*ssa.Function).Name()) + ".call,[])" //TODO will change for go instr } // function has no implementation // TODO maybe put a list of over-loaded functions here and only error if not found // NOTE the reflect package comes through this path TODO fix! pogo.LogWarning(errorInfo, "Haxe", fmt.Errorf("haxe.Value(): *ssa.Function has no implementation: %s", v.(*ssa.Function).Name())) return "new Closure(null,[])" // Should fail at runtime if it is used... case *ssa.UnOp: return pogo.RegisterName(val) case *ssa.BinOp: return pogo.RegisterName(val) case *ssa.MakeInterface: return pogo.RegisterName(val) default: return pogo.RegisterName(val) } }
func (l langType) inlineRegisterName(vi interface{}) string { vp, okPtr := vi.(*ssa.Value) if !okPtr { v, ok := vi.(ssa.Value) if !ok { panic(fmt.Sprintf("inlineRegisterName not a pointer to a value, or a value; it is a %T", vi)) } vp = &v } nm := strings.TrimSpace(pogo.RegisterName(*vp)) if l.CanInline(vi) { code, found := pogo.InlineMap(nm) if !found { //for k, v := range pogo.InlineMap { // println("DEBUG dump pogo.InlineMap[", k, "] is ", v) //} //pogo.LogError(vi.(ssa.Instruction).Parent().String(), "haxe", errors.New("internal error - cannot find "+nm+" in pogo.InlineMap")) return nm } return code } return nm }