Example #1
0
/* from the SSA documentation:
The ChangeType instruction applies to X a value-preserving type change to Type().

Type changes are permitted:

- between a named type and its underlying type.
- between two named types of the same underlying type.
- between (possibly named) pointers to identical base types.
- between f(T) functions and (T) func f() methods.
- from a bidirectional channel to a read- or write-channel,
  optionally adding/removing a name.
*/
func (l langType) ChangeType(register string, regTyp interface{}, v interface{}, errorInfo string) string {
	//fmt.Printf("DEBUG CHANGE TYPE: %v -- %v\n", regTyp, v)
	switch v.(ssa.Value).(type) {
	case *ssa.Function:
		return register + "=" +
			"new Closure(Go_" + l.LangName(pogo.FuncPathName(v.(*ssa.Function))) + ".call,[]);"
	default:
		hType := getHaxeClass(regTyp.(types.Type).String())
		if hType != "" {
			switch v.(ssa.Value).Type().Underlying().(type) {
			case *types.Interface:
				return register + "=" + l.IndirectValue(v, errorInfo) + ".val;"
			default:
				return register + "=cast " + l.IndirectValue(v, errorInfo) + ";" // unsafe cast!
			}
		}
		switch v.(ssa.Value).Type().Underlying().(type) {
		case *types.Basic:
			if v.(ssa.Value).Type().Underlying().(*types.Basic).Kind() == types.UnsafePointer {
				/* from https://groups.google.com/forum/#!topic/golang-dev/6eDTDZPWvoM
				   	Treat unsafe.Pointer -> *T conversions by returning new(T).
				   	This is incorrect but at least preserves type-safety...
					TODO decide if the above method is better than just copying the value as below
				*/
				return register + "=" + l.LangType(regTyp.(types.Type), true, errorInfo) + ";"
			}
		}
	}
	return register + `=` + l.IndirectValue(v, errorInfo) + ";" // usually, this is a no-op as far as Haxe is concerned

}
Example #2
0
func (l langType) FuncName(fnx *ssa.Function) string {
	pn := ""
	if fnx.Signature.Recv() != nil {
		pn = fnx.Signature.Recv().Type().String() // NOTE no use of underlying here
	} else {
		pn, _ = pogo.FuncPathName(fnx) //fmt.Sprintf("fn%d", fnx.Pos())
		fn := ssa.EnclosingFunction(fnx.Package(), []ast.Node{fnx.Syntax()})
		if fn == nil {
			fn = fnx
		}
		if fn.Pkg != nil {
			if fn.Pkg.Object != nil {
				pn = fn.Pkg.Object.Path() // was .Name()
			}
		} else {
			if fn.Object() != nil {
				if fn.Object().Pkg() != nil {
					pn = fn.Object().Pkg().Path() // was .Name()
				}
			}
		}
	}
	return l.LangName(pn, fnx.Name())
}