Пример #1
0
// dynamicToInterface - limited runtime conversion of Haxe->Go types
// with URL un-escaping of strings
// TODO consider making public
func dynamicToInterface(dyn uintptr) interface{} {
	switch {
	case hx.CodeBool("", "Std.is(_a.param(0).val,Array);", dyn):
		l := hx.CodeInt("", "_a.param(0).val.length;", dyn)
		ret := make([]interface{}, l)
		for i := 0; i < l; i++ {
			ret[i] =
				dynamicToInterface(hx.CodeDynamic("",
					"_a.param(0).val[_a.param(1).val];", dyn, i))
		}
		return ret
	case hx.IsNull(dyn):
		return nil
	case hx.CodeBool("", "Std.is(_a.param(0).val,Bool);", dyn):
		return hx.CodeBool("", "_a.param(0).val;", dyn)
	case hx.CodeBool("", "Std.is(_a.param(0).val,Int);", dyn):
		return hx.CodeInt("", "_a.param(0).val;", dyn)
	case hx.CodeBool("", "Std.is(_a.param(0).val,Float);", dyn):
		return hx.CodeFloat("", "_a.param(0).val;", dyn)
	case hx.CodeBool("", "Std.is(_a.param(0).val,String);", dyn):
		return hx.CodeString("", "_a.param(0).val;", dyn)
	case hx.CodeBool("", "Std.is(_a.param(0).val,haxe.io.Bytes);", dyn):
		return hx.CodeIface("", "[]byte",
			"Slice.fromBytes(_a.param(0).val);", dyn)
	default:
		panic("unhandled haxe Dynamic to Go interface{} :" +
			hx.CallString("", "Std.string", 1, dyn))
	}
	return nil
}
Пример #2
0
func StartTimer(up unsafe.Pointer) { // function body is an Haxe addition
	StopTimer(up) // just in case it is still running
	rt := (*runtimeTimer)(up)
	for !hx.IsNull(rt.seq) { // wait for the timer to stop -- NOTE potential for deadlock?
		//println("DEBUG Wait for timer to stop")
		runtime.Gosched()
	}
	go HaxeTimer(up)
}
Пример #3
0
func getMethod(tid int, path, name string) uintptr {
	//println("DEBUG getMethod:", tid, path, name)
	if tid < 1 || tid >= len(TypeTable) { // entry 0 is always nil
		hx.Call("", "Scheduler.panicFromHaxe", 1, "haxegoruntime.method() type id out of range")
	}
	rt := TypeTable[tid]
	ut := (*uncommonType)(rt.uncommonType)
	if ut == nil {
		hx.Call("", "Scheduler.panicFromHaxe", 1, "haxegoruntime.method() type has no uncommonType record")
	}
	if name == "" {
		hx.Call("", "Scheduler.panicFromHaxe", 1, "haxegoruntime.method() no method name")
	}
	exported := false
	if name[0] >= 'A' && name[0] <= 'Z' {
		exported = true
		// exported name, so path should be ""
		path = ""
	}
	if path != "" {
		for _, m := range ut.methods { // TODO these should be in order, so could use sort.search to speed up?
			mname := ""
			if m.name != nil {
				mname = *m.name
			}
			mpath := ""
			if m.pkgPath != nil {
				mpath = *m.pkgPath
			}
			//println("DEBUG check:", getTypeString(tid), mname, name, mpath, path)
			if mname == name && mpath == path {
				ret := m.ifn // is ifn the right one?
				if hx.IsNull(ret) {
					hx.Call("", "Scheduler.panicFromHaxe", 1, "haxegoruntime.method() null method for "+
						getTypeString(tid)+"."+name+" called from "+path)
				}
				//println("DEBUG found:", getTypeString(tid), path, name, ret)
				return ret
			}
		}
	} else {
		// no path so find the method without the path, but only if it is unique when not exported
		found := -1
		for f, m := range ut.methods { // TODO these should be in order, so could use sort.search to speed up?
			mname := ""
			if m.name != nil {
				mname = *m.name
			}
			//println("DEBUG check (ignore path):", getTypeString(tid), mname, name)
			if mname == name {
				//println("DEBUG found (ignore path):", getTypeString(tid), name)
				if found == -1 {
					found = f
					if exported {
						break
					}
				} else {
					hx.Call("", "Scheduler.panicFromHaxe", 1,
						"haxegoruntime.method() duplicates method found (ignoring path) for "+
							getTypeString(tid)+"."+name+" called from "+path)
				}
			}
		}
		if found >= 0 {
			ret := ut.methods[found].ifn // is ifn the right one?
			if hx.IsNull(ret) {
				hx.Call("", "Scheduler.panicFromHaxe", 1, "haxegoruntime.method() null method for "+
					getTypeString(tid)+"."+name+" called from "+path)
			}
			return ret
		}
	}
	//println("DEBUG not found:", getTypeString(tid), path, name)
	hx.Call("", "Scheduler.panicFromHaxe", 1, "haxegoruntime.method() no method found for "+
		getTypeString(tid)+"."+name+" called from "+path)
	return 0
}
Пример #4
0
func (p *pp) handleMethods(verb rune, depth int) (handled bool) {
	if p.erroring {
		return
	}
	// Is it a Formatter?
	if formatter, ok := p.arg.(Formatter); ok {
		handled = true
		defer p.restoreSpecialFlags(p.clearSpecialFlags())
		defer p.catchPanic(p.arg, verb)
		if hx.IsNull(hx.CodeDynamic("", "_a.itemAddr(0).load().val;", formatter)) {
			panic("<nil>")
		}
		formatter.Format(p, verb)
		return
	}

	// If we're doing Go syntax and the argument knows how to supply it, take care of it now.
	if p.fmt.sharpV {
		if stringer, ok := p.arg.(GoStringer); ok {
			handled = true
			defer p.catchPanic(p.arg, verb)
			if hx.IsNull(hx.CodeDynamic("", "_a.itemAddr(0).load().val;", stringer)) {
				panic("<nil>")
			}
			// Print the result of GoString unadorned.
			p.fmt.fmt_s(stringer.GoString())
			return
		}
	} else {
		// If a string is acceptable according to the format, see if
		// the value satisfies one of the string-valued interfaces.
		// Println etc. set verb to %v, which is "stringable".
		switch verb {
		case 'v', 's', 'x', 'X', 'q':
			// Is it an error or Stringer?
			// The duplication in the bodies is necessary:
			// setting handled and deferring catchPanic
			// must happen before calling the method.
			switch v := p.arg.(type) {
			case error:
				handled = true
				defer p.catchPanic(p.arg, verb)
				if hx.IsNull(hx.CodeDynamic("", "_a.itemAddr(0).load().val;", v)) {
					panic("<nil>")
				}
				p.printArg(v.Error(), verb, depth)
				return

			case Stringer:
				handled = true
				defer p.catchPanic(p.arg, verb)
				if hx.IsNull(hx.CodeDynamic("", "_a.itemAddr(0).load().val;", v)) {
					panic("<nil>")
				}
				p.printArg(v.String(), verb, depth)
				return
			}
		}
	}
	return false
}