From 56d213ca9b9510d439916a34898d2b3f90cbd60d Mon Sep 17 00:00:00 2001 From: narimiran Date: Tue, 5 Feb 2019 15:41:00 +0100 Subject: [PATCH 01/29] bump version number to 0.19.5 --- lib/system.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/system.nim b/lib/system.nim index 0c6cde9fd348..6f55e113d59f 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2023,7 +2023,7 @@ const NimMinor* {.intdefine.}: int = 19 ## is the minor number of Nim's version. - NimPatch* {.intdefine.}: int = 4 + NimPatch* {.intdefine.}: int = 5 ## is the patch number of Nim's version. NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch From c366a8e3864c48a0cf90d631cbf8cdb8e2249a10 Mon Sep 17 00:00:00 2001 From: cooldome Date: Thu, 31 Jan 2019 18:48:39 +0000 Subject: [PATCH 02/29] vm fix for bitwise signed ints (#10507) * fixes #10482 * add missing file * bug fix (cherry picked from commit 1d5437e9d2c5800e4b90e87e32acc600c52cf739) --- compiler/vmgen.nim | 8 ++++---- tests/vm/tbitops.nim | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 tests/vm/tbitops.nim diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 4cce1590a47c..257cfa678a15 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -939,10 +939,10 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = c.freeTemp(tmp2) of mShlI: genBinaryABCnarrowU(c, n, dest, opcShlInt) - of mAshrI: genBinaryABCnarrow(c, n, dest, opcAshrInt) - of mBitandI: genBinaryABCnarrowU(c, n, dest, opcBitandInt) - of mBitorI: genBinaryABCnarrowU(c, n, dest, opcBitorInt) - of mBitxorI: genBinaryABCnarrowU(c, n, dest, opcBitxorInt) + of mAshrI: genBinaryABC(c, n, dest, opcAshrInt) + of mBitandI: genBinaryABC(c, n, dest, opcBitandInt) + of mBitorI: genBinaryABC(c, n, dest, opcBitorInt) + of mBitxorI: genBinaryABC(c, n, dest, opcBitxorInt) of mAddU: genBinaryABCnarrowU(c, n, dest, opcAddu) of mSubU: genBinaryABCnarrowU(c, n, dest, opcSubu) of mMulU: genBinaryABCnarrowU(c, n, dest, opcMulu) diff --git a/tests/vm/tbitops.nim b/tests/vm/tbitops.nim new file mode 100644 index 000000000000..3d1a8aa0cdc0 --- /dev/null +++ b/tests/vm/tbitops.nim @@ -0,0 +1,39 @@ +discard """ +output: "" +""" + +import strutils + +const x = [1'i32, -1, -10, 10, -10, 10, -20, 30, -40, 50, 7 shl 28, -(7 shl 28), 7 shl 28, -(7 shl 28)] +const y = [-1'i32, 1, -10, -10, 10, 10, -20, -30, 40, 50, 1 shl 30, 1 shl 30, -(1 shl 30), -(1 shl 30)] + + +const res_xor = block: + var tmp: seq[int64] + for i in 0.. Date: Fri, 1 Feb 2019 12:12:10 +0100 Subject: [PATCH 03/29] Fix vm signed xor (#10519) * fix #10482 * undo changes * fix for bitwise not * remove dead opcode (cherry picked from commit b80dbdb77d373cda27b00a742f17d1c385dc4a46) --- compiler/vmgen.nim | 7 +++++-- tests/vm/tbitops.nim | 16 +++++++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 257cfa678a15..d560bce1c94a 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -961,7 +961,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = of mLtPtr, mLtU, mLtU64: genBinaryABC(c, n, dest, opcLtu) of mEqProc, mEqRef, mEqUntracedRef: genBinaryABC(c, n, dest, opcEqRef) - of mXor: genBinaryABCnarrowU(c, n, dest, opcXor) + of mXor: genBinaryABC(c, n, dest, opcXor) of mNot: genUnaryABC(c, n, dest, opcNot) of mUnaryMinusI, mUnaryMinusI64: genUnaryABC(c, n, dest, opcUnaryMinusInt) @@ -970,7 +970,10 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = of mUnaryPlusI, mUnaryPlusF64: gen(c, n.sons[1], dest) of mBitnotI: genUnaryABC(c, n, dest, opcBitnotInt) - genNarrowU(c, n, dest) + #genNarrowU modified, do not narrow signed types + let t = skipTypes(n.typ, abstractVar-{tyTypeDesc}) + if t.kind in {tyUInt8..tyUInt32} or (t.kind == tyUInt and t.size < 8): + c.gABC(n, opcNarrowU, dest, TRegister(t.size*8)) of mToFloat, mToBiggestFloat, mToInt, mToBiggestInt, mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr: diff --git a/tests/vm/tbitops.nim b/tests/vm/tbitops.nim index 3d1a8aa0cdc0..90d463ec96ab 100644 --- a/tests/vm/tbitops.nim +++ b/tests/vm/tbitops.nim @@ -7,25 +7,29 @@ import strutils const x = [1'i32, -1, -10, 10, -10, 10, -20, 30, -40, 50, 7 shl 28, -(7 shl 28), 7 shl 28, -(7 shl 28)] const y = [-1'i32, 1, -10, -10, 10, 10, -20, -30, 40, 50, 1 shl 30, 1 shl 30, -(1 shl 30), -(1 shl 30)] - const res_xor = block: var tmp: seq[int64] - for i in 0.. Date: Tue, 5 Feb 2019 09:31:37 +0100 Subject: [PATCH 04/29] Vm bitops fixes (#10520) --- compiler/vm.nim | 5 ++ compiler/vmdef.nim | 1 + compiler/vmgen.nim | 9 +++- lib/pure/bitops.nim | 27 +++++++---- tests/stdlib/tbitops.nim | 101 +++++++++++++++++++++++---------------- 5 files changed, 92 insertions(+), 51 deletions(-) diff --git a/compiler/vm.nim b/compiler/vm.nim index a902721c9d4b..95f232207a29 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1211,6 +1211,11 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcNarrowU: decodeB(rkInt) regs[ra].intVal = regs[ra].intVal and ((1'i64 shl rb)-1) + of opcSignExtend: + # like opcNarrowS, but no out of range possible + decodeB(rkInt) + let imm = 64 - rb + regs[ra].intVal = ashr(regs[ra].intVal shl imm, imm) of opcIsNil: decodeB(rkInt) let node = regs[rb].node diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index 7a2bc16072ba..ea41f368565a 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -71,6 +71,7 @@ type opcSubStr, opcParseFloat, opcConv, opcCast, opcQuit, opcNarrowS, opcNarrowU, + opcSignExtend, opcAddStrCh, opcAddStrStr, diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index d560bce1c94a..2f96f60bc82e 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -938,7 +938,14 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = c.freeTemp(tmp) c.freeTemp(tmp2) - of mShlI: genBinaryABCnarrowU(c, n, dest, opcShlInt) + of mShlI: + genBinaryABC(c, n, dest, opcShlInt) + # genNarrowU modified + let t = skipTypes(n.typ, abstractVar-{tyTypeDesc}) + if t.kind in {tyUInt8..tyUInt32} or (t.kind == tyUInt and t.size < 8): + c.gABC(n, opcNarrowU, dest, TRegister(t.size*8)) + elif t.kind in {tyInt8..tyInt32} or (t.kind == tyInt and t.size < 8): + c.gABC(n, opcSignExtend, dest, TRegister(t.size*8)) of mAshrI: genBinaryABC(c, n, dest, opcAshrInt) of mBitandI: genBinaryABC(c, n, dest, opcBitandInt) of mBitorI: genBinaryABC(c, n, dest, opcBitorInt) diff --git a/lib/pure/bitops.nim b/lib/pure/bitops.nim index 3f213c5ea374..707cfaa75084 100644 --- a/lib/pure/bitops.nim +++ b/lib/pure/bitops.nim @@ -32,6 +32,18 @@ const useICC_builtins = defined(icc) and useBuiltins const useVCC_builtins = defined(vcc) and useBuiltins const arch64 = sizeof(int) == 8 +template forwardImpl(impl, arg) {.dirty.} = + when sizeof(x) <= 4: + when x is SomeSignedInt: + impl(cast[uint32](x.int32)) + else: + impl(x.uint32) + else: + when x is SomeSignedInt: + impl(cast[uint64](x.int64)) + else: + impl(x.uint64) + # #### Pure Nim version #### proc firstSetBit_nim(x: uint32): int {.inline, nosideeffect.} = @@ -185,8 +197,7 @@ proc countSetBits*(x: SomeInteger): int {.inline, nosideeffect.} = # TODO: figure out if ICC support _popcnt32/_popcnt64 on platform without POPCNT. # like GCC and MSVC when nimvm: - when sizeof(x) <= 4: result = countSetBits_nim(x.uint32) - else: result = countSetBits_nim(x.uint64) + result = forwardImpl(countSetBits_nim, x) else: when useGCC_builtins: when sizeof(x) <= 4: result = builtin_popcount(x.cuint).int @@ -216,8 +227,7 @@ proc parityBits*(x: SomeInteger): int {.inline, nosideeffect.} = # Can be used a base if creating ASM version. # https://stackoverflow.com/questions/21617970/how-to-check-if-value-has-even-parity-of-bits-or-odd when nimvm: - when sizeof(x) <= 4: result = parity_impl(x.uint32) - else: result = parity_impl(x.uint64) + result = forwardImpl(parity_impl, x) else: when useGCC_builtins: when sizeof(x) <= 4: result = builtin_parity(x.uint32).int @@ -235,8 +245,7 @@ proc firstSetBit*(x: SomeInteger): int {.inline, nosideeffect.} = when noUndefined: if x == 0: return 0 - when sizeof(x) <= 4: result = firstSetBit_nim(x.uint32) - else: result = firstSetBit_nim(x.uint64) + result = forwardImpl(firstSetBit_nim, x) else: when noUndefined and not useGCC_builtins: if x == 0: @@ -270,8 +279,7 @@ proc fastLog2*(x: SomeInteger): int {.inline, nosideeffect.} = if x == 0: return -1 when nimvm: - when sizeof(x) <= 4: result = fastlog2_nim(x.uint32) - else: result = fastlog2_nim(x.uint64) + result = forwardImpl(fastlog2_nim, x) else: when useGCC_builtins: when sizeof(x) <= 4: result = 31 - builtin_clz(x.uint32).int @@ -302,8 +310,7 @@ proc countLeadingZeroBits*(x: SomeInteger): int {.inline, nosideeffect.} = if x == 0: return 0 when nimvm: - when sizeof(x) <= 4: result = sizeof(x)*8 - 1 - fastlog2_nim(x.uint32) - else: result = sizeof(x)*8 - 1 - fastlog2_nim(x.uint64) + result = sizeof(x)*8 - 1 - forwardImpl(fastlog2_nim, x) else: when useGCC_builtins: when sizeof(x) <= 4: result = builtin_clz(x.uint32).int - (32 - sizeof(x)*8) diff --git a/tests/stdlib/tbitops.nim b/tests/stdlib/tbitops.nim index 8301256c443a..1cbab4870775 100644 --- a/tests/stdlib/tbitops.nim +++ b/tests/stdlib/tbitops.nim @@ -1,10 +1,9 @@ discard """ - file: "tbitops.nim" + nimout: "OK" output: "OK" """ import bitops - proc main() = const U8 = 0b0011_0010'u8 const I8 = 0b0011_0010'i8 @@ -80,25 +79,6 @@ proc main() = doAssert( U8.rotateLeftBits(3) == 0b10010001'u8) doAssert( U8.rotateRightBits(3) == 0b0100_0110'u8) - static : - # test bitopts at compile time with vm - doAssert( U8.fastLog2 == 5) - doAssert( I8.fastLog2 == 5) - doAssert( U8.countLeadingZeroBits == 2) - doAssert( I8.countLeadingZeroBits == 2) - doAssert( U8.countTrailingZeroBits == 1) - doAssert( I8.countTrailingZeroBits == 1) - doAssert( U8.firstSetBit == 2) - doAssert( I8.firstSetBit == 2) - doAssert( U8.parityBits == 1) - doAssert( I8.parityBits == 1) - doAssert( U8.countSetBits == 3) - doAssert( I8.countSetBits == 3) - doAssert( U8.rotateLeftBits(3) == 0b10010001'u8) - doAssert( U8.rotateRightBits(3) == 0b0100_0110'u8) - - - template test_undefined_impl(ffunc: untyped; expected: int; is_static: bool) = doAssert( ffunc(0'u8) == expected) doAssert( ffunc(0'i8) == expected) @@ -143,26 +123,67 @@ proc main() = doAssert( U64A.rotateLeftBits(64) == U64A) doAssert( U64A.rotateRightBits(64) == U64A) - static: # check for undefined behavior with rotate by zero. - doAssert( U8.rotateLeftBits(0) == U8) - doAssert( U8.rotateRightBits(0) == U8) - doAssert( U16.rotateLeftBits(0) == U16) - doAssert( U16.rotateRightBits(0) == U16) - doAssert( U32.rotateLeftBits(0) == U32) - doAssert( U32.rotateRightBits(0) == U32) - doAssert( U64A.rotateLeftBits(0) == U64A) - doAssert( U64A.rotateRightBits(0) == U64A) - - # check for undefined behavior with rotate by integer width. - doAssert( U8.rotateLeftBits(8) == U8) - doAssert( U8.rotateRightBits(8) == U8) - doAssert( U16.rotateLeftBits(16) == U16) - doAssert( U16.rotateRightBits(16) == U16) - doAssert( U32.rotateLeftBits(32) == U32) - doAssert( U32.rotateRightBits(32) == U32) - doAssert( U64A.rotateLeftBits(64) == U64A) - doAssert( U64A.rotateRightBits(64) == U64A) + block: + # mask operations + var v: uint8 + v.setMask(0b1100_0000) + v.setMask(0b0000_1100) + doAssert(v == 0b1100_1100) + v.flipMask(0b0101_0101) + doAssert(v == 0b1001_1001) + v.clearMask(0b1000_1000) + doAssert(v == 0b0001_0001) + v.clearMask(0b0001_0001) + doAssert(v == 0b0000_0000) + block: + # single bit operations + var v: uint8 + v.setBit(0) + doAssert v == 0x0000_0001 + v.setBit(1) + doAssert v == 0b0000_0011 + v.flipBit(7) + doAssert v == 0b1000_0011 + v.clearBit(0) + doAssert v == 0b1000_0010 + v.flipBit(1) + doAssert v == 0b1000_0000 + doAssert v.testbit(7) + doAssert not v.testbit(6) + block: + # multi bit operations + var v: uint8 + v.setBits(0, 1, 7) + doAssert v == 0b1000_0011 + v.flipBits(2, 3) + doAssert v == 0b1000_1111 + v.clearBits(7, 0, 1) + doAssert v == 0b0000_1100 + block: + # signed + var v: int8 + v.setBit(7) + doAssert v == -128 + block: + var v: uint64 + v.setBit(63) + doAssert v == 0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000'u64 echo "OK" +block: # not ready for vm because exception is compile error + try: + var v: uint32 + var i = 32 + v.setBit(i) + doAssert false + except RangeError: + discard + except: + doAssert false + + main() +static: + # test everything on vm as well + main() From 12bc7c98821cfe039dfb533db27660faeb916918 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 6 Feb 2019 14:39:23 +0100 Subject: [PATCH 05/29] koch winrelease: also bundle c2nim for Windows --- koch.nim | 9 ++++++++- tools/kochdocs.nim | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/koch.nim b/koch.nim index 0c5e0a341346..e299d7641483 100644 --- a/koch.nim +++ b/koch.nim @@ -74,7 +74,7 @@ template withDir(dir, body) = setCurrentDir(dir) body finally: - setCurrentdir(old) + setCurrentDir(old) proc tryExec(cmd: string): bool = echo(cmd) @@ -110,6 +110,11 @@ proc bundleNimbleSrc(latest: bool) = exec("git checkout -f stable") exec("git pull") +proc bundleC2nim() = + if not dirExists("dist/c2nim/.git"): + exec("git clone https://github.com/nim-lang/c2nim.git dist/c2nim") + nimCompile("dist/c2nim/c2nim", options = "--noNimblePath --path:.") + proc bundleNimbleExe(latest: bool) = bundleNimbleSrc(latest) # now compile Nimble and copy it to $nim/bin for the installer.ini @@ -160,6 +165,7 @@ proc bundleWinTools() = buildVccTool() nimexec("c -o:bin/nimgrab.exe -d:ssl tools/nimgrab.nim") nimexec("c -o:bin/nimgrep.exe tools/nimgrep.nim") + bundleC2nim() when false: # not yet a tool worth including nimexec(r"c --cc:vcc --app:gui -o:bin\downloader.exe -d:ssl --noNimblePath " & @@ -548,6 +554,7 @@ when isMainModule: else: buildTools(existsDir(".git") or latest) of "pushcsource", "pushcsources": pushCsources() of "valgrind": valgrind(op.cmdLineRest) + of "c2nim": bundleC2nim() else: showHelp() break of cmdEnd: break diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim index 57c6c596816b..9b5a637baee9 100644 --- a/tools/kochdocs.nim +++ b/tools/kochdocs.nim @@ -54,6 +54,11 @@ proc execCleanPath*(cmd: string, proc nimexec*(cmd: string) = exec findNim() & " " & cmd +proc nimCompile*(input: string, outputDir = "bin", mode = "c", options = "") = + let output = outputDir / input.splitFile.name.exe + let cmd = findNim() & " " & mode & " -o:" & output & " " & options & " " & input + exec cmd + const pdf = """ doc/manual.rst From f1a78b8b4c9249c1d36ccf5f898a1c06c11457bb Mon Sep 17 00:00:00 2001 From: narimiran Date: Thu, 7 Feb 2019 09:35:06 +0100 Subject: [PATCH 06/29] tbitops: remove unavailable tests --- tests/stdlib/tbitops.nim | 63 ---------------------------------------- 1 file changed, 63 deletions(-) diff --git a/tests/stdlib/tbitops.nim b/tests/stdlib/tbitops.nim index 1cbab4870775..528359c34057 100644 --- a/tests/stdlib/tbitops.nim +++ b/tests/stdlib/tbitops.nim @@ -1,7 +1,3 @@ -discard """ - nimout: "OK" - output: "OK" -""" import bitops proc main() = @@ -123,65 +119,6 @@ proc main() = doAssert( U64A.rotateLeftBits(64) == U64A) doAssert( U64A.rotateRightBits(64) == U64A) - block: - # mask operations - var v: uint8 - v.setMask(0b1100_0000) - v.setMask(0b0000_1100) - doAssert(v == 0b1100_1100) - v.flipMask(0b0101_0101) - doAssert(v == 0b1001_1001) - v.clearMask(0b1000_1000) - doAssert(v == 0b0001_0001) - v.clearMask(0b0001_0001) - doAssert(v == 0b0000_0000) - block: - # single bit operations - var v: uint8 - v.setBit(0) - doAssert v == 0x0000_0001 - v.setBit(1) - doAssert v == 0b0000_0011 - v.flipBit(7) - doAssert v == 0b1000_0011 - v.clearBit(0) - doAssert v == 0b1000_0010 - v.flipBit(1) - doAssert v == 0b1000_0000 - doAssert v.testbit(7) - doAssert not v.testbit(6) - block: - # multi bit operations - var v: uint8 - v.setBits(0, 1, 7) - doAssert v == 0b1000_0011 - v.flipBits(2, 3) - doAssert v == 0b1000_1111 - v.clearBits(7, 0, 1) - doAssert v == 0b0000_1100 - block: - # signed - var v: int8 - v.setBit(7) - doAssert v == -128 - block: - var v: uint64 - v.setBit(63) - doAssert v == 0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000'u64 - - echo "OK" - -block: # not ready for vm because exception is compile error - try: - var v: uint32 - var i = 32 - v.setBit(i) - doAssert false - except RangeError: - discard - except: - doAssert false - main() static: From 37ff8753a1a69b696c46641b30f90ce0976e081e Mon Sep 17 00:00:00 2001 From: Matt Haggard Date: Fri, 8 Feb 2019 01:39:58 -0700 Subject: [PATCH 07/29] Add non-interactive installer flag (-y) to finish.nim (#10603) [backport] (cherry picked from commit fd62d24c4c141a368b1eb1ca5a862a3f989110e8) --- tools/finish.nim | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/tools/finish.nim b/tools/finish.nim index 4f2c725953e6..815b99a1230e 100644 --- a/tools/finish.nim +++ b/tools/finish.nim @@ -8,6 +8,9 @@ const mingw = "mingw$1-6.3.0.7z" % arch url = r"https://nim-lang.org/download/" & mingw +var + interactive = true + type DownloadResult = enum Failure, @@ -38,19 +41,28 @@ proc downloadMingw(): DownloadResult = if cmd.len > 0: if execShellCmd(cmd) != 0: echo "download failed! ", cmd - openDefaultBrowser(url) - result = Manual + if interactive: + openDefaultBrowser(url) + result = Manual + else: + result = Failure else: if unzip(): result = Success else: - openDefaultBrowser(url) - result = Manual + if interactive: + openDefaultBrowser(url) + result = Manual + else: + result = Failure when defined(windows): import registry proc askBool(m: string): bool = stdout.write m + if not interactive: + stdout.writeLine "y (non-interactive mode)" + return true while true: try: let answer = stdin.readLine().normalize @@ -67,6 +79,9 @@ when defined(windows): proc askNumber(m: string; a, b: int): int = stdout.write m stdout.write " [" & $a & ".." & $b & "] " + if not interactive: + stdout.writeLine $a & " (non-interactive mode)" + return a while true: let answer = stdin.readLine() try: @@ -291,4 +306,6 @@ when isMainModule: when defined(testdownload): discard downloadMingw() else: + if "-y" in commandLineParams(): + interactive = false main() From 99fc4029e0c1ffc08e371fb1fb5d9534dec72253 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Wed, 6 Feb 2019 20:58:21 +0100 Subject: [PATCH 08/29] fixes #10584 [backport] (cherry picked from commit 65f3e390e814f84fe745d1894cea7e2f6c881ec3) --- lib/pure/concurrency/threadpool.nim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index 9c9425d9f724..4846c610f2d6 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -320,6 +320,10 @@ gSomeReady.initSemaphore() proc slave(w: ptr Worker) {.thread.} = isSlave = true while true: + if w.shutdown: + w.shutdown = false + atomicDec currentPoolSize + break when declared(atomicStoreN): atomicStoreN(addr(w.ready), true, ATOMIC_SEQ_CST) else: @@ -340,9 +344,6 @@ proc slave(w: ptr Worker) {.thread.} = dec numSlavesRunning if w.q.len != 0: w.cleanFlowVars - if w.shutdown: - w.shutdown = false - atomicDec currentPoolSize proc distinguishedSlave(w: ptr Worker) {.thread.} = while true: From 3aeaa90bd828975a8accfb271ad02cf22639a250 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 8 Feb 2019 09:56:32 +0100 Subject: [PATCH 09/29] Fix edge case in type hashing (#10601) [backport] Empty types introduced by a template produced the same hash of the "clean" type sharing the same name. (cherry picked from commit 631a8ab57f6935d34d290089b7cc36d23dc03504) --- compiler/ccgtypes.nim | 1 - compiler/sighashes.nim | 29 +++++++++++-------- .../ccgbugs/tsighash_typename_regression.nim | 15 ++++++++++ 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 8b2cd6b2824c..ec59c703b76b 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -165,7 +165,6 @@ proc mapType(conf: ConfigRef; typ: PType): TCTypeKind = of tySet: if mapSetType(conf, base) == ctArray: result = ctPtrToArray else: result = ctPtr - # XXX for some reason this breaks the pegs module else: result = ctPtr of tyPointer: result = ctPtr of tySequence: result = ctNimSeq diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index 218011b1d60a..3096d94a0c17 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -196,18 +196,23 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = else: c.hashSym(t.sym) if {sfAnon, sfGenSym} * t.sym.flags != {}: - # generated object names can be identical, so we need to - # disambiguate furthermore by hashing the field types and names: - # mild hack to prevent endless recursions (makes nimforum compile again): - let oldFlags = t.sym.flags - t.sym.flags = t.sym.flags - {sfAnon, sfGenSym} - let n = t.n - for i in 0 ..< n.len: - assert n[i].kind == nkSym - let s = n[i].sym - c.hashSym s - c.hashType s.typ, flags - t.sym.flags = oldFlags + # Generated object names can be identical, so we need to + # disambiguate furthermore by hashing the field types and names. + if t.n.len > 0: + let oldFlags = t.sym.flags + # Mild hack to prevent endless recursion. + t.sym.flags = t.sym.flags - {sfAnon, sfGenSym} + for n in t.n: + assert(n.kind == nkSym) + let s = n.sym + c.hashSym s + c.hashType s.typ, flags + t.sym.flags = oldFlags + else: + # The object has no fields: we _must_ add something here in order to + # make the hash different from the one we produce by hashing only the + # type name. + c &= ".empty" else: c &= t.id if t.len > 0 and t.sons[0] != nil: diff --git a/tests/ccgbugs/tsighash_typename_regression.nim b/tests/ccgbugs/tsighash_typename_regression.nim index 7122902d98ad..457902b767f6 100644 --- a/tests/ccgbugs/tsighash_typename_regression.nim +++ b/tests/ccgbugs/tsighash_typename_regression.nim @@ -8,3 +8,18 @@ proc foo[T](t: T) = foo(123) foo("baz") + +# Empty type in template is correctly disambiguated +block: + template foo() = + type M = object + discard + var y = M() + + foo() + + type M = object + x: int + + var x = M(x: 1) + doAssert(x.x == 1) From 32780acc618b4ff2853683bc2885a20c4af8bad4 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 19 Feb 2019 11:54:19 +0100 Subject: [PATCH 10/29] fixes 10697 [backport] (cherry picked from commit 257965e105c219f2504a2d1d0952fc43efb9598c) --- compiler/jsgen.nim | 5 +++-- tests/js/tbasics.nim | 48 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 tests/js/tbasics.nim diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 0627d80058d2..f8f6febc79f2 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -476,6 +476,7 @@ proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string, r.res = "$1 = (($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, trimmer] else: r.res = "(($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, trimmer] + r.kind = resExpr proc ternaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = var x, y, z: TCompRes @@ -1706,13 +1707,13 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = of mHigh: unaryExpr(p, n, r, "", "($1 != null ? ($1.length-1) : -1)") of mInc: - if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64: + if n[1].typ.skipTypes(abstractRange).kind in {tyUInt..tyUInt64}: binaryUintExpr(p, n, r, "+", true) else: if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 += $2") else: binaryExpr(p, n, r, "addInt", "$1 = addInt($1, $2)") of ast.mDec: - if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64: + if n[1].typ.skipTypes(abstractRange).kind in {tyUInt..tyUInt64}: binaryUintExpr(p, n, r, "-", true) else: if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2") diff --git a/tests/js/tbasics.nim b/tests/js/tbasics.nim new file mode 100644 index 000000000000..33616776fccf --- /dev/null +++ b/tests/js/tbasics.nim @@ -0,0 +1,48 @@ +discard """ + output: '''ABCDC +1 +14 +ok +1''' +""" + +type + MyEnum = enum + A,B,C,D +# trick the optimizer with an seq: +var x = @[A,B,C,D] +echo x[0],x[1],x[2],x[3],MyEnum(2) + +# bug #10651 + +var xa: seq[int] +var ya = @[1,2] +xa &= ya +echo xa[0] + +proc test = + var yup: seq[int] + try: + yup.add 14 + echo yup.pop + finally: + discard + +test() + +when true: + var a: seq[int] + + a.setLen(0) + + echo "ok" + +# bug #10697 +proc test2 = + var val = uint16(0) + var i = 0 + if i < 2: + val += uint16(1) + echo int(val) + +test2() From aa2dfd1cefa55221715155c33d25474a5bed346c Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 19 Feb 2019 19:37:16 +0100 Subject: [PATCH 11/29] fixes a critical strutils bug [backport] (cherry picked from commit 68ce92d4eb6143b8c49001f4782b74eb98027c77) --- lib/pure/strutils.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index cc5530175299..e373baa46de2 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -435,7 +435,7 @@ proc isNilOrWhitespace*(s: string): bool {.noSideEffect, procvar, rtl, extern: " proc substrEq(s: string, pos: int, substr: string): bool = var i = 0 var length = substr.len - while i < length and s[pos+i] == substr[i]: + while i < length and pos+i < s.len and s[pos+i] == substr[i]: inc i return i == length From 2d1dea9484a3e0080336d2aec806c2f42480b1fc Mon Sep 17 00:00:00 2001 From: narimiran Date: Thu, 21 Feb 2019 08:56:43 +0100 Subject: [PATCH 12/29] keep only the relevant part of `tbasics` test --- tests/js/tbasics.nim | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/tests/js/tbasics.nim b/tests/js/tbasics.nim index 33616776fccf..ec429ba9e537 100644 --- a/tests/js/tbasics.nim +++ b/tests/js/tbasics.nim @@ -1,42 +1,7 @@ discard """ - output: '''ABCDC -1 -14 -ok -1''' + output: '''1''' """ -type - MyEnum = enum - A,B,C,D -# trick the optimizer with an seq: -var x = @[A,B,C,D] -echo x[0],x[1],x[2],x[3],MyEnum(2) - -# bug #10651 - -var xa: seq[int] -var ya = @[1,2] -xa &= ya -echo xa[0] - -proc test = - var yup: seq[int] - try: - yup.add 14 - echo yup.pop - finally: - discard - -test() - -when true: - var a: seq[int] - - a.setLen(0) - - echo "ok" - # bug #10697 proc test2 = var val = uint16(0) From 541b8df315e987975cc25179907b8bc567b140da Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 14 Mar 2019 09:03:21 +0100 Subject: [PATCH 13/29] multi-methods: remove hack, make tmethod_various compile under strict C++ [backport] (cherry picked from commit 4181baf400cfb63609cc2c195cfaf0b7a2e75153) --- compiler/ast.nim | 2 +- compiler/cgmeth.nim | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 694944631213..69523a09b285 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -990,7 +990,7 @@ const miscPos* = 5 # used for undocumented and hacky stuff bodyPos* = 6 # position of body; use rodread.getBody() instead! resultPos* = 7 - dispatcherPos* = 8 # caution: if method has no 'result' it can be position 7! + dispatcherPos* = 8 nkCallKinds* = {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit, nkHiddenCallConv} diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index f2ad3dca0e96..22675a7cf17e 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -37,10 +37,9 @@ proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode = proc getDispatcher*(s: PSym): PSym = ## can return nil if is has no dispatcher. - let dispn = lastSon(s.ast) - if dispn.kind == nkSym: - let disp = dispn.sym - if sfDispatcher in disp.flags: result = disp + if dispatcherPos < s.ast.len: + result = s.ast[dispatcherPos].sym + doAssert sfDispatcher in result.flags proc methodCall*(n: PNode; conf: ConfigRef): PNode = result = n @@ -99,13 +98,14 @@ proc sameMethodBucket(a, b: PSym): MethodResult = return No proc attachDispatcher(s: PSym, dispatcher: PNode) = - var L = s.ast.len-1 - var x = s.ast.sons[L] - if x.kind == nkSym and sfDispatcher in x.sym.flags: + if dispatcherPos < s.ast.len: # we've added a dispatcher already, so overwrite it - s.ast.sons[L] = dispatcher + s.ast.sons[dispatcherPos] = dispatcher else: - s.ast.add(dispatcher) + setLen(s.ast.sons, dispatcherPos+1) + if s.ast[resultPos] == nil: + s.ast[resultPos] = newNodeI(nkEmpty, s.info) + s.ast.sons[dispatcherPos] = dispatcher proc createDispatcher(s: PSym): PSym = var disp = copySym(s) @@ -165,7 +165,7 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) = case sameMethodBucket(disp, s) of Yes: add(g.methods[i].methods, s) - attachDispatcher(s, lastSon(disp.ast)) + attachDispatcher(s, disp.ast[dispatcherPos]) fixupDispatcher(s, disp, g.config) #echo "fixup ", disp.name.s, " ", disp.id when useEffectSystem: checkMethodEffects(g, disp, s) From c9c5abcdc17daa3aeb583f4473925b6ea19b0d64 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sat, 23 Mar 2019 14:44:53 +0100 Subject: [PATCH 14/29] fixes #10886 [backport] (#10897) (cherry picked from commit 0b2a3f6f7f7dfc40e08d287f41f7ce7c2e51fd9c) --- compiler/vmgen.nim | 23 ++++++++++++++++------- tests/vm/tvmmisc.nim | 29 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 2f96f60bc82e..6cfc07446c7e 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -361,16 +361,28 @@ proc genIf(c: PCtx, n: PNode; dest: var TDest) = for endPos in endings: c.patch(endPos) c.clearDest(n, dest) +proc isTemp(c: PCtx; dest: TDest): bool = + result = dest >= 0 and c.prc.slots[dest].kind >= slotTempUnknown + proc genAndOr(c: PCtx; n: PNode; opc: TOpcode; dest: var TDest) = # asgn dest, a # tjmp|fjmp L1 # asgn dest, b # L1: - if dest < 0: dest = getTemp(c, n.typ) - c.gen(n.sons[1], dest) - let L1 = c.xjmp(n, opc, dest) - c.gen(n.sons[2], dest) + let copyBack = dest < 0 or not isTemp(c, dest) + let tmp = if copyBack: + getTemp(c, n.typ) + else: + TRegister dest + c.gen(n.sons[1], tmp) + let L1 = c.xjmp(n, opc, tmp) + c.gen(n.sons[2], tmp) c.patch(L1) + if dest < 0: + dest = tmp + elif copyBack: + c.gABC(n, opcAsgnInt, dest, tmp) + freeTemp(c, tmp) proc canonValue*(n: PNode): PNode = result = n @@ -1396,9 +1408,6 @@ proc checkCanEval(c: PCtx; n: PNode) = skIterator} and sfForward in s.flags: cannotEval(c, n) -proc isTemp(c: PCtx; dest: TDest): bool = - result = dest >= 0 and c.prc.slots[dest].kind >= slotTempUnknown - template needsAdditionalCopy(n): untyped = not c.isTemp(dest) and not fitsRegister(n.typ) diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim index 6a8084647fd1..a178bb95ebe5 100644 --- a/tests/vm/tvmmisc.nim +++ b/tests/vm/tvmmisc.nim @@ -148,3 +148,32 @@ static: static: doAssert foo().i == 1 + +# #10333 +block: + const + encoding: auto = [ + ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"], + ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"], + ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"], + ["", "M", "MM", "MMM", "--", "-", "--", "---", "----", "--"], + ] + doAssert encoding.len == 4 + +# #10886 + +proc tor(): bool = + result = true + result = false or result + +proc tand(): bool = + result = false + result = true and result + +const + ctor = tor() + ctand = not tand() + +static: + doAssert ctor + doAssert ctand From 897b63e5cd08839c167839267de514a8e885b195 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sat, 23 Mar 2019 15:09:19 +0100 Subject: [PATCH 15/29] stats.nim: bugfix: use min in '+' [backport] (cherry picked from commit 1332f649b2e32a84fb643b580750e2f554eb8a4f) --- lib/pure/stats.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/stats.nim b/lib/pure/stats.nim index ce32108c2768..3a31f35a76e7 100644 --- a/lib/pure/stats.nim +++ b/lib/pure/stats.nim @@ -175,7 +175,7 @@ proc `+`*(a, b: RunningStat): RunningStat = (n*n) + 4.0*delta*(a.n.float*b.mom3 - b.n.float*a.mom3) / n result.max = max(a.max, b.max) - result.min = max(a.min, b.min) + result.min = min(a.min, b.min) proc `+=`*(a: var RunningStat, b: RunningStat) {.inline.} = ## add a second RunningStats `b` to `a` From 0e3425874922a00d0d6a716c6aa3835d997df0ac Mon Sep 17 00:00:00 2001 From: narimiran Date: Sun, 24 Mar 2019 21:37:32 +0100 Subject: [PATCH 16/29] remove the test for stuff that is not backported --- tests/vm/tvmmisc.nim | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim index a178bb95ebe5..815d9be7205e 100644 --- a/tests/vm/tvmmisc.nim +++ b/tests/vm/tvmmisc.nim @@ -31,7 +31,7 @@ static: assert str == "abc" # #6086 -import math, sequtils, future +import math, sequtils, sugar block: proc f: int = @@ -149,16 +149,6 @@ static: static: doAssert foo().i == 1 -# #10333 -block: - const - encoding: auto = [ - ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"], - ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"], - ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"], - ["", "M", "MM", "MMM", "--", "-", "--", "---", "----", "--"], - ] - doAssert encoding.len == 4 # #10886 From 3cf038027b1df0455f5c6cd2bc47b61377c49761 Mon Sep 17 00:00:00 2001 From: cooldome Date: Thu, 11 Apr 2019 12:51:51 +0100 Subject: [PATCH 17/29] fixes #10765 (#10993) [backport] (cherry picked from commit de02fd0b898e41fa91087300d82573d83e357b34) --- lib/system/excpt.nim | 35 ++++++++++++++++++++++++++++++++ tests/cpp/tterminate_handler.nim | 9 ++++++++ 2 files changed, 44 insertions(+) create mode 100644 tests/cpp/tterminate_handler.nim diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 05d6be632908..83eb70a2d1b4 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -466,6 +466,41 @@ when defined(endb): var dbgAborting: bool # whether the debugger wants to abort +when defined(cpp) and appType != "lib" and + not defined(js) and not defined(nimscript) and + hostOS != "standalone" and not defined(noCppExceptions): + + type + StdException {.importcpp: "std::exception", header: "".} = object + + proc what(ex: StdException): cstring {.importcpp: "((char *)#.what())".} + + proc setTerminate(handler: proc() {.noconv.}) + {.importc: "std::set_terminate", header: "".} + + setTerminate proc() {.noconv.} = + # Remove ourself as a handler, reinstalling the default handler. + setTerminate(nil) + + var msg = "Unknown error in unexpected exception handler" + try: + raise + except Exception: + msg = currException.getStackTrace() & "Error: unhandled exception: " & + currException.msg & " [" & $currException.name & "]" + except StdException as e: + msg = "Error: unhandled cpp exception: " & $e.what() + except: + msg = "Error: unhandled unknown cpp exception" + + when defined(genode): + # stderr not available by default, use the LOG session + echo msg + else: + writeToStdErr msg & "\n" + + quit 1 + when not defined(noSignalHandler) and not defined(useNimRtl): proc signalHandler(sign: cint) {.exportc: "signalHandler", noconv.} = template processSignal(s, action: untyped) {.dirty.} = diff --git a/tests/cpp/tterminate_handler.nim b/tests/cpp/tterminate_handler.nim new file mode 100644 index 000000000000..79949f4dab0c --- /dev/null +++ b/tests/cpp/tterminate_handler.nim @@ -0,0 +1,9 @@ +discard """ + targets: "cpp" + outputsub: "Error: unhandled unknown cpp exception" + exitcode: 1 +""" +type Crap {.importcpp: "int".} = object + +var c: Crap +raise c \ No newline at end of file From f1c297e439641e25f749650fca4de7999985e81b Mon Sep 17 00:00:00 2001 From: narimiran Date: Fri, 12 Apr 2019 09:38:22 +0200 Subject: [PATCH 18/29] fix duplicate definition --- lib/system.nim | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 6f55e113d59f..4edfb767bb42 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -4321,25 +4321,6 @@ template doAssertRaises*(exception, code: untyped): typed = if wrong: raiseAssert(astToStr(exception) & " wasn't raised by:\n" & astToStr(code)) -when defined(cpp) and appType != "lib" and - not defined(js) and not defined(nimscript) and - hostOS != "standalone" and not defined(noCppExceptions): - proc setTerminate(handler: proc() {.noconv.}) - {.importc: "std::set_terminate", header: "".} - setTerminate proc() {.noconv.} = - # Remove ourself as a handler, reinstalling the default handler. - setTerminate(nil) - - let ex = getCurrentException() - let trace = ex.getStackTrace() - when defined(genode): - # stderr not available by default, use the LOG session - echo trace & "Error: unhandled exception: " & ex.msg & - " [" & $ex.name & "]\n" - else: - stderr.write trace & "Error: unhandled exception: " & ex.msg & - " [" & $ex.name & "]\n" - quit 1 when not defined(js): proc toOpenArray*[T](x: seq[T]; first, last: int): openarray[T] {. From dbca89730bc168ad7586e83fd0bdd91027857731 Mon Sep 17 00:00:00 2001 From: cooldome Date: Thu, 28 Jun 2018 09:21:09 +0100 Subject: [PATCH 19/29] Fixes #7845 (Cannot raise generic exception) (cherry picked from commit 541c2a3fecd7b1f3e6d9dc7e23a7583000cb68f1) --- compiler/ast.nim | 11 +++++------ compiler/semstmts.nim | 7 ++++--- tests/exception/texcpt1.nim | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 69523a09b285..15d897bed7bb 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1711,8 +1711,7 @@ proc toVar*(typ: PType): PType = proc toRef*(typ: PType): PType = ## If ``typ`` is a tyObject then it is converted into a `ref ` and ## returned. Otherwise ``typ`` is simply returned as-is. - result = typ - if typ.kind == tyObject: + if typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject: result = newType(tyRef, typ.owner) rawAddSon(result, typ) @@ -1720,15 +1719,15 @@ proc toObject*(typ: PType): PType = ## If ``typ`` is a tyRef then its immediate son is returned (which in many ## cases should be a ``tyObject``). ## Otherwise ``typ`` is simply returned as-is. - result = typ - if result.kind == tyRef: - result = result.lastSon + let t = typ.skipTypes({tyAlias, tyGenericInst}) + if t.kind == tyRef: t.lastSon + else: typ proc isException*(t: PType): bool = # check if `y` is object type and it inherits from Exception assert(t != nil) - if t.kind != tyObject: + if t.kind notin {tyObject, tyGenericInst}: return false var base = t diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index e0874d1a32a7..2e8eda8caddf 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -823,11 +823,12 @@ proc semRaise(c: PContext, n: PNode): PNode = checkSonsLen(n, 1, c.config) if n[0].kind != nkEmpty: n[0] = semExprWithType(c, n[0]) - let typ = n[0].typ + var typ = n[0].typ if not isImportedException(typ, c.config): - if typ.kind != tyRef or typ.lastSon.kind != tyObject: + typ = typ.skipTypes({tyAlias, tyGenericInst}) + if typ.kind != tyRef: localError(c.config, n.info, errExprCannotBeRaised) - if typ.len > 0 and not isException(typ.lastSon): + if not isException(typ.lastSon): localError(c.config, n.info, "raised object of type $1 does not inherit from Exception", [typeToString(typ)]) diff --git a/tests/exception/texcpt1.nim b/tests/exception/texcpt1.nim index 50a95eeec822..4c2d4ebcd45a 100644 --- a/tests/exception/texcpt1.nim +++ b/tests/exception/texcpt1.nim @@ -4,6 +4,8 @@ discard """ type ESomething = object of Exception ESomeOtherErr = object of Exception + ESomethingGen[T] = object of Exception + ESomethingGenRef[T] = ref object of Exception proc genErrors(s: string) = if s == "error!": @@ -27,4 +29,17 @@ proc blah(): int = echo blah() +# Issue #7845, raise generic exception +var x: ref ESomethingGen[int] +new(x) +try: + raise x +except ESomethingGen[int] as e: + discard +try: + raise new(ESomethingGenRef[int]) +except ESomethingGenRef[int] as e: + discard +except: + discard From d92f322faa7239e80bd83d4e0d3e650737789110 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 30 Apr 2019 09:30:35 +0200 Subject: [PATCH 20/29] backport sane ast.isException implementation --- compiler/ast.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 15d897bed7bb..eda2f171c773 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1731,7 +1731,7 @@ proc isException*(t: PType): bool = return false var base = t - while base != nil: + while base != nil and base.kind in {tyRef, tyObject, tyGenericInst}: if base.sym != nil and base.sym.magic == mException: return true base = base.lastSon From 80e9270580e00cf99a20839bde0cd854f6fab395 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Tue, 26 Mar 2019 09:50:16 +0100 Subject: [PATCH 21/29] macros: typo (cherry picked from commit 802ecbc49ef2a79f7fdef60e24983bd2be0c3bad) --- lib/core/macros.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index ef8e1e21a955..9b82e658c8f7 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -649,7 +649,7 @@ proc newLit*(f: float64): NimNode {.compileTime.} = result = newNimNode(nnkFloat64Lit) result.floatVal = f -when compiles(float128): +when declared(float128): proc newLit*(f: float128): NimNode {.compileTime.} = ## produces a new float literal node. result = newNimNode(nnkFloat128Lit) From 8b7cd2e19f1a425cbc6b1a673a028748de1b3e82 Mon Sep 17 00:00:00 2001 From: genotrance Date: Tue, 26 Mar 2019 16:20:26 -0500 Subject: [PATCH 22/29] Fix #10907 - remove unused typedef string (#10908) (cherry picked from commit 0378bfa40213d77e3c0fb5f35dcb11cadd42256c) --- lib/nimbase.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/nimbase.h b/lib/nimbase.h index 2cb632787a99..c81181108031 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -389,8 +389,6 @@ static N_INLINE(NI32, float32ToInt32)(float x) { NIM_CHAR data[(length) + 1]; \ } name = {{length, (NI) ((NU)length | NIM_STRLIT_FLAG)}, str} -typedef struct TStringDesc* string; - /* declared size of a sequence/variable length array: */ #if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) # define SEQ_DECL_SIZE /* empty is correct! */ From a62685372f8a588ce3d13ce24f448a411bd842ce Mon Sep 17 00:00:00 2001 From: Miran Date: Wed, 10 Apr 2019 15:54:49 +0200 Subject: [PATCH 23/29] json: add '\v' support, fixes #10541 (#10987) (cherry picked from commit 2608bc369e5df6535528eb1987eb33b85e532141) --- lib/pure/json.nim | 1 + lib/pure/parsejson.nim | 3 +++ 2 files changed, 4 insertions(+) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 05c2985ded9c..4afb889a9979 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -600,6 +600,7 @@ proc escapeJsonUnquoted*(s: string; result: var string) = of '\b': result.add("\\b") of '\f': result.add("\\f") of '\t': result.add("\\t") + of '\v': result.add("\\v") of '\r': result.add("\\r") of '"': result.add("\\\"") of '\0'..'\7': result.add("\\u000" & $ord(c)) diff --git a/lib/pure/parsejson.nim b/lib/pure/parsejson.nim index 9c53af6a6caa..419572dba0e9 100644 --- a/lib/pure/parsejson.nim +++ b/lib/pure/parsejson.nim @@ -218,6 +218,9 @@ proc parseString(my: var JsonParser): TokKind = of 't': add(my.a, '\t') inc(pos, 2) + of 'v': + add(my.a, '\v') + inc(pos, 2) of 'u': if my.rawStringLiterals: add(my.a, 'u') From 15c526c298b9838b015002e3acf6ec4eabb8e69e Mon Sep 17 00:00:00 2001 From: Andy Davidoff Date: Sun, 14 Apr 2019 02:20:23 -0400 Subject: [PATCH 24/29] render urls correctly (#11022) (cherry picked from commit 485d5448fa325b74b3636ffd53ede4066c3aad96) --- compiler/commands.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/commands.nim b/compiler/commands.nim index 1b56ee19dc1e..6296cf9c2567 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -48,14 +48,14 @@ const "Copyright (c) 2006-" & copyrightYear & " by Andreas Rumpf\n" const - Usage = slurp"../doc/basicopt.txt".replace("//", "") + Usage = slurp"../doc/basicopt.txt".replace(" //", " ") FeatureDesc = block: var x = "" for f in low(Feature)..high(Feature): if x.len > 0: x.add "|" x.add $f x - AdvancedUsage = slurp"../doc/advopt.txt".replace("//", "") % FeatureDesc + AdvancedUsage = slurp"../doc/advopt.txt".replace(" //", " ") % FeatureDesc proc getCommandLineDesc(conf: ConfigRef): string = result = (HelpMessage % [VersionAsString, platform.OS[conf.target.hostOS].name, From f575cdc1aecd9d666473951da399ae0ab41e35f4 Mon Sep 17 00:00:00 2001 From: Jasper Jenkins Date: Mon, 15 Apr 2019 08:02:25 -0700 Subject: [PATCH 25/29] Add len check for newIfStmt to avoid segfault (#11032) (cherry picked from commit a68c5662f2e3fa732a330ff373cf224495472372) --- lib/core/macros.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 9b82e658c8f7..f838a0fc74c0 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -976,6 +976,8 @@ proc newIfStmt*(branches: varargs[tuple[cond, body: NimNode]]): ## ) ## result = newNimNode(nnkIfStmt) + if len(branches) < 1: + error("If statement must have at least one branch") for i in branches: result.add(newTree(nnkElifBranch, i.cond, i.body)) From 8c4c3464e15ca24dcd6ea1fef4c580bf164cead5 Mon Sep 17 00:00:00 2001 From: genotrance Date: Sat, 4 May 2019 15:38:52 -0500 Subject: [PATCH 26/29] Fix 105, few fixes for 101 (#11148) (cherry picked from commit 45759b5e904380554dc590ee87e56b61d5a17cf2) --- compiler/importer.nim | 1 + compiler/semtypes.nim | 2 +- compiler/semtypinst.nim | 6 ++++-- compiler/types.nim | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/importer.nim b/compiler/importer.nim index 60b7872feea0..aada524046f7 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -92,6 +92,7 @@ proc importSymbol(c: PContext, n: PNode, fromMod: PSym) = rawImportSymbol(c, e) e = nextIdentIter(it, fromMod.tab) else: rawImportSymbol(c, s) + suggestSym(c.config, n.info, s, c.graph.usageSym, false) proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: IntSet) = var i: TTabIter diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 5e16b009a3c9..9aaab4a922fe 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -972,7 +972,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, if lifted != nil: paramType.sons[i] = lifted let body = paramType.base - if body.kind == tyForward: + if body.kind in {tyForward, tyError}: # this may happen for proc type appearing in a type section # before one of its param types return diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index bf06b019f9e9..f8e532048cd6 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -67,11 +67,10 @@ proc cacheTypeInst*(inst: PType) = # update the refcount let gt = inst.sons[0] let t = if gt.kind == tyGenericBody: gt.lastSon else: gt - if t.kind in {tyStatic, tyGenericParam} + tyTypeClasses: + if t.kind in {tyStatic, tyError, tyGenericParam} + tyTypeClasses: return gt.sym.typeInstCache.safeAdd(inst) - type LayeredIdTable* = object topLayer*: TIdTable @@ -336,6 +335,9 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = # but we already raised an error! rawAddSon(result, header.sons[i]) + if body.kind == tyError: + return + let bbody = lastSon body var newbody = replaceTypeVarsT(cl, bbody) let bodyIsNew = newbody != bbody diff --git a/compiler/types.nim b/compiler/types.nim index d8e038480e8d..2201b69ad4ae 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -130,6 +130,7 @@ proc elemType*(t: PType): PType = case t.kind of tyGenericInst, tyDistinct, tyAlias, tySink: result = elemType(lastSon(t)) of tyArray: result = t.sons[1] + of tyError: result = t else: result = t.lastSon assert(result != nil) From b85cc179989d5d9ddcccc777b5036bf010fdacae Mon Sep 17 00:00:00 2001 From: Clyybber Date: Thu, 9 May 2019 22:58:41 +0200 Subject: [PATCH 27/29] Fix #9844 (#11216) (cherry picked from commit 6be9b98e35551fcdeccef0379c9771626a307ed2) --- compiler/aliases.nim | 9 ++++++++- tests/ccgbugs/tobjconstr_bad_aliasing.nim | 19 ++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/compiler/aliases.nim b/compiler/aliases.nim index f79210dd7378..2ba21b9ff93a 100644 --- a/compiler/aliases.nim +++ b/compiler/aliases.nim @@ -181,9 +181,16 @@ proc isPartOf*(a, b: PNode): TAnalysisResult = else: discard of nkObjConstr: result = arNo - for i in 1.. Date: Fri, 10 May 2019 08:48:12 +0200 Subject: [PATCH 28/29] fixes #7569, all credit to @vincentvidal (#11213) (cherry picked from commit e54546bcffd2224ed0c809992b5e47163c3bc5dc) --- compiler/semtypes.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 9aaab4a922fe..6f41dcc0f2e4 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -725,8 +725,8 @@ proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int, of nkOfBranch, nkElse: addInheritedFieldsAux(c, check, pos, lastSon(n.sons[i])) else: internalError(c.config, n.info, "addInheritedFieldsAux(record case branch)") - of nkRecList: - for i in countup(0, sonsLen(n) - 1): + of nkRecList, nkRecWhen, nkElifBranch, nkElse: + for i in 0 ..< sonsLen(n): addInheritedFieldsAux(c, check, pos, n.sons[i]) of nkSym: incl(check, n.sym.name.id) From c6f601d48ec81e0d6e052ba0d19a195b55cc68f2 Mon Sep 17 00:00:00 2001 From: narimiran Date: Fri, 10 May 2019 13:35:12 +0200 Subject: [PATCH 29/29] bump version to 0.19.6 --- lib/system.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/system.nim b/lib/system.nim index 4edfb767bb42..a66751fd8402 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2023,7 +2023,7 @@ const NimMinor* {.intdefine.}: int = 19 ## is the minor number of Nim's version. - NimPatch* {.intdefine.}: int = 5 + NimPatch* {.intdefine.}: int = 6 ## is the patch number of Nim's version. NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch