diff options
author | konsumlamm <44230978+konsumlamm@users.noreply.github.com> | 2023-08-06 14:24:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-06 14:24:35 +0200 |
commit | 53586d1f32dfe4f2e859178a3e43a6614520763f (patch) | |
tree | d8d96d8148feef252d860cd8f3e0afbf5731e2fd /compiler | |
parent | 67122a9cb6be78b070a71941e74cbcc812633fa6 (diff) | |
download | Nim-53586d1f32dfe4f2e859178a3e43a6614520763f.tar.gz |
Fix some jsgen bugs (#22330)
Fix `succ`, `pred` Fix `genRangeChck` for unsigned ints Fix typo in `dec`
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/jsgen.nim | 53 | ||||
-rw-r--r-- | compiler/semmagic.nim | 4 |
2 files changed, 45 insertions, 12 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index a5f4d29b2..f4d7d6456 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -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") diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 97a320774..4fba4eaf9 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -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: |