mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-14 23:33:28 +00:00
Merge branch 'devel' of github.com:Araq/Nimrod into devel
This commit is contained in:
@@ -1313,6 +1313,10 @@ proc newSons(father: PNode, length: int) =
|
||||
setLen(father.sons, length)
|
||||
|
||||
proc skipTypes*(t: PType, kinds: TTypeKinds): PType =
|
||||
## Used throughout the compiler code to test whether a type tree contains or
|
||||
## doesn't contain a specific type/types - it is often the case that only the
|
||||
## last child nodes of a type tree need to be searched. This is a really hot
|
||||
## path within the compiler!
|
||||
result = t
|
||||
while result.kind in kinds: result = lastSon(result)
|
||||
|
||||
|
||||
@@ -122,6 +122,7 @@ proc mapSetType(typ: PType): TCTypeKind =
|
||||
else: result = ctArray
|
||||
|
||||
proc mapType(typ: PType): TCTypeKind =
|
||||
## Maps a nimrod type to a C type
|
||||
case typ.kind
|
||||
of tyNone, tyStmt: result = ctVoid
|
||||
of tyBool: result = ctBool
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -199,6 +199,8 @@ proc isCastable(dst, src: PType): bool =
|
||||
result = (dstSize >= srcSize) or
|
||||
(skipTypes(dst, abstractInst).kind in IntegralTypes) or
|
||||
(skipTypes(src, abstractInst-{tyTypeDesc}).kind in IntegralTypes)
|
||||
if result and src.kind == tyNil:
|
||||
result = dst.size <= platform.ptrSize
|
||||
|
||||
proc isSymChoice(n: PNode): bool {.inline.} =
|
||||
result = n.kind in nkSymChoices
|
||||
@@ -1643,10 +1645,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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
18
tests/parallel/tdeepcopy.nim
Normal file
18
tests/parallel/tdeepcopy.nim
Normal file
@@ -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()
|
||||
Reference in New Issue
Block a user