clean up stdlib with --jsbigint64 (#24255)

refs #6978, refs #6752, refs #21613, refs #24234

The `jsNoInt64`, `whenHasBigInt64`, `whenJsNoBigInt64` templates are
replaced with bool constants to use with `when`. Weird that I didn't do
this in the first place.

The `whenJsNoBigInt64` template was also slightly misleading. The first
branch was compiled for both no bigint64 on JS as well as on C/C++. It
seems only `trandom` depended on this by mistake.

The workaround for #6752 added in #6978 to `times` is also removed with
`--jsbigint64:on`, but #24233 was also encountered with this, so this PR
depends on #24234.

(cherry picked from commit 041098e882)
This commit is contained in:
metagn
2024-10-19 17:40:28 +03:00
committed by narimiran
parent 0cce80071b
commit cd760b00c2
14 changed files with 73 additions and 94 deletions

View File

@@ -77,10 +77,10 @@ proc newDate*(): DateTime {.
proc newDate*(date: int|string): DateTime {.
importcpp: "new Date(#)".}
whenJsNoBigInt64:
when jsNoBigInt64:
proc newDate*(date: int64): DateTime {.
importcpp: "new Date(#)".}
do:
else:
proc newDate*(date: int64): DateTime {.
importcpp: "new Date(Number(#))".}

View File

@@ -65,7 +65,7 @@ runnableExamples:
## * `sha1 module <sha1.html>`_ for the SHA-1 checksum algorithm
## * `tables module <tables.html>`_ for hash tables
import std/private/since
import std/private/[since, jsutils]
when defined(nimPreviewSlimSystem):
import std/assertions
@@ -518,17 +518,10 @@ proc hashFarm(s: openArray[byte]): uint64 {.inline.} =
swap z, x
len16 len16(v[0],w[0],mul) + shiftMix(y)*k0 + z, len16(v[1],w[1],mul) + x, mul
template jsNoInt64: untyped =
when defined js:
when compiles(compileOption("jsbigint64")):
when not compileOption("jsbigint64"): true
else: false
else: false
else: false
const sHash2 = (when defined(nimStringHash2) or jsNoInt64(): true else: false)
const sHash2 = defined(nimStringHash2) or jsNoBigInt64
template maybeFailJS_Number =
when jsNoInt64() and not defined(nimStringHash2):
when jsNoBigInt64 and not defined(nimStringHash2):
{.error: "Must use `-d:nimStringHash2` when using `--jsbigint64:off`".}
proc hash*(x: string): Hash =

View File

@@ -79,24 +79,13 @@ when defined(nimPreviewSlimSystem):
include system/inclrtl
{.push debugger: off.}
template whenHasBigInt64(yes64, no64): untyped =
when defined(js):
when compiles(compileOption("jsbigint64")):
when compileOption("jsbigint64"):
yes64
else:
no64
else:
no64
else:
yes64
whenHasBigInt64:
when hasWorkingInt64:
type Ui = uint64
const randMax = 18_446_744_073_709_551_615u64
do:
else:
type Ui = uint32
const randMax = 4_294_967_295u32
@@ -118,14 +107,14 @@ type
## generator are **not** thread-safe!
a0, a1: Ui
whenHasBigInt64:
when hasWorkingInt64:
const DefaultRandSeed = Rand(
a0: 0x69B4C98CB8530805u64,
a1: 0xFED1DD3004688D67CAu64)
# racy for multi-threading but good enough for now:
var state = DefaultRandSeed # global for backwards compatibility
do:
else:
var state = Rand(
a0: 0x69B4C98Cu32,
a1: 0xFED1DD30u32) # global for backwards compatibility
@@ -221,9 +210,9 @@ proc skipRandomNumbers*(s: var Rand) =
doAssert vals == [501737, 497901, 500683, 500157]
whenHasBigInt64:
when hasWorkingInt64:
const helper = [0xbeac0467eba5facbu64, 0xd86b048b86aa9922u64]
do:
else:
const helper = [0xbeac0467u32, 0xd86b048bu32]
var
s0 = Ui 0
@@ -359,9 +348,9 @@ proc rand*[T: Ordinal or SomeFloat](r: var Rand; x: HSlice[T, T]): T =
when T is SomeFloat:
result = rand(r, x.b - x.a) + x.a
else: # Integers and Enum types
whenJsNoBigInt64:
when jsNoBigInt64:
result = cast[T](rand(r, cast[uint](x.b) - cast[uint](x.a)) + cast[uint](x.a))
do:
else:
result = cast[T](rand(r, cast[uint64](x.b) - cast[uint64](x.a)) + cast[uint64](x.a))
proc rand*[T: Ordinal or SomeFloat](x: HSlice[T, T]): T =
@@ -402,9 +391,9 @@ proc rand*[T: Ordinal](r: var Rand; t: typedesc[T]): T {.since: (1, 7, 1).} =
elif T is bool:
result = r.next < randMax div 2
else:
whenJsNoBigInt64:
when jsNoBigInt64:
result = cast[T](r.next shr (sizeof(uint)*8 - sizeof(T)*8))
do:
else:
result = cast[T](r.next shr (sizeof(uint64)*8 - sizeof(T)*8))
proc rand*[T: Ordinal](t: typedesc[T]): T =

View File

@@ -998,9 +998,9 @@ func toHex*[T: SomeInteger](x: T, len: Positive): string =
doAssert b.toHex(4) == "1001"
doAssert toHex(62, 3) == "03E"
doAssert toHex(-8, 6) == "FFFFF8"
whenJsNoBigInt64:
when jsNoBigInt64:
toHexImpl(cast[BiggestUInt](x), len, x < 0)
do:
else:
when T is SomeSignedInt:
toHexImpl(cast[BiggestUInt](BiggestInt(x)), len, x < 0)
else:
@@ -1011,9 +1011,9 @@ func toHex*[T: SomeInteger](x: T): string =
runnableExamples:
doAssert toHex(1984'i64) == "00000000000007C0"
doAssert toHex(1984'i16) == "07C0"
whenJsNoBigInt64:
when jsNoBigInt64:
toHexImpl(cast[BiggestUInt](x), 2*sizeof(T), x < 0)
do:
else:
when T is SomeSignedInt:
toHexImpl(cast[BiggestUInt](BiggestInt(x)), 2*sizeof(T), x < 0)
else:

View File

@@ -215,27 +215,29 @@ when defined(nimPreviewSlimSystem):
when defined(js):
import std/jscore
import std/private/jsutils
# This is really bad, but overflow checks are broken badly for
# ints on the JS backend. See #6752.
{.push overflowChecks: off.}
proc `*`(a, b: int64): int64 =
system.`*`(a, b)
proc `*`(a, b: int): int =
system.`*`(a, b)
proc `+`(a, b: int64): int64 =
system.`+`(a, b)
proc `+`(a, b: int): int =
system.`+`(a, b)
proc `-`(a, b: int64): int64 =
system.`-`(a, b)
proc `-`(a, b: int): int =
system.`-`(a, b)
proc inc(a: var int, b: int) =
system.inc(a, b)
proc inc(a: var int64, b: int) =
system.inc(a, b)
{.pop.}
when jsNoBigInt64:
# This is really bad, but overflow checks are broken badly for
# ints on the JS backend. See #6752.
{.push overflowChecks: off.}
proc `*`(a, b: int64): int64 =
system.`*`(a, b)
proc `*`(a, b: int): int =
system.`*`(a, b)
proc `+`(a, b: int64): int64 =
system.`+`(a, b)
proc `+`(a, b: int): int =
system.`+`(a, b)
proc `-`(a, b: int64): int64 =
system.`-`(a, b)
proc `-`(a, b: int): int =
system.`-`(a, b)
proc inc(a: var int, b: int) =
system.inc(a, b)
proc inc(a: var int64, b: int) =
system.inc(a, b)
{.pop.}
elif defined(posix):
import std/posix

View File

@@ -83,14 +83,21 @@ when defined(js):
assert 9007199254740991.toJs.isSafeInteger
assert not 9007199254740992.toJs.isSafeInteger
template whenJsNoBigInt64*(no64, yes64): untyped =
const jsNoBigInt64* =
when defined(js):
when compiles(compileOption("jsbigint64")):
when compileOption("jsbigint64"):
yes64
else:
no64
not compileOption("jsbigint64")
else:
no64
true
else:
no64
false
const hasWorkingInt64* =
# equal to `not jsNoBigInt64`, but define it by itself anyway
when defined(js):
when compiles(compileOption("jsbigint64")):
compileOption("jsbigint64")
else:
false
else:
true

View File

@@ -27,8 +27,7 @@ template test(opr, a, b, c: untyped): untyped =
test(`+`, 12'i8, -13'i16, -1'i16)
test(`shl`, 0b11, 0b100, 0b110000)
whenJsNoBigInt64: discard
do:
when hasWorkingInt64:
test(`shl`, 0b11'i64, 0b100'i64, 0b110000'i64)
when not defined(js):
# mixed type shr needlessly complicates codegen with bigint
@@ -39,25 +38,21 @@ test(`shl`, 0b11'i32, 0b100'i32, 0b110000'i32)
test(`or`, 0xf0f0'i16, 0x0d0d'i16, 0xfdfd'i16)
test(`and`, 0xf0f0'i16, 0xfdfd'i16, 0xf0f0'i16)
whenJsNoBigInt64: discard
do:
when hasWorkingInt64:
test(`shr`, 0xffffffffffffffff'i64, 0x4'i64, 0xffffffffffffffff'i64)
test(`shr`, 0xffff'i16, 0x4'i16, 0xffff'i16)
test(`shr`, 0xff'i8, 0x4'i8, 0xff'i8)
whenJsNoBigInt64: discard
do:
when hasWorkingInt64:
test(`shr`, 0xffffffff'i64, 0x4'i64, 0x0fffffff'i64)
test(`shr`, 0xffffffff'i32, 0x4'i32, 0xffffffff'i32)
whenJsNoBigInt64: discard
do:
when hasWorkingInt64:
test(`shl`, 0xffffffffffffffff'i64, 0x4'i64, 0xfffffffffffffff0'i64)
test(`shl`, 0xffff'i16, 0x4'i16, 0xfff0'i16)
test(`shl`, 0xff'i8, 0x4'i8, 0xf0'i8)
whenJsNoBigInt64: discard
do:
when hasWorkingInt64:
test(`shl`, 0xffffffff'i64, 0x4'i64, 0xffffffff0'i64)
test(`shl`, 0xffffffff'i32, 0x4'i32, 0xfffffff0'i32)

View File

@@ -10,8 +10,7 @@ proc main()=
doAssert fn(array[2, uint8].default) == "Uint8Array"
doAssert fn(array[2, byte].default) == "Uint8Array"
doAssert fn(array[2, char].default) == "Uint8Array"
whenJsNoBigInt64: discard
do:
when not jsNoBigInt64:
doAssert fn(array[2, uint64].default) == "BigUint64Array"
doAssert fn([1'u8]) == "Uint8Array"
doAssert fn([1'u16]) == "Uint16Array"

View File

@@ -61,8 +61,7 @@ template main =
doAssert -2147483648'i32 == int32.low
when int.sizeof > 4:
doAssert -9223372036854775808 == int.low
whenJsNoBigInt64: discard
do:
when hasWorkingInt64:
doAssert -9223372036854775808 == int64.low
block: # check when a minus (-) is an unary op

View File

@@ -3,7 +3,7 @@ discard """
matrix: "--hint:processing"
nimout: '''
compile start
..
...
warn_module.nim(6, 6) Hint: 'test' is declared but not used [XDeclaredButNotUsed]
compile end
'''

View File

@@ -314,8 +314,7 @@ block: # bug #17383
else:
testRoundtrip(int.high): "9223372036854775807"
testRoundtrip(uint.high): "18446744073709551615"
whenJsNoBigInt64: discard
do:
when hasWorkingInt64:
testRoundtrip(int64.high): "9223372036854775807"
testRoundtrip(uint64.high): "18446744073709551615"

View File

@@ -225,8 +225,9 @@ block: # same as above but use slice overload
doAssert a3.type is a2.type
test cast[uint](int.high)
test cast[uint](int.high) + 1
whenJsNoBigInt64: discard
do:
when hasWorkingInt64 and defined(js):
# weirdly this has to run only in JS for the final int32.high test
# to be the same between C/C++ and --jsbigint64:on
test uint64.high
test uint64.high - 1
test uint.high - 2

View File

@@ -527,8 +527,7 @@ template main() =
block: # toHex
doAssert(toHex(100i16, 32) == "00000000000000000000000000000064")
whenJsNoBigInt64: discard
do:
when hasWorkingInt64:
doAssert(toHex(-100i16, 32) == "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C")
doAssert(toHex(high(uint64)) == "FFFFFFFFFFFFFFFF")
doAssert(toHex(high(uint64), 16) == "FFFFFFFFFFFFFFFF")
@@ -550,9 +549,8 @@ template main() =
doAssert(spaces(0) == "")
block: # toBin, toOct
whenJsNoBigInt64: # bug #11369
discard
do:
when hasWorkingInt64:
# bug #11369
var num: int64 = -1
doAssert num.toBin(64) == "1111111111111111111111111111111111111111111111111111111111111111"
doAssert num.toOct(24) == "001777777777777777777777"
@@ -773,8 +771,7 @@ bar
block: # formatSize
disableVm:
whenJsNoBigInt64: discard
do:
when hasWorkingInt64:
doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB" # <=== bug #8231
doAssert formatSize((2.234*1024*1024).int) == "2.234MiB"
doAssert formatSize(4096) == "4KiB"

View File

@@ -66,8 +66,7 @@ block: # `$`(SomeInteger)
testType int
testType bool
whenJsNoBigInt64: discard
do:
when hasWorkingInt64:
testType uint64
testType int64
testType BiggestInt
@@ -177,8 +176,7 @@ proc main()=
res.addInt int64(i)
doAssert res == "-9-8-7-6-5-4-3-2-10"
whenJsNoBigInt64: discard
do:
when hasWorkingInt64:
test2 high(int64), "9223372036854775807"
test2 low(int64), "-9223372036854775808"
test2 high(int32), "2147483647"