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
commit 8b08e98e9f
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) 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)

View file

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

View file

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

View file

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

View file

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

View file

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

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