Skip to content

Commit

Permalink
Fix unexpected runtime exceptions with Scala Native on Windows (#1294)
Browse files Browse the repository at this point in the history
  • Loading branch information
plokhotnyuk authored Feb 8, 2025
1 parent f12c952 commit 2d6cc6f
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ object SafeNumbers {
val s = vb >> 2
if (
s < 100 || {
dv = NativeMath.multiplyHigh(s, 1844674407370955168L) // divide a positive long by 10
dv = Math.multiplyHigh(s, 1844674407370955168L) // divide a positive long by 10
val sp40 = dv * 40
val upin = (vbls - sp40).toInt
(((sp40 + vbrd).toInt + 40) ^ upin) >= 0 || {
Expand Down Expand Up @@ -315,26 +315,26 @@ object SafeNumbers {
}

private[this] def rop(g1: Long, g0: Long, cp: Long): Long = {
val x = NativeMath.multiplyHigh(g0, cp) + (g1 * cp >>> 1)
NativeMath.multiplyHigh(g1, cp) + (x >>> 63) | (-x ^ x) >>> 63
val x = Math.multiplyHigh(g0, cp) + (g1 * cp >>> 1)
Math.multiplyHigh(g1, cp) + (x >>> 63) | (-x ^ x) >>> 63
}

private[this] def rop(g: Long, cp: Int): Int = {
val x = NativeMath.multiplyHigh(g, cp.toLong << 32)
val x = Math.multiplyHigh(g, cp.toLong << 32)
(x >>> 31).toInt | -x.toInt >>> 31
}

private[this] def stripTrailingZeros(x: Long): Long = {
var q0 = x.toInt
if (
q0 == x || {
q0 = (NativeMath.multiplyHigh(x, 6189700196426901375L) >>> 25).toInt // divide a positive long by 100000000
q0 = (Math.multiplyHigh(x, 6189700196426901375L) >>> 25).toInt // divide a positive long by 100000000
(x - q0 * 100000000L).toInt == 0
}
) return stripTrailingZeros(q0).toLong
var y, q1 = x
while ({
q1 = NativeMath.multiplyHigh(q1, 1844674407370955168L) // divide a positive long by 10
q1 = Math.multiplyHigh(q1, 1844674407370955168L) // divide a positive long by 10
q1 * 10 == y
}) y = q1
y
Expand Down Expand Up @@ -368,10 +368,10 @@ object SafeNumbers {
if (q0 < m1) write(q0.toInt, out)
else {
val m2 = 6189700196426901375L
val q1 = NativeMath.multiplyHigh(q0, m2) >>> 25 // divide a positive long by 100000000
val q1 = Math.multiplyHigh(q0, m2) >>> 25 // divide a positive long by 100000000
if (q1 < m1) write(q1.toInt, out)
else {
val q2 = NativeMath.multiplyHigh(q1, m2) >>> 25 // divide a small positive long by 100000000
val q2 = Math.multiplyHigh(q1, m2) >>> 25 // divide a small positive long by 100000000
write(q2.toInt, out)
write8Digits((q1 - q2 * m1).toInt, out)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,12 +344,12 @@ object UnsafeNumbers {

// Based on the 'Moderate Path' algorithm from the awesome library of Alexander Huszagh: https://github.com/Alexhuszagh/rust-lexical
// Here is his inspiring post: https://www.reddit.com/r/rust/comments/a6j5j1/making_rust_float_parsing_fast_and_correct
@noinline private[this] def toFloat(m10: Long, e10: Int): Float =
private[this] def toFloat(m10: Long, e10: Int): Float =
if (m10 == 0 || e10 < -64) 0.0f
else if (e10 >= 39) Float.PositiveInfinity
else {
var shift = java.lang.Long.numberOfLeadingZeros(m10)
var m2 = NativeMath.unsignedMultiplyHigh(pow10Mantissas(e10 + 343), m10 << shift)
var m2 = unsignedMultiplyHigh(pow10Mantissas(e10 + 343), m10 << shift)
var e2 = (e10 * 108853 >> 15) - shift + 1 // (e10 * Math.log(10) / Math.log(2)).toInt - shift + 1
shift = java.lang.Long.numberOfLeadingZeros(m2)
m2 <<= shift
Expand Down Expand Up @@ -481,7 +481,7 @@ object UnsafeNumbers {
else if (e10 >= 310) Double.PositiveInfinity
else {
var shift = java.lang.Long.numberOfLeadingZeros(m10)
var m2 = NativeMath.unsignedMultiplyHigh(pow10Mantissas(e10 + 343), m10 << shift)
var m2 = unsignedMultiplyHigh(pow10Mantissas(e10 + 343), m10 << shift)
var e2 = (e10 * 108853 >> 15) - shift + 1 // (e10 * Math.log(10) / Math.log(2)).toInt - shift + 1
shift = java.lang.Long.numberOfLeadingZeros(m2)
m2 <<= shift
Expand Down Expand Up @@ -518,6 +518,9 @@ object UnsafeNumbers {
if (consume && current != -1) throw UnsafeNumber
}

@inline private[this] def unsignedMultiplyHigh(x: Long, y: Long): Long =
Math.multiplyHigh(x, y) + x + y // FIXME: Use Math.unsignedMultiplyHigh after dropping of JDK 17 support

private[this] final val pow10Doubles: Array[Double] =
Array(1, 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16,
1e+17, 1e+18, 1e+19, 1e+20, 1e+21, 1e+22)
Expand Down

0 comments on commit 2d6cc6f

Please sign in to comment.