fixes #1181
This commit is contained in:
parent
06a4ab54aa
commit
37cc9b2226
5 changed files with 46 additions and 33 deletions
|
|
@ -655,13 +655,15 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
ropef(unArithTab[op], [rdLoc(a), toRope(getSize(t) * 8),
|
ropef(unArithTab[op], [rdLoc(a), toRope(getSize(t) * 8),
|
||||||
getSimpleTypeDesc(p.module, e.typ)]))
|
getSimpleTypeDesc(p.module, e.typ)]))
|
||||||
|
|
||||||
proc genDeref(p: BProc, e: PNode, d: var TLoc) =
|
proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
|
||||||
var a: TLoc
|
if mapType(e.sons[0].typ) in {ctArray, ctPtrToArray} and not enforceDeref:
|
||||||
if mapType(e.sons[0].typ) in {ctArray, ctPtrToArray}:
|
|
||||||
# XXX the amount of hacks for C's arrays is incredible, maybe we should
|
# XXX the amount of hacks for C's arrays is incredible, maybe we should
|
||||||
# simply wrap them in a struct? --> Losing auto vectorization then?
|
# simply wrap them in a struct? --> Losing auto vectorization then?
|
||||||
|
#if e[0].kind != nkBracketExpr:
|
||||||
|
# message(e.info, warnUser, "CAME HERE " & renderTree(e))
|
||||||
expr(p, e.sons[0], d)
|
expr(p, e.sons[0], d)
|
||||||
else:
|
else:
|
||||||
|
var a: TLoc
|
||||||
initLocExpr(p, e.sons[0], a)
|
initLocExpr(p, e.sons[0], a)
|
||||||
case skipTypes(a.t, abstractInst).kind
|
case skipTypes(a.t, abstractInst).kind
|
||||||
of tyRef:
|
of tyRef:
|
||||||
|
|
@ -794,15 +796,15 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||||
else:
|
else:
|
||||||
genRecordField(p, e.sons[0], d)
|
genRecordField(p, e.sons[0], d)
|
||||||
|
|
||||||
proc genArrayElem(p: BProc, e: PNode, d: var TLoc) =
|
proc genArrayElem(p: BProc, x, y: PNode, d: var TLoc) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
initLocExpr(p, e.sons[0], a)
|
initLocExpr(p, x, a)
|
||||||
initLocExpr(p, e.sons[1], b)
|
initLocExpr(p, y, b)
|
||||||
var ty = skipTypes(skipTypes(a.t, abstractVarRange), abstractPtrs)
|
var ty = skipTypes(skipTypes(a.t, abstractVarRange), abstractPtrs)
|
||||||
var first = intLiteral(firstOrd(ty))
|
var first = intLiteral(firstOrd(ty))
|
||||||
# emit range check:
|
# emit range check:
|
||||||
if optBoundsCheck in p.options and tfUncheckedArray notin ty.flags:
|
if optBoundsCheck in p.options and tfUncheckedArray notin ty.flags:
|
||||||
if not isConstExpr(e.sons[1]):
|
if not isConstExpr(y):
|
||||||
# semantic pass has already checked for const index expressions
|
# semantic pass has already checked for const index expressions
|
||||||
if firstOrd(ty) == 0:
|
if firstOrd(ty) == 0:
|
||||||
if (firstOrd(b.t) < firstOrd(ty)) or (lastOrd(b.t) > lastOrd(ty)):
|
if (firstOrd(b.t) < firstOrd(ty)) or (lastOrd(b.t) > lastOrd(ty)):
|
||||||
|
|
@ -812,26 +814,26 @@ proc genArrayElem(p: BProc, e: PNode, d: var TLoc) =
|
||||||
linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n",
|
linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n",
|
||||||
rdCharLoc(b), first, intLiteral(lastOrd(ty)))
|
rdCharLoc(b), first, intLiteral(lastOrd(ty)))
|
||||||
else:
|
else:
|
||||||
let idx = getOrdValue(e.sons[1])
|
let idx = getOrdValue(y)
|
||||||
if idx < firstOrd(ty) or idx > lastOrd(ty):
|
if idx < firstOrd(ty) or idx > lastOrd(ty):
|
||||||
localError(e.info, errIndexOutOfBounds)
|
localError(x.info, errIndexOutOfBounds)
|
||||||
d.inheritLocation(a)
|
d.inheritLocation(a)
|
||||||
putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)),
|
putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)),
|
||||||
rfmt(nil, "$1[($2)- $3]", rdLoc(a), rdCharLoc(b), first))
|
rfmt(nil, "$1[($2)- $3]", rdLoc(a), rdCharLoc(b), first))
|
||||||
|
|
||||||
proc genCStringElem(p: BProc, e: PNode, d: var TLoc) =
|
proc genCStringElem(p: BProc, x, y: PNode, d: var TLoc) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
initLocExpr(p, e.sons[0], a)
|
initLocExpr(p, x, a)
|
||||||
initLocExpr(p, e.sons[1], b)
|
initLocExpr(p, y, b)
|
||||||
var ty = skipTypes(a.t, abstractVarRange)
|
var ty = skipTypes(a.t, abstractVarRange)
|
||||||
if d.k == locNone: d.s = a.s
|
if d.k == locNone: d.s = a.s
|
||||||
putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)),
|
putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)),
|
||||||
rfmt(nil, "$1[$2]", rdLoc(a), rdCharLoc(b)))
|
rfmt(nil, "$1[$2]", rdLoc(a), rdCharLoc(b)))
|
||||||
|
|
||||||
proc genOpenArrayElem(p: BProc, e: PNode, d: var TLoc) =
|
proc genOpenArrayElem(p: BProc, x, y: PNode, d: var TLoc) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
initLocExpr(p, e.sons[0], a)
|
initLocExpr(p, x, a)
|
||||||
initLocExpr(p, e.sons[1], b) # emit range check:
|
initLocExpr(p, y, b) # emit range check:
|
||||||
if optBoundsCheck in p.options:
|
if optBoundsCheck in p.options:
|
||||||
linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len0)) #raiseIndexError();$n",
|
linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len0)) #raiseIndexError();$n",
|
||||||
rdLoc(b), rdLoc(a)) # BUGFIX: ``>=`` and not ``>``!
|
rdLoc(b), rdLoc(a)) # BUGFIX: ``>=`` and not ``>``!
|
||||||
|
|
@ -839,10 +841,10 @@ proc genOpenArrayElem(p: BProc, e: PNode, d: var TLoc) =
|
||||||
putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)),
|
putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)),
|
||||||
rfmt(nil, "$1[$2]", rdLoc(a), rdCharLoc(b)))
|
rfmt(nil, "$1[$2]", rdLoc(a), rdCharLoc(b)))
|
||||||
|
|
||||||
proc genSeqElem(p: BProc, e: PNode, d: var TLoc) =
|
proc genSeqElem(p: BProc, x, y: PNode, d: var TLoc) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
initLocExpr(p, e.sons[0], a)
|
initLocExpr(p, x, a)
|
||||||
initLocExpr(p, e.sons[1], b)
|
initLocExpr(p, y, b)
|
||||||
var ty = skipTypes(a.t, abstractVarRange)
|
var ty = skipTypes(a.t, abstractVarRange)
|
||||||
if ty.kind in {tyRef, tyPtr}:
|
if ty.kind in {tyRef, tyPtr}:
|
||||||
ty = skipTypes(ty.lastSon, abstractVarRange) # emit range check:
|
ty = skipTypes(ty.lastSon, abstractVarRange) # emit range check:
|
||||||
|
|
@ -862,6 +864,17 @@ proc genSeqElem(p: BProc, e: PNode, d: var TLoc) =
|
||||||
putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)),
|
putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)),
|
||||||
rfmt(nil, "$1->data[$2]", rdLoc(a), rdCharLoc(b)))
|
rfmt(nil, "$1->data[$2]", rdLoc(a), rdCharLoc(b)))
|
||||||
|
|
||||||
|
proc genBracketExpr(p: BProc; n: PNode; d: var TLoc) =
|
||||||
|
var ty = skipTypes(n.sons[0].typ, abstractVarRange)
|
||||||
|
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
|
||||||
|
case ty.kind
|
||||||
|
of tyArray, tyArrayConstr: genArrayElem(p, n.sons[0], n.sons[1], d)
|
||||||
|
of tyOpenArray, tyVarargs: genOpenArrayElem(p, n.sons[0], n.sons[1], d)
|
||||||
|
of tySequence, tyString: genSeqElem(p, n.sons[0], n.sons[1], d)
|
||||||
|
of tyCString: genCStringElem(p, n.sons[0], n.sons[1], d)
|
||||||
|
of tyTuple: genTupleElem(p, n, d)
|
||||||
|
else: internalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')')
|
||||||
|
|
||||||
proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
# how to generate code?
|
# how to generate code?
|
||||||
# 'expr1 and expr2' becomes:
|
# 'expr1 and expr2' becomes:
|
||||||
|
|
@ -1985,16 +1998,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
of nkCast: genCast(p, n, d)
|
of nkCast: genCast(p, n, d)
|
||||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, n, d)
|
of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, n, d)
|
||||||
of nkHiddenAddr, nkAddr: genAddr(p, n, d)
|
of nkHiddenAddr, nkAddr: genAddr(p, n, d)
|
||||||
of nkBracketExpr:
|
of nkBracketExpr: genBracketExpr(p, n, d)
|
||||||
var ty = skipTypes(n.sons[0].typ, abstractVarRange)
|
|
||||||
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
|
|
||||||
case ty.kind
|
|
||||||
of tyArray, tyArrayConstr: genArrayElem(p, n, d)
|
|
||||||
of tyOpenArray, tyVarargs: genOpenArrayElem(p, n, d)
|
|
||||||
of tySequence, tyString: genSeqElem(p, n, d)
|
|
||||||
of tyCString: genCStringElem(p, n, d)
|
|
||||||
of tyTuple: genTupleElem(p, n, d)
|
|
||||||
else: internalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')')
|
|
||||||
of nkDerefExpr, nkHiddenDeref: genDeref(p, n, d)
|
of nkDerefExpr, nkHiddenDeref: genDeref(p, n, d)
|
||||||
of nkDotExpr: genRecordField(p, n, d)
|
of nkDotExpr: genRecordField(p, n, d)
|
||||||
of nkCheckedFieldExpr: genCheckedRecordField(p, n, d)
|
of nkCheckedFieldExpr: genCheckedRecordField(p, n, d)
|
||||||
|
|
|
||||||
|
|
@ -68,10 +68,21 @@ proc genVarTuple(p: BProc, n: PNode) =
|
||||||
[rdLoc(tup), mangleRecFieldName(t.n.sons[i].sym, t)])
|
[rdLoc(tup), mangleRecFieldName(t.n.sons[i].sym, t)])
|
||||||
putLocIntoDest(p, v.loc, field)
|
putLocIntoDest(p, v.loc, field)
|
||||||
|
|
||||||
|
proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false)
|
||||||
|
|
||||||
proc loadInto(p: BProc, le, ri: PNode, a: var TLoc) {.inline.} =
|
proc loadInto(p: BProc, le, ri: PNode, a: var TLoc) {.inline.} =
|
||||||
if ri.kind in nkCallKinds and (ri.sons[0].kind != nkSym or
|
if ri.kind in nkCallKinds and (ri.sons[0].kind != nkSym or
|
||||||
ri.sons[0].sym.magic == mNone):
|
ri.sons[0].sym.magic == mNone):
|
||||||
genAsgnCall(p, le, ri, a)
|
genAsgnCall(p, le, ri, a)
|
||||||
|
elif ri.kind in {nkDerefExpr, nkHiddenDeref}:
|
||||||
|
# this is a hacky way to fix #1181 (tmissingderef)::
|
||||||
|
#
|
||||||
|
# var arr1 = cast[ptr array[4, int8]](addr foo)[]
|
||||||
|
#
|
||||||
|
# However, fixing this properly really requires modelling 'array' as
|
||||||
|
# a 'struct' in C to preserve dereferencing semantics completely. Not
|
||||||
|
# worth the effort until version 1.0 is out.
|
||||||
|
genDeref(p, ri, a, enforceDeref=true)
|
||||||
else:
|
else:
|
||||||
expr(p, ri, a)
|
expr(p, ri, a)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,6 @@ proc initLoc(result: var TLoc, k: TLocKind, typ: PType, s: TStorageLoc) =
|
||||||
result.s = s
|
result.s = s
|
||||||
result.t = getUniqueType(typ)
|
result.t = getUniqueType(typ)
|
||||||
result.r = nil
|
result.r = nil
|
||||||
#result.a = - 1
|
|
||||||
result.flags = {}
|
result.flags = {}
|
||||||
|
|
||||||
proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: PRope, s: TStorageLoc) =
|
proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: PRope, s: TStorageLoc) =
|
||||||
|
|
@ -63,7 +62,6 @@ proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: PRope, s: TStorageLoc) =
|
||||||
if a.k == locNone:
|
if a.k == locNone:
|
||||||
a.k = k
|
a.k = k
|
||||||
a.t = getUniqueType(typ)
|
a.t = getUniqueType(typ)
|
||||||
#a.a = - 1
|
|
||||||
a.s = s
|
a.s = s
|
||||||
if a.r == nil: a.r = r
|
if a.r == nil: a.r = r
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -495,10 +495,10 @@ when defined(Windows) and not defined(useNimRtl):
|
||||||
if running(p):
|
if running(p):
|
||||||
discard terminateProcess(p.fProcessHandle, 0)
|
discard terminateProcess(p.fProcessHandle, 0)
|
||||||
|
|
||||||
proc kill(p: PProcess) =
|
proc kill(p: Process) =
|
||||||
terminate(p)
|
terminate(p)
|
||||||
|
|
||||||
proc waitForExit(p: PProcess, timeout: int = -1): int =
|
proc waitForExit(p: Process, timeout: int = -1): int =
|
||||||
discard waitForSingleObject(p.fProcessHandle, timeout.int32)
|
discard waitForSingleObject(p.fProcessHandle, timeout.int32)
|
||||||
|
|
||||||
var res: int32
|
var res: int32
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue