mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-11 22:08:54 +00:00
Fix some jsgen bugs (#22330)
Fix `succ`, `pred` Fix `genRangeChck` for unsigned ints Fix typo in `dec`
This commit is contained in:
@@ -676,8 +676,38 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
|
||||
applyFormat("modInt64($1, $2)", "$1 % $2")
|
||||
else:
|
||||
applyFormat("modInt($1, $2)", "Math.trunc($1 % $2)")
|
||||
of mSucc: applyFormat("addInt($1, $2)", "($1 + $2)")
|
||||
of mPred: applyFormat("subInt($1, $2)", "($1 - $2)")
|
||||
of mSucc:
|
||||
let typ = n[1].typ.skipTypes(abstractVarRange)
|
||||
case typ.kind
|
||||
of tyUInt..tyUInt32:
|
||||
binaryUintExpr(p, n, r, "+")
|
||||
of tyUInt64:
|
||||
if optJsBigInt64 in p.config.globalOptions:
|
||||
applyFormat("BigInt.asUintN(64, $1 + BigInt($2))")
|
||||
else: binaryUintExpr(p, n, r, "+")
|
||||
elif typ.kind == tyInt64 and optJsBigInt64 in p.config.globalOptions:
|
||||
if optOverflowCheck notin p.options:
|
||||
applyFormat("BigInt.asIntN(64, $1 + BigInt($2))")
|
||||
else: binaryExpr(p, n, r, "addInt64", "addInt64($1, BigInt($2))")
|
||||
else:
|
||||
if optOverflowCheck notin p.options: applyFormat("$1 + $2")
|
||||
else: binaryExpr(p, n, r, "addInt", "addInt($1, $2)")
|
||||
of mPred:
|
||||
let typ = n[1].typ.skipTypes(abstractVarRange)
|
||||
case typ.kind
|
||||
of tyUInt..tyUInt32:
|
||||
binaryUintExpr(p, n, r, "-")
|
||||
of tyUInt64:
|
||||
if optJsBigInt64 in p.config.globalOptions:
|
||||
applyFormat("BigInt.asUintN(64, $1 - BigInt($2))")
|
||||
else: binaryUintExpr(p, n, r, "-")
|
||||
elif typ.kind == tyInt64 and optJsBigInt64 in p.config.globalOptions:
|
||||
if optOverflowCheck notin p.options:
|
||||
applyFormat("BigInt.asIntN(64, $1 - BigInt($2))")
|
||||
else: binaryExpr(p, n, r, "subInt64", "subInt64($1, BigInt($2))")
|
||||
else:
|
||||
if optOverflowCheck notin p.options: applyFormat("$1 - $2")
|
||||
else: binaryExpr(p, n, r, "subInt", "subInt($1, $2)")
|
||||
of mAddF64: applyFormat("($1 + $2)", "($1 + $2)")
|
||||
of mSubF64: applyFormat("($1 - $2)", "($1 - $2)")
|
||||
of mMulF64: applyFormat("($1 * $2)", "($1 * $2)")
|
||||
@@ -2346,7 +2376,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
|
||||
of tyUInt64:
|
||||
if optJsBigInt64 in p.config.globalOptions:
|
||||
binaryExpr(p, n, r, "", "$1 = BigInt.asUintN(64, $3 - BigInt($2))", true)
|
||||
else: binaryUintExpr(p, n, r, "+", true)
|
||||
else: binaryUintExpr(p, n, r, "-", true)
|
||||
elif typ.kind == tyInt64 and optJsBigInt64 in p.config.globalOptions:
|
||||
if optOverflowCheck notin p.options:
|
||||
binaryExpr(p, n, r, "", "$1 = BigInt.asIntN(64, $3 - BigInt($2))", true)
|
||||
@@ -2564,12 +2594,19 @@ proc genRangeChck(p: PProc, n: PNode, r: var TCompRes, magic: string) =
|
||||
gen(p, n[0], r)
|
||||
let src = skipTypes(n[0].typ, abstractVarRange)
|
||||
let dest = skipTypes(n.typ, abstractVarRange)
|
||||
if src.kind in {tyInt64, tyUInt64} and dest.kind notin {tyInt64, tyUInt64} and optJsBigInt64 in p.config.globalOptions:
|
||||
r.res = "Number($1)" % [r.res]
|
||||
if optRangeCheck notin p.options or (dest.kind in {tyUInt..tyUInt64} and
|
||||
checkUnsignedConversions notin p.config.legacyFeatures):
|
||||
discard "XXX maybe emit masking instructions here"
|
||||
if optRangeCheck notin p.options:
|
||||
return
|
||||
elif dest.kind in {tyUInt..tyUInt64} and checkUnsignedConversions notin p.config.legacyFeatures:
|
||||
if src.kind in {tyInt64, tyUInt64} and optJsBigInt64 in p.config.globalOptions:
|
||||
r.res = "BigInt.asUintN($1, $2)" % [$(dest.size * 8), r.res]
|
||||
else:
|
||||
r.res = "BigInt.asUintN($1, BigInt($2))" % [$(dest.size * 8), r.res]
|
||||
if not (dest.kind == tyUInt64 and optJsBigInt64 in p.config.globalOptions):
|
||||
r.res = "Number($1)" % [r.res]
|
||||
else:
|
||||
if src.kind in {tyInt64, tyUInt64} and dest.kind notin {tyInt64, tyUInt64} and optJsBigInt64 in p.config.globalOptions:
|
||||
# we do a range check anyway, so it's ok if the number gets rounded
|
||||
r.res = "Number($1)" % [r.res]
|
||||
gen(p, n[1], a)
|
||||
gen(p, n[2], b)
|
||||
useMagic(p, "chckRange")
|
||||
|
||||
@@ -656,10 +656,6 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||
if not checkIsolate(n[1]):
|
||||
localError(c.config, n.info, "expression cannot be isolated: " & $n[1])
|
||||
result = n
|
||||
of mPred:
|
||||
if n[1].typ.skipTypes(abstractInst).kind in {tyUInt..tyUInt64}:
|
||||
n[0].sym.magic = mSubU
|
||||
result = n
|
||||
of mPrivateAccess:
|
||||
result = semPrivateAccess(c, n)
|
||||
of mArrToSeq:
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
discard """
|
||||
targets: "c cpp js"
|
||||
"""
|
||||
|
||||
# Tests unsigned literals and implicit conversion between uints and ints
|
||||
|
||||
var h8:uint8 = 128
|
||||
var h16:uint16 = 32768
|
||||
var h32:uint32 = 2147483648'u32
|
||||
var h64:uint64 = 9223372036854775808'u64
|
||||
var foobar:uint64 = 9223372036854775813'u64 # Issue 728
|
||||
var h8: uint8 = 128
|
||||
var h16: uint16 = 32768
|
||||
var h32: uint32 = 2147483648'u32
|
||||
var h64: uint64 = 9223372036854775808'u64
|
||||
var foobar: uint64 = 9223372036854775813'u64 # Issue 728
|
||||
|
||||
var v8:uint8 = 10
|
||||
var v16:uint16 = 10
|
||||
var v32:uint32 = 10
|
||||
var v64:uint64 = 10
|
||||
var v8: uint8 = 10
|
||||
var v16: uint16 = 10
|
||||
var v32: uint32 = 10
|
||||
var v64: uint64 = 10
|
||||
|
||||
# u8 + literal produces u8:
|
||||
var a8: uint8 = v8 + 10
|
||||
@@ -95,3 +99,17 @@ template main() =
|
||||
|
||||
static: main()
|
||||
main()
|
||||
|
||||
block:
|
||||
let a = uint64.high
|
||||
let b = uint32.high
|
||||
|
||||
doAssert a.uint64 == a
|
||||
doAssert a.uint32 == uint32.high
|
||||
doAssert a.uint16 == uint16.high
|
||||
doAssert a.uint8 == uint8.high
|
||||
|
||||
doAssert b.uint64 == b
|
||||
doAssert b.uint32 == b
|
||||
doAssert b.uint16 == uint16.high
|
||||
doAssert b.uint8 == uint8.high
|
||||
|
||||
Reference in New Issue
Block a user