tyInt tyUint fit target int bit width (#20829)

This commit is contained in:
Bung 2022-12-01 20:34:00 +08:00 • committed by GitHub
commit 658b28dc57
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 306 additions and 267 deletions

View file

@ -373,14 +373,16 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
else: else:
result = t # Note: empty is valid here result = t # Note: empty is valid here
proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation = proc handleRange(c: PContext, f, a: PType, min, max: TTypeKind): TTypeRelation =
if a.kind == f.kind: if a.kind == f.kind:
result = isEqual result = isEqual
else: else:
let ab = skipTypes(a, {tyRange}) let ab = skipTypes(a, {tyRange})
let k = ab.kind let k = ab.kind
let nf = c.config.normalizeKind(f.kind)
let na = c.config.normalizeKind(k)
if k == f.kind: result = isSubrange if k == f.kind: result = isSubrange
elif k == tyInt and f.kind in {tyRange, tyInt8..tyInt64, elif k == tyInt and f.kind in {tyRange, tyInt..tyInt64,
tyUInt..tyUInt64} and tyUInt..tyUInt64} and
isIntLit(ab) and getInt(ab.n) >= firstOrd(nil, f) and isIntLit(ab) and getInt(ab.n) >= firstOrd(nil, f) and
getInt(ab.n) <= lastOrd(nil, f): getInt(ab.n) <= lastOrd(nil, f):
@ -389,9 +391,13 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
# integer literal in the proper range; we want ``i16 + 4`` to stay an # integer literal in the proper range; we want ``i16 + 4`` to stay an
# ``int16`` operation so we declare the ``4`` pseudo-equal to int16 # ``int16`` operation so we declare the ``4`` pseudo-equal to int16
result = isFromIntLit result = isFromIntLit
elif f.kind == tyInt and k in {tyInt8..tyInt32}: elif a.kind == tyInt and nf == c.config.targetSizeSignedToKind:
result = isIntConv result = isIntConv
elif f.kind == tyUInt and k in {tyUInt8..tyUInt32}: elif a.kind == tyUInt and nf == c.config.targetSizeUnsignedToKind:
result = isIntConv
elif f.kind == tyInt and na in {tyInt8 .. c.config.targetSizeSignedToKind}:
result = isIntConv
elif f.kind == tyUInt and na in {tyUInt8 .. c.config.targetSizeUnsignedToKind}:
result = isIntConv result = isIntConv
elif k >= min and k <= max: elif k >= min and k <= max:
result = isConvertible result = isConvertible
@ -405,7 +411,7 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
result = isConvertible result = isConvertible
else: result = isNone else: result = isNone
proc isConvertibleToRange(f, a: PType): bool = proc isConvertibleToRange(c: PContext, f, a: PType): bool =
if f.kind in {tyInt..tyInt64, tyUInt..tyUInt64} and if f.kind in {tyInt..tyInt64, tyUInt..tyUInt64} and
a.kind in {tyInt..tyInt64, tyUInt..tyUInt64}: a.kind in {tyInt..tyInt64, tyUInt..tyUInt64}:
case f.kind case f.kind
@ -413,13 +419,14 @@ proc isConvertibleToRange(f, a: PType): bool =
of tyInt16: result = isIntLit(a) or a.kind in {tyInt8, tyInt16} of tyInt16: result = isIntLit(a) or a.kind in {tyInt8, tyInt16}
of tyInt32: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32} of tyInt32: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32}
# This is wrong, but seems like there's a lot of code that relies on it :( # This is wrong, but seems like there's a lot of code that relies on it :(
of tyInt, tyUInt, tyUInt64: result = true of tyInt, tyUInt: result = true
# of tyInt: result = isIntLit(a) or a.kind in {tyInt8 .. c.config.targetSizeSignedToKind}
of tyInt64: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64} of tyInt64: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64}
of tyUInt8: result = isIntLit(a) or a.kind in {tyUInt8} of tyUInt8: result = isIntLit(a) or a.kind in {tyUInt8}
of tyUInt16: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16} of tyUInt16: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16}
of tyUInt32: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32} of tyUInt32: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32}
#of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt} # of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8 .. c.config.targetSizeUnsignedToKind}
#of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt, tyUInt64} of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt64}
else: result = false else: result = false
elif f.kind in {tyFloat..tyFloat128}: elif f.kind in {tyFloat..tyFloat128}:
# `isIntLit` is correct and should be used above as well, see PR: # `isIntLit` is correct and should be used above as well, see PR:
@ -1148,18 +1155,18 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
let f = skipTypes(f, {tyRange}) let f = skipTypes(f, {tyRange})
if f.kind == a.kind and (f.kind != tyEnum or sameEnumTypes(f, a)): if f.kind == a.kind and (f.kind != tyEnum or sameEnumTypes(f, a)):
result = isIntConv result = isIntConv
elif isConvertibleToRange(f, a): elif isConvertibleToRange(c.c, f, a):
result = isConvertible # a convertible to f result = isConvertible # a convertible to f
of tyInt: result = handleRange(f, a, tyInt8, tyInt32) of tyInt: result = handleRange(c.c, f, a, tyInt8, c.c.config.targetSizeSignedToKind)
of tyInt8: result = handleRange(f, a, tyInt8, tyInt8) of tyInt8: result = handleRange(c.c, f, a, tyInt8, tyInt8)
of tyInt16: result = handleRange(f, a, tyInt8, tyInt16) of tyInt16: result = handleRange(c.c, f, a, tyInt8, tyInt16)
of tyInt32: result = handleRange(f, a, tyInt8, tyInt32) of tyInt32: result = handleRange(c.c, f, a, tyInt8, tyInt32)
of tyInt64: result = handleRange(f, a, tyInt, tyInt64) of tyInt64: result = handleRange(c.c, f, a, tyInt, tyInt64)
of tyUInt: result = handleRange(f, a, tyUInt8, tyUInt32) of tyUInt: result = handleRange(c.c, f, a, tyUInt8, c.c.config.targetSizeUnsignedToKind)
of tyUInt8: result = handleRange(f, a, tyUInt8, tyUInt8) of tyUInt8: result = handleRange(c.c, f, a, tyUInt8, tyUInt8)
of tyUInt16: result = handleRange(f, a, tyUInt8, tyUInt16) of tyUInt16: result = handleRange(c.c, f, a, tyUInt8, tyUInt16)
of tyUInt32: result = handleRange(f, a, tyUInt8, tyUInt32) of tyUInt32: result = handleRange(c.c, f, a, tyUInt8, tyUInt32)
of tyUInt64: result = handleRange(f, a, tyUInt, tyUInt64) of tyUInt64: result = handleRange(c.c, f, a, tyUInt, tyUInt64)
of tyFloat: result = handleFloatRange(f, a) of tyFloat: result = handleFloatRange(f, a)
of tyFloat32: result = handleFloatRange(f, a) of tyFloat32: result = handleFloatRange(f, a)
of tyFloat64: result = handleFloatRange(f, a) of tyFloat64: result = handleFloatRange(f, a)
@ -2114,6 +2121,8 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
of isIntConv: of isIntConv:
# I'm too lazy to introduce another ``*matches`` field, so we conflate # I'm too lazy to introduce another ``*matches`` field, so we conflate
# ``isIntConv`` and ``isIntLit`` here: # ``isIntConv`` and ``isIntLit`` here:
if f.skipTypes({tyRange}).kind notin {tyInt, tyUInt}:
inc(m.intConvMatches)
inc(m.intConvMatches) inc(m.intConvMatches)
result = implicitConv(nkHiddenStdConv, f, arg, m, c) result = implicitConv(nkHiddenStdConv, f, arg, m, c)
of isSubtype: of isSubtype:

