Пример #1
0
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],
	})
}
Пример #2
0
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
}