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>
This commit is contained in:
cooldome
2020-10-01 16:39:48 +01:00
committed by GitHub
parent 3919f0aa54
commit 531ed2dc36
9 changed files with 52 additions and 5 deletions

View File

@@ -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.

View File

@@ -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)

View File

@@ -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)

View File

@@ -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:

View File

@@ -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]

View File

@@ -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``

View File

@@ -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 =

View File

@@ -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)

View File

@@ -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