mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 06:18:51 +00:00
@@ -567,19 +567,36 @@ proc genReturn(c: var Con; n: PNode) =
|
||||
|
||||
const
|
||||
InterestingSyms = {skVar, skResult, skLet, skParam, skForVar, skTemp}
|
||||
PathKinds* = {nkDotExpr, nkCheckedFieldExpr,
|
||||
PathKinds0 = {nkDotExpr, nkCheckedFieldExpr,
|
||||
nkBracketExpr, nkDerefExpr, nkHiddenDeref,
|
||||
nkAddr, nkHiddenAddr,
|
||||
nkHiddenStdConv, nkHiddenSubConv, nkObjDownConv, nkObjUpConv}
|
||||
nkObjDownConv, nkObjUpConv}
|
||||
PathKinds1 = {nkHiddenStdConv, nkHiddenSubConv}
|
||||
|
||||
proc getRoot(n: PNode): PNode =
|
||||
result = n
|
||||
while true:
|
||||
case result.kind
|
||||
of PathKinds0:
|
||||
result = result[0]
|
||||
of PathKinds1:
|
||||
result = result[1]
|
||||
else: break
|
||||
|
||||
proc skipConvDfa*(n: PNode): PNode =
|
||||
result = n
|
||||
while true:
|
||||
case result.kind
|
||||
of nkObjDownConv, nkObjUpConv:
|
||||
result = result[0]
|
||||
of PathKinds1:
|
||||
result = result[1]
|
||||
else: break
|
||||
|
||||
proc genUse(c: var Con; orig: PNode) =
|
||||
var n = orig
|
||||
var iters = 0
|
||||
while n.kind in PathKinds:
|
||||
n = n[0]
|
||||
inc iters
|
||||
let n = dfa.getRoot(orig)
|
||||
if n.kind == nkSym and n.sym.kind in InterestingSyms:
|
||||
c.code.add Instr(n: orig, kind: use, sym: if iters > 0: nil else: n.sym)
|
||||
c.code.add Instr(n: orig, kind: use, sym: if orig != n: nil else: n.sym)
|
||||
|
||||
proc aliases(obj, field: PNode): bool =
|
||||
var n = field
|
||||
@@ -729,7 +746,7 @@ proc gen(c: var Con; n: PNode) =
|
||||
# "uses" 'i'. But we are only talking about builtin array indexing so
|
||||
# it doesn't matter and 'x = 34' is NOT a usage of 'x'.
|
||||
genDef(c, n[0])
|
||||
of PathKinds:
|
||||
of PathKinds0 - {nkHiddenStdConv, nkHiddenSubConv, nkObjDownConv, nkObjUpConv}:
|
||||
genUse(c, n)
|
||||
of nkIfStmt, nkIfExpr: genIf(c, n)
|
||||
of nkWhenStmt:
|
||||
@@ -746,8 +763,8 @@ proc gen(c: var Con; n: PNode) =
|
||||
nkBracket, nkCurly, nkPar, nkTupleConstr, nkClosure, nkObjConstr:
|
||||
for x in n: gen(c, x)
|
||||
of nkPragmaBlock: gen(c, n.lastSon)
|
||||
of nkDiscardStmt: gen(c, n.sons[0])
|
||||
of nkConv, nkExprColonExpr, nkExprEqExpr, nkCast:
|
||||
of nkDiscardStmt, nkObjDownConv, nkObjUpConv: gen(c, n.sons[0])
|
||||
of nkConv, nkExprColonExpr, nkExprEqExpr, nkCast, nkHiddenSubConv, nkHiddenStdConv:
|
||||
gen(c, n.sons[1])
|
||||
of nkStringToCString, nkCStringToString: gen(c, n.sons[0])
|
||||
of nkVarSection, nkLetSection: genVarSection(c, n)
|
||||
|
||||
@@ -195,15 +195,17 @@ proc isLastRead(n: PNode; c: var Con): bool =
|
||||
# first we need to search for the instruction that belongs to 'n':
|
||||
c.otherRead = nil
|
||||
var instr = -1
|
||||
let m = dfa.skipConvDfa(n)
|
||||
|
||||
for i in 0..<c.g.len:
|
||||
# This comparison is correct and MUST not be ``instrTargets``:
|
||||
if c.g[i].kind == use and c.g[i].n == n:
|
||||
if c.g[i].kind == use and c.g[i].n == m:
|
||||
if instr < 0:
|
||||
instr = i
|
||||
break
|
||||
|
||||
dbg:
|
||||
echo "starting point for ", n, " is ", instr
|
||||
echo "starting point for ", n, " is ", instr, " ", n.kind
|
||||
|
||||
if instr < 0: return false
|
||||
# we go through all paths beginning from 'instr+1' and need to
|
||||
@@ -625,7 +627,9 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
|
||||
result = genCopy(c, dest.typ, dest, ri)
|
||||
result.add p(ri, c)
|
||||
of nkHiddenSubConv, nkHiddenStdConv:
|
||||
if ri[1].kind in movableNodeKinds:
|
||||
if sameType(ri.typ, ri[1].typ):
|
||||
result = moveOrCopy(dest, ri[1], c)
|
||||
elif ri[1].kind in movableNodeKinds:
|
||||
result = moveOrCopy(dest, ri[1], c)
|
||||
var b = newNodeIT(ri.kind, ri.info, ri.typ)
|
||||
b.add ri[0] # add empty node
|
||||
|
||||
@@ -2,30 +2,46 @@ discard """
|
||||
output: '''works'''
|
||||
"""
|
||||
|
||||
type
|
||||
MyVal = object
|
||||
f: ptr float
|
||||
# bug #11095
|
||||
|
||||
proc `=destroy`(x: var MyVal) =
|
||||
type
|
||||
MyVal[T] = object
|
||||
f: ptr T
|
||||
|
||||
proc `=destroy`[T](x: var MyVal[T]) =
|
||||
if x.f != nil:
|
||||
dealloc(x.f)
|
||||
|
||||
proc `=sink`(x1: var MyVal, x2: Myval) =
|
||||
proc `=sink`[T](x1: var MyVal[T], x2: MyVal[T]) =
|
||||
if x1.f != x2.f:
|
||||
`=destroy`(x1)
|
||||
x1.f = x2.f
|
||||
|
||||
proc `=`(x1: var MyVal, x2: Myval) {.error.}
|
||||
proc `=`[T](x1: var MyVal[T], x2: MyVal[T]) {.error.}
|
||||
|
||||
proc newVal(x: float): MyVal =
|
||||
result.f = create(float)
|
||||
proc newVal[T](x: sink T): MyVal[T] =
|
||||
result.f = create(T)
|
||||
result.f[] = x
|
||||
|
||||
proc sinkMe(x: sink MyVal) =
|
||||
proc set[T](x: var MyVal[T], val: T) =
|
||||
x.f[] = val
|
||||
|
||||
proc sinkMe[T](x: sink MyVal[T]) =
|
||||
discard
|
||||
|
||||
var flag = false
|
||||
|
||||
proc main =
|
||||
var y = (newVal(3.0), newVal(4.0))
|
||||
var y = case flag
|
||||
of true:
|
||||
var x1 = newVal[float](1.0)
|
||||
var x2 = newVal[float](2.0)
|
||||
(newVal(x1), newVal(x2))
|
||||
|
||||
of false:
|
||||
var x1 = newVal[float](1.0)
|
||||
var x2 = newVal[float](2.0)
|
||||
(newVal(x1), newVal(x2))
|
||||
|
||||
sinkMe y[0]
|
||||
sinkMe y[1]
|
||||
|
||||
Reference in New Issue
Block a user