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
commit 531ed2dc36
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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. performance this keyword can enable.
- `items` no longer compiles with enum with holes as its behavior was error prone, see #14004 - `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. - 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) let n = semparallel.liftParallel(p.module.g.graph, p.module.module, e)
expr(p, n, d) expr(p, n, d)
of mDeepCopy: 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 var a, b: TLoc
let x = if e[1].kind in {nkAddr, nkHiddenAddr}: e[1][0] else: e[1] let x = if e[1].kind in {nkAddr, nkHiddenAddr}: e[1][0] else: e[1]
initLocExpr(p, x, a) 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, name, destroyImpl, getTypeDesc(m, t), typeName,
traceImpl, disposeImpl]) 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 = proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope =
let origType = t let origType = t
var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses) 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) genTupleInfo(m, x, x, result, info)
of tySequence: of tySequence:
genTypeInfoAux(m, t, t, result, info) 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) let markerProc = genTraverseProc(m, origType, sig)
m.s[cfsTypeInit3].addf("$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc]) m.s[cfsTypeInit3].addf("$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc])
of tyRef: of tyRef:
genTypeInfoAux(m, t, t, result, info) 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) let markerProc = genTraverseProc(m, origType, sig)
m.s[cfsTypeInit3].addf("$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc]) m.s[cfsTypeInit3].addf("$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc])
of tyPtr, tyRange, tyUncheckedArray: genTypeInfoAux(m, t, t, result, info) 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": of "sourcemap":
conf.globalOptions.incl optSourcemap conf.globalOptions.incl optSourcemap
conf.options.incl optLineDir 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 -) of "": # comes from "-" in for example: `nim c -r -` (gets stripped from -)
handleStdinInput(conf) handleStdinInput(conf)
else: else:

View file

@ -96,6 +96,7 @@ type # please make sure we have under 32 options
optNimV1Emulation # emulate Nim v1.0 optNimV1Emulation # emulate Nim v1.0
optSourcemap optSourcemap
optProfileVM # enable VM profiler optProfileVM # enable VM profiler
optEnableDeepCopy # ORC specific: enable 'deepcopy' for all types.
TGlobalOptions* = set[TGlobalOption] TGlobalOptions* = set[TGlobalOption]

View file

@ -153,3 +153,4 @@ Advanced options:
--profileVM:on|off enable compile time VM profiler --profileVM:on|off enable compile time VM profiler
--sinkInference:on|off en-/disable sink parameter inference (default: on) --sinkInference:on|off en-/disable sink parameter inference (default: on)
--panics:on|off turn panics into process terminations (default: off) --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 ## This is also used by the code generator
## for the implementation of ``spawn``. ## for the implementation of ``spawn``.
##
## For ``--gc:arc`` or ``--gc:orc`` deepcopy support has to be enabled
## via ``--deepcopy:on``.
discard discard
proc deepCopy*[T](y: T): T = proc deepCopy*[T](y: T): T =

View file

@ -30,7 +30,7 @@ closed
destroying variable: 20 destroying variable: 20
destroying variable: 10 destroying variable: 10
''' '''
cmd: "nim c --gc:arc $file" cmd: "nim c --gc:arc --deepcopy:on $file"
""" """
proc takeSink(x: sink string): bool = true proc takeSink(x: sink string): bool = true
@ -347,3 +347,34 @@ var data = {
# For ARC listVal is empty for some reason # For ARC listVal is empty for some reason
doAssert data["examples"]["values"].listVal[0].strVal == "test" 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 """ discard """
cmd: "nim c --gc:arc $file" cmd: "nim c --gc:arc --deepcopy:on $file"
output: '''13 abc output: '''13 abc
13 abc 13 abc
13 abc 13 abc