// TODO(haxe): optimize to use the Timer call-back methods for the targets - flash, flash8, java, js, python func HaxeWait(target *int64, whileTrue *bool) { fNow := hx.CallFloat("", "haxe.Timer.stamp", 0) firstTarget := *target fTarget := reverseNano(*target) //println("DEBUG haxeWait:start now, target, *whileTrue diff = ", fNow, *target, *whileTrue, fTarget-fNow) for fNow < fTarget && *target == firstTarget && *whileTrue { runtime.Gosched() // let other code run fNow = hx.CallFloat("", "haxe.Timer.stamp", 0) //println("DEBUG haxeWait:loop now, target, *whileTrue diff = ", fNow, *target, *whileTrue, fTarget-fNow) } }
func Ldexp(frac float64, exp int) float64 { // adapted from GopherJS if frac == 0 { return frac } if exp >= 1024 { return frac * hx.CallFloat("", "Math.pow", 2, 2, 1023) * hx.CallFloat("", "Math.pow", 2, 2, exp-1023) } if exp <= -1024 { return frac * hx.CallFloat("", "Math.pow", 2, 2, -1023) * hx.CallFloat("", "Math.pow", 2, 2, exp+1023) } return frac * hx.CallFloat("", "Math.pow", 2, 2, exp) }
// Ldexp is the inverse of Frexp. // It returns frac × 2**exp. // // Special cases are: // Ldexp(±0, exp) = ±0 // Ldexp(±Inf, exp) = ±Inf // Ldexp(NaN, exp) = NaN func Ldexp(frac float64, exp int) float64 { // this inspired by the GopherJS project, see there for copyright etc if frac == 0 { return frac } if exp >= 1024 { return frac * hx.CallFloat("", "Math.pow", 2, 2, 1023) * hx.CallFloat("", "Math.pow", 2, 2, exp-1023) } if exp <= -1024 { return frac * hx.CallFloat("", "Math.pow", 2, 2, -1023) * hx.CallFloat("", "Math.pow", 2, 2, exp+1023) } return frac * hx.CallFloat("", "Math.pow", 2, 2, exp) }
func tc64(f float64) float64 { if runtime.GOOS == "nacl" { return hx.CallFloat("", "Go_haxegoruntime_FFloat64frombits.hx", 1, hx.CallDynamic("", "Go_haxegoruntime_FFloat64bits.hx", 1, f)) } return f }
// RuntimeNano returns the current value of the runtime clock in nanoseconds. func RuntimeNano() int64 { // function body is an Haxe addition fv := hx.CallFloat("", "haxe.Timer.stamp", 0) // cs and maybe Java have stamp values too large for int64, so set a baseline if runtimeNanoBase == 0 { //println("DEBUG set runtimeNanoBase") runtimeNanoBase = fv } fv -= runtimeNanoBase return int64(fv * 1000000000) // haxe.Timer.stamp is in seconds }
// Abs returns the absolute value of x. // // Special cases are: // Abs(±Inf) = +Inf // Abs(NaN) = NaN func Abs(x float64) float64 { //switch x { //case hx.GetFloat("", "Math.NaN"): // return x //case hx.GetFloat("", "Math.POSITIVE_INFINITY"), // hx.GetFloat("", "Math.NEGATIVE_INFINITY"): // return hx.GetFloat("", "Math.POSITIVE_INFINITY") //default: return hx.CallFloat("", "Math.abs", 1, x) //} }
// Float64frombits returns the floating point number corresponding // the IEEE 754 binary representation b. //func Float64frombits(b uint64) float64 { return *(*float64)(unsafe.Pointer(&b)) } func Float64frombits(b uint64) float64 { if hx.GetBool("", "Object.nativeFloats") { var t uint64 = b return *(*float64)(unsafe.Pointer(&t)) } switch runtime.GOARCH { case "cs": return hx.CallFloat("", "Force.Float64frombits", 1, b) // TODO js/cpp/neko short-cut //case "js", "cpp", "neko": // return hx.CallFloat("", "Force.Float64frombits", 1, b) } // first handle the special cases switch b { case uvnan: return nan case uvnan | 1<<63: return nan * -1 // -NaN case uvinf: return posInf case uvneginf: return negInf case 0: return 0 case 1 << 63: return zero * -1 // -0 } // below from GopherJS s := hx.GetFloat("", "1") if b&(1<<63) != 0 { s = hx.GetFloat("", "-1") } e := (b >> 52) & uint64((1<<11)-1) m := b & uint64((1<<52)-1) if e == uint64((1<<11)-1) { if m == 0 { return s / hx.GetFloat("", "0") } return nan } if e != 0 { m += 1 << 52 } if e == 0 { e = 1 } return Ldexp(float64(m), int(e)-1023-52) * s }
// TODO optimize to use the Timer call-back methods for the targets - flash, java, js, python func HaxeWait(target *int64, whileTrue *bool) { fNow := hx.CallFloat("", "haxe.Timer.stamp", 0) fTarget := reverseNano(*target) //println("DEBUG haxeWait:start now, target, *whileTrue diff = ", fNow, *target, *whileTrue, fTarget-fNow) /* this "optimization" is not working, and may not be better anyway useCallback := false switch runtime.GOARCH { case "js": if JScallbackOK { useCallback = true } case "flash", "java", "python": useCallback = true } if useCallback { wait := true ms := int(1000 * (fTarget - fNow)) println("DEBUG TIMER MS DELAY=", ms) if ms > 0 { tmr := hx.New("flash||java||js||python", "haxe.Timer", 1, ms) hx.Code("flash||java||js||python", "_a.param(0).val.run=_a.param(1).val;", tmr, func() { wait = true }) for wait && *whileTrue { runtime.Gosched() // let other code run } hx.Meth("flash||java||js||python", tmr, "haxe.Timer", "stop", 0) } } else { */ for fNow < fTarget && *whileTrue { runtime.Gosched() // let other code run fNow = hx.CallFloat("", "haxe.Timer.stamp", 0) //println("DEBUG haxeWait:loop now, target, *whileTrue diff = ", fNow, *target, *whileTrue, fTarget-fNow) } /*}*/ }
// Pow returns x**y, the base-x exponential of y. // // Special cases are (in order): // Pow(x, ±0) = 1 for any x // Pow(1, y) = 1 for any y // Pow(x, 1) = x for any x // Pow(NaN, y) = NaN // Pow(x, NaN) = NaN // Pow(±0, y) = ±Inf for y an odd integer < 0 // Pow(±0, -Inf) = +Inf // Pow(±0, +Inf) = +0 // Pow(±0, y) = +Inf for finite y < 0 and not an odd integer // Pow(±0, y) = ±0 for y an odd integer > 0 // Pow(±0, y) = +0 for finite y > 0 and not an odd integer // Pow(-1, ±Inf) = 1 // Pow(x, +Inf) = +Inf for |x| > 1 // Pow(x, -Inf) = +0 for |x| > 1 // Pow(x, +Inf) = +0 for |x| < 1 // Pow(x, -Inf) = +Inf for |x| < 1 // Pow(+Inf, y) = +Inf for y > 0 // Pow(+Inf, y) = +0 for y < 0 // Pow(-Inf, y) = Pow(-0, -y) // Pow(x, y) = NaN for finite x < 0 and finite non-integer y func Pow(x, y float64) float64 { if runtime.GOARCH == "cs" { return pow(x, y) } // follow GopherJS approach for copyright etc see that project /* if x == 1 || (x == -1 && (y == posInf || y == negInf)) { return 1 } return math.Call("pow", x, y).Float() */ if x == 1 || (x == -1 && !hx.CallBool("", "Math.isFinite", 1, y) && (y < SmallestNonzeroFloat64 || y > MaxFloat64)) { return 1 } if x == -1 && IsNaN(y) { return NaN() } return hx.CallFloat("", "Math.pow", 2, x, y) }
// Provided by package runtime. func now() (sec int64, nsec int32) { haxeNow := hx.GetFloat("", "Date.now().getTime()") // milliseconds secFloat := hx.CallFloat("", "Math.ffloor", 1, haxeNow/1000) return int64(secFloat), int32(1000000000 * ((haxeNow / 1000) - secFloat)) }
// Asin returns the arcsine, in radians, of x. // // Special cases are: // Asin(±0) = ±0 // Asin(x) = NaN if x < -1 or x > 1 func Asin(x float64) float64 { return hx.CallFloat("", "Math.asin", 1, x) }
// Atan returns the arctangent, in radians, of x. // // Special cases are: // Atan(±0) = ±0 // Atan(±Inf) = ±Pi/2 func Atan(x float64) float64 { if runtime.GOARCH == "cs" { return atan(x) } return hx.CallFloat("", "Math.atan", 1, x) }
// Ceil returns the least integer value greater than or equal to x. // // Special cases are: // Ceil(±0) = ±0 // Ceil(±Inf) = ±Inf // Ceil(NaN) = NaN func Ceil(x float64) float64 { return hx.CallFloat("", "Math.fceil", 1, x) }
// Floor returns the greatest integer value less than or equal to x. // // Special cases are: // Floor(±0) = ±0 // Floor(±Inf) = ±Inf // Floor(NaN) = NaN func Floor(x float64) float64 { return hx.CallFloat("", "Math.ffloor", 1, x) }
// Provided by package runtime. func now() (sec int64, nsec int32) { haxeNow := hx.GetFloat("", "Date.now().getTime()") secFloat := hx.CallFloat("", "Math.ffloor", 1, haxeNow) return int64(secFloat), int32(1000000000 * (haxeNow - secFloat)) }
// Exp returns e**x, the base-e exponential of x. // // Special cases are: // Exp(+Inf) = +Inf // Exp(NaN) = NaN // Very large values overflow to 0 or +Inf. // Very small values underflow to 1. func Exp(x float64) float64 { return hx.CallFloat("", "Math.exp", 1, x) }
// Cos returns the cosine of the radian argument x. // // Special cases are: // Cos(±Inf) = NaN // Cos(NaN) = NaN func Cos(x float64) float64 { return hx.CallFloat("", "Math.cos", 1, x) }
// Atan2 returns the arc tangent of y/x, using // the signs of the two to determine the quadrant // of the return value. // // Special cases are (in order): // Atan2(y, NaN) = NaN // Atan2(NaN, x) = NaN // Atan2(+0, x>=0) = +0 // Atan2(-0, x>=0) = -0 // Atan2(+0, x<=-0) = +Pi // Atan2(-0, x<=-0) = -Pi // Atan2(y>0, 0) = +Pi/2 // Atan2(y<0, 0) = -Pi/2 // Atan2(+Inf, +Inf) = +Pi/4 // Atan2(-Inf, +Inf) = -Pi/4 // Atan2(+Inf, -Inf) = 3Pi/4 // Atan2(-Inf, -Inf) = -3Pi/4 // Atan2(y, +Inf) = 0 // Atan2(y>0, -Inf) = +Pi // Atan2(y<0, -Inf) = -Pi // Atan2(+Inf, x) = +Pi/2 // Atan2(-Inf, x) = -Pi/2 func Atan2(y, x float64) float64 { if runtime.GOARCH == "cs" { return atan2(y, x) } return hx.CallFloat("", "Math.atan2", 2, y, x) }
// Sin returns the sine of the radian argument x. // // Special cases are: // Sin(±0) = ±0 // Sin(±Inf) = NaN // Sin(NaN) = NaN func Sin(x float64) float64 { if runtime.GOARCH == "cs" { return sin(x) } return hx.CallFloat("", "Math.sin", 1, x) }