func ext۰reflect۰ChanOf(a *analysis, cgn *cgnode) { // If we have access to the callsite, // and the channel argument is a constant (as is usual), // only generate the requested direction. var dir reflect.ChanDir // unknown if site := cgn.callersite; site != nil { if c, ok := site.instr.Common().Args[0].(*ssa.Const); ok { v, _ := exact.Int64Val(c.Value) if 0 <= v && v <= int64(reflect.BothDir) { dir = reflect.ChanDir(v) } } } params := a.funcParams(cgn.obj) a.addConstraint(&reflectChanOfConstraint{ cgn: cgn, t: params + 1, result: a.funcResults(cgn.obj), dirs: dirMap[dir], }) }
func (l langType) typeBuild(i int, t types.Type) string { sizes := &haxeStdSizes ret := fmt.Sprintf( // sizeof largest struct (funcType) is 76 "private static var type%dptr:Pointer=null; // %s\npublic static function type%d():Pointer { if(type%dptr==null) { type%dptr=Pointer.make(Object.make(80));", i, t.String(), i, i, i) ret += "" name := "" if namedT, named := t.(*types.Named); named { name = namedT.Obj().Name() } if basic, isBasic := t.(*types.Basic); isBasic { name = basic.Name() } rtype, kind := l.rtypeBuild(i, sizes, t, name) switch t.(type) { case *types.Named: t = t.(*types.Named).Underlying() } switch kind & kindMask { case reflect.Invalid, reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.String, reflect.UnsafePointer: ret += fmt.Sprintf("Go_haxegoruntime_fillRRtype.callFromRT(0,type%dptr,%s)", i, rtype) case reflect.Ptr: ret += fmt.Sprintf("Go_haxegoruntime_fillPPtrTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n" if l.hc.pte.At(t.(*types.Pointer).Elem()) == nil { ret += fmt.Sprintf("/*elem:*/ nil,\n") } else { ret += fmt.Sprintf("/*elem:*/ type%d()\n", l.hc.pte.At(t.(*types.Pointer).Elem()).(int)) } ret += ")" case reflect.Array: ret += fmt.Sprintf("Go_haxegoruntime_fillAArrayTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n" ret += fmt.Sprintf("/*elem:*/ type%d(),\n", l.hc.pte.At(t.(*types.Array).Elem()).(int)) asl := "null" // slice type for _, tt := range l.hc.pte.Keys() { slt, isSlice := tt.(*types.Slice) if isSlice { if l.hc.pte.At(slt.Elem()) == l.hc.pte.At(t.(*types.Array).Elem()) { asl = fmt.Sprintf("type%d()", l.hc.pte.At(slt).(int)) break } } } // TODO make missing slice types before we start outputting types to avoid not having one? ret += fmt.Sprintf("/*slice:*/ %s,\n", asl) ret += fmt.Sprintf("/*len:*/ %d\n", t.(*types.Array).Len()) ret += ")" case reflect.Slice: ret += fmt.Sprintf("Go_haxegoruntime_fillSSliceTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n" ret += fmt.Sprintf("/*elem:*/ type%d()\n", l.hc.pte.At(t.(*types.Slice).Elem()).(int)) ret += ")" case reflect.Struct: fields := []*types.Var{} for fld := 0; fld < t.(*types.Struct).NumFields(); fld++ { fldInfo := t.(*types.Struct).Field(fld) //if fldInfo.IsField() { fields = append(fields, fldInfo) //} } offs := sizes.Offsetsof(fields) ret += fmt.Sprintf("Go_haxegoruntime_fillSStructTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n/*fields:*/ " fret := "Go_haxegoruntime_newSStructFFieldSSlice.callFromRT(0)" numFlds := t.(*types.Struct).NumFields() for fld := 0; fld < numFlds; fld++ { fldInfo := t.(*types.Struct).Field(fld) name := fldInfo.Name() path := fldInfo.Pkg().Path() if fldInfo.Exported() { path = "" } if fldInfo.Anonymous() { name = "" } fret = "\tGo_haxegoruntime_addSStructFFieldSSlice.callFromRT(0," + fret + "," fret += "\n\t\t/*name:*/ \"" + name + "\",\n" fret += "\t\t/*pkgPath:*/ \"" + path + "\",\n" fret += fmt.Sprintf("\t\t/*typ:*/ type%d(),// %s\n", l.hc.pte.At(fldInfo.Type()), fldInfo.Type().String()) fret += "\t\t/*tag:*/ \"" + escapedTypeString(t.(*types.Struct).Tag(fld)) + "\", // " + t.(*types.Struct).Tag(fld) + "\n" fret += fmt.Sprintf("\t\t/*offset:*/ %d\n", offs[fld]) fret += "\t)" } ret += fret + ")" case reflect.Interface: ret += fmt.Sprintf("Go_haxegoruntime_fillIInterfaceTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n/*methods:*/ " mret := "Go_haxegoruntime_newIImethodSSlice.callFromRT(0)" for m := 0; m < t.(*types.Interface).NumMethods(); m++ { meth := t.(*types.Interface).Method(m) mret = "Go_haxegoruntime_addIImethodSSlice.callFromRT(0," + mret + "," mret += "\t\t/*name:*/ \"" + meth.Name() + "\",\n" path := "\"\"" if !meth.Exported() { path = "\"" + meth.Pkg().Path() + "\"" } mret += "\t\t/*pkgPath:*/ " + path + ",\n" typ := "null" iface := l.hc.pte.At(meth.Type()) if iface != interface{}(nil) { typ = fmt.Sprintf("type%d()", iface.(int)) } mret += fmt.Sprintf("\t\t/*typ:*/ %s // %s\n", typ, meth.String()) mret += "\t)\n" } ret += mret + ")" case reflect.Map: ret += fmt.Sprintf("Go_haxegoruntime_fillMMapTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n" ret += fmt.Sprintf("/*key:*/ type%d(),\n", l.hc.pte.At(t.(*types.Map).Key()).(int)) ret += fmt.Sprintf("/*elem:*/ type%d()\n", l.hc.pte.At(t.(*types.Map).Elem()).(int)) ret += ")" case reflect.Func: ret += fmt.Sprintf("Go_haxegoruntime_fillFFuncTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n" ret += fmt.Sprintf("/*dotdotdot:*/ %v,\n", t.(*types.Signature).Variadic()) ret += "/*in:*/ " iret := "Go_haxegoruntime_newPPtrTToRRtypeSSlice.callFromRT(0)" for i := 0; i < t.(*types.Signature).Params().Len(); i++ { iret = fmt.Sprintf("Go_haxegoruntime_addPPtrTToRRtypeSSlice.callFromRT(0,%s,\n\ttype%d())", iret, l.hc.pte.At((t.(*types.Signature).Params().At(i).Type())).(int)) } ret += iret + ",\n/*out:*/ " oret := "Go_haxegoruntime_newPPtrTToRRtypeSSlice.callFromRT(0)" for o := 0; o < t.(*types.Signature).Results().Len(); o++ { oret = fmt.Sprintf("Go_haxegoruntime_addPPtrTToRRtypeSSlice.callFromRT(0,%s,\n\ttype%d())", oret, l.hc.pte.At((t.(*types.Signature).Results().At(o).Type())).(int)) } ret += oret + " )\n" case reflect.Chan: ret += fmt.Sprintf("Go_haxegoruntime_fillCChanTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n" ret += fmt.Sprintf("/*elem:*/ type%d(),\n", l.hc.pte.At(t.(*types.Chan).Elem()).(int)) reflectDir := reflect.ChanDir(0) switch t.(*types.Chan).Dir() { case types.SendRecv: reflectDir = reflect.BothDir case types.SendOnly: reflectDir = reflect.SendDir case types.RecvOnly: reflectDir = reflect.RecvDir } ret += fmt.Sprintf("/*dir:*/ %d\n", reflectDir) ret += ")" default: panic("unhandled reeflect.type") } ret += ";" ret += fmt.Sprintf("}; return type%dptr; }\n", i) return ret }