Merge branch 'devel' of github.com:Araq/Nimrod into devel

This commit is contained in:
Dominik Picheta
2014-08-10 10:55:46 +01:00
7 changed files with 40 additions and 10 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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()