View file

@ -753,8 +753,13 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 =
assert(t.n.kind == nkRange) assert(t.n.kind == nkRange)
result = getOrdValue(t.n[0]) result = getOrdValue(t.n[0])
of tyInt: of tyInt:
if conf != nil and conf.target.intSize == 4: if conf != nil:
result = toInt128(-2147483648) case conf.target.intSize
of 8: result = toInt128(0x8000000000000000'i64)
of 4: result = toInt128(-2147483648)
of 2: result = toInt128(-32768)
of 1: result = toInt128(-128)
else: discard
else: else:
result = toInt128(0x8000000000000000'i64) result = toInt128(0x8000000000000000'i64)
of tyInt8: result = toInt128(-128) of tyInt8: result = toInt128(-128)
@ -797,6 +802,29 @@ proc firstFloat*(t: PType): BiggestFloat =
internalError(newPartialConfigRef(), "invalid kind for firstFloat(" & $t.kind & ')') internalError(newPartialConfigRef(), "invalid kind for firstFloat(" & $t.kind & ')')
NaN NaN
proc targetSizeSignedToKind*(conf: ConfigRef): TTypeKind =
case conf.target.intSize
of 8: result = tyInt64
of 4: result = tyInt32
of 2: result = tyInt16
else: discard
proc targetSizeUnsignedToKind*(conf: ConfigRef): TTypeKind =
case conf.target.intSize
of 8: result = tyUInt64
of 4: result = tyUInt32
of 2: result = tyUInt16
else: discard
proc normalizeKind*(conf: ConfigRef, k: TTypeKind): TTypeKind =
case k
of tyInt:
result = conf.targetSizeSignedToKind()
of tyUInt:
result = conf.targetSizeUnsignedToKind()
else:
result = k
proc lastOrd*(conf: ConfigRef; t: PType): Int128 = proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
case t.kind case t.kind
of tyBool: result = toInt128(1'u) of tyBool: result = toInt128(1'u)
@ -808,7 +836,13 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
assert(t.n.kind == nkRange) assert(t.n.kind == nkRange)
result = getOrdValue(t.n[1]) result = getOrdValue(t.n[1])
of tyInt: of tyInt:
if conf != nil and conf.target.intSize == 4: result = toInt128(0x7FFFFFFF) if conf != nil:
case conf.target.intSize
of 8: result = toInt128(0x7FFFFFFFFFFFFFFF'u64)
of 4: result = toInt128(0x7FFFFFFF)
of 2: result = toInt128(0x00007FFF)
of 1: result = toInt128(0x0000007F)
else: discard
else: result = toInt128(0x7FFFFFFFFFFFFFFF'u64) else: result = toInt128(0x7FFFFFFFFFFFFFFF'u64)
of tyInt8: result = toInt128(0x0000007F) of tyInt8: result = toInt128(0x0000007F)
of tyInt16: result = toInt128(0x00007FFF) of tyInt16: result = toInt128(0x00007FFF)

View file

@ -28,11 +28,11 @@ proc writeFloatToBufferRoundtrip*(buf: var array[65, char]; value: BiggestFloat)
## ##
## returns the amount of bytes written to `buf` not counting the ## returns the amount of bytes written to `buf` not counting the
## terminating '\0' character. ## terminating '\0' character.
result = toChars(buf, value, forceTrailingDotZero=true) result = toChars(buf, value, forceTrailingDotZero=true).int
buf[result] = '\0' buf[result] = '\0'
proc writeFloatToBufferRoundtrip*(buf: var array[65, char]; value: float32): int = proc writeFloatToBufferRoundtrip*(buf: var array[65, char]; value: float32): int =
result = float32ToChars(buf, value, forceTrailingDotZero=true) result = float32ToChars(buf, value, forceTrailingDotZero=true).int
buf[result] = '\0' buf[result] = '\0'
proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>", proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
@ -49,7 +49,7 @@ proc writeFloatToBufferSprintf*(buf: var array[65, char]; value: BiggestFloat):
## ##
## returns the amount of bytes written to `buf` not counting the ## returns the amount of bytes written to `buf` not counting the
## terminating '\0' character. ## terminating '\0' character.
var n: int = c_sprintf(cast[cstring](addr buf), "%.16g", value) var n = c_sprintf(cast[cstring](addr buf), "%.16g", value).int
var hasDot = false var hasDot = false
for i in 0..n-1: for i in 0..n-1:
if buf[i] == ',': if buf[i] == ',':

View file

@ -34,7 +34,7 @@ proc utoa2Digits*(buf: var openArray[char]; pos: int; digits: uint32) {.inline.}
#copyMem(buf, unsafeAddr(digits100[2 * digits]), 2 * sizeof((char))) #copyMem(buf, unsafeAddr(digits100[2 * digits]), 2 * sizeof((char)))
proc trailingZeros2Digits*(digits: uint32): int32 {.inline.} = proc trailingZeros2Digits*(digits: uint32): int32 {.inline.} =
return trailingZeros100[digits] return trailingZeros100[digits.int8]
when defined(js): when defined(js):
proc numToString(a: SomeInteger): cstring {.importjs: "((#) + \"\")".} proc numToString(a: SomeInteger): cstring {.importjs: "((#) + \"\")".}
@ -63,14 +63,14 @@ func addIntImpl(result: var string, x: uint64) {.inline.} =
while num >= nbatch: while num >= nbatch:
let originNum = num let originNum = num
num = num div nbatch num = num div nbatch
let index = (originNum - num * nbatch) shl 1 let index = int16((originNum - num * nbatch) shl 1)
tmp[next] = digits100[index + 1] tmp[next] = digits100[index + 1]
tmp[next - 1] = digits100[index] tmp[next - 1] = digits100[index]
dec(next, 2) dec(next, 2)
# process last 1-2 digits # process last 1-2 digits
if num < 10: if num < 10:
tmp[next] = chr(ord('0') + num) tmp[next] = chr(ord('0') + num.uint8)
else: else:
let index = num * 2 let index = num * 2
tmp[next] = digits100[index + 1] tmp[next] = digits100[index + 1]

View file

@ -1146,7 +1146,7 @@ proc printDecimalDigitsBackwards*(buf: var openArray[char]; pos: int; output64:
buf[pos] = chr(ord('0') + q) buf[pos] = chr(ord('0') + q)
return tz return tz
proc decimalLength*(v: uint64): int32 {.inline.} = proc decimalLength*(v: uint64): int {.inline.} =
dragonbox_Assert(v >= 1) dragonbox_Assert(v >= 1)
dragonbox_Assert(v <= 99999999999999999'u64) dragonbox_Assert(v <= 99999999999999999'u64)
if cast[uint32](v shr 32) != 0: if cast[uint32](v shr 32) != 0:
@ -1166,48 +1166,48 @@ proc decimalLength*(v: uint64): int32 {.inline.} =
return 11 return 11
return 10 return 10
let v32: uint32 = cast[uint32](v) let v32: uint32 = cast[uint32](v)
if v32 >= 1000000000'u: if v32 >= 1000000000'u32:
return 10 return 10
if v32 >= 100000000'u: if v32 >= 100000000'u32:
return 9 return 9
if v32 >= 10000000'u: if v32 >= 10000000'u32:
return 8 return 8
if v32 >= 1000000'u: if v32 >= 1000000'u32:
return 7 return 7
if v32 >= 100000'u: if v32 >= 100000'u32:
return 6 return 6
if v32 >= 10000'u: if v32 >= 10000'u32:
return 5 return 5
if v32 >= 1000'u: if v32 >= 1000'u32:
return 4 return 4
if v32 >= 100'u: if v32 >= 100'u32:
return 3 return 3
if v32 >= 10'u: if v32 >= 10'u32:
return 2 return 2
return 1 return 1
proc formatDigits*(buffer: var openArray[char]; pos: int; digits: uint64; decimalExponent: int32; proc formatDigits*[T: Ordinal](buffer: var openArray[char]; pos: T; digits: uint64; decimalExponent: int;
forceTrailingDotZero = false): int {.inline.} = forceTrailingDotZero = false): int {.inline.} =
const const
minFixedDecimalPoint: int32 = -6 minFixedDecimalPoint = -6
const const
maxFixedDecimalPoint: int32 = 17 maxFixedDecimalPoint = 17
var pos = pos var pos:int = pos.int
assert(minFixedDecimalPoint <= -1, "internal error") assert(minFixedDecimalPoint <= -1, "internal error")
assert(maxFixedDecimalPoint >= 17, "internal error") assert(maxFixedDecimalPoint >= 17, "internal error")
dragonbox_Assert(digits >= 1) dragonbox_Assert(digits >= 1)
dragonbox_Assert(digits <= 99999999999999999'u64) dragonbox_Assert(digits <= 99999999999999999'u64)
dragonbox_Assert(decimalExponent >= -999) dragonbox_Assert(decimalExponent >= -999)
dragonbox_Assert(decimalExponent <= 999) dragonbox_Assert(decimalExponent <= 999)
var numDigits: int32 = decimalLength(digits) var numDigits = decimalLength(digits)
let decimalPoint: int32 = numDigits + decimalExponent let decimalPoint = numDigits + decimalExponent
let useFixed: bool = minFixedDecimalPoint <= decimalPoint and let useFixed: bool = minFixedDecimalPoint <= decimalPoint and
decimalPoint <= maxFixedDecimalPoint decimalPoint <= maxFixedDecimalPoint
## Prepare the buffer. ## Prepare the buffer.
for i in 0..<32: buffer[pos+i] = '0' for i in 0..<32: buffer[pos+i] = '0'
assert(minFixedDecimalPoint >= -30, "internal error") assert(minFixedDecimalPoint >= -30, "internal error")
assert(maxFixedDecimalPoint <= 32, "internal error") assert(maxFixedDecimalPoint <= 32, "internal error")
var decimalDigitsPosition: int32 var decimalDigitsPosition: int
if useFixed: if useFixed:
if decimalPoint <= 0: if decimalPoint <= 0:
## 0.[000]digits ## 0.[000]digits
@ -1258,7 +1258,7 @@ proc formatDigits*(buffer: var openArray[char]; pos: int; digits: uint64; decima
## d.igitsE+123 ## d.igitsE+123
buffer[pos+1] = '.' buffer[pos+1] = '.'
pos = digitsEnd pos = digitsEnd
let scientificExponent: int32 = decimalPoint - 1 let scientificExponent: int = decimalPoint - 1
## SF_ASSERT(scientific_exponent != 0); ## SF_ASSERT(scientific_exponent != 0);
buffer[pos] = 'e' buffer[pos] = 'e'
buffer[pos+1] = if scientificExponent < 0: '-' else: '+' buffer[pos+1] = if scientificExponent < 0: '-' else: '+'
@ -1291,7 +1291,7 @@ proc toChars*(buffer: var openArray[char]; v: float; forceTrailingDotZero = fals
if exponent != 0 or significand != 0: if exponent != 0 or significand != 0:
## != 0 ## != 0
let dec = toDecimal64(significand, exponent) let dec = toDecimal64(significand, exponent)
return formatDigits(buffer, pos, dec.significand, dec.exponent, return formatDigits(buffer, pos, dec.significand, dec.exponent.int,
forceTrailingDotZero) forceTrailingDotZero)
else: else:
buffer[pos] = '0' buffer[pos] = '0'

View file

@ -244,7 +244,7 @@ proc toDecimal32(ieeeSignificand: uint32; ieeeExponent: uint32): FloatingDecimal
## ToChars ## ToChars
## ================================================================================================== ## ==================================================================================================
proc printDecimalDigitsBackwards(buf: var openArray[char]; pos: int; output: uint32): int32 {.inline.} = proc printDecimalDigitsBackwards[T: Ordinal](buf: var openArray[char]; pos: T; output: uint32): int32 {.inline.} =
var output = output var output = output
var pos = pos var pos = pos
var tz: int32 = 0 var tz: int32 = 0
@ -300,7 +300,7 @@ proc printDecimalDigitsBackwards(buf: var openArray[char]; pos: int; output: uin
buf[pos] = chr(uint32('0') + q) buf[pos] = chr(uint32('0') + q)
return tz return tz
proc decimalLength(v: uint32): int32 {.inline.} = proc decimalLength(v: uint32): int {.inline.} =
sf_Assert(v >= 1) sf_Assert(v >= 1)
sf_Assert(v <= 999999999'u) sf_Assert(v <= 999999999'u)
if v >= 100000000'u: if v >= 100000000'u:
@ -321,7 +321,7 @@ proc decimalLength(v: uint32): int32 {.inline.} =
return 2 return 2
return 1 return 1
proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimalExponent: int32; proc formatDigits[T: Ordinal](buffer: var openArray[char]; pos: T; digits: uint32; decimalExponent: int;
forceTrailingDotZero: bool = false): int {.inline.} = forceTrailingDotZero: bool = false): int {.inline.} =
const const
minFixedDecimalPoint: int32 = -4 minFixedDecimalPoint: int32 = -4
@ -333,8 +333,8 @@ proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimal
sf_Assert(digits <= 999999999'u) sf_Assert(digits <= 999999999'u)
sf_Assert(decimalExponent >= -99) sf_Assert(decimalExponent >= -99)
sf_Assert(decimalExponent <= 99) sf_Assert(decimalExponent <= 99)
var numDigits: int32 = decimalLength(digits) var numDigits = decimalLength(digits)
let decimalPoint: int32 = numDigits + decimalExponent let decimalPoint = numDigits + decimalExponent
let useFixed: bool = minFixedDecimalPoint <= decimalPoint and let useFixed: bool = minFixedDecimalPoint <= decimalPoint and
decimalPoint <= maxFixedDecimalPoint decimalPoint <= maxFixedDecimalPoint
## Prepare the buffer. ## Prepare the buffer.
@ -342,7 +342,7 @@ proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimal
for i in 0..<32: buffer[pos+i] = '0' for i in 0..<32: buffer[pos+i] = '0'
assert(minFixedDecimalPoint >= -30, "internal error") assert(minFixedDecimalPoint >= -30, "internal error")
assert(maxFixedDecimalPoint <= 32, "internal error") assert(maxFixedDecimalPoint <= 32, "internal error")
var decimalDigitsPosition: int32 var decimalDigitsPosition: int
if useFixed: if useFixed:
if decimalPoint <= 0: if decimalPoint <= 0:
## 0.[000]digits ## 0.[000]digits
@ -386,7 +386,7 @@ proc formatDigits(buffer: var openArray[char]; pos: int; digits: uint32; decimal
## d.igitsE+123 ## d.igitsE+123
buffer[pos+1] = '.' buffer[pos+1] = '.'
pos = digitsEnd pos = digitsEnd
let scientificExponent: int32 = decimalPoint - 1 let scientificExponent = decimalPoint - 1
## SF_ASSERT(scientific_exponent != 0); ## SF_ASSERT(scientific_exponent != 0);
buffer[pos] = 'e' buffer[pos] = 'e'
buffer[pos+1] = if scientificExponent < 0: '-' else: '+' buffer[pos+1] = if scientificExponent < 0: '-' else: '+'
@ -412,7 +412,7 @@ proc float32ToChars*(buffer: var openArray[char]; v: float32; forceTrailingDotZe
if exponent != 0 or significand != 0: if exponent != 0 or significand != 0:
## != 0 ## != 0
let dec: auto = toDecimal32(significand, exponent) let dec: auto = toDecimal32(significand, exponent)
return formatDigits(buffer, pos, dec.digits, dec.exponent, forceTrailingDotZero) return formatDigits(buffer, pos, dec.digits, dec.exponent.int, forceTrailingDotZero)
else: else:
buffer[pos] = '0' buffer[pos] = '0'
buffer[pos+1] = '.' buffer[pos+1] = '.'

View file

@ -573,7 +573,7 @@ proc readAllFile(file: File, len: int64): string =
result = newString(len) result = newString(len)
let bytes = readBuffer(file, addr(result[0]), len) let bytes = readBuffer(file, addr(result[0]), len)
if endOfFile(file): if endOfFile(file):
if bytes < len: if bytes.int64 < len:
result.setLen(bytes) result.setLen(bytes)
else: else:
# We read all the bytes but did not reach the EOF # We read all the bytes but did not reach the EOF
@ -717,7 +717,7 @@ proc open*(f: var File, filename: string,
result = true result = true
f = cast[File](p) f = cast[File](p)
if bufSize > 0 and bufSize <= high(cint).int: if bufSize > 0 and bufSize.uint <= high(uint):
discard c_setvbuf(f, nil, IOFBF, cast[csize_t](bufSize)) discard c_setvbuf(f, nil, IOFBF, cast[csize_t](bufSize))
elif bufSize == 0: elif bufSize == 0:
discard c_setvbuf(f, nil, IONBF, 0) discard c_setvbuf(f, nil, IONBF, 0)
@ -821,7 +821,7 @@ when defined(windows) and appType == "console" and
proc getConsoleCP(): cuint {.stdcall, dynlib: "kernel32", proc getConsoleCP(): cuint {.stdcall, dynlib: "kernel32",
importc: "GetConsoleCP".} importc: "GetConsoleCP".}
const Utf8codepage = 65001 const Utf8codepage = 65001'u32
let let
consoleOutputCP = getConsoleOutputCP() consoleOutputCP = getConsoleOutputCP()

View file

@ -52,7 +52,7 @@ when defined(genode):
import genode/env import genode/env
when hasAllocStack or defined(zephyr) or defined(freertos): when hasAllocStack or defined(zephyr) or defined(freertos) or defined(cpu16) or defined(cpu8):
const const
nimThreadStackSize {.intdefine.} = 8192 nimThreadStackSize {.intdefine.} = 8192
nimThreadStackGuard {.intdefine.} = 128 nimThreadStackGuard {.intdefine.} = 128

View file

@ -15,214 +15,215 @@
type type
Utf16Char* = distinct int16 Utf16Char* = distinct int16
when defined(nimv2): when not (defined(cpu16) or defined(cpu8)):
when defined(nimv2):
type type
WideCString* = ptr UncheckedArray[Utf16Char] WideCString* = ptr UncheckedArray[Utf16Char]
WideCStringObj* = object WideCStringObj* = object
bytes: int bytes: int
data: WideCString data: WideCString
proc `=destroy`(a: var WideCStringObj) = proc `=destroy`(a: var WideCStringObj) =
if a.data != nil: if a.data != nil:
when compileOption("threads"):
deallocShared(a.data)
else:
dealloc(a.data)
proc `=copy`(a: var WideCStringObj; b: WideCStringObj) {.error.}
proc `=sink`(a: var WideCStringObj; b: WideCStringObj) =
a.bytes = b.bytes
a.data = b.data
proc createWide(a: var WideCStringObj; bytes: int) =
a.bytes = bytes
when compileOption("threads"): when compileOption("threads"):
deallocShared(a.data) a.data = cast[typeof(a.data)](allocShared0(bytes))
else: else:
dealloc(a.data) a.data = cast[typeof(a.data)](alloc0(bytes))
proc `=copy`(a: var WideCStringObj; b: WideCStringObj) {.error.} template `[]`*(a: WideCStringObj; idx: int): Utf16Char = a.data[idx]
template `[]=`*(a: WideCStringObj; idx: int; val: Utf16Char) = a.data[idx] = val
proc `=sink`(a: var WideCStringObj; b: WideCStringObj) = template nullWide(): untyped = WideCStringObj(bytes: 0, data: nil)
a.bytes = b.bytes
a.data = b.data
proc createWide(a: var WideCStringObj; bytes: int) = converter toWideCString*(x: WideCStringObj): WideCString {.inline.} =
a.bytes = bytes result = x.data
when compileOption("threads"):
a.data = cast[typeof(a.data)](allocShared0(bytes))
else:
a.data = cast[typeof(a.data)](alloc0(bytes))
template `[]`*(a: WideCStringObj; idx: int): Utf16Char = a.data[idx]
template `[]=`*(a: WideCStringObj; idx: int; val: Utf16Char) = a.data[idx] = val
template nullWide(): untyped = WideCStringObj(bytes: 0, data: nil)
converter toWideCString*(x: WideCStringObj): WideCString {.inline.} =
result = x.data
else:
template nullWide(): untyped = nil
type
WideCString* = ref UncheckedArray[Utf16Char]
WideCStringObj* = WideCString
template createWide(a; L) =
unsafeNew(a, L)
proc ord(arg: Utf16Char): int = int(cast[uint16](arg))
proc len*(w: WideCString): int =
## returns the length of a widestring. This traverses the whole string to
## find the binary zero end marker!
result = 0
while int16(w[result]) != 0'i16: inc result
const
UNI_REPLACEMENT_CHAR = Utf16Char(0xFFFD'i16)
UNI_MAX_BMP = 0x0000FFFF
UNI_MAX_UTF16 = 0x0010FFFF
# UNI_MAX_UTF32 = 0x7FFFFFFF
# UNI_MAX_LEGAL_UTF32 = 0x0010FFFF
halfShift = 10
halfBase = 0x0010000
halfMask = 0x3FF
UNI_SUR_HIGH_START = 0xD800
UNI_SUR_HIGH_END = 0xDBFF
UNI_SUR_LOW_START = 0xDC00
UNI_SUR_LOW_END = 0xDFFF
UNI_REPL = 0xFFFD
template ones(n: untyped): untyped = ((1 shl n)-1)
template fastRuneAt(s: cstring, i, L: int, result: untyped, doInc = true) =
## Returns the unicode character `s[i]` in `result`. If `doInc == true`
## `i` is incremented by the number of bytes that have been processed.
bind ones
if ord(s[i]) <= 127:
result = ord(s[i])
when doInc: inc(i)
elif ord(s[i]) shr 5 == 0b110:
#assert(ord(s[i+1]) shr 6 == 0b10)
if i <= L - 2:
result = (ord(s[i]) and (ones(5))) shl 6 or (ord(s[i+1]) and ones(6))
when doInc: inc(i, 2)
else:
result = UNI_REPL
when doInc: inc(i)
elif ord(s[i]) shr 4 == 0b1110:
if i <= L - 3:
#assert(ord(s[i+1]) shr 6 == 0b10)
#assert(ord(s[i+2]) shr 6 == 0b10)
result = (ord(s[i]) and ones(4)) shl 12 or
(ord(s[i+1]) and ones(6)) shl 6 or
(ord(s[i+2]) and ones(6))
when doInc: inc(i, 3)
else:
result = UNI_REPL
when doInc: inc(i)
elif ord(s[i]) shr 3 == 0b11110:
if i <= L - 4:
#assert(ord(s[i+1]) shr 6 == 0b10)
#assert(ord(s[i+2]) shr 6 == 0b10)
#assert(ord(s[i+3]) shr 6 == 0b10)
result = (ord(s[i]) and ones(3)) shl 18 or
(ord(s[i+1]) and ones(6)) shl 12 or
(ord(s[i+2]) and ones(6)) shl 6 or
(ord(s[i+3]) and ones(6))
when doInc: inc(i, 4)
else:
result = UNI_REPL
when doInc: inc(i)
else: else:
result = 0xFFFD template nullWide(): untyped = nil
when doInc: inc(i)
iterator runes(s: cstring, L: int): int = type
var WideCString* = ref UncheckedArray[Utf16Char]
i = 0 WideCStringObj* = WideCString
result: int
while i < L:
fastRuneAt(s, i, L, result, true)
yield result
proc newWideCString*(size: int): WideCStringObj = template createWide(a; L) =
createWide(result, size * 2 + 2) unsafeNew(a, L)
proc newWideCString*(source: cstring, L: int): WideCStringObj = proc ord(arg: Utf16Char): int = int(cast[uint16](arg))
createWide(result, L * 2 + 2)
var d = 0
for ch in runes(source, L):
if ch <= UNI_MAX_BMP: proc len*(w: WideCString): int =
if ch >= UNI_SUR_HIGH_START and ch <= UNI_SUR_LOW_END: ## returns the length of a widestring. This traverses the whole string to
## find the binary zero end marker!
result = 0
while int16(w[result]) != 0'i16: inc result
const
UNI_REPLACEMENT_CHAR = Utf16Char(0xFFFD'i16)
UNI_MAX_BMP = 0x0000FFFF
UNI_MAX_UTF16 = 0x0010FFFF
# UNI_MAX_UTF32 = 0x7FFFFFFF
# UNI_MAX_LEGAL_UTF32 = 0x0010FFFF
halfShift = 10
halfBase = 0x0010000
halfMask = 0x3FF
UNI_SUR_HIGH_START = 0xD800
UNI_SUR_HIGH_END = 0xDBFF
UNI_SUR_LOW_START = 0xDC00
UNI_SUR_LOW_END = 0xDFFF
UNI_REPL = 0xFFFD
template ones(n: untyped): untyped = ((1 shl n)-1)
template fastRuneAt(s: cstring, i, L: int, result: untyped, doInc = true) =
## Returns the unicode character `s[i]` in `result`. If `doInc == true`
## `i` is incremented by the number of bytes that have been processed.
bind ones
if ord(s[i]) <= 127:
result = ord(s[i])
when doInc: inc(i)
elif ord(s[i]) shr 5 == 0b110:
#assert(ord(s[i+1]) shr 6 == 0b10)
if i <= L - 2:
result = (ord(s[i]) and (ones(5))) shl 6 or (ord(s[i+1]) and ones(6))
when doInc: inc(i, 2)
else:
result = UNI_REPL
when doInc: inc(i)
elif ord(s[i]) shr 4 == 0b1110:
if i <= L - 3:
#assert(ord(s[i+1]) shr 6 == 0b10)
#assert(ord(s[i+2]) shr 6 == 0b10)
result = (ord(s[i]) and ones(4)) shl 12 or
(ord(s[i+1]) and ones(6)) shl 6 or
(ord(s[i+2]) and ones(6))
when doInc: inc(i, 3)
else:
result = UNI_REPL
when doInc: inc(i)
elif ord(s[i]) shr 3 == 0b11110:
if i <= L - 4:
#assert(ord(s[i+1]) shr 6 == 0b10)
#assert(ord(s[i+2]) shr 6 == 0b10)
#assert(ord(s[i+3]) shr 6 == 0b10)
result = (ord(s[i]) and ones(3)) shl 18 or
(ord(s[i+1]) and ones(6)) shl 12 or
(ord(s[i+2]) and ones(6)) shl 6 or
(ord(s[i+3]) and ones(6))
when doInc: inc(i, 4)
else:
result = UNI_REPL
when doInc: inc(i)
else:
result = 0xFFFD
when doInc: inc(i)
iterator runes(s: cstring, L: int): int =
var
i = 0
result: int
while i < L:
fastRuneAt(s, i, L, result, true)
yield result
proc newWideCString*(size: int): WideCStringObj =
createWide(result, size * 2 + 2)
proc newWideCString*(source: cstring, L: int): WideCStringObj =
createWide(result, L * 2 + 2)
var d = 0
for ch in runes(source, L):
if ch <= UNI_MAX_BMP:
if ch >= UNI_SUR_HIGH_START and ch <= UNI_SUR_LOW_END:
result[d] = UNI_REPLACEMENT_CHAR
else:
result[d] = cast[Utf16Char](uint16(ch))
elif ch > UNI_MAX_UTF16:
result[d] = UNI_REPLACEMENT_CHAR result[d] = UNI_REPLACEMENT_CHAR
else: else:
result[d] = cast[Utf16Char](uint16(ch)) let ch = ch - halfBase
elif ch > UNI_MAX_UTF16: result[d] = cast[Utf16Char](uint16((ch shr halfShift) + UNI_SUR_HIGH_START))
result[d] = UNI_REPLACEMENT_CHAR inc d
else: result[d] = cast[Utf16Char](uint16((ch and halfMask) + UNI_SUR_LOW_START))
let ch = ch - halfBase
result[d] = cast[Utf16Char](uint16((ch shr halfShift) + UNI_SUR_HIGH_START))
inc d inc d
result[d] = cast[Utf16Char](uint16((ch and halfMask) + UNI_SUR_LOW_START)) result[d] = Utf16Char(0)
inc d
result[d] = Utf16Char(0)
proc newWideCString*(s: cstring): WideCStringObj = proc newWideCString*(s: cstring): WideCStringObj =
if s.isNil: return nullWide if s.isNil: return nullWide
result = newWideCString(s, s.len) result = newWideCString(s, s.len)
proc newWideCString*(s: string): WideCStringObj = proc newWideCString*(s: string): WideCStringObj =
result = newWideCString(cstring s, s.len) result = newWideCString(cstring s, s.len)
proc `$`*(w: WideCString, estimate: int, replacement: int = 0xFFFD): string = proc `$`*(w: WideCString, estimate: int, replacement: int = 0xFFFD): string =
result = newStringOfCap(estimate + estimate shr 2) result = newStringOfCap(estimate + estimate shr 2)
var i = 0 var i = 0
while w[i].int16 != 0'i16: while w[i].int16 != 0'i16:
var ch = ord(w[i]) var ch = ord(w[i])
inc i inc i
if ch >= UNI_SUR_HIGH_START and ch <= UNI_SUR_HIGH_END: if ch >= UNI_SUR_HIGH_START and ch <= UNI_SUR_HIGH_END:
# If the 16 bits following the high surrogate are in the source buffer... # If the 16 bits following the high surrogate are in the source buffer...
let ch2 = ord(w[i]) let ch2 = ord(w[i])
# If it's a low surrogate, convert to UTF32: # If it's a low surrogate, convert to UTF32:
if ch2 >= UNI_SUR_LOW_START and ch2 <= UNI_SUR_LOW_END: if ch2 >= UNI_SUR_LOW_START and ch2 <= UNI_SUR_LOW_END:
ch = (((ch and halfMask) shl halfShift) + (ch2 and halfMask)) + halfBase ch = (((ch and halfMask) shl halfShift) + (ch2 and halfMask)) + halfBase
inc i inc i
else: else:
#invalid UTF-16
ch = replacement
elif ch >= UNI_SUR_LOW_START and ch <= UNI_SUR_LOW_END:
#invalid UTF-16 #invalid UTF-16
ch = replacement ch = replacement
elif ch >= UNI_SUR_LOW_START and ch <= UNI_SUR_LOW_END:
#invalid UTF-16
ch = replacement
if ch < 0x80: if ch < 0x80:
result.add chr(ch) result.add chr(ch)
elif ch < 0x800: elif ch < 0x800:
result.add chr((ch shr 6) or 0xc0) result.add chr((ch shr 6) or 0xc0)
result.add chr((ch and 0x3f) or 0x80) result.add chr((ch and 0x3f) or 0x80)
elif ch < 0x10000: elif ch < 0x10000:
result.add chr((ch shr 12) or 0xe0) result.add chr((ch shr 12) or 0xe0)
result.add chr(((ch shr 6) and 0x3f) or 0x80) result.add chr(((ch shr 6) and 0x3f) or 0x80)
result.add chr((ch and 0x3f) or 0x80) result.add chr((ch and 0x3f) or 0x80)
elif ch <= 0x10FFFF: elif ch <= 0x10FFFF:
result.add chr((ch shr 18) or 0xf0) result.add chr((ch shr 18) or 0xf0)
result.add chr(((ch shr 12) and 0x3f) or 0x80) result.add chr(((ch shr 12) and 0x3f) or 0x80)
result.add chr(((ch shr 6) and 0x3f) or 0x80) result.add chr(((ch shr 6) and 0x3f) or 0x80)
result.add chr((ch and 0x3f) or 0x80) result.add chr((ch and 0x3f) or 0x80)
else: else:
# replacement char(in case user give very large number): # replacement char(in case user give very large number):
result.add chr(0xFFFD shr 12 or 0b1110_0000) result.add chr(0xFFFD shr 12 or 0b1110_0000)
result.add chr(0xFFFD shr 6 and ones(6) or 0b10_0000_00) result.add chr(0xFFFD shr 6 and ones(6) or 0b10_0000_00)
result.add chr(0xFFFD and ones(6) or 0b10_0000_00) result.add chr(0xFFFD and ones(6) or 0b10_0000_00)
proc `$`*(s: WideCString): string = proc `$`*(s: WideCString): string =
result = s $ 80 result = s $ 80
when defined(nimv2): when defined(nimv2):
proc `$`*(s: WideCStringObj, estimate: int, replacement: int = 0xFFFD): string = proc `$`*(s: WideCStringObj, estimate: int, replacement: int = 0xFFFD): string =
`$`(s.data, estimate, replacement) `$`(s.data, estimate, replacement)
proc `$`*(s: WideCStringObj): string = proc `$`*(s: WideCStringObj): string =
$(s.data) $(s.data)
proc len*(w: WideCStringObj): int {.inline.} = proc len*(w: WideCStringObj): int {.inline.} =
len(w.data) len(w.data)

View file

@ -2001,7 +2001,7 @@ when notJSnotNims:
proc equalMem(a, b: pointer, size: Natural): bool = proc equalMem(a, b: pointer, size: Natural): bool =
nimCmpMem(a, b, size) == 0 nimCmpMem(a, b, size) == 0
proc cmpMem(a, b: pointer, size: Natural): int = proc cmpMem(a, b: pointer, size: Natural): int =
nimCmpMem(a, b, size) nimCmpMem(a, b, size).int
when not defined(js): when not defined(js):
proc cmp(x, y: string): int = proc cmp(x, y: string): int =
@ -2300,11 +2300,13 @@ else:
type ExitCodeRange = int8 type ExitCodeRange = int8
else: # win32 uses low 32 bits else: # win32 uses low 32 bits
type ExitCodeRange = cint type ExitCodeRange = cint
when sizeof(errorcode) > sizeof(ExitCodeRange):
if errorcode < low(ExitCodeRange): if errorcode < low(ExitCodeRange):
rawQuit(low(ExitCodeRange).cint) rawQuit(low(ExitCodeRange).cint)
elif errorcode > high(ExitCodeRange): elif errorcode > high(ExitCodeRange):
rawQuit(high(ExitCodeRange).cint) rawQuit(high(ExitCodeRange).cint)
else:
rawQuit(errorcode.cint)
else: else:
rawQuit(errorcode.cint) rawQuit(errorcode.cint)

View file

@ -24,7 +24,7 @@ template track(op, address, size) =
const const
nimMinHeapPages {.intdefine.} = 128 # 0.5 MB nimMinHeapPages {.intdefine.} = 128 # 0.5 MB
SmallChunkSize = PageSize SmallChunkSize = PageSize
MaxFli = 30 MaxFli = when sizeof(int) > 2: 30 else: 14
MaxLog2Sli = 5 # 32, this cannot be increased without changing 'uint32' MaxLog2Sli = 5 # 32, this cannot be increased without changing 'uint32'
# everywhere! # everywhere!
MaxSli = 1 shl MaxLog2Sli MaxSli = 1 shl MaxLog2Sli
@ -32,7 +32,7 @@ const
RealFli = MaxFli - FliOffset RealFli = MaxFli - FliOffset
# size of chunks in last matrix bin # size of chunks in last matrix bin
MaxBigChunkSize = 1 shl MaxFli - 1 shl (MaxFli-MaxLog2Sli-1) MaxBigChunkSize = int(1'i32 shl MaxFli - 1'i32 shl (MaxFli-MaxLog2Sli-1))
HugeChunkSize = MaxBigChunkSize + 1 HugeChunkSize = MaxBigChunkSize + 1
type type
@ -115,7 +115,7 @@ type
MemRegion = object MemRegion = object
when not defined(gcDestructors): when not defined(gcDestructors):
minLargeObj, maxLargeObj: int minLargeObj, maxLargeObj: int
freeSmallChunks: array[0..SmallChunkSize div MemAlign-1, PSmallChunk] freeSmallChunks: array[0..max(1,SmallChunkSize div MemAlign-1), PSmallChunk]
flBitmap: uint32 flBitmap: uint32
slBitmap: array[RealFli, uint32] slBitmap: array[RealFli, uint32]
matrix: array[RealFli, array[MaxSli, PBigChunk]] matrix: array[RealFli, array[MaxSli, PBigChunk]]
@ -196,7 +196,7 @@ proc mappingSearch(r, fl, sl: var int) {.inline.} =
let t = roundup((1 shl (msbit(uint32 r) - MaxLog2Sli)), PageSize) - 1 let t = roundup((1 shl (msbit(uint32 r) - MaxLog2Sli)), PageSize) - 1
r = r + t r = r + t
r = r and not t r = r and not t
r = min(r, MaxBigChunkSize) r = min(r, MaxBigChunkSize).int
fl = msbit(uint32 r) fl = msbit(uint32 r)
sl = (r shr (fl - MaxLog2Sli)) - MaxSli sl = (r shr (fl - MaxLog2Sli)) - MaxSli
dec fl, FliOffset dec fl, FliOffset
@ -472,7 +472,7 @@ proc requestOsChunks(a: var MemRegion, size: int): PBigChunk =
a.nextChunkSize = PageSize*4 a.nextChunkSize = PageSize*4
else: else:
a.nextChunkSize = min(roundup(usedMem shr 2, PageSize), a.nextChunkSize * 2) a.nextChunkSize = min(roundup(usedMem shr 2, PageSize), a.nextChunkSize * 2)
a.nextChunkSize = min(a.nextChunkSize, MaxBigChunkSize) a.nextChunkSize = min(a.nextChunkSize, MaxBigChunkSize).int
var size = size var size = size
if size > a.nextChunkSize: if size > a.nextChunkSize:

View file

@ -1,4 +1,4 @@
proc succ*[T: Ordinal](x: T, y = 1): T {.magic: "Succ", noSideEffect.} = proc succ*[T, V: Ordinal](x: T, y: V = 1): T {.magic: "Succ", noSideEffect.} =
## Returns the `y`-th successor (default: 1) of the value `x`. ## Returns the `y`-th successor (default: 1) of the value `x`.
## ##
## If such a value does not exist, `OverflowDefect` is raised ## If such a value does not exist, `OverflowDefect` is raised
@ -7,7 +7,7 @@ proc succ*[T: Ordinal](x: T, y = 1): T {.magic: "Succ", noSideEffect.} =
assert succ(5) == 6 assert succ(5) == 6
assert succ(5, 3) == 8 assert succ(5, 3) == 8
proc pred*[T: Ordinal](x: T, y = 1): T {.magic: "Pred", noSideEffect.} = proc pred*[T, V: Ordinal](x: T, y: V = 1): T {.magic: "Pred", noSideEffect.} =
## Returns the `y`-th predecessor (default: 1) of the value `x`. ## Returns the `y`-th predecessor (default: 1) of the value `x`.
## ##
## If such a value does not exist, `OverflowDefect` is raised ## If such a value does not exist, `OverflowDefect` is raised
@ -16,7 +16,7 @@ proc pred*[T: Ordinal](x: T, y = 1): T {.magic: "Pred", noSideEffect.} =
assert pred(5) == 4 assert pred(5) == 4
assert pred(5, 3) == 2 assert pred(5, 3) == 2
proc inc*[T: Ordinal](x: var T, y = 1) {.magic: "Inc", noSideEffect.} = proc inc*[T, V: Ordinal](x: var T, y: V = 1) {.magic: "Inc", noSideEffect.} =
## Increments the ordinal `x` by `y`. ## Increments the ordinal `x` by `y`.
## ##
## If such a value does not exist, `OverflowDefect` is raised or a compile ## If such a value does not exist, `OverflowDefect` is raised or a compile
@ -28,7 +28,7 @@ proc inc*[T: Ordinal](x: var T, y = 1) {.magic: "Inc", noSideEffect.} =
inc(i, 3) inc(i, 3)
assert i == 6 assert i == 6
proc dec*[T: Ordinal](x: var T, y = 1) {.magic: "Dec", noSideEffect.} = proc dec*[T, V: Ordinal](x: var T, y: V = 1) {.magic: "Dec", noSideEffect.} =
## Decrements the ordinal `x` by `y`. ## Decrements the ordinal `x` by `y`.
## ##
## If such a value does not exist, `OverflowDefect` is raised or a compile ## If such a value does not exist, `OverflowDefect` is raised or a compile

View file

@ -10,7 +10,7 @@
# Page size of the system; in most cases 4096 bytes. For exotic OS or # Page size of the system; in most cases 4096 bytes. For exotic OS or
# CPU this needs to be changed: # CPU this needs to be changed:
const const
PageShift = when defined(nimPage256) or defined(cpu16): 8 PageShift = when defined(nimPage256) or defined(cpu16): 3
elif defined(nimPage512): 9 elif defined(nimPage512): 9
elif defined(nimPage1k): 10 elif defined(nimPage1k): 10
else: 12 # \ # my tests showed no improvements for using larger page sizes. else: 12 # \ # my tests showed no improvements for using larger page sizes.

View file

@ -17,7 +17,7 @@ proc cmpStrings(a, b: string): int {.inline, compilerproc.} =
let blen = b.len let blen = b.len
let minlen = min(alen, blen) let minlen = min(alen, blen)
if minlen > 0: if minlen > 0:
result = c_memcmp(unsafeAddr a[0], unsafeAddr b[0], cast[csize_t](minlen)) result = c_memcmp(unsafeAddr a[0], unsafeAddr b[0], cast[csize_t](minlen)).int
if result == 0: if result == 0:
result = alen - blen result = alen - blen
else: else:

View file

@ -36,7 +36,7 @@ template frees(s) =
proc resize(old: int): int {.inline.} = proc resize(old: int): int {.inline.} =
if old <= 0: result = 4 if old <= 0: result = 4
elif old < 65536: result = old * 2 elif old <= high(int16): result = old * 2
else: result = old * 3 div 2 # for large arrays * 3/2 is better else: result = old * 3 div 2 # for large arrays * 3/2 is better
proc prepareAdd(s: var NimStringV2; addlen: int) {.compilerRtl.} = proc prepareAdd(s: var NimStringV2; addlen: int) {.compilerRtl.} =

2
tests/arithm/t1.nim Normal file
View file

@ -0,0 +1,2 @@
doAssert typeOf(1.int64 + 1.int) is int64
doAssert typeOf(1.uint64 + 1.uint) is uint64

View file

@ -1,14 +1,5 @@
discard """ discard """
errormsg: "type mismatch: got <int>" errormsg: "type mismatch: got <int>"
nimout: '''tprevent_forloopvar_mutations.nim(16, 7) Error: type mismatch: got <int>
but expected one of:
proc inc[T: Ordinal](x: var T; y = 1)
first type mismatch at position: 1
required type for x: var T: Ordinal
but expression 'i' is immutable, not 'var'
expression: inc i
'''
""" """
for i in 0..10: for i in 0..10: