Merge branch 'devel' of github.com:Araq/Nimrod into devel
This commit is contained in:
commit
8b08e98e9f
7 changed files with 40 additions and 10 deletions
|
|
@ -1313,6 +1313,10 @@ proc newSons(father: PNode, length: int) =
|
||||||
setLen(father.sons, length)
|
setLen(father.sons, length)
|
||||||
|
|
||||||
proc skipTypes*(t: PType, kinds: TTypeKinds): PType =
|
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
|
result = t
|
||||||
while result.kind in kinds: result = lastSon(result)
|
while result.kind in kinds: result = lastSon(result)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,7 @@ proc mapSetType(typ: PType): TCTypeKind =
|
||||||
else: result = ctArray
|
else: result = ctArray
|
||||||
|
|
||||||
proc mapType(typ: PType): TCTypeKind =
|
proc mapType(typ: PType): TCTypeKind =
|
||||||
|
## Maps a nimrod type to a C type
|
||||||
case typ.kind
|
case typ.kind
|
||||||
of tyNone, tyStmt: result = ctVoid
|
of tyNone, tyStmt: result = ctVoid
|
||||||
of tyBool: result = ctBool
|
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
|
# - a proc returning non GC'ed memory --> pass as hidden 'var' parameter
|
||||||
# - not in a parallel environment --> requires a flowVar for memory safety
|
# - not in a parallel environment --> requires a flowVar for memory safety
|
||||||
type
|
type
|
||||||
TSpawnResult = enum
|
TSpawnResult* = enum
|
||||||
srVoid, srFlowVar, srByVar
|
srVoid, srFlowVar, srByVar
|
||||||
TFlowVarKind = enum
|
TFlowVarKind = enum
|
||||||
fvInvalid # invalid type T for 'FlowVar[T]'
|
fvInvalid # invalid type T for 'FlowVar[T]'
|
||||||
fvGC # FlowVar of a GC'ed type
|
fvGC # FlowVar of a GC'ed type
|
||||||
fvBlob # FlowVar of a blob 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
|
if t.isEmptyType: srVoid
|
||||||
elif inParallel and not containsGarbageCollectedRef(t): srByVar
|
elif inParallel and not containsGarbageCollectedRef(t): srByVar
|
||||||
else: srFlowVar
|
else: srFlowVar
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import
|
||||||
procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch,
|
procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch,
|
||||||
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
|
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
|
||||||
evaltempl, patterns, parampatterns, sempass2, pretty, semmacrosanity,
|
evaltempl, patterns, parampatterns, sempass2, pretty, semmacrosanity,
|
||||||
semparallel
|
semparallel, lowerings
|
||||||
|
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,8 @@ proc isCastable(dst, src: PType): bool =
|
||||||
result = (dstSize >= srcSize) or
|
result = (dstSize >= srcSize) or
|
||||||
(skipTypes(dst, abstractInst).kind in IntegralTypes) or
|
(skipTypes(dst, abstractInst).kind in IntegralTypes) or
|
||||||
(skipTypes(src, abstractInst-{tyTypeDesc}).kind in IntegralTypes)
|
(skipTypes(src, abstractInst-{tyTypeDesc}).kind in IntegralTypes)
|
||||||
|
if result and src.kind == tyNil:
|
||||||
|
result = dst.size <= platform.ptrSize
|
||||||
|
|
||||||
proc isSymChoice(n: PNode): bool {.inline.} =
|
proc isSymChoice(n: PNode): bool {.inline.} =
|
||||||
result = n.kind in nkSymChoices
|
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 = setMs(n, s)
|
||||||
result.sons[1] = semExpr(c, n.sons[1])
|
result.sons[1] = semExpr(c, n.sons[1])
|
||||||
if not result[1].typ.isEmptyType:
|
if not result[1].typ.isEmptyType:
|
||||||
if c.inParallelStmt > 0:
|
if spawnResult(result[1].typ, c.inParallelStmt > 0) == srFlowVar:
|
||||||
result.typ = result[1].typ
|
|
||||||
else:
|
|
||||||
result.typ = createFlowVar(c, result[1].typ, n.info)
|
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
|
result.add instantiateCreateFlowVarCall(c, result[1].typ, n.info).newSymNode
|
||||||
else: result = semDirectOp(c, n, flags)
|
else: result = semDirectOp(c, n, flags)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, idents, lowerings, magicsys, guards, sempass2, msgs,
|
ast, astalgo, idents, lowerings, magicsys, guards, sempass2, msgs,
|
||||||
renderer
|
renderer, types
|
||||||
from trees import getMagic
|
from trees import getMagic
|
||||||
from strutils import `%`
|
from strutils import `%`
|
||||||
|
|
||||||
|
|
@ -406,12 +406,17 @@ proc transformSpawn(owner: PSym; n, barrier: PNode): PNode =
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
result = newNodeI(nkStmtList, n.info)
|
result = newNodeI(nkStmtList, n.info)
|
||||||
result.add n
|
result.add n
|
||||||
|
let t = b[1][0].typ.sons[0]
|
||||||
|
if spawnResult(t, true) == srByVar:
|
||||||
result.add wrapProcForSpawn(owner, m, b.typ, barrier, it[0])
|
result.add wrapProcForSpawn(owner, m, b.typ, barrier, it[0])
|
||||||
it.sons[it.len-1] = emptyNode
|
it.sons[it.len-1] = emptyNode
|
||||||
|
else:
|
||||||
|
it.sons[it.len-1] = wrapProcForSpawn(owner, m, b.typ, barrier, nil)
|
||||||
if result.isNil: result = n
|
if result.isNil: result = n
|
||||||
of nkAsgn, nkFastAsgn:
|
of nkAsgn, nkFastAsgn:
|
||||||
let b = n[1]
|
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)
|
let m = transformSlices(b)
|
||||||
return wrapProcForSpawn(owner, m, b.typ, barrier, n[0])
|
return wrapProcForSpawn(owner, m, b.typ, barrier, n[0])
|
||||||
result = transformSpawnSons(owner, n, barrier)
|
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()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue