diff options
author | cooldome <ariabushenko@gmail.com> | 2020-10-01 16:39:48 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-01 17:39:48 +0200 |
commit | 531ed2dc365d6d33c7bccdfbe22df561cf14af86 (patch) | |
tree | d4d88cf40fb7b6f805011c4796e421bffc212fef | |
parent | 3919f0aa544d84c7a236e5095b87d7d0c8fb63b4 (diff) | |
download | Nim-531ed2dc365d6d33c7bccdfbe22df561cf14af86.tar.gz |
fix #15405. deepcopy arc (#15410)
* fix #15405 * fix tests * deepcopy for ARC has to be enabled via --deepcopy:on Co-authored-by: Araq <rumpf_a@web.de>
-rw-r--r-- | changelog.md | 3 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 4 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 7 | ||||
-rw-r--r-- | compiler/commands.nim | 3 | ||||
-rw-r--r-- | compiler/options.nim | 1 | ||||
-rw-r--r-- | doc/advopt.txt | 1 | ||||
-rw-r--r-- | lib/system.nim | 3 | ||||
-rw-r--r-- | tests/arc/tarcmisc.nim | 33 | ||||
-rw-r--r-- | tests/arc/tdeepcopy.nim | 2 |
9 files changed, 52 insertions, 5 deletions
diff --git a/changelog.md b/changelog.md index 5061a90b6..3bae911e9 100644 --- a/changelog.md +++ b/changelog.md @@ -287,6 +287,9 @@ proc mydiv(a, b): int {.raises: [].} = performance this keyword can enable. - `items` no longer compiles with enum with holes as its behavior was error prone, see #14004 +- `system.deepcopy` has to be enabled explicitly for `--gc:arc` and `--gc:orc` via + `--deepcopy:on`. + - Added `critbits.toCritBitTree`, similar to `tables.toTable`, creates a new `CritBitTree` with given arguments. diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index b6808a55e..49b1f3d16 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -2394,6 +2394,10 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = let n = semparallel.liftParallel(p.module.g.graph, p.module.module, e) expr(p, n, d) of mDeepCopy: + if p.config.selectedGC in {gcArc, gcOrc} and optEnableDeepCopy notin p.config.globalOptions: + localError(p.config, e.info, + "for --gc:arc|orc 'deepcopy' support has to be enabled with --deepcopy:on") + var a, b: TLoc let x = if e[1].kind in {nkAddr, nkHiddenAddr}: e[1][0] else: e[1] initLocExpr(p, x, a) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index c1a214532..0df7c8d2a 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -1355,6 +1355,9 @@ proc genTypeInfoV2Impl(m: BModule, t, origType: PType, name: Rope; info: TLineIn name, destroyImpl, getTypeDesc(m, t), typeName, traceImpl, disposeImpl]) + if t.kind == tyObject and t.len > 0 and t[0] != nil and optEnableDeepCopy in m.config.globalOptions: + discard genTypeInfoV1(m, t, info) + proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope = let origType = t var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses) @@ -1454,12 +1457,12 @@ proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope = genTupleInfo(m, x, x, result, info) of tySequence: genTypeInfoAux(m, t, t, result, info) - if m.config.selectedGC >= gcMarkAndSweep: + if m.config.selectedGC in {gcMarkAndSweep, gcRefc, gcV2, gcGo}: let markerProc = genTraverseProc(m, origType, sig) m.s[cfsTypeInit3].addf("$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc]) of tyRef: genTypeInfoAux(m, t, t, result, info) - if m.config.selectedGC >= gcMarkAndSweep: + if m.config.selectedGC in {gcMarkAndSweep, gcRefc, gcV2, gcGo}: let markerProc = genTraverseProc(m, origType, sig) m.s[cfsTypeInit3].addf("$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc]) of tyPtr, tyRange, tyUncheckedArray: genTypeInfoAux(m, t, t, result, info) diff --git a/compiler/commands.nim b/compiler/commands.nim index 17124a759..19048065f 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -901,7 +901,8 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; of "sourcemap": conf.globalOptions.incl optSourcemap conf.options.incl optLineDir - # processOnOffSwitchG(conf, {optSourcemap, opt}, arg, pass, info) + of "deepcopy": + processOnOffSwitchG(conf, {optEnableDeepCopy}, arg, pass, info) of "": # comes from "-" in for example: `nim c -r -` (gets stripped from -) handleStdinInput(conf) else: diff --git a/compiler/options.nim b/compiler/options.nim index efb0aa2da..40d86a01d 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -96,6 +96,7 @@ type # please make sure we have under 32 options optNimV1Emulation # emulate Nim v1.0 optSourcemap optProfileVM # enable VM profiler + optEnableDeepCopy # ORC specific: enable 'deepcopy' for all types. TGlobalOptions* = set[TGlobalOption] diff --git a/doc/advopt.txt b/doc/advopt.txt index 830b8bfc6..60f5a1e10 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -153,3 +153,4 @@ Advanced options: --profileVM:on|off enable compile time VM profiler --sinkInference:on|off en-/disable sink parameter inference (default: on) --panics:on|off turn panics into process terminations (default: off) + --deepcopy:on|off enable 'system.deepCopy' for ``--gc:arc|orc`` diff --git a/lib/system.nim b/lib/system.nim index 0784cacce..fe73a70f5 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2895,6 +2895,9 @@ when hasAlloc and notJSnotNims: ## ## This is also used by the code generator ## for the implementation of ``spawn``. + ## + ## For ``--gc:arc`` or ``--gc:orc`` deepcopy support has to be enabled + ## via ``--deepcopy:on``. discard proc deepCopy*[T](y: T): T = diff --git a/tests/arc/tarcmisc.nim b/tests/arc/tarcmisc.nim index 542e4f316..b53d49df8 100644 --- a/tests/arc/tarcmisc.nim +++ b/tests/arc/tarcmisc.nim @@ -30,7 +30,7 @@ closed destroying variable: 20 destroying variable: 10 ''' - cmd: "nim c --gc:arc $file" + cmd: "nim c --gc:arc --deepcopy:on $file" """ proc takeSink(x: sink string): bool = true @@ -347,3 +347,34 @@ var data = { # For ARC listVal is empty for some reason doAssert data["examples"]["values"].listVal[0].strVal == "test" + + + + +############################################################################### +# bug #15405 +import parsexml +const test_xml_str = "<A><B>value</B></A>" +var stream = newStringStream(test_xml_str) +var xml: XmlParser +open(xml, stream, "test") +var xml2 = deepCopy(xml) + +proc text_parser(xml: var XmlParser) = + var test_passed = false + while true: + xml.next() + case xml.kind + of xmlElementStart: + if xml.elementName == "B": + xml.next() + if xml.kind == xmlCharData and xml.charData == "value": + test_passed = true + + of xmlEof: break + else: discard + xml.close() + doAssert(test_passed) + +text_parser(xml) +text_parser(xml2) \ No newline at end of file diff --git a/tests/arc/tdeepcopy.nim b/tests/arc/tdeepcopy.nim index 0eaf7ea40..91d93aa28 100644 --- a/tests/arc/tdeepcopy.nim +++ b/tests/arc/tdeepcopy.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim c --gc:arc $file" + cmd: "nim c --gc:arc --deepcopy:on $file" output: '''13 abc 13 abc 13 abc |