From 76011e40ef37018fe5cf69171e55b5c321152fbd Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 10 Aug 2014 03:17:30 +0200 Subject: [PATCH] progress on 'spawn' --- compiler/lowerings.nim | 4 ++-- compiler/sem.nim | 2 +- compiler/semexprs.nim | 6 +++--- compiler/semparallel.nim | 13 +++++++++---- tests/parallel/tdeepcopy.nim | 18 ++++++++++++++++++ 5 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 tests/parallel/tdeepcopy.nim diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 4050bb9b44..ddfcb4f011 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -185,14 +185,14 @@ proc callProc(a: PNode): PNode = # - a proc returning non GC'ed memory --> pass as hidden 'var' parameter # - not in a parallel environment --> requires a flowVar for memory safety type - TSpawnResult = enum + TSpawnResult* = enum srVoid, srFlowVar, srByVar TFlowVarKind = enum fvInvalid # invalid type T for 'FlowVar[T]' fvGC # FlowVar of a GC'ed type fvBlob # FlowVar of a blob type -proc spawnResult(t: PType; inParallel: bool): TSpawnResult = +proc spawnResult*(t: PType; inParallel: bool): TSpawnResult = if t.isEmptyType: srVoid elif inParallel and not containsGarbageCollectedRef(t): srByVar else: srFlowVar diff --git a/compiler/sem.nim b/compiler/sem.nim index 8025ef70de..26a59334c0 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -16,7 +16,7 @@ import procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch, intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting, evaltempl, patterns, parampatterns, sempass2, pretty, semmacrosanity, - semparallel + semparallel, lowerings # implementation diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index d040675fa1..b81d53d41f 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1643,10 +1643,10 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = result = setMs(n, s) result.sons[1] = semExpr(c, n.sons[1]) if not result[1].typ.isEmptyType: - if c.inParallelStmt > 0: - result.typ = result[1].typ - else: + if spawnResult(result[1].typ, c.inParallelStmt > 0) == srFlowVar: result.typ = createFlowVar(c, result[1].typ, n.info) + else: + result.typ = result[1].typ result.add instantiateCreateFlowVarCall(c, result[1].typ, n.info).newSymNode else: result = semDirectOp(c, n, flags) diff --git a/compiler/semparallel.nim b/compiler/semparallel.nim index 2ad7ef3416..7c489c3b6f 100644 --- a/compiler/semparallel.nim +++ b/compiler/semparallel.nim @@ -23,7 +23,7 @@ import ast, astalgo, idents, lowerings, magicsys, guards, sempass2, msgs, - renderer + renderer, types from trees import getMagic from strutils import `%` @@ -406,12 +406,17 @@ proc transformSpawn(owner: PSym; n, barrier: PNode): PNode = if result.isNil: result = newNodeI(nkStmtList, n.info) result.add n - result.add wrapProcForSpawn(owner, m, b.typ, barrier, it[0]) - it.sons[it.len-1] = emptyNode + let t = b[1][0].typ.sons[0] + if spawnResult(t, true) == srByVar: + result.add wrapProcForSpawn(owner, m, b.typ, barrier, it[0]) + it.sons[it.len-1] = emptyNode + else: + it.sons[it.len-1] = wrapProcForSpawn(owner, m, b.typ, barrier, nil) if result.isNil: result = n of nkAsgn, nkFastAsgn: let b = n[1] - if getMagic(b) == mSpawn: + if getMagic(b) == mSpawn and (let t = b[1][0].typ.sons[0]; + spawnResult(t, true) == srByVar): let m = transformSlices(b) return wrapProcForSpawn(owner, m, b.typ, barrier, n[0]) result = transformSpawnSons(owner, n, barrier) diff --git a/tests/parallel/tdeepcopy.nim b/tests/parallel/tdeepcopy.nim new file mode 100644 index 0000000000..84e2edf3f4 --- /dev/null +++ b/tests/parallel/tdeepcopy.nim @@ -0,0 +1,18 @@ +discard """ + output: '''13 abc''' +""" + +type + PBinaryTree = ref object + le, ri: PBinaryTree + value: int + + +proc main = + var x: PBinaryTree + deepCopy(x, PBinaryTree(ri: PBinaryTree(le: PBinaryTree(value: 13)))) + var y: string + deepCopy y, "abc" + echo x.ri.le.value, " ", y + +main()