Less ropes (#10979)
* convert ropecg to a macro * fewer intermediate ropes
This commit is contained in:
parent
9f94199d0c
commit
1da98b1636
7 changed files with 451 additions and 349 deletions
|
|
@ -171,13 +171,13 @@ proc canMove(p: BProc, n: PNode): bool =
|
||||||
|
|
||||||
proc genRefAssign(p: BProc, dest, src: TLoc) =
|
proc genRefAssign(p: BProc, dest, src: TLoc) =
|
||||||
if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config):
|
if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config):
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||||
elif dest.storage == OnHeap:
|
elif dest.storage == OnHeap:
|
||||||
linefmt(p, cpsStmts, "#asgnRef((void**) $1, $2);$n",
|
linefmt(p, cpsStmts, "#asgnRef((void**) $1, $2);$n",
|
||||||
addrLoc(p.config, dest), rdLoc(src))
|
[addrLoc(p.config, dest), rdLoc(src)])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n",
|
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n",
|
||||||
addrLoc(p.config, dest), rdLoc(src))
|
[addrLoc(p.config, dest), rdLoc(src)])
|
||||||
|
|
||||||
proc asgnComplexity(n: PNode): int =
|
proc asgnComplexity(n: PNode): int =
|
||||||
if n != nil:
|
if n != nil:
|
||||||
|
|
@ -243,26 +243,26 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
if p.config.selectedGC == gcDestructors:
|
if p.config.selectedGC == gcDestructors:
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"$1 = $2;$n",
|
"$1 = $2;$n",
|
||||||
rdLoc(dest), rdLoc(src))
|
[rdLoc(dest), rdLoc(src)])
|
||||||
elif needToCopy notin flags or
|
elif needToCopy notin flags or
|
||||||
tfShallow in skipTypes(dest.t, abstractVarRange).flags:
|
tfShallow in skipTypes(dest.t, abstractVarRange).flags:
|
||||||
if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config):
|
if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config):
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
|
"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
|
||||||
addrLoc(p.config, dest), addrLoc(p.config, src), rdLoc(dest))
|
[addrLoc(p.config, dest), addrLoc(p.config, src), rdLoc(dest)])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n",
|
linefmt(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n",
|
||||||
addrLoc(p.config, dest), addrLoc(p.config, src), genTypeInfo(p.module, dest.t, dest.lode.info))
|
[addrLoc(p.config, dest), addrLoc(p.config, src), genTypeInfo(p.module, dest.t, dest.lode.info)])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n",
|
linefmt(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n",
|
||||||
addrLoc(p.config, dest), addrLoc(p.config, src), genTypeInfo(p.module, dest.t, dest.lode.info))
|
[addrLoc(p.config, dest), addrLoc(p.config, src), genTypeInfo(p.module, dest.t, dest.lode.info)])
|
||||||
|
|
||||||
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
# This function replaces all other methods for generating
|
# This function replaces all other methods for generating
|
||||||
# the assignment operation in C.
|
# the assignment operation in C.
|
||||||
if src.t != nil and src.t.kind == tyPtr:
|
if src.t != nil and src.t.kind == tyPtr:
|
||||||
# little HACK to support the new 'var T' as return type:
|
# little HACK to support the new 'var T' as return type:
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||||
return
|
return
|
||||||
let ty = skipTypes(dest.t, abstractRange + tyUserTypeClasses + {tyStatic})
|
let ty = skipTypes(dest.t, abstractRange + tyUserTypeClasses + {tyStatic})
|
||||||
case ty.kind
|
case ty.kind
|
||||||
|
|
@ -275,8 +275,8 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
genRefAssign(p, dest, src)
|
genRefAssign(p, dest, src)
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n",
|
linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n",
|
||||||
addrLoc(p.config, dest), rdLoc(src),
|
[addrLoc(p.config, dest), rdLoc(src),
|
||||||
genTypeInfo(p.module, dest.t, dest.lode.info))
|
genTypeInfo(p.module, dest.t, dest.lode.info)])
|
||||||
of tyString:
|
of tyString:
|
||||||
if p.config.selectedGC == gcDestructors:
|
if p.config.selectedGC == gcDestructors:
|
||||||
genGenericAsgn(p, dest, src, flags)
|
genGenericAsgn(p, dest, src, flags)
|
||||||
|
|
@ -284,36 +284,36 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
genRefAssign(p, dest, src)
|
genRefAssign(p, dest, src)
|
||||||
else:
|
else:
|
||||||
if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config):
|
if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config):
|
||||||
linefmt(p, cpsStmts, "$1 = #copyString($2);$n", dest.rdLoc, src.rdLoc)
|
linefmt(p, cpsStmts, "$1 = #copyString($2);$n", [dest.rdLoc, src.rdLoc])
|
||||||
elif dest.storage == OnHeap:
|
elif dest.storage == OnHeap:
|
||||||
# we use a temporary to care for the dreaded self assignment:
|
# we use a temporary to care for the dreaded self assignment:
|
||||||
var tmp: TLoc
|
var tmp: TLoc
|
||||||
getTemp(p, ty, tmp)
|
getTemp(p, ty, tmp)
|
||||||
linefmt(p, cpsStmts, "$3 = $1; $1 = #copyStringRC1($2);$n",
|
linefmt(p, cpsStmts, "$3 = $1; $1 = #copyStringRC1($2);$n",
|
||||||
dest.rdLoc, src.rdLoc, tmp.rdLoc)
|
[dest.rdLoc, src.rdLoc, tmp.rdLoc])
|
||||||
linefmt(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", tmp.rdLoc)
|
linefmt(p, cpsStmts, "if ($1) #nimGCunrefNoCycle($1);$n", [tmp.rdLoc])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n",
|
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n",
|
||||||
addrLoc(p.config, dest), rdLoc(src))
|
[addrLoc(p.config, dest), rdLoc(src)])
|
||||||
of tyProc:
|
of tyProc:
|
||||||
if containsGarbageCollectedRef(dest.t):
|
if containsGarbageCollectedRef(dest.t):
|
||||||
# optimize closure assignment:
|
# optimize closure assignment:
|
||||||
let a = optAsgnLoc(dest, dest.t, "ClE_0".rope)
|
let a = optAsgnLoc(dest, dest.t, "ClE_0".rope)
|
||||||
let b = optAsgnLoc(src, dest.t, "ClE_0".rope)
|
let b = optAsgnLoc(src, dest.t, "ClE_0".rope)
|
||||||
genRefAssign(p, a, b)
|
genRefAssign(p, a, b)
|
||||||
linefmt(p, cpsStmts, "$1.ClP_0 = $2.ClP_0;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1.ClP_0 = $2.ClP_0;$n", [rdLoc(dest), rdLoc(src)])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
if containsGarbageCollectedRef(dest.t):
|
if containsGarbageCollectedRef(dest.t):
|
||||||
if dest.t.len <= 4: genOptAsgnTuple(p, dest, src, flags)
|
if dest.t.len <= 4: genOptAsgnTuple(p, dest, src, flags)
|
||||||
else: genGenericAsgn(p, dest, src, flags)
|
else: genGenericAsgn(p, dest, src, flags)
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||||
of tyObject:
|
of tyObject:
|
||||||
# XXX: check for subtyping?
|
# XXX: check for subtyping?
|
||||||
if ty.isImportedCppType:
|
if ty.isImportedCppType:
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||||
elif not isObjLackingTypeField(ty):
|
elif not isObjLackingTypeField(ty):
|
||||||
genGenericAsgn(p, dest, src, flags)
|
genGenericAsgn(p, dest, src, flags)
|
||||||
elif containsGarbageCollectedRef(ty):
|
elif containsGarbageCollectedRef(ty):
|
||||||
|
|
@ -324,46 +324,46 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||||
else:
|
else:
|
||||||
genGenericAsgn(p, dest, src, flags)
|
genGenericAsgn(p, dest, src, flags)
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||||
of tyArray:
|
of tyArray:
|
||||||
if containsGarbageCollectedRef(dest.t):
|
if containsGarbageCollectedRef(dest.t):
|
||||||
genGenericAsgn(p, dest, src, flags)
|
genGenericAsgn(p, dest, src, flags)
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
|
"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
|
||||||
rdLoc(dest), rdLoc(src), getTypeDesc(p.module, dest.t))
|
[rdLoc(dest), rdLoc(src), getTypeDesc(p.module, dest.t)])
|
||||||
of tyOpenArray, tyVarargs:
|
of tyOpenArray, tyVarargs:
|
||||||
# open arrays are always on the stack - really? What if a sequence is
|
# open arrays are always on the stack - really? What if a sequence is
|
||||||
# passed to an open array?
|
# passed to an open array?
|
||||||
if containsGarbageCollectedRef(dest.t):
|
if containsGarbageCollectedRef(dest.t):
|
||||||
linefmt(p, cpsStmts, # XXX: is this correct for arrays?
|
linefmt(p, cpsStmts, # XXX: is this correct for arrays?
|
||||||
"#genericAssignOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n",
|
"#genericAssignOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n",
|
||||||
addrLoc(p.config, dest), addrLoc(p.config, src),
|
[addrLoc(p.config, dest), addrLoc(p.config, src),
|
||||||
genTypeInfo(p.module, dest.t, dest.lode.info))
|
genTypeInfo(p.module, dest.t, dest.lode.info)])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
# bug #4799, keep the nimCopyMem for a while
|
# bug #4799, keep the nimCopyMem for a while
|
||||||
#"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len_0);$n",
|
#"#nimCopyMem((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len_0);$n",
|
||||||
"$1 = $2;$n",
|
"$1 = $2;$n",
|
||||||
rdLoc(dest), rdLoc(src))
|
[rdLoc(dest), rdLoc(src)])
|
||||||
of tySet:
|
of tySet:
|
||||||
if mapType(p.config, ty) == ctArray:
|
if mapType(p.config, ty) == ctArray:
|
||||||
linefmt(p, cpsStmts, "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, $3);$n",
|
linefmt(p, cpsStmts, "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, $3);$n",
|
||||||
rdLoc(dest), rdLoc(src), rope(getSize(p.config, dest.t)))
|
[rdLoc(dest), rdLoc(src), getSize(p.config, dest.t)])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||||
of tyPtr, tyPointer, tyChar, tyBool, tyEnum, tyCString,
|
of tyPtr, tyPointer, tyChar, tyBool, tyEnum, tyCString,
|
||||||
tyInt..tyUInt64, tyRange, tyVar, tyLent:
|
tyInt..tyUInt64, tyRange, tyVar, tyLent:
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||||
else: internalError(p.config, "genAssignment: " & $ty.kind)
|
else: internalError(p.config, "genAssignment: " & $ty.kind)
|
||||||
|
|
||||||
if optMemTracker in p.options and dest.storage in {OnHeap, OnUnknown}:
|
if optMemTracker in p.options and dest.storage in {OnHeap, OnUnknown}:
|
||||||
#writeStackTrace()
|
#writeStackTrace()
|
||||||
#echo p.currLineInfo, " requesting"
|
#echo p.currLineInfo, " requesting"
|
||||||
linefmt(p, cpsStmts, "#memTrackerWrite((void*)$1, $2, $3, $4);$n",
|
linefmt(p, cpsStmts, "#memTrackerWrite((void*)$1, $2, $3, $4);$n",
|
||||||
addrLoc(p.config, dest), rope getSize(p.config, dest.t),
|
[addrLoc(p.config, dest), getSize(p.config, dest.t),
|
||||||
makeCString(toFullPath(p.config, p.currLineInfo)),
|
makeCString(toFullPath(p.config, p.currLineInfo)),
|
||||||
rope p.currLineInfo.safeLineNm)
|
p.currLineInfo.safeLineNm])
|
||||||
|
|
||||||
proc genDeepCopy(p: BProc; dest, src: TLoc) =
|
proc genDeepCopy(p: BProc; dest, src: TLoc) =
|
||||||
template addrLocOrTemp(a: TLoc): Rope =
|
template addrLocOrTemp(a: TLoc): Rope =
|
||||||
|
|
@ -380,26 +380,26 @@ proc genDeepCopy(p: BProc; dest, src: TLoc) =
|
||||||
of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray:
|
of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray:
|
||||||
# XXX optimize this
|
# XXX optimize this
|
||||||
linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);$n",
|
linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);$n",
|
||||||
addrLoc(p.config, dest), addrLocOrTemp(src),
|
[addrLoc(p.config, dest), addrLocOrTemp(src),
|
||||||
genTypeInfo(p.module, dest.t, dest.lode.info))
|
genTypeInfo(p.module, dest.t, dest.lode.info)])
|
||||||
of tySequence, tyString:
|
of tySequence, tyString:
|
||||||
linefmt(p, cpsStmts, "#genericSeqDeepCopy($1, $2, $3);$n",
|
linefmt(p, cpsStmts, "#genericSeqDeepCopy($1, $2, $3);$n",
|
||||||
addrLoc(p.config, dest), rdLoc(src),
|
[addrLoc(p.config, dest), rdLoc(src),
|
||||||
genTypeInfo(p.module, dest.t, dest.lode.info))
|
genTypeInfo(p.module, dest.t, dest.lode.info)])
|
||||||
of tyOpenArray, tyVarargs:
|
of tyOpenArray, tyVarargs:
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"#genericDeepCopyOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n",
|
"#genericDeepCopyOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n",
|
||||||
addrLoc(p.config, dest), addrLocOrTemp(src),
|
[addrLoc(p.config, dest), addrLocOrTemp(src),
|
||||||
genTypeInfo(p.module, dest.t, dest.lode.info))
|
genTypeInfo(p.module, dest.t, dest.lode.info)])
|
||||||
of tySet:
|
of tySet:
|
||||||
if mapType(p.config, ty) == ctArray:
|
if mapType(p.config, ty) == ctArray:
|
||||||
linefmt(p, cpsStmts, "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, $3);$n",
|
linefmt(p, cpsStmts, "#nimCopyMem((void*)$1, (NIM_CONST void*)$2, $3);$n",
|
||||||
rdLoc(dest), rdLoc(src), rope(getSize(p.config, dest.t)))
|
[rdLoc(dest), rdLoc(src), getSize(p.config, dest.t)])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||||
of tyPointer, tyChar, tyBool, tyEnum, tyCString,
|
of tyPointer, tyChar, tyBool, tyEnum, tyCString,
|
||||||
tyInt..tyUInt64, tyRange, tyVar, tyLent:
|
tyInt..tyUInt64, tyRange, tyVar, tyLent:
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
linefmt(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
|
||||||
else: internalError(p.config, "genDeepCopy: " & $ty.kind)
|
else: internalError(p.config, "genDeepCopy: " & $ty.kind)
|
||||||
|
|
||||||
proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc) =
|
proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc) =
|
||||||
|
|
@ -439,27 +439,27 @@ proc putIntoDest(p: BProc, d: var TLoc, n: PNode, r: Rope; s=OnUnknown) =
|
||||||
d.lode = n
|
d.lode = n
|
||||||
d.r = r
|
d.r = r
|
||||||
|
|
||||||
proc binaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
proc binaryStmt(p: BProc, e: PNode, d: var TLoc, op: string) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
if d.k != locNone: internalError(p.config, e.info, "binaryStmt")
|
if d.k != locNone: internalError(p.config, e.info, "binaryStmt")
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
lineCg(p, cpsStmts, frmt, rdLoc(a), rdLoc(b))
|
lineCg(p, cpsStmts, "$1 $2 $3;$n", [rdLoc(a), op, rdLoc(b)])
|
||||||
|
|
||||||
proc binaryStmtAddr(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
proc binaryStmtAddr(p: BProc, e: PNode, d: var TLoc, cpname: string) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
if d.k != locNone: internalError(p.config, e.info, "binaryStmtAddr")
|
if d.k != locNone: internalError(p.config, e.info, "binaryStmtAddr")
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
lineCg(p, cpsStmts, frmt, byRefLoc(p, a), rdLoc(b))
|
lineCg(p, cpsStmts, "#$1($2, $3);$n", [cpname, byRefLoc(p, a), rdLoc(b)])
|
||||||
|
|
||||||
proc unaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
template unaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
if d.k != locNone: internalError(p.config, e.info, "unaryStmt")
|
if d.k != locNone: internalError(p.config, e.info, "unaryStmt")
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
lineCg(p, cpsStmts, frmt, [rdLoc(a)])
|
lineCg(p, cpsStmts, frmt, [rdLoc(a)])
|
||||||
|
|
||||||
proc binaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
template binaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
assert(e.sons[1].typ != nil)
|
assert(e.sons[1].typ != nil)
|
||||||
assert(e.sons[2].typ != nil)
|
assert(e.sons[2].typ != nil)
|
||||||
|
|
@ -467,7 +467,7 @@ proc binaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
putIntoDest(p, d, e, ropecg(p.module, frmt, [rdLoc(a), rdLoc(b)]))
|
putIntoDest(p, d, e, ropecg(p.module, frmt, [rdLoc(a), rdLoc(b)]))
|
||||||
|
|
||||||
proc binaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
template binaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
assert(e.sons[1].typ != nil)
|
assert(e.sons[1].typ != nil)
|
||||||
assert(e.sons[2].typ != nil)
|
assert(e.sons[2].typ != nil)
|
||||||
|
|
@ -475,40 +475,41 @@ proc binaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
putIntoDest(p, d, e, ropecg(p.module, frmt, [a.rdCharLoc, b.rdCharLoc]))
|
putIntoDest(p, d, e, ropecg(p.module, frmt, [a.rdCharLoc, b.rdCharLoc]))
|
||||||
|
|
||||||
proc unaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
template unaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
putIntoDest(p, d, e, ropecg(p.module, frmt, [rdLoc(a)]))
|
putIntoDest(p, d, e, ropecg(p.module, frmt, [rdLoc(a)]))
|
||||||
|
|
||||||
proc unaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
template unaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
putIntoDest(p, d, e, ropecg(p.module, frmt, [rdCharLoc(a)]))
|
putIntoDest(p, d, e, ropecg(p.module, frmt, [rdCharLoc(a)]))
|
||||||
|
|
||||||
proc binaryArithOverflowRaw(p: BProc, t: PType, a, b: TLoc;
|
template binaryArithOverflowRaw(p: BProc, t: PType, a, b: TLoc;
|
||||||
frmt: string): Rope =
|
cpname: string): Rope =
|
||||||
var size = getSize(p.config, t)
|
var size = getSize(p.config, t)
|
||||||
let storage = if size < p.config.target.intSize: rope("NI")
|
let storage = if size < p.config.target.intSize: rope("NI")
|
||||||
else: getTypeDesc(p.module, t)
|
else: getTypeDesc(p.module, t)
|
||||||
result = getTempName(p.module)
|
var result = getTempName(p.module)
|
||||||
linefmt(p, cpsLocals, "$1 $2;$n", storage, result)
|
linefmt(p, cpsLocals, "$1 $2;$n", [storage, result])
|
||||||
lineCg(p, cpsStmts, frmt, result, rdCharLoc(a), rdCharLoc(b))
|
lineCg(p, cpsStmts, "$1 = #$2($3, $4);$n", [result, cpname, rdCharLoc(a), rdCharLoc(b)])
|
||||||
if size < p.config.target.intSize or t.kind in {tyRange, tyEnum}:
|
if size < p.config.target.intSize or t.kind in {tyRange, tyEnum}:
|
||||||
linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
|
linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
|
||||||
result, intLiteral(firstOrd(p.config, t)), intLiteral(lastOrd(p.config, t)))
|
[result, intLiteral(firstOrd(p.config, t)), intLiteral(lastOrd(p.config, t))])
|
||||||
|
result
|
||||||
|
|
||||||
proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
const
|
const
|
||||||
prc: array[mAddI..mPred, string] = [
|
prc: array[mAddI..mPred, string] = [
|
||||||
"$# = #addInt($#, $#);$n", "$# = #subInt($#, $#);$n",
|
"addInt", "subInt",
|
||||||
"$# = #mulInt($#, $#);$n", "$# = #divInt($#, $#);$n",
|
"mulInt", "divInt", "modInt",
|
||||||
"$# = #modInt($#, $#);$n",
|
"addInt", "subInt"
|
||||||
"$# = #addInt($#, $#);$n", "$# = #subInt($#, $#);$n"]
|
]
|
||||||
prc64: array[mAddI..mPred, string] = [
|
prc64: array[mAddI..mPred, string] = [
|
||||||
"$# = #addInt64($#, $#);$n", "$# = #subInt64($#, $#);$n",
|
"addInt64", "subInt64",
|
||||||
"$# = #mulInt64($#, $#);$n", "$# = #divInt64($#, $#);$n",
|
"mulInt64", "divInt64", "modInt64",
|
||||||
"$# = #modInt64($#, $#);$n",
|
"addInt64", "subInt64"
|
||||||
"$# = #addInt64($#, $#);$n", "$# = #subInt64($#, $#);$n"]
|
]
|
||||||
opr: array[mAddI..mPred, string] = [
|
opr: array[mAddI..mPred, string] = [
|
||||||
"($#)($# + $#)", "($#)($# - $#)", "($#)($# * $#)",
|
"($#)($# + $#)", "($#)($# - $#)", "($#)($# * $#)",
|
||||||
"($#)($# / $#)", "($#)($# % $#)",
|
"($#)($# / $#)", "($#)($# % $#)",
|
||||||
|
|
@ -526,7 +527,7 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
putIntoDest(p, d, e, res)
|
putIntoDest(p, d, e, res)
|
||||||
else:
|
else:
|
||||||
let res = binaryArithOverflowRaw(p, t, a, b,
|
let res = binaryArithOverflowRaw(p, t, a, b,
|
||||||
if t.kind == tyInt64: prc64[m] else: prc[m])
|
if t.kind == tyInt64: prc64[m] else: prc[m])
|
||||||
putIntoDest(p, d, e, "($#)($#)" % [getTypeDesc(p.module, e.typ), res])
|
putIntoDest(p, d, e, "($#)($#)" % [getTypeDesc(p.module, e.typ), res])
|
||||||
|
|
||||||
proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
|
|
@ -543,7 +544,7 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
t = skipTypes(e.typ, abstractRange)
|
t = skipTypes(e.typ, abstractRange)
|
||||||
if optOverflowCheck in p.options:
|
if optOverflowCheck in p.options:
|
||||||
linefmt(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n",
|
linefmt(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n",
|
||||||
rdLoc(a), intLiteral(firstOrd(p.config, t)))
|
[rdLoc(a), intLiteral(firstOrd(p.config, t))])
|
||||||
putIntoDest(p, d, e, opr[m] % [rdLoc(a), rope(getSize(p.config, t) * 8)])
|
putIntoDest(p, d, e, opr[m] % [rdLoc(a), rope(getSize(p.config, t) * 8)])
|
||||||
|
|
||||||
proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
|
|
@ -814,11 +815,11 @@ proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym) =
|
||||||
if op.magic == mNot:
|
if op.magic == mNot:
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"if ($1) #raiseFieldError($2);$n",
|
"if ($1) #raiseFieldError($2);$n",
|
||||||
rdLoc(test), genStringLiteralFromData(p.module, strLit, e.info))
|
[rdLoc(test), genStringLiteralFromData(p.module, strLit, e.info)])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"if (!($1)) #raiseFieldError($2);$n",
|
"if (!($1)) #raiseFieldError($2);$n",
|
||||||
rdLoc(test), genStringLiteralFromData(p.module, strLit, e.info))
|
[rdLoc(test), genStringLiteralFromData(p.module, strLit, e.info)])
|
||||||
|
|
||||||
proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
|
proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||||
if optFieldCheck in p.options:
|
if optFieldCheck in p.options:
|
||||||
|
|
@ -832,7 +833,7 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||||
if field.loc.r == nil:
|
if field.loc.r == nil:
|
||||||
internalError(p.config, e.info, "genCheckedRecordField") # generate the checks:
|
internalError(p.config, e.info, "genCheckedRecordField") # generate the checks:
|
||||||
genFieldCheck(p, e, r, field)
|
genFieldCheck(p, e, r, field)
|
||||||
add(r, ropecg(p.module, ".$1", field.loc.r))
|
add(r, ropecg(p.module, ".$1", [field.loc.r]))
|
||||||
putIntoDest(p, d, e.sons[0], r, a.storage)
|
putIntoDest(p, d, e.sons[0], r, a.storage)
|
||||||
else:
|
else:
|
||||||
genRecordField(p, e.sons[0], d)
|
genRecordField(p, e.sons[0], d)
|
||||||
|
|
@ -842,7 +843,7 @@ proc genUncheckedArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||||
initLocExpr(p, x, a)
|
initLocExpr(p, x, a)
|
||||||
initLocExpr(p, y, b)
|
initLocExpr(p, y, b)
|
||||||
d.inheritLocation(a)
|
d.inheritLocation(a)
|
||||||
putIntoDest(p, d, n, ropecg(p.module, "$1[$2]", rdLoc(a), rdCharLoc(b)),
|
putIntoDest(p, d, n, ropecg(p.module, "$1[$2]", [rdLoc(a), rdCharLoc(b)]),
|
||||||
a.storage)
|
a.storage)
|
||||||
|
|
||||||
proc genArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
proc genArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||||
|
|
@ -858,17 +859,17 @@ proc genArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||||
if firstOrd(p.config, ty) == 0:
|
if firstOrd(p.config, ty) == 0:
|
||||||
if (firstOrd(p.config, b.t) < firstOrd(p.config, ty)) or (lastOrd(p.config, b.t) > lastOrd(p.config, ty)):
|
if (firstOrd(p.config, b.t) < firstOrd(p.config, ty)) or (lastOrd(p.config, b.t) > lastOrd(p.config, ty)):
|
||||||
linefmt(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError2($1, $2);$n",
|
linefmt(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError2($1, $2);$n",
|
||||||
rdCharLoc(b), intLiteral(lastOrd(p.config, ty)))
|
[rdCharLoc(b), intLiteral(lastOrd(p.config, ty))])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError3($1, $2, $3);$n",
|
linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError3($1, $2, $3);$n",
|
||||||
rdCharLoc(b), first, intLiteral(lastOrd(p.config, ty)))
|
[rdCharLoc(b), first, intLiteral(lastOrd(p.config, ty))])
|
||||||
else:
|
else:
|
||||||
let idx = getOrdValue(y)
|
let idx = getOrdValue(y)
|
||||||
if idx < firstOrd(p.config, ty) or idx > lastOrd(p.config, ty):
|
if idx < firstOrd(p.config, ty) or idx > lastOrd(p.config, ty):
|
||||||
localError(p.config, x.info, formatErrorIndexBound(idx, firstOrd(p.config, ty), lastOrd(p.config, ty)))
|
localError(p.config, x.info, formatErrorIndexBound(idx, firstOrd(p.config, ty), lastOrd(p.config, ty)))
|
||||||
d.inheritLocation(a)
|
d.inheritLocation(a)
|
||||||
putIntoDest(p, d, n,
|
putIntoDest(p, d, n,
|
||||||
ropecg(p.module, "$1[($2)- $3]", rdLoc(a), rdCharLoc(b), first), a.storage)
|
ropecg(p.module, "$1[($2)- $3]", [rdLoc(a), rdCharLoc(b), first]), a.storage)
|
||||||
|
|
||||||
proc genCStringElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
proc genCStringElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
|
|
@ -876,7 +877,7 @@ proc genCStringElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||||
initLocExpr(p, y, b)
|
initLocExpr(p, y, b)
|
||||||
inheritLocation(d, a)
|
inheritLocation(d, a)
|
||||||
putIntoDest(p, d, n,
|
putIntoDest(p, d, n,
|
||||||
ropecg(p.module, "$1[$2]", rdLoc(a), rdCharLoc(b)), a.storage)
|
ropecg(p.module, "$1[$2]", [rdLoc(a), rdCharLoc(b)]), a.storage)
|
||||||
|
|
||||||
proc genBoundsCheck(p: BProc; arr, a, b: TLoc) =
|
proc genBoundsCheck(p: BProc; arr, a, b: TLoc) =
|
||||||
let ty = skipTypes(arr.t, abstractVarRange)
|
let ty = skipTypes(arr.t, abstractVarRange)
|
||||||
|
|
@ -885,18 +886,18 @@ proc genBoundsCheck(p: BProc; arr, a, b: TLoc) =
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"if ($2-$1 != -1 && " &
|
"if ($2-$1 != -1 && " &
|
||||||
"((NU)($1) >= (NU)($3Len_0) || (NU)($2) >= (NU)($3Len_0))) #raiseIndexError();$n",
|
"((NU)($1) >= (NU)($3Len_0) || (NU)($2) >= (NU)($3Len_0))) #raiseIndexError();$n",
|
||||||
rdLoc(a), rdLoc(b), rdLoc(arr))
|
[rdLoc(a), rdLoc(b), rdLoc(arr)])
|
||||||
of tyArray:
|
of tyArray:
|
||||||
let first = intLiteral(firstOrd(p.config, ty))
|
let first = intLiteral(firstOrd(p.config, ty))
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"if ($2-$1 != -1 && " &
|
"if ($2-$1 != -1 && " &
|
||||||
"($2-$1 < -1 || $1 < $3 || $1 > $4 || $2 < $3 || $2 > $4)) #raiseIndexError();$n",
|
"($2-$1 < -1 || $1 < $3 || $1 > $4 || $2 < $3 || $2 > $4)) #raiseIndexError();$n",
|
||||||
rdCharLoc(a), rdCharLoc(b), first, intLiteral(lastOrd(p.config, ty)))
|
[rdCharLoc(a), rdCharLoc(b), first, intLiteral(lastOrd(p.config, ty))])
|
||||||
of tySequence, tyString:
|
of tySequence, tyString:
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"if ($2-$1 != -1 && " &
|
"if ($2-$1 != -1 && " &
|
||||||
"((NU)($1) >= (NU)$3 || (NU)($2) >= (NU)$3)) #raiseIndexError();$n",
|
"((NU)($1) >= (NU)$3 || (NU)($2) >= (NU)$3)) #raiseIndexError();$n",
|
||||||
rdLoc(a), rdLoc(b), lenExpr(p, arr))
|
[rdLoc(a), rdLoc(b), lenExpr(p, arr)])
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc genOpenArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
proc genOpenArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||||
|
|
@ -905,10 +906,10 @@ proc genOpenArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||||
initLocExpr(p, y, 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)($2Len_0)) #raiseIndexError2($1,$2Len_0-1);$n",
|
linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len_0)) #raiseIndexError2($1,$2Len_0-1);$n",
|
||||||
rdLoc(b), rdLoc(a)) # BUGFIX: ``>=`` and not ``>``!
|
[rdLoc(b), rdLoc(a)]) # BUGFIX: ``>=`` and not ``>``!
|
||||||
inheritLocation(d, a)
|
inheritLocation(d, a)
|
||||||
putIntoDest(p, d, n,
|
putIntoDest(p, d, n,
|
||||||
ropecg(p.module, "$1[$2]", rdLoc(a), rdCharLoc(b)), a.storage)
|
ropecg(p.module, "$1[$2]", [rdLoc(a), rdCharLoc(b)]), a.storage)
|
||||||
|
|
||||||
proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||||
var a, b: TLoc
|
var a, b: TLoc
|
||||||
|
|
@ -921,16 +922,16 @@ proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||||
if ty.kind == tyString and (not defined(nimNoZeroTerminator) or optLaxStrings in p.options):
|
if ty.kind == tyString and (not defined(nimNoZeroTerminator) or optLaxStrings in p.options):
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"if ((NU)($1) > (NU)$2) #raiseIndexError2($1,$2);$n",
|
"if ((NU)($1) > (NU)$2) #raiseIndexError2($1,$2);$n",
|
||||||
rdLoc(b), lenExpr(p, a))
|
[rdLoc(b), lenExpr(p, a)])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"if ((NU)($1) >= (NU)$2) #raiseIndexError2($1,$2-1);$n",
|
"if ((NU)($1) >= (NU)$2) #raiseIndexError2($1,$2-1);$n",
|
||||||
rdLoc(b), lenExpr(p, a))
|
[rdLoc(b), lenExpr(p, a)])
|
||||||
if d.k == locNone: d.storage = OnHeap
|
if d.k == locNone: d.storage = OnHeap
|
||||||
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
|
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
|
||||||
a.r = ropecg(p.module, "(*$1)", a.r)
|
a.r = ropecg(p.module, "(*$1)", [a.r])
|
||||||
putIntoDest(p, d, n,
|
putIntoDest(p, d, n,
|
||||||
ropecg(p.module, "$1$3[$2]", rdLoc(a), rdCharLoc(b), dataField(p)), a.storage)
|
ropecg(p.module, "$1$3[$2]", [rdLoc(a), rdCharLoc(b), dataField(p)]), a.storage)
|
||||||
|
|
||||||
proc genBracketExpr(p: BProc; n: PNode; d: var TLoc) =
|
proc genBracketExpr(p: BProc; n: PNode; d: var TLoc) =
|
||||||
var ty = skipTypes(n.sons[0].typ, abstractVarRange + tyUserTypeClasses)
|
var ty = skipTypes(n.sons[0].typ, abstractVarRange + tyUserTypeClasses)
|
||||||
|
|
@ -1000,19 +1001,19 @@ proc genEcho(p: BProc, n: PNode) =
|
||||||
add(args, ropecg(p.module, ", Genode::Cstring($1->data, $1->len)", [rdLoc(a)]))
|
add(args, ropecg(p.module, ", Genode::Cstring($1->data, $1->len)", [rdLoc(a)]))
|
||||||
p.module.includeHeader("<base/log.h>")
|
p.module.includeHeader("<base/log.h>")
|
||||||
p.module.includeHeader("<util/string.h>")
|
p.module.includeHeader("<util/string.h>")
|
||||||
linefmt(p, cpsStmts, """Genode::log(""$1);$n""", args)
|
linefmt(p, cpsStmts, """Genode::log(""$1);$n""", [args])
|
||||||
else:
|
else:
|
||||||
if n.len == 0:
|
if n.len == 0:
|
||||||
linefmt(p, cpsStmts, "#echoBinSafe(NIM_NIL, $1);$n", n.len.rope)
|
linefmt(p, cpsStmts, "#echoBinSafe(NIM_NIL, $1);$n", [n.len])
|
||||||
else:
|
else:
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, n, a)
|
initLocExpr(p, n, a)
|
||||||
linefmt(p, cpsStmts, "#echoBinSafe($1, $2);$n", a.rdLoc, n.len.rope)
|
linefmt(p, cpsStmts, "#echoBinSafe($1, $2);$n", [a.rdLoc, n.len])
|
||||||
when false:
|
when false:
|
||||||
p.module.includeHeader("<stdio.h>")
|
p.module.includeHeader("<stdio.h>")
|
||||||
linefmt(p, cpsStmts, "printf($1$2);$n",
|
linefmt(p, cpsStmts, "printf($1$2);$n",
|
||||||
makeCString(repeat("%s", n.len) & "\L"), args)
|
makeCString(repeat("%s", n.len) & "\L"), [args])
|
||||||
linefmt(p, cpsStmts, "fflush(stdout);$n")
|
linefmt(p, cpsStmts, "fflush(stdout);$n", [])
|
||||||
|
|
||||||
proc gcUsage(conf: ConfigRef; n: PNode) =
|
proc gcUsage(conf: ConfigRef; n: PNode) =
|
||||||
if conf.selectedGC == gcNone: message(conf, n.info, warnGcMem, n.renderTree)
|
if conf.selectedGC == gcNone: message(conf, n.info, warnGcMem, n.renderTree)
|
||||||
|
|
@ -1050,15 +1051,15 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
|
||||||
initLocExpr(p, e.sons[i + 1], a)
|
initLocExpr(p, e.sons[i + 1], a)
|
||||||
if skipTypes(e.sons[i + 1].typ, abstractVarRange).kind == tyChar:
|
if skipTypes(e.sons[i + 1].typ, abstractVarRange).kind == tyChar:
|
||||||
inc(L)
|
inc(L)
|
||||||
add(appends, ropecg(p.module, "#appendChar($1, $2);$n", strLoc(p, tmp), rdLoc(a)))
|
add(appends, ropecg(p.module, "#appendChar($1, $2);$n", [strLoc(p, tmp), rdLoc(a)]))
|
||||||
else:
|
else:
|
||||||
if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
|
if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
|
||||||
inc(L, len(e.sons[i + 1].strVal))
|
inc(L, len(e.sons[i + 1].strVal))
|
||||||
else:
|
else:
|
||||||
add(lens, lenExpr(p, a))
|
add(lens, lenExpr(p, a))
|
||||||
add(lens, " + ")
|
add(lens, " + ")
|
||||||
add(appends, ropecg(p.module, "#appendString($1, $2);$n", strLoc(p, tmp), rdLoc(a)))
|
add(appends, ropecg(p.module, "#appendString($1, $2);$n", [strLoc(p, tmp), rdLoc(a)]))
|
||||||
linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", tmp.r, lens, rope(L))
|
linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", [tmp.r, lens, L])
|
||||||
add(p.s(cpsStmts), appends)
|
add(p.s(cpsStmts), appends)
|
||||||
if d.k == locNone:
|
if d.k == locNone:
|
||||||
d = tmp
|
d = tmp
|
||||||
|
|
@ -1090,7 +1091,7 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||||
if skipTypes(e.sons[i + 2].typ, abstractVarRange).kind == tyChar:
|
if skipTypes(e.sons[i + 2].typ, abstractVarRange).kind == tyChar:
|
||||||
inc(L)
|
inc(L)
|
||||||
add(appends, ropecg(p.module, "#appendChar($1, $2);$n",
|
add(appends, ropecg(p.module, "#appendChar($1, $2);$n",
|
||||||
strLoc(p, dest), rdLoc(a)))
|
[strLoc(p, dest), rdLoc(a)]))
|
||||||
else:
|
else:
|
||||||
if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}:
|
if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}:
|
||||||
inc(L, len(e.sons[i + 2].strVal))
|
inc(L, len(e.sons[i + 2].strVal))
|
||||||
|
|
@ -1098,13 +1099,13 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||||
add(lens, lenExpr(p, a))
|
add(lens, lenExpr(p, a))
|
||||||
add(lens, " + ")
|
add(lens, " + ")
|
||||||
add(appends, ropecg(p.module, "#appendString($1, $2);$n",
|
add(appends, ropecg(p.module, "#appendString($1, $2);$n",
|
||||||
strLoc(p, dest), rdLoc(a)))
|
[strLoc(p, dest), rdLoc(a)]))
|
||||||
if p.config.selectedGC == gcDestructors:
|
if p.config.selectedGC == gcDestructors:
|
||||||
linefmt(p, cpsStmts, "#prepareAdd($1, $2$3);$n",
|
linefmt(p, cpsStmts, "#prepareAdd($1, $2$3);$n",
|
||||||
byRefLoc(p, dest), lens, rope(L))
|
[byRefLoc(p, dest), lens, L])
|
||||||
else:
|
else:
|
||||||
initLoc(call, locCall, e, OnHeap)
|
initLoc(call, locCall, e, OnHeap)
|
||||||
call.r = ropecg(p.module, "#resizeString($1, $2$3)", [rdLoc(dest), lens, rope(L)])
|
call.r = ropecg(p.module, "#resizeString($1, $2$3)", [rdLoc(dest), lens, L])
|
||||||
genAssignment(p, dest, call, {})
|
genAssignment(p, dest, call, {})
|
||||||
gcUsage(p.config, e)
|
gcUsage(p.config, e)
|
||||||
add(p.s(cpsStmts), appends)
|
add(p.s(cpsStmts), appends)
|
||||||
|
|
@ -1113,18 +1114,21 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||||
# seq &= x -->
|
# seq &= x -->
|
||||||
# seq = (typeof seq) incrSeq(&seq->Sup, sizeof(x));
|
# seq = (typeof seq) incrSeq(&seq->Sup, sizeof(x));
|
||||||
# seq->data[seq->len-1] = x;
|
# seq->data[seq->len-1] = x;
|
||||||
let seqAppendPattern = if not p.module.compileToCpp:
|
|
||||||
"($2) #incrSeqV3((TGenericSeq*)($1), $3)"
|
|
||||||
else:
|
|
||||||
"($2) #incrSeqV3($1, $3)"
|
|
||||||
var a, b, dest, tmpL, call: TLoc
|
var a, b, dest, tmpL, call: TLoc
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
let seqType = skipTypes(e.sons[1].typ, {tyVar})
|
let seqType = skipTypes(e.sons[1].typ, {tyVar})
|
||||||
initLoc(call, locCall, e, OnHeap)
|
initLoc(call, locCall, e, OnHeap)
|
||||||
call.r = ropecg(p.module, seqAppendPattern, [rdLoc(a),
|
if not p.module.compileToCpp:
|
||||||
getTypeDesc(p.module, e.sons[1].typ),
|
const seqAppendPattern = "($2) #incrSeqV3((TGenericSeq*)($1), $3)"
|
||||||
genTypeInfo(p.module, seqType, e.info)])
|
call.r = ropecg(p.module, seqAppendPattern, [rdLoc(a),
|
||||||
|
getTypeDesc(p.module, e.sons[1].typ),
|
||||||
|
genTypeInfo(p.module, seqType, e.info)])
|
||||||
|
else:
|
||||||
|
const seqAppendPattern = "($2) #incrSeqV3($1, $3)"
|
||||||
|
call.r = ropecg(p.module, seqAppendPattern, [rdLoc(a),
|
||||||
|
getTypeDesc(p.module, e.sons[1].typ),
|
||||||
|
genTypeInfo(p.module, seqType, e.info)])
|
||||||
# emit the write barrier if required, but we can always move here, so
|
# emit the write barrier if required, but we can always move here, so
|
||||||
# use 'genRefAssign' for the seq.
|
# use 'genRefAssign' for the seq.
|
||||||
genRefAssign(p, a, call)
|
genRefAssign(p, a, call)
|
||||||
|
|
@ -1132,8 +1136,8 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||||
# echo "YES ", e.info, " new: ", typeToString(bt), " old: ", typeToString(b.t)
|
# echo "YES ", e.info, " new: ", typeToString(bt), " old: ", typeToString(b.t)
|
||||||
initLoc(dest, locExpr, e.sons[2], OnHeap)
|
initLoc(dest, locExpr, e.sons[2], OnHeap)
|
||||||
getIntTemp(p, tmpL)
|
getIntTemp(p, tmpL)
|
||||||
lineCg(p, cpsStmts, "$1 = $2->$3++;$n", tmpL.r, rdLoc(a), lenField(p))
|
lineCg(p, cpsStmts, "$1 = $2->$3++;$n", [tmpL.r, rdLoc(a), lenField(p)])
|
||||||
dest.r = ropecg(p.module, "$1$3[$2]", rdLoc(a), tmpL.r, dataField(p))
|
dest.r = ropecg(p.module, "$1$3[$2]", [rdLoc(a), tmpL.r, dataField(p)])
|
||||||
genAssignment(p, dest, b, {needToCopy})
|
genAssignment(p, dest, b, {needToCopy})
|
||||||
gcUsage(p.config, e)
|
gcUsage(p.config, e)
|
||||||
|
|
||||||
|
|
@ -1141,8 +1145,8 @@ proc genReset(p: BProc, n: PNode) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, n.sons[1], a)
|
initLocExpr(p, n.sons[1], a)
|
||||||
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
|
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
|
||||||
addrLoc(p.config, a),
|
[addrLoc(p.config, a),
|
||||||
genTypeInfo(p.module, skipTypes(a.t, {tyVar}), n.info))
|
genTypeInfo(p.module, skipTypes(a.t, {tyVar}), n.info)])
|
||||||
|
|
||||||
proc genDefault(p: BProc; n: PNode; d: var TLoc) =
|
proc genDefault(p: BProc; n: PNode; d: var TLoc) =
|
||||||
if d.k == locNone: getTemp(p, n.typ, d, needsInit=true)
|
if d.k == locNone: getTemp(p, n.typ, d, needsInit=true)
|
||||||
|
|
@ -1177,23 +1181,23 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
|
||||||
initLocExpr(p, newSymNode(bt.destructor), f)
|
initLocExpr(p, newSymNode(bt.destructor), f)
|
||||||
addf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
|
addf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
|
||||||
|
|
||||||
let args = [getTypeDesc(p.module, typ), ti, sizeExpr]
|
|
||||||
if a.storage == OnHeap and usesWriteBarrier(p.config):
|
if a.storage == OnHeap and usesWriteBarrier(p.config):
|
||||||
if canFormAcycle(a.t):
|
if canFormAcycle(a.t):
|
||||||
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefRC1($1); $1 = NIM_NIL; }$n", a.rdLoc)
|
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefRC1($1); $1 = NIM_NIL; }$n", [a.rdLoc])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefNoCycle($1); $1 = NIM_NIL; }$n", a.rdLoc)
|
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefNoCycle($1); $1 = NIM_NIL; }$n", [a.rdLoc])
|
||||||
if p.config.selectedGC == gcGo:
|
if p.config.selectedGC == gcGo:
|
||||||
# newObjRC1() would clash with unsureAsgnRef() - which is used by gcGo to
|
# newObjRC1() would clash with unsureAsgnRef() - which is used by gcGo to
|
||||||
# implement the write barrier
|
# implement the write barrier
|
||||||
b.r = ropecg(p.module, "($1) #newObj($2, $3)", args)
|
b.r = ropecg(p.module, "($1) #newObj($2, $3)", [getTypeDesc(p.module, typ), ti, sizeExpr])
|
||||||
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n", addrLoc(p.config, a), b.rdLoc)
|
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n",
|
||||||
|
[addrLoc(p.config, a), b.rdLoc])
|
||||||
else:
|
else:
|
||||||
# use newObjRC1 as an optimization
|
# use newObjRC1 as an optimization
|
||||||
b.r = ropecg(p.module, "($1) #newObjRC1($2, $3)", args)
|
b.r = ropecg(p.module, "($1) #newObjRC1($2, $3)", [getTypeDesc(p.module, typ), ti, sizeExpr])
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", a.rdLoc, b.rdLoc)
|
linefmt(p, cpsStmts, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
|
||||||
else:
|
else:
|
||||||
b.r = ropecg(p.module, "($1) #newObj($2, $3)", args)
|
b.r = ropecg(p.module, "($1) #newObj($2, $3)", [getTypeDesc(p.module, typ), ti, sizeExpr])
|
||||||
genAssignment(p, a, b, {})
|
genAssignment(p, a, b, {})
|
||||||
# set the object type:
|
# set the object type:
|
||||||
genObjectInit(p, cpsStmts, bt, a, false)
|
genObjectInit(p, cpsStmts, bt, a, false)
|
||||||
|
|
@ -1212,28 +1216,29 @@ proc genNew(p: BProc, e: PNode) =
|
||||||
|
|
||||||
proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope; lenIsZero: bool) =
|
proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope; lenIsZero: bool) =
|
||||||
let seqtype = skipTypes(dest.t, abstractVarRange)
|
let seqtype = skipTypes(dest.t, abstractVarRange)
|
||||||
let args = [getTypeDesc(p.module, seqtype),
|
|
||||||
genTypeInfo(p.module, seqtype, dest.lode.info), length]
|
|
||||||
var call: TLoc
|
var call: TLoc
|
||||||
initLoc(call, locExpr, dest.lode, OnHeap)
|
initLoc(call, locExpr, dest.lode, OnHeap)
|
||||||
if dest.storage == OnHeap and usesWriteBarrier(p.config):
|
if dest.storage == OnHeap and usesWriteBarrier(p.config):
|
||||||
if canFormAcycle(dest.t):
|
if canFormAcycle(dest.t):
|
||||||
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefRC1($1); $1 = NIM_NIL; }$n", dest.rdLoc)
|
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefRC1($1); $1 = NIM_NIL; }$n", [dest.rdLoc])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefNoCycle($1); $1 = NIM_NIL; }$n", dest.rdLoc)
|
linefmt(p, cpsStmts, "if ($1) { #nimGCunrefNoCycle($1); $1 = NIM_NIL; }$n", [dest.rdLoc])
|
||||||
if not lenIsZero:
|
if not lenIsZero:
|
||||||
if p.config.selectedGC == gcGo:
|
if p.config.selectedGC == gcGo:
|
||||||
# we need the write barrier
|
# we need the write barrier
|
||||||
call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args)
|
call.r = ropecg(p.module, "($1) #newSeq($2, $3)", [getTypeDesc(p.module, seqtype),
|
||||||
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n", addrLoc(p.config, dest), call.rdLoc)
|
genTypeInfo(p.module, seqtype, dest.lode.info), length])
|
||||||
|
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n", [addrLoc(p.config, dest), call.rdLoc])
|
||||||
else:
|
else:
|
||||||
call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", args)
|
call.r = ropecg(p.module, "($1) #newSeqRC1($2, $3)", [getTypeDesc(p.module, seqtype),
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc)
|
genTypeInfo(p.module, seqtype, dest.lode.info), length])
|
||||||
|
linefmt(p, cpsStmts, "$1 = $2;$n", [dest.rdLoc, call.rdLoc])
|
||||||
else:
|
else:
|
||||||
if lenIsZero:
|
if lenIsZero:
|
||||||
call.r = rope"NIM_NIL"
|
call.r = rope"NIM_NIL"
|
||||||
else:
|
else:
|
||||||
call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args)
|
call.r = ropecg(p.module, "($1) #newSeq($2, $3)", [getTypeDesc(p.module, seqtype),
|
||||||
|
genTypeInfo(p.module, seqtype, dest.lode.info), length])
|
||||||
genAssignment(p, dest, call, {})
|
genAssignment(p, dest, call, {})
|
||||||
|
|
||||||
proc genNewSeq(p: BProc, e: PNode) =
|
proc genNewSeq(p: BProc, e: PNode) =
|
||||||
|
|
@ -1243,8 +1248,8 @@ proc genNewSeq(p: BProc, e: PNode) =
|
||||||
if p.config.selectedGC == gcDestructors:
|
if p.config.selectedGC == gcDestructors:
|
||||||
let seqtype = skipTypes(e.sons[1].typ, abstractVarRange)
|
let seqtype = skipTypes(e.sons[1].typ, abstractVarRange)
|
||||||
linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
|
linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
|
||||||
a.rdLoc, b.rdLoc, getTypeDesc(p.module, seqtype.lastSon),
|
[a.rdLoc, b.rdLoc, getTypeDesc(p.module, seqtype.lastSon),
|
||||||
getSeqPayloadType(p.module, seqtype))
|
getSeqPayloadType(p.module, seqtype)])
|
||||||
else:
|
else:
|
||||||
let lenIsZero = optNilSeqs notin p.options and
|
let lenIsZero = optNilSeqs notin p.options and
|
||||||
e[2].kind == nkIntLit and e[2].intVal == 0
|
e[2].kind == nkIntLit and e[2].intVal == 0
|
||||||
|
|
@ -1352,15 +1357,15 @@ proc genSeqConstr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
if p.config.selectedGC == gcDestructors:
|
if p.config.selectedGC == gcDestructors:
|
||||||
let seqtype = n.typ
|
let seqtype = n.typ
|
||||||
linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
|
linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
|
||||||
rdLoc dest[], l, getTypeDesc(p.module, seqtype.lastSon),
|
[rdLoc dest[], l, getTypeDesc(p.module, seqtype.lastSon),
|
||||||
getSeqPayloadType(p.module, seqtype))
|
getSeqPayloadType(p.module, seqtype)])
|
||||||
else:
|
else:
|
||||||
# generate call to newSeq before adding the elements per hand:
|
# generate call to newSeq before adding the elements per hand:
|
||||||
genNewSeqAux(p, dest[], l,
|
genNewSeqAux(p, dest[], l,
|
||||||
optNilSeqs notin p.options and n.len == 0)
|
optNilSeqs notin p.options and n.len == 0)
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
initLoc(arr, locExpr, n[i], OnHeap)
|
initLoc(arr, locExpr, n[i], OnHeap)
|
||||||
arr.r = ropecg(p.module, "$1$3[$2]", rdLoc(dest[]), intLiteral(i), dataField(p))
|
arr.r = ropecg(p.module, "$1$3[$2]", [rdLoc(dest[]), intLiteral(i), dataField(p)])
|
||||||
arr.storage = OnHeap # we know that sequences are on the heap
|
arr.storage = OnHeap # we know that sequences are on the heap
|
||||||
expr(p, n[i], arr)
|
expr(p, n[i], arr)
|
||||||
gcUsage(p.config, n)
|
gcUsage(p.config, n)
|
||||||
|
|
@ -1383,8 +1388,8 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) =
|
||||||
if p.config.selectedGC == gcDestructors:
|
if p.config.selectedGC == gcDestructors:
|
||||||
let seqtype = n.typ
|
let seqtype = n.typ
|
||||||
linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
|
linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
|
||||||
rdLoc d, rope L, getTypeDesc(p.module, seqtype.lastSon),
|
[rdLoc d, L, getTypeDesc(p.module, seqtype.lastSon),
|
||||||
getSeqPayloadType(p.module, seqtype))
|
getSeqPayloadType(p.module, seqtype)])
|
||||||
else:
|
else:
|
||||||
genNewSeqAux(p, d, intLiteral(L), optNilSeqs notin p.options and L == 0)
|
genNewSeqAux(p, d, intLiteral(L), optNilSeqs notin p.options and L == 0)
|
||||||
initLocExpr(p, n.sons[1], a)
|
initLocExpr(p, n.sons[1], a)
|
||||||
|
|
@ -1392,20 +1397,20 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) =
|
||||||
if L < 10:
|
if L < 10:
|
||||||
for i in countup(0, L - 1):
|
for i in countup(0, L - 1):
|
||||||
initLoc(elem, locExpr, lodeTyp elemType(skipTypes(n.typ, abstractInst)), OnHeap)
|
initLoc(elem, locExpr, lodeTyp elemType(skipTypes(n.typ, abstractInst)), OnHeap)
|
||||||
elem.r = ropecg(p.module, "$1$3[$2]", rdLoc(d), intLiteral(i), dataField(p))
|
elem.r = ropecg(p.module, "$1$3[$2]", [rdLoc(d), intLiteral(i), dataField(p)])
|
||||||
elem.storage = OnHeap # we know that sequences are on the heap
|
elem.storage = OnHeap # we know that sequences are on the heap
|
||||||
initLoc(arr, locExpr, lodeTyp elemType(skipTypes(n.sons[1].typ, abstractInst)), a.storage)
|
initLoc(arr, locExpr, lodeTyp elemType(skipTypes(n.sons[1].typ, abstractInst)), a.storage)
|
||||||
arr.r = ropecg(p.module, "$1[$2]", rdLoc(a), intLiteral(i))
|
arr.r = ropecg(p.module, "$1[$2]", [rdLoc(a), intLiteral(i)])
|
||||||
genAssignment(p, elem, arr, {needToCopy})
|
genAssignment(p, elem, arr, {needToCopy})
|
||||||
else:
|
else:
|
||||||
var i: TLoc
|
var i: TLoc
|
||||||
getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), i)
|
getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), i)
|
||||||
linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n", i.r, L.rope)
|
linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n", [i.r, L])
|
||||||
initLoc(elem, locExpr, lodeTyp elemType(skipTypes(n.typ, abstractInst)), OnHeap)
|
initLoc(elem, locExpr, lodeTyp elemType(skipTypes(n.typ, abstractInst)), OnHeap)
|
||||||
elem.r = ropecg(p.module, "$1$3[$2]", rdLoc(d), rdLoc(i), dataField(p))
|
elem.r = ropecg(p.module, "$1$3[$2]", [rdLoc(d), rdLoc(i), dataField(p)])
|
||||||
elem.storage = OnHeap # we know that sequences are on the heap
|
elem.storage = OnHeap # we know that sequences are on the heap
|
||||||
initLoc(arr, locExpr, lodeTyp elemType(skipTypes(n.sons[1].typ, abstractInst)), a.storage)
|
initLoc(arr, locExpr, lodeTyp elemType(skipTypes(n.sons[1].typ, abstractInst)), a.storage)
|
||||||
arr.r = ropecg(p.module, "$1[$2]", rdLoc(a), rdLoc(i))
|
arr.r = ropecg(p.module, "$1[$2]", [rdLoc(a), rdLoc(i)])
|
||||||
genAssignment(p, elem, arr, {needToCopy})
|
genAssignment(p, elem, arr, {needToCopy})
|
||||||
lineF(p, cpsStmts, "}$n", [])
|
lineF(p, cpsStmts, "}$n", [])
|
||||||
|
|
||||||
|
|
@ -1432,7 +1437,7 @@ proc genNewFinalize(p: BProc, e: PNode) =
|
||||||
proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo): Rope =
|
proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo): Rope =
|
||||||
if optNimV2 in p.config.globalOptions:
|
if optNimV2 in p.config.globalOptions:
|
||||||
result = ropecg(p.module, "#isObj($1.m_type, $2)",
|
result = ropecg(p.module, "#isObj($1.m_type, $2)",
|
||||||
a, genTypeInfo2Name(p.module, dest))
|
[a, genTypeInfo2Name(p.module, dest)])
|
||||||
else:
|
else:
|
||||||
# unfortunately 'genTypeInfo' sets tfObjHasKids as a side effect, so we
|
# unfortunately 'genTypeInfo' sets tfObjHasKids as a side effect, so we
|
||||||
# have to call it here first:
|
# have to call it here first:
|
||||||
|
|
@ -1445,11 +1450,11 @@ proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo): Rope =
|
||||||
inc p.module.labels
|
inc p.module.labels
|
||||||
let cache = "Nim_OfCheck_CACHE" & p.module.labels.rope
|
let cache = "Nim_OfCheck_CACHE" & p.module.labels.rope
|
||||||
addf(p.module.s[cfsVars], "static TNimType* $#[2];$n", [cache])
|
addf(p.module.s[cfsVars], "static TNimType* $#[2];$n", [cache])
|
||||||
result = ropecg(p.module, "#isObjWithCache($#.m_type, $#, $#)", a, ti, cache)
|
result = ropecg(p.module, "#isObjWithCache($#.m_type, $#, $#)", [a, ti, cache])
|
||||||
when false:
|
when false:
|
||||||
# former version:
|
# former version:
|
||||||
result = ropecg(p.module, "#isObj($1.m_type, $2)",
|
result = ropecg(p.module, "#isObj($1.m_type, $2)",
|
||||||
a, genTypeInfo(p.module, dest, info))
|
[a, genTypeInfo(p.module, dest, info)])
|
||||||
|
|
||||||
proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
|
|
@ -1461,7 +1466,7 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||||
while t.kind in {tyVar, tyLent, tyPtr, tyRef}:
|
while t.kind in {tyVar, tyLent, tyPtr, tyRef}:
|
||||||
if t.kind notin {tyVar, tyLent}: nilCheck = r
|
if t.kind notin {tyVar, tyLent}: nilCheck = r
|
||||||
if t.kind notin {tyVar, tyLent} or not p.module.compileToCpp:
|
if t.kind notin {tyVar, tyLent} or not p.module.compileToCpp:
|
||||||
r = ropecg(p.module, "(*$1)", r)
|
r = ropecg(p.module, "(*$1)", [r])
|
||||||
t = skipTypes(t.lastSon, typedescInst)
|
t = skipTypes(t.lastSon, typedescInst)
|
||||||
discard getTypeDesc(p.module, t)
|
discard getTypeDesc(p.module, t)
|
||||||
if not p.module.compileToCpp:
|
if not p.module.compileToCpp:
|
||||||
|
|
@ -1472,9 +1477,9 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||||
globalError(p.config, x.info,
|
globalError(p.config, x.info,
|
||||||
"no 'of' operator available for pure objects")
|
"no 'of' operator available for pure objects")
|
||||||
if nilCheck != nil:
|
if nilCheck != nil:
|
||||||
r = ropecg(p.module, "(($1) && ($2))", nilCheck, genOfHelper(p, dest, r, x.info))
|
r = ropecg(p.module, "(($1) && ($2))", [nilCheck, genOfHelper(p, dest, r, x.info)])
|
||||||
else:
|
else:
|
||||||
r = ropecg(p.module, "($1)", genOfHelper(p, dest, r, x.info))
|
r = ropecg(p.module, "($1)", [genOfHelper(p, dest, r, x.info)])
|
||||||
putIntoDest(p, d, x, r, a.storage)
|
putIntoDest(p, d, x, r, a.storage)
|
||||||
|
|
||||||
proc genOf(p: BProc, n: PNode, d: var TLoc) =
|
proc genOf(p: BProc, n: PNode, d: var TLoc) =
|
||||||
|
|
@ -1536,7 +1541,7 @@ proc genGetTypeInfo(p: BProc, e: PNode, d: var TLoc) =
|
||||||
let t = e.sons[1].typ
|
let t = e.sons[1].typ
|
||||||
putIntoDest(p, d, e, genTypeInfo(p.module, t, e.info))
|
putIntoDest(p, d, e, genTypeInfo(p.module, t, e.info))
|
||||||
|
|
||||||
proc genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
|
template genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, n.sons[1], a)
|
initLocExpr(p, n.sons[1], a)
|
||||||
a.r = ropecg(p.module, frmt, [rdLoc(a)])
|
a.r = ropecg(p.module, frmt, [rdLoc(a)])
|
||||||
|
|
@ -1580,7 +1585,7 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
getIntTemp(p, tmp)
|
getIntTemp(p, tmp)
|
||||||
var x = lenExpr(p, a)
|
var x = lenExpr(p, a)
|
||||||
if op == mHigh: x = "($1-1)" % [x]
|
if op == mHigh: x = "($1-1)" % [x]
|
||||||
lineCg(p, cpsStmts, "$1 = $2;$n", tmp.r, x)
|
lineCg(p, cpsStmts, "$1 = $2;$n", [tmp.r, x])
|
||||||
putIntoDest(p, d, e, tmp.r)
|
putIntoDest(p, d, e, tmp.r)
|
||||||
of tyArray:
|
of tyArray:
|
||||||
# YYY: length(sideeffect) is optimized away incorrectly?
|
# YYY: length(sideeffect) is optimized away incorrectly?
|
||||||
|
|
@ -1608,21 +1613,26 @@ proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
|
||||||
initLocExpr(p, x, a)
|
initLocExpr(p, x, a)
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
let t = skipTypes(e.sons[1].typ, {tyVar})
|
let t = skipTypes(e.sons[1].typ, {tyVar})
|
||||||
let setLenPattern = if not p.module.compileToCpp:
|
|
||||||
"($3) #setLengthSeqV2(&($1)->Sup, $4, $2)"
|
|
||||||
else:
|
|
||||||
"($3) #setLengthSeqV2($1, $4, $2)"
|
|
||||||
|
|
||||||
initLoc(call, locCall, e, OnHeap)
|
initLoc(call, locCall, e, OnHeap)
|
||||||
call.r = ropecg(p.module, setLenPattern, [
|
if not p.module.compileToCpp:
|
||||||
|
const setLenPattern = "($3) #setLengthSeqV2(&($1)->Sup, $4, $2)"
|
||||||
|
call.r = ropecg(p.module, setLenPattern, [
|
||||||
rdLoc(a), rdLoc(b), getTypeDesc(p.module, t),
|
rdLoc(a), rdLoc(b), getTypeDesc(p.module, t),
|
||||||
genTypeInfo(p.module, t.skipTypes(abstractInst), e.info)])
|
genTypeInfo(p.module, t.skipTypes(abstractInst), e.info)])
|
||||||
|
|
||||||
|
else:
|
||||||
|
const setLenPattern = "($3) #setLengthSeqV2($1, $4, $2)"
|
||||||
|
call.r = ropecg(p.module, setLenPattern, [
|
||||||
|
rdLoc(a), rdLoc(b), getTypeDesc(p.module, t),
|
||||||
|
genTypeInfo(p.module, t.skipTypes(abstractInst), e.info)])
|
||||||
|
|
||||||
genAssignment(p, a, call, {})
|
genAssignment(p, a, call, {})
|
||||||
gcUsage(p.config, e)
|
gcUsage(p.config, e)
|
||||||
|
|
||||||
proc genSetLengthStr(p: BProc, e: PNode, d: var TLoc) =
|
proc genSetLengthStr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
if p.config.selectedGc == gcDestructors:
|
if p.config.selectedGc == gcDestructors:
|
||||||
binaryStmtAddr(p, e, d, "#setLengthStrV2($1, $2);$n")
|
binaryStmtAddr(p, e, d, "setLengthStrV2")
|
||||||
else:
|
else:
|
||||||
var a, b, call: TLoc
|
var a, b, call: TLoc
|
||||||
if d.k != locNone: internalError(p.config, e.info, "genSetLengthStr")
|
if d.k != locNone: internalError(p.config, e.info, "genSetLengthStr")
|
||||||
|
|
@ -1770,16 +1780,28 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
case op
|
case op
|
||||||
of mIncl: binaryStmtInExcl(p, e, d, "$1[(NU)($2)>>3] |=(1U<<($2&7U));$n")
|
of mIncl: binaryStmtInExcl(p, e, d, "$1[(NU)($2)>>3] |=(1U<<($2&7U));$n")
|
||||||
of mExcl: binaryStmtInExcl(p, e, d, "$1[(NU)($2)>>3] &= ~(1U<<($2&7U));$n")
|
of mExcl: binaryStmtInExcl(p, e, d, "$1[(NU)($2)>>3] &= ~(1U<<($2&7U));$n")
|
||||||
of mCard: unaryExprChar(p, e, d, "#cardSet($1, " & $size & ')')
|
of mCard:
|
||||||
|
var a: TLoc
|
||||||
|
initLocExpr(p, e.sons[1], a)
|
||||||
|
putIntoDest(p, d, e, ropecg(p.module, "#cardSet($1, $2)", [rdCharLoc(a), size]))
|
||||||
of mLtSet, mLeSet:
|
of mLtSet, mLeSet:
|
||||||
getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), i) # our counter
|
getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), i) # our counter
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
if d.k == locNone: getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyBool), d)
|
if d.k == locNone: getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyBool), d)
|
||||||
linefmt(p, cpsStmts, lookupOpr[op],
|
if op == mLtSet:
|
||||||
[rdLoc(i), rope(size), rdLoc(d), rdLoc(a), rdLoc(b)])
|
linefmt(p, cpsStmts, lookupOpr[mLtSet],
|
||||||
|
[rdLoc(i), size, rdLoc(d), rdLoc(a), rdLoc(b)])
|
||||||
|
else:
|
||||||
|
linefmt(p, cpsStmts, lookupOpr[mLeSet],
|
||||||
|
[rdLoc(i), size, rdLoc(d), rdLoc(a), rdLoc(b)])
|
||||||
of mEqSet:
|
of mEqSet:
|
||||||
binaryExprChar(p, e, d, "(#nimCmpMem($1, $2, " & $(size) & ")==0)")
|
var a, b: TLoc
|
||||||
|
assert(e.sons[1].typ != nil)
|
||||||
|
assert(e.sons[2].typ != nil)
|
||||||
|
initLocExpr(p, e.sons[1], a)
|
||||||
|
initLocExpr(p, e.sons[2], b)
|
||||||
|
putIntoDest(p, d, e, ropecg(p.module, "(#nimCmpMem($1, $2, $3)==0)", [a.rdCharLoc, b.rdCharLoc, size]))
|
||||||
of mMulSet, mPlusSet, mMinusSet, mSymDiffSet:
|
of mMulSet, mPlusSet, mMinusSet, mSymDiffSet:
|
||||||
# we inline the simple for loop for better code generation:
|
# we inline the simple for loop for better code generation:
|
||||||
getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), i) # our counter
|
getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), i) # our counter
|
||||||
|
|
@ -1833,7 +1855,7 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var tmp: TLoc
|
var tmp: TLoc
|
||||||
tmp.r = "LOC$1.source" % [lbl]
|
tmp.r = "LOC$1.source" % [lbl]
|
||||||
linefmt(p, cpsLocals, "union { $1 source; $2 dest; } LOC$3;$n",
|
linefmt(p, cpsLocals, "union { $1 source; $2 dest; } LOC$3;$n",
|
||||||
getTypeDesc(p.module, e.sons[1].typ), getTypeDesc(p.module, e.typ), lbl)
|
[getTypeDesc(p.module, e.sons[1].typ), getTypeDesc(p.module, e.typ), lbl])
|
||||||
tmp.k = locExpr
|
tmp.k = locExpr
|
||||||
tmp.lode = lodeTyp srct
|
tmp.lode = lodeTyp srct
|
||||||
tmp.storage = OnStack
|
tmp.storage = OnStack
|
||||||
|
|
@ -1859,7 +1881,7 @@ proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
|
||||||
putIntoDest(p, d, lodeTyp dest, ropecg(p.module, "(($1)#$5($2, $3, $4))", [
|
putIntoDest(p, d, lodeTyp dest, ropecg(p.module, "(($1)#$5($2, $3, $4))", [
|
||||||
getTypeDesc(p.module, dest), rdCharLoc(a),
|
getTypeDesc(p.module, dest), rdCharLoc(a),
|
||||||
genLiteral(p, n.sons[1], dest), genLiteral(p, n.sons[2], dest),
|
genLiteral(p, n.sons[1], dest), genLiteral(p, n.sons[2], dest),
|
||||||
rope(magic)]), a.storage)
|
magic]), a.storage)
|
||||||
|
|
||||||
proc genConv(p: BProc, e: PNode, d: var TLoc) =
|
proc genConv(p: BProc, e: PNode, d: var TLoc) =
|
||||||
let destType = e.typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink})
|
let destType = e.typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink})
|
||||||
|
|
@ -1891,11 +1913,11 @@ proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
|
||||||
if a.kind in {nkStrLit..nkTripleStrLit} and a.strVal == "":
|
if a.kind in {nkStrLit..nkTripleStrLit} and a.strVal == "":
|
||||||
initLocExpr(p, e.sons[2], x)
|
initLocExpr(p, e.sons[2], x)
|
||||||
putIntoDest(p, d, e,
|
putIntoDest(p, d, e,
|
||||||
ropecg(p.module, "($1 == 0)", lenExpr(p, x)))
|
ropecg(p.module, "($1 == 0)", [lenExpr(p, x)]))
|
||||||
elif b.kind in {nkStrLit..nkTripleStrLit} and b.strVal == "":
|
elif b.kind in {nkStrLit..nkTripleStrLit} and b.strVal == "":
|
||||||
initLocExpr(p, e.sons[1], x)
|
initLocExpr(p, e.sons[1], x)
|
||||||
putIntoDest(p, d, e,
|
putIntoDest(p, d, e,
|
||||||
ropecg(p.module, "($1 == 0)", lenExpr(p, x)))
|
ropecg(p.module, "($1 == 0)", [lenExpr(p, x)]))
|
||||||
else:
|
else:
|
||||||
binaryExpr(p, e, d, "#eqStrings($1, $2)")
|
binaryExpr(p, e, d, "#eqStrings($1, $2)")
|
||||||
|
|
||||||
|
|
@ -1908,12 +1930,12 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
putIntoDest(p, d, e, ropecg(p.module, "(($4)($2) $1 ($4)($3))",
|
putIntoDest(p, d, e, ropecg(p.module, "(($4)($2) $1 ($4)($3))",
|
||||||
rope(opr[m]), rdLoc(a), rdLoc(b),
|
[opr[m], rdLoc(a), rdLoc(b),
|
||||||
getSimpleTypeDesc(p.module, e[1].typ)))
|
getSimpleTypeDesc(p.module, e[1].typ)]))
|
||||||
if optNaNCheck in p.options:
|
if optNaNCheck in p.options:
|
||||||
linefmt(p, cpsStmts, "#nanCheck($1);$n", rdLoc(d))
|
linefmt(p, cpsStmts, "#nanCheck($1);$n", [rdLoc(d)])
|
||||||
if optInfCheck in p.options:
|
if optInfCheck in p.options:
|
||||||
linefmt(p, cpsStmts, "#infCheck($1);$n", rdLoc(d))
|
linefmt(p, cpsStmts, "#infCheck($1);$n", [rdLoc(d)])
|
||||||
else:
|
else:
|
||||||
binaryArith(p, e, d, m)
|
binaryArith(p, e, d, m)
|
||||||
|
|
||||||
|
|
@ -1925,7 +1947,7 @@ proc genWasMoved(p: BProc; n: PNode) =
|
||||||
initLocExpr(p, n[1].skipAddr, a)
|
initLocExpr(p, n[1].skipAddr, a)
|
||||||
resetLoc(p, a)
|
resetLoc(p, a)
|
||||||
#linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n",
|
#linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n",
|
||||||
# addrLoc(p.config, a), getTypeDesc(p.module, a.t))
|
# [addrLoc(p.config, a), getTypeDesc(p.module, a.t)])
|
||||||
|
|
||||||
proc genMove(p: BProc; n: PNode; d: var TLoc) =
|
proc genMove(p: BProc; n: PNode; d: var TLoc) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
|
|
@ -1976,11 +1998,11 @@ proc genDispose(p: BProc; n: PNode) =
|
||||||
if elemType.destructor != nil:
|
if elemType.destructor != nil:
|
||||||
var destroyCall = newNodeI(nkCall, n.info)
|
var destroyCall = newNodeI(nkCall, n.info)
|
||||||
genStmts(p, destroyCall)
|
genStmts(p, destroyCall)
|
||||||
lineCg(p, cpsStmts, "#nimRawDispose($#)", rdLoc(a))
|
lineCg(p, cpsStmts, ["#nimRawDispose($#)", rdLoc(a)])
|
||||||
else:
|
else:
|
||||||
# ``nimRawDisposeVirtual`` calls the ``finalizer`` which is the same as the
|
# ``nimRawDisposeVirtual`` calls the ``finalizer`` which is the same as the
|
||||||
# destructor, but it uses the runtime type. Afterwards the memory is freed:
|
# destructor, but it uses the runtime type. Afterwards the memory is freed:
|
||||||
lineCg(p, cpsStmts, "#nimDestroyAndDispose($#)", rdLoc(a))
|
lineCg(p, cpsStmts, ["#nimDestroyAndDispose($#)", rdLoc(a)])
|
||||||
|
|
||||||
proc genEnumToStr(p: BProc, e: PNode, d: var TLoc) =
|
proc genEnumToStr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
const ToStringProcSlot = -4
|
const ToStringProcSlot = -4
|
||||||
|
|
@ -2013,11 +2035,11 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
if optOverflowCheck notin p.options: unaryExpr(p, e, d, "($1 - 1)")
|
if optOverflowCheck notin p.options: unaryExpr(p, e, d, "($1 - 1)")
|
||||||
else: unaryExpr(p, e, d, "#subInt($1, 1)")
|
else: unaryExpr(p, e, d, "#subInt($1, 1)")
|
||||||
of mInc, mDec:
|
of mInc, mDec:
|
||||||
const opr: array[mInc..mDec, string] = ["$1 += $2;$n", "$1 -= $2;$n"]
|
const opr: array[mInc..mDec, string] = ["+=", "-="]
|
||||||
const fun64: array[mInc..mDec, string] = ["$# = #addInt64($#, $#);$n",
|
const fun64: array[mInc..mDec, string] = ["addInt64",
|
||||||
"$# = #subInt64($#, $#);$n"]
|
"subInt64"]
|
||||||
const fun: array[mInc..mDec, string] = ["$# = #addInt($#, $#);$n",
|
const fun: array[mInc..mDec, string] = ["addInt",
|
||||||
"$# = #subInt($#, $#);$n"]
|
"subInt"]
|
||||||
let underlying = skipTypes(e.sons[1].typ, {tyGenericInst, tyAlias, tySink, tyVar, tyLent, tyRange})
|
let underlying = skipTypes(e.sons[1].typ, {tyGenericInst, tyAlias, tySink, tyVar, tyLent, tyRange})
|
||||||
if optOverflowCheck notin p.options or underlying.kind in {tyUInt..tyUInt64}:
|
if optOverflowCheck notin p.options or underlying.kind in {tyUInt..tyUInt64}:
|
||||||
binaryStmt(p, e, d, opr[op])
|
binaryStmt(p, e, d, opr[op])
|
||||||
|
|
@ -2031,13 +2053,14 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
let ranged = skipTypes(e.sons[1].typ, {tyGenericInst, tyAlias, tySink, tyVar, tyLent})
|
let ranged = skipTypes(e.sons[1].typ, {tyGenericInst, tyAlias, tySink, tyVar, tyLent})
|
||||||
let res = binaryArithOverflowRaw(p, ranged, a, b,
|
let res = binaryArithOverflowRaw(p, ranged, a, b,
|
||||||
if underlying.kind == tyInt64: fun64[op] else: fun[op])
|
if underlying.kind == tyInt64: fun64[op] else: fun[op])
|
||||||
|
|
||||||
putIntoDest(p, a, e.sons[1], "($#)($#)" % [
|
putIntoDest(p, a, e.sons[1], "($#)($#)" % [
|
||||||
getTypeDesc(p.module, ranged), res])
|
getTypeDesc(p.module, ranged), res])
|
||||||
|
|
||||||
of mConStrStr: genStrConcat(p, e, d)
|
of mConStrStr: genStrConcat(p, e, d)
|
||||||
of mAppendStrCh:
|
of mAppendStrCh:
|
||||||
if p.config.selectedGC == gcDestructors:
|
if p.config.selectedGC == gcDestructors:
|
||||||
binaryStmtAddr(p, e, d, "#nimAddCharV1($1, $2);$n")
|
binaryStmtAddr(p, e, d, "nimAddCharV1")
|
||||||
else:
|
else:
|
||||||
var dest, b, call: TLoc
|
var dest, b, call: TLoc
|
||||||
initLoc(call, locCall, e, OnHeap)
|
initLoc(call, locCall, e, OnHeap)
|
||||||
|
|
@ -2095,12 +2118,10 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
var a, tmp: TLoc
|
var a, tmp: TLoc
|
||||||
initLocExpr(p, e[1], a)
|
initLocExpr(p, e[1], a)
|
||||||
getIntTemp(p, tmp)
|
getIntTemp(p, tmp)
|
||||||
var frmt: FormatStr
|
|
||||||
if not p.module.compileToCpp:
|
if not p.module.compileToCpp:
|
||||||
frmt = "$1 = $2->Sup.len;$n"
|
lineCg(p, cpsStmts, "$1 = $2->Sup.len;$n", [tmp.r, rdLoc(a)])
|
||||||
else:
|
else:
|
||||||
frmt = "$1 = $2->len;$n"
|
lineCg(p, cpsStmts, "$1 = $2->len;$n", [tmp.r, rdLoc(a)])
|
||||||
lineCg(p, cpsStmts, frmt, tmp.r, rdLoc(a))
|
|
||||||
putIntoDest(p, d, e, tmp.r)
|
putIntoDest(p, d, e, tmp.r)
|
||||||
of mGCref: unaryStmt(p, e, d, "if ($1) { #nimGCref($1); }$n")
|
of mGCref: unaryStmt(p, e, d, "if ($1) { #nimGCref($1); }$n")
|
||||||
of mGCunref: unaryStmt(p, e, d, "if ($1) { #nimGCunref($1); }$n")
|
of mGCunref: unaryStmt(p, e, d, "if ($1) { #nimGCunref($1); }$n")
|
||||||
|
|
@ -2252,11 +2273,11 @@ proc genClosure(p: BProc, n: PNode, d: var TLoc) =
|
||||||
when false:
|
when false:
|
||||||
if d.k != locNone:
|
if d.k != locNone:
|
||||||
linefmt(p, cpsStmts, "$1.ClP_0 = $2; $1.ClE_0 = $3;$n",
|
linefmt(p, cpsStmts, "$1.ClP_0 = $2; $1.ClE_0 = $3;$n",
|
||||||
d.rdLoc, a.rdLoc, b.rdLoc)
|
[d.rdLoc, a.rdLoc, b.rdLoc])
|
||||||
else:
|
else:
|
||||||
getTemp(p, n.typ, tmp)
|
getTemp(p, n.typ, tmp)
|
||||||
linefmt(p, cpsStmts, "$1.ClP_0 = $2; $1.ClE_0 = $3;$n",
|
linefmt(p, cpsStmts, "$1.ClP_0 = $2; $1.ClE_0 = $3;$n",
|
||||||
tmp.rdLoc, a.rdLoc, b.rdLoc)
|
[tmp.rdLoc, a.rdLoc, b.rdLoc])
|
||||||
putLocIntoDest(p, d, tmp)
|
putLocIntoDest(p, d, tmp)
|
||||||
|
|
||||||
proc genArrayConstr(p: BProc, n: PNode, d: var TLoc) =
|
proc genArrayConstr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
|
|
@ -2327,10 +2348,10 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
genTypeInfo(p.module, dest, n.info)
|
genTypeInfo(p.module, dest, n.info)
|
||||||
if nilCheck != nil:
|
if nilCheck != nil:
|
||||||
linefmt(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n",
|
linefmt(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n",
|
||||||
nilCheck, r, checkFor)
|
[nilCheck, r, checkFor])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#chckObj($1.m_type, $2);$n",
|
linefmt(p, cpsStmts, "#chckObj($1.m_type, $2);$n",
|
||||||
r, checkFor)
|
[r, checkFor])
|
||||||
if n.sons[0].typ.kind != tyObject:
|
if n.sons[0].typ.kind != tyObject:
|
||||||
putIntoDest(p, d, n,
|
putIntoDest(p, d, n,
|
||||||
"(($1) ($2))" % [getTypeDesc(p.module, n.typ), rdLoc(a)], a.storage)
|
"(($1) ($2))" % [getTypeDesc(p.module, n.typ), rdLoc(a)], a.storage)
|
||||||
|
|
@ -2367,7 +2388,7 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
# this by ensuring the destination is also a pointer:
|
# this by ensuring the destination is also a pointer:
|
||||||
if d.k == locNone and skipTypes(n.typ, abstractInst).kind in {tyRef, tyPtr, tyVar, tyLent}:
|
if d.k == locNone and skipTypes(n.typ, abstractInst).kind in {tyRef, tyPtr, tyVar, tyLent}:
|
||||||
getTemp(p, n.typ, d)
|
getTemp(p, n.typ, d)
|
||||||
linefmt(p, cpsStmts, "$1 = &$2;$n", rdLoc(d), r)
|
linefmt(p, cpsStmts, "$1 = &$2;$n", [rdLoc(d), r])
|
||||||
else:
|
else:
|
||||||
r = "&" & r
|
r = "&" & r
|
||||||
putIntoDest(p, d, n, r, a.storage)
|
putIntoDest(p, d, n, r, a.storage)
|
||||||
|
|
@ -2709,7 +2730,7 @@ proc genConstSeq(p: BProc, n: PNode, t: PType): Rope =
|
||||||
" #TGenericSeq Sup;$n" &
|
" #TGenericSeq Sup;$n" &
|
||||||
" $1 data[$2];$n" &
|
" $1 data[$2];$n" &
|
||||||
"} $3 = $4;$n", [
|
"} $3 = $4;$n", [
|
||||||
getTypeDesc(p.module, base), n.len.rope, result, data])
|
getTypeDesc(p.module, base), n.len, result, data])
|
||||||
|
|
||||||
result = "(($1)&$2)" % [getTypeDesc(p.module, t), result]
|
result = "(($1)&$2)" % [getTypeDesc(p.module, t), result]
|
||||||
|
|
||||||
|
|
@ -2727,7 +2748,7 @@ proc genConstSeqV2(p: BProc, n: PNode, t: PType): Rope =
|
||||||
"static const struct {$n" &
|
"static const struct {$n" &
|
||||||
" NI cap; void* allocator; $1 data[$2];$n" &
|
" NI cap; void* allocator; $1 data[$2];$n" &
|
||||||
"} $3 = {$2, NIM_NIL, $4};$n", [
|
"} $3 = {$2, NIM_NIL, $4};$n", [
|
||||||
getTypeDesc(p.module, base), rope(len(n)), payload, data])
|
getTypeDesc(p.module, base), len(n), payload, data])
|
||||||
result = "{$1, ($2*)&$3}" % [rope(len(n)), getSeqPayloadType(p.module, t), payload]
|
result = "{$1, ($2*)&$3}" % [rope(len(n)), getSeqPayloadType(p.module, t), payload]
|
||||||
|
|
||||||
proc genConstExpr(p: BProc, n: PNode): Rope =
|
proc genConstExpr(p: BProc, n: PNode): Rope =
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ proc genStringLiteralV1(m: BModule; n: PNode): Rope =
|
||||||
[genStringLiteralDataOnlyV1(m, n.strVal)])
|
[genStringLiteralDataOnlyV1(m, n.strVal)])
|
||||||
else:
|
else:
|
||||||
result = ropecg(m, "((#NimStringDesc*) &$1$2)",
|
result = ropecg(m, "((#NimStringDesc*) &$1$2)",
|
||||||
[m.tmpBase, rope(id)])
|
[m.tmpBase, id])
|
||||||
|
|
||||||
# ------ Version 2: destructor based strings and seqs -----------------------
|
# ------ Version 2: destructor based strings and seqs -----------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,19 @@ proc inExceptBlockLen(p: BProc): int =
|
||||||
for x in p.nestedTryStmts:
|
for x in p.nestedTryStmts:
|
||||||
if x.inExcept: result.inc
|
if x.inExcept: result.inc
|
||||||
|
|
||||||
proc startBlock(p: BProc, start: FormatStr = "{$n",
|
proc startBlockInternal(p: BProc): int {.discardable.} =
|
||||||
args: varargs[Rope]): int {.discardable.}
|
inc(p.labels)
|
||||||
|
result = len(p.blocks)
|
||||||
|
setLen(p.blocks, result + 1)
|
||||||
|
p.blocks[result].id = p.labels
|
||||||
|
p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16
|
||||||
|
p.blocks[result].nestedExceptStmts = p.inExceptBlockLen.int16
|
||||||
|
|
||||||
|
template startBlock(p: BProc, start: FormatStr = "{$n",
|
||||||
|
args: varargs[Rope]): int =
|
||||||
|
lineCg(p, cpsStmts, start, args)
|
||||||
|
startBlockInternal(p)
|
||||||
|
|
||||||
proc endBlock(p: BProc)
|
proc endBlock(p: BProc)
|
||||||
|
|
||||||
proc genVarTuple(p: BProc, n: PNode) =
|
proc genVarTuple(p: BProc, n: PNode) =
|
||||||
|
|
@ -70,7 +81,7 @@ proc genVarTuple(p: BProc, n: PNode) =
|
||||||
|
|
||||||
if forHcr:
|
if forHcr:
|
||||||
# check with the boolean if the initializing code for the tuple should be ran
|
# check with the boolean if the initializing code for the tuple should be ran
|
||||||
lineCg(p, cpsStmts, "if ($1)$n", hcrCond)
|
lineCg(p, cpsStmts, "if ($1)$n", [hcrCond])
|
||||||
startBlock(p)
|
startBlock(p)
|
||||||
defer:
|
defer:
|
||||||
if forHcr:
|
if forHcr:
|
||||||
|
|
@ -80,10 +91,10 @@ proc genVarTuple(p: BProc, n: PNode) =
|
||||||
# insert the registration of the globals for the different parts of the tuple at the
|
# insert the registration of the globals for the different parts of the tuple at the
|
||||||
# start of the current scope (after they have been iterated) and init a boolean to
|
# start of the current scope (after they have been iterated) and init a boolean to
|
||||||
# check if any of them is newly introduced and the initializing code has to be ran
|
# check if any of them is newly introduced and the initializing code has to be ran
|
||||||
lineCg(p, cpsLocals, "NIM_BOOL $1 = NIM_FALSE;$n", hcrCond)
|
lineCg(p, cpsLocals, "NIM_BOOL $1 = NIM_FALSE;$n", [hcrCond])
|
||||||
for curr in hcrGlobals:
|
for curr in hcrGlobals:
|
||||||
lineCg(p, cpsLocals, "$1 |= hcrRegisterGlobal($4, \"$2\", sizeof($3), $5, (void**)&$2);$N",
|
lineCg(p, cpsLocals, "$1 |= hcrRegisterGlobal($4, \"$2\", sizeof($3), $5, (void**)&$2);$N",
|
||||||
hcrCond, curr.loc.r, rdLoc(curr.loc), getModuleDllPath(p.module, n.sons[0].sym), curr.tp)
|
[hcrCond, curr.loc.r, rdLoc(curr.loc), getModuleDllPath(p.module, n.sons[0].sym), curr.tp])
|
||||||
|
|
||||||
genLineDir(p, n)
|
genLineDir(p, n)
|
||||||
initLocExpr(p, n.sons[L-1], tup)
|
initLocExpr(p, n.sons[L-1], tup)
|
||||||
|
|
@ -130,16 +141,6 @@ proc loadInto(p: BProc, le, ri: PNode, a: var TLoc) {.inline.} =
|
||||||
else:
|
else:
|
||||||
expr(p, ri, a)
|
expr(p, ri, a)
|
||||||
|
|
||||||
proc startBlock(p: BProc, start: FormatStr = "{$n",
|
|
||||||
args: varargs[Rope]): int {.discardable.} =
|
|
||||||
lineCg(p, cpsStmts, start, args)
|
|
||||||
inc(p.labels)
|
|
||||||
result = len(p.blocks)
|
|
||||||
setLen(p.blocks, result + 1)
|
|
||||||
p.blocks[result].id = p.labels
|
|
||||||
p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16
|
|
||||||
p.blocks[result].nestedExceptStmts = p.inExceptBlockLen.int16
|
|
||||||
|
|
||||||
proc assignLabel(b: var TBlock): Rope {.inline.} =
|
proc assignLabel(b: var TBlock): Rope {.inline.} =
|
||||||
b.label = "LA" & b.id.rope
|
b.label = "LA" & b.id.rope
|
||||||
result = b.label
|
result = b.label
|
||||||
|
|
@ -192,9 +193,9 @@ proc genState(p: BProc, n: PNode) =
|
||||||
let n0 = n[0]
|
let n0 = n[0]
|
||||||
if n0.kind == nkIntLit:
|
if n0.kind == nkIntLit:
|
||||||
let idx = n.sons[0].intVal
|
let idx = n.sons[0].intVal
|
||||||
linefmt(p, cpsStmts, "STATE$1: ;$n", idx.rope)
|
linefmt(p, cpsStmts, "STATE$1: ;$n", [idx])
|
||||||
elif n0.kind == nkStrLit:
|
elif n0.kind == nkStrLit:
|
||||||
linefmt(p, cpsStmts, "$1: ;$n", n0.strVal.rope)
|
linefmt(p, cpsStmts, "$1: ;$n", [n0.strVal])
|
||||||
|
|
||||||
proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
||||||
# Called by return and break stmts.
|
# Called by return and break stmts.
|
||||||
|
|
@ -207,7 +208,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
||||||
if not p.module.compileToCpp or optNoCppExceptions in p.config.globalOptions:
|
if not p.module.compileToCpp or optNoCppExceptions in p.config.globalOptions:
|
||||||
# Pop safe points generated by try
|
# Pop safe points generated by try
|
||||||
if not tryStmt.inExcept and not isDefined(p.config, "nimQuirky"):
|
if not tryStmt.inExcept and not isDefined(p.config, "nimQuirky"):
|
||||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
linefmt(p, cpsStmts, "#popSafePoint();$n", [])
|
||||||
|
|
||||||
# Pop this try-stmt of the list of nested trys
|
# Pop this try-stmt of the list of nested trys
|
||||||
# so we don't infinite recurse on it in the next step.
|
# so we don't infinite recurse on it in the next step.
|
||||||
|
|
@ -227,7 +228,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
||||||
# Pop exceptions that was handled by the
|
# Pop exceptions that was handled by the
|
||||||
# except-blocks we are in
|
# except-blocks we are in
|
||||||
for i in countdown(howManyExcepts-1, 0):
|
for i in countdown(howManyExcepts-1, 0):
|
||||||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
linefmt(p, cpsStmts, "#popCurrentException();$n", [])
|
||||||
|
|
||||||
proc genGotoState(p: BProc, n: PNode) =
|
proc genGotoState(p: BProc, n: PNode) =
|
||||||
# we resist the temptation to translate it into duff's device as it later
|
# we resist the temptation to translate it into duff's device as it later
|
||||||
|
|
@ -352,7 +353,7 @@ proc genSingleVar(p: BProc, a: PNode) =
|
||||||
# put it in the locals section - mainly because of loops which
|
# put it in the locals section - mainly because of loops which
|
||||||
# use the var in a call to resetLoc() in the statements section
|
# use the var in a call to resetLoc() in the statements section
|
||||||
lineCg(targetProc, cpsLocals, "hcrRegisterGlobal($3, \"$1\", sizeof($2), $4, (void**)&$1);$n",
|
lineCg(targetProc, cpsLocals, "hcrRegisterGlobal($3, \"$1\", sizeof($2), $4, (void**)&$1);$n",
|
||||||
v.loc.r, rdLoc(v.loc), getModuleDllPath(p.module, v), traverseProc)
|
[v.loc.r, rdLoc(v.loc), getModuleDllPath(p.module, v), traverseProc])
|
||||||
# nothing special left to do later on - let's avoid closing and reopening blocks
|
# nothing special left to do later on - let's avoid closing and reopening blocks
|
||||||
forHcr = false
|
forHcr = false
|
||||||
|
|
||||||
|
|
@ -361,7 +362,7 @@ proc genSingleVar(p: BProc, a: PNode) =
|
||||||
# be able to re-run it but without the top level code - just the init of globals
|
# be able to re-run it but without the top level code - just the init of globals
|
||||||
if forHcr:
|
if forHcr:
|
||||||
lineCg(targetProc, cpsStmts, "if (hcrRegisterGlobal($3, \"$1\", sizeof($2), $4, (void**)&$1))$N",
|
lineCg(targetProc, cpsStmts, "if (hcrRegisterGlobal($3, \"$1\", sizeof($2), $4, (void**)&$1))$N",
|
||||||
v.loc.r, rdLoc(v.loc), getModuleDllPath(p.module, v), traverseProc)
|
[v.loc.r, rdLoc(v.loc), getModuleDllPath(p.module, v), traverseProc])
|
||||||
startBlock(targetProc)
|
startBlock(targetProc)
|
||||||
defer:
|
defer:
|
||||||
if forHcr:
|
if forHcr:
|
||||||
|
|
@ -452,7 +453,7 @@ proc genReturnStmt(p: BProc, t: PNode) =
|
||||||
# If we're in a finally block, and we came here by exception
|
# If we're in a finally block, and we came here by exception
|
||||||
# consume it before we return.
|
# consume it before we return.
|
||||||
var safePoint = p.finallySafePoints[p.finallySafePoints.len-1]
|
var safePoint = p.finallySafePoints[p.finallySafePoints.len-1]
|
||||||
linefmt(p, cpsStmts, "if ($1.status != 0) #popCurrentException();$n", safePoint)
|
linefmt(p, cpsStmts, "if ($1.status != 0) #popCurrentException();$n", [safePoint])
|
||||||
lineF(p, cpsStmts, "goto BeforeRet_;$n", [])
|
lineF(p, cpsStmts, "goto BeforeRet_;$n", [])
|
||||||
|
|
||||||
proc genGotoForCase(p: BProc; caseStmt: PNode) =
|
proc genGotoForCase(p: BProc; caseStmt: PNode) =
|
||||||
|
|
@ -589,7 +590,7 @@ proc genWhileStmt(p: BProc, t: PNode) =
|
||||||
|
|
||||||
if optProfiler in p.options:
|
if optProfiler in p.options:
|
||||||
# invoke at loop body exit:
|
# invoke at loop body exit:
|
||||||
linefmt(p, cpsStmts, "#nimProfile();$n")
|
linefmt(p, cpsStmts, "#nimProfile();$n", [])
|
||||||
endBlock(p)
|
endBlock(p)
|
||||||
|
|
||||||
dec(p.withinLoop)
|
dec(p.withinLoop)
|
||||||
|
|
@ -690,7 +691,7 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
||||||
lineCg(p, cpsStmts, "#raiseExceptionEx((#Exception*)$1, $2, $3, $4, $5);$n",
|
lineCg(p, cpsStmts, "#raiseExceptionEx((#Exception*)$1, $2, $3, $4, $5);$n",
|
||||||
[e, makeCString(typ.sym.name.s),
|
[e, makeCString(typ.sym.name.s),
|
||||||
makeCString(if p.prc != nil: p.prc.name.s else: p.module.module.name.s),
|
makeCString(if p.prc != nil: p.prc.name.s else: p.module.module.name.s),
|
||||||
makeCString(toFileName(p.config, t.info)), rope(toLinenumber(t.info))])
|
makeCString(toFileName(p.config, t.info)), toLinenumber(t.info)])
|
||||||
if optNimV2 in p.config.globalOptions:
|
if optNimV2 in p.config.globalOptions:
|
||||||
lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [e])
|
lineCg(p, cpsStmts, "$1 = NIM_NIL;$n", [e])
|
||||||
else:
|
else:
|
||||||
|
|
@ -699,9 +700,9 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
||||||
if p.module.compileToCpp and optNoCppExceptions notin p.config.globalOptions:
|
if p.module.compileToCpp and optNoCppExceptions notin p.config.globalOptions:
|
||||||
line(p, cpsStmts, ~"throw;$n")
|
line(p, cpsStmts, ~"throw;$n")
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#reraiseException();$n")
|
linefmt(p, cpsStmts, "#reraiseException();$n", [])
|
||||||
|
|
||||||
proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
|
template genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
|
||||||
rangeFormat, eqFormat: FormatStr, labl: TLabel) =
|
rangeFormat, eqFormat: FormatStr, labl: TLabel) =
|
||||||
var
|
var
|
||||||
x, y: TLoc
|
x, y: TLoc
|
||||||
|
|
@ -731,10 +732,11 @@ proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc,
|
||||||
exprBlock(p, t.sons[i].sons[0], d)
|
exprBlock(p, t.sons[i].sons[0], d)
|
||||||
result = lend
|
result = lend
|
||||||
|
|
||||||
proc genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
|
template genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
|
||||||
rangeFormat, eqFormat: FormatStr,
|
rangeFormat, eqFormat: FormatStr,
|
||||||
until: int, a: TLoc): TLabel =
|
until: int, a: TLoc): TLabel =
|
||||||
# generate a C-if statement for a Nim case statement
|
# generate a C-if statement for a Nim case statement
|
||||||
|
var res: TLabel
|
||||||
var labId = p.labels
|
var labId = p.labels
|
||||||
for i in 1..until:
|
for i in 1..until:
|
||||||
inc(p.labels)
|
inc(p.labels)
|
||||||
|
|
@ -747,12 +749,13 @@ proc genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
|
||||||
inc(p.labels)
|
inc(p.labels)
|
||||||
var gotoTarget = p.labels
|
var gotoTarget = p.labels
|
||||||
lineF(p, cpsStmts, "goto LA$1_;$n", [rope(gotoTarget)])
|
lineF(p, cpsStmts, "goto LA$1_;$n", [rope(gotoTarget)])
|
||||||
result = genCaseSecondPass(p, t, d, labId, until)
|
res = genCaseSecondPass(p, t, d, labId, until)
|
||||||
lineF(p, cpsStmts, "LA$1_: ;$n", [rope(gotoTarget)])
|
lineF(p, cpsStmts, "LA$1_: ;$n", [rope(gotoTarget)])
|
||||||
else:
|
else:
|
||||||
result = genCaseSecondPass(p, t, d, labId, until)
|
res = genCaseSecondPass(p, t, d, labId, until)
|
||||||
|
res
|
||||||
|
|
||||||
proc genCaseGeneric(p: BProc, t: PNode, d: var TLoc,
|
template genCaseGeneric(p: BProc, t: PNode, d: var TLoc,
|
||||||
rangeFormat, eqFormat: FormatStr) =
|
rangeFormat, eqFormat: FormatStr) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, t.sons[0], a)
|
initLocExpr(p, t.sons[0], a)
|
||||||
|
|
@ -793,7 +796,7 @@ proc genStringCase(p: BProc, t: PNode, d: var TLoc) =
|
||||||
# but we reserved a label, which we use later
|
# but we reserved a label, which we use later
|
||||||
discard
|
discard
|
||||||
linefmt(p, cpsStmts, "switch (#hashString($1) & $2) {$n",
|
linefmt(p, cpsStmts, "switch (#hashString($1) & $2) {$n",
|
||||||
rdLoc(a), rope(bitMask))
|
[rdLoc(a), bitMask])
|
||||||
for j in countup(0, high(branches)):
|
for j in countup(0, high(branches)):
|
||||||
if branches[j] != nil:
|
if branches[j] != nil:
|
||||||
lineF(p, cpsStmts, "case $1: $n$2break;$n",
|
lineF(p, cpsStmts, "case $1: $n$2break;$n",
|
||||||
|
|
@ -895,7 +898,7 @@ proc genRestoreFrameAfterException(p: BProc) =
|
||||||
p.hasCurFramePointer = true
|
p.hasCurFramePointer = true
|
||||||
p.procSec(cpsLocals).add(ropecg(p.module, "\tTFrame* _nimCurFrame;$n", []))
|
p.procSec(cpsLocals).add(ropecg(p.module, "\tTFrame* _nimCurFrame;$n", []))
|
||||||
p.procSec(cpsInit).add(ropecg(p.module, "\t_nimCurFrame = #getFrame();$n", []))
|
p.procSec(cpsInit).add(ropecg(p.module, "\t_nimCurFrame = #getFrame();$n", []))
|
||||||
linefmt(p, cpsStmts, "#setFrame(_nimCurFrame);$n")
|
linefmt(p, cpsStmts, "#setFrame(_nimCurFrame);$n", [])
|
||||||
|
|
||||||
proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
||||||
# code to generate:
|
# code to generate:
|
||||||
|
|
@ -1006,25 +1009,25 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
||||||
var safePoint: Rope
|
var safePoint: Rope
|
||||||
if not quirkyExceptions:
|
if not quirkyExceptions:
|
||||||
safePoint = getTempName(p.module)
|
safePoint = getTempName(p.module)
|
||||||
linefmt(p, cpsLocals, "#TSafePoint $1;$n", safePoint)
|
linefmt(p, cpsLocals, "#TSafePoint $1;$n", [safePoint])
|
||||||
linefmt(p, cpsStmts, "#pushSafePoint(&$1);$n", safePoint)
|
linefmt(p, cpsStmts, "#pushSafePoint(&$1);$n", [safePoint])
|
||||||
if isDefined(p.config, "nimStdSetjmp"):
|
if isDefined(p.config, "nimStdSetjmp"):
|
||||||
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
|
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint])
|
||||||
elif isDefined(p.config, "nimSigSetjmp"):
|
elif isDefined(p.config, "nimSigSetjmp"):
|
||||||
linefmt(p, cpsStmts, "$1.status = sigsetjmp($1.context, 0);$n", safePoint)
|
linefmt(p, cpsStmts, "$1.status = sigsetjmp($1.context, 0);$n", [safePoint])
|
||||||
elif isDefined(p.config, "nimRawSetjmp"):
|
elif isDefined(p.config, "nimRawSetjmp"):
|
||||||
linefmt(p, cpsStmts, "$1.status = _setjmp($1.context);$n", safePoint)
|
linefmt(p, cpsStmts, "$1.status = _setjmp($1.context);$n", [safePoint])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
|
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint])
|
||||||
startBlock(p, "if ($1.status == 0) {$n", [safePoint])
|
startBlock(p, "if ($1.status == 0) {$n", [safePoint])
|
||||||
var length = sonsLen(t)
|
var length = sonsLen(t)
|
||||||
add(p.nestedTryStmts, (t, false))
|
add(p.nestedTryStmts, (t, false))
|
||||||
expr(p, t.sons[0], d)
|
expr(p, t.sons[0], d)
|
||||||
if not quirkyExceptions:
|
if not quirkyExceptions:
|
||||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
linefmt(p, cpsStmts, "#popSafePoint();$n", [])
|
||||||
endBlock(p)
|
endBlock(p)
|
||||||
startBlock(p, "else {$n")
|
startBlock(p, "else {$n")
|
||||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
linefmt(p, cpsStmts, "#popSafePoint();$n", [])
|
||||||
genRestoreFrameAfterException(p)
|
genRestoreFrameAfterException(p)
|
||||||
elif 1 < length and t.sons[1].kind == nkExceptBranch:
|
elif 1 < length and t.sons[1].kind == nkExceptBranch:
|
||||||
startBlock(p, "if (#getCurrentException()) {$n")
|
startBlock(p, "if (#getCurrentException()) {$n")
|
||||||
|
|
@ -1041,30 +1044,28 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
||||||
if i > 1: lineF(p, cpsStmts, "else", [])
|
if i > 1: lineF(p, cpsStmts, "else", [])
|
||||||
startBlock(p)
|
startBlock(p)
|
||||||
if not quirkyExceptions:
|
if not quirkyExceptions:
|
||||||
linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
|
linefmt(p, cpsStmts, "$1.status = 0;$n", [safePoint])
|
||||||
expr(p, t.sons[i].sons[0], d)
|
expr(p, t.sons[i].sons[0], d)
|
||||||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
linefmt(p, cpsStmts, "#popCurrentException();$n", [])
|
||||||
endBlock(p)
|
endBlock(p)
|
||||||
else:
|
else:
|
||||||
var orExpr: Rope = nil
|
var orExpr: Rope = nil
|
||||||
for j in countup(0, blen - 2):
|
for j in countup(0, blen - 2):
|
||||||
assert(t.sons[i].sons[j].kind == nkType)
|
assert(t.sons[i].sons[j].kind == nkType)
|
||||||
if orExpr != nil: add(orExpr, "||")
|
if orExpr != nil: add(orExpr, "||")
|
||||||
let isObjFormat = if not p.module.compileToCpp:
|
|
||||||
"#isObj(#getCurrentException()->Sup.m_type, $1)"
|
|
||||||
else: "#isObj(#getCurrentException()->m_type, $1)"
|
|
||||||
|
|
||||||
let checkFor = if optNimV2 in p.config.globalOptions:
|
let checkFor = if optNimV2 in p.config.globalOptions:
|
||||||
genTypeInfo2Name(p.module, t[i][j].typ)
|
genTypeInfo2Name(p.module, t[i][j].typ)
|
||||||
else:
|
else:
|
||||||
genTypeInfo(p.module, t[i][j].typ, t[i][j].info)
|
genTypeInfo(p.module, t[i][j].typ, t[i][j].info)
|
||||||
appcg(p.module, orExpr, isObjFormat, [checkFor])
|
let memberName = if p.module.compileToCpp: "m_type" else: "Sup.m_type"
|
||||||
|
appcg(p.module, orExpr, "#isObj(#getCurrentException()->$1, $2)", [memberName, checkFor])
|
||||||
|
|
||||||
if i > 1: line(p, cpsStmts, "else ")
|
if i > 1: line(p, cpsStmts, "else ")
|
||||||
startBlock(p, "if ($1) {$n", [orExpr])
|
startBlock(p, "if ($1) {$n", [orExpr])
|
||||||
if not quirkyExceptions:
|
if not quirkyExceptions:
|
||||||
linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
|
linefmt(p, cpsStmts, "$1.status = 0;$n", [safePoint])
|
||||||
expr(p, t.sons[i].sons[blen-1], d)
|
expr(p, t.sons[i].sons[blen-1], d)
|
||||||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
linefmt(p, cpsStmts, "#popCurrentException();$n", [])
|
||||||
endBlock(p)
|
endBlock(p)
|
||||||
inc(i)
|
inc(i)
|
||||||
discard pop(p.nestedTryStmts)
|
discard pop(p.nestedTryStmts)
|
||||||
|
|
@ -1074,7 +1075,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
||||||
genSimpleBlock(p, t.sons[i].sons[0])
|
genSimpleBlock(p, t.sons[i].sons[0])
|
||||||
discard pop(p.finallySafePoints)
|
discard pop(p.finallySafePoints)
|
||||||
if not quirkyExceptions:
|
if not quirkyExceptions:
|
||||||
linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", safePoint)
|
linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint])
|
||||||
|
|
||||||
proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): Rope =
|
proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): Rope =
|
||||||
var res = ""
|
var res = ""
|
||||||
|
|
@ -1169,7 +1170,7 @@ proc genBreakPoint(p: BProc, t: PNode) =
|
||||||
genLineDir(p, t) # BUGFIX
|
genLineDir(p, t) # BUGFIX
|
||||||
appcg(p.module, p.module.g.breakpoints,
|
appcg(p.module, p.module.g.breakpoints,
|
||||||
"#dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [
|
"#dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [
|
||||||
rope(toLinenumber(t.info)), makeCString(toFilename(p.config, t.info)),
|
toLinenumber(t.info), makeCString(toFilename(p.config, t.info)),
|
||||||
makeCString(name)])
|
makeCString(name)])
|
||||||
|
|
||||||
proc genWatchpoint(p: BProc, n: PNode) =
|
proc genWatchpoint(p: BProc, n: PNode) =
|
||||||
|
|
@ -1212,7 +1213,7 @@ proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType,
|
||||||
var L = lengthOrd(p.config, field.typ)
|
var L = lengthOrd(p.config, field.typ)
|
||||||
if not containsOrIncl(p.module.declaredThings, field.id):
|
if not containsOrIncl(p.module.declaredThings, field.id):
|
||||||
appcg(p.module, cfsVars, "extern $1",
|
appcg(p.module, cfsVars, "extern $1",
|
||||||
discriminatorTableDecl(p.module, t, field))
|
[discriminatorTableDecl(p.module, t, field)])
|
||||||
lineCg(p, cpsStmts,
|
lineCg(p, cpsStmts,
|
||||||
"#FieldDiscriminantCheck((NI)(NU)($1), (NI)(NU)($2), $3, $4);$n",
|
"#FieldDiscriminantCheck((NI)(NU)($1), (NI)(NU)($2), $3, $4);$n",
|
||||||
[rdLoc(a), rdLoc(tmp), discriminatorTableName(p.module, t, field),
|
[rdLoc(a), rdLoc(tmp), discriminatorTableName(p.module, t, field),
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ proc accessThreadLocalVar(p: BProc, s: PSym) =
|
||||||
incl p.module.flags, usesThreadVars
|
incl p.module.flags, usesThreadVars
|
||||||
addf(p.procSec(cpsLocals), "\tNimThreadVars* NimTV_;$n", [])
|
addf(p.procSec(cpsLocals), "\tNimThreadVars* NimTV_;$n", [])
|
||||||
add(p.procSec(cpsInit),
|
add(p.procSec(cpsInit),
|
||||||
ropecg(p.module, "\tNimTV_ = (NimThreadVars*) #GetThreadLocalVars();$n"))
|
ropecg(p.module, "\tNimTV_ = (NimThreadVars*) #GetThreadLocalVars();$n", []))
|
||||||
|
|
||||||
proc declareThreadVar(m: BModule, s: PSym, isExtern: bool) =
|
proc declareThreadVar(m: BModule, s: PSym, isExtern: bool) =
|
||||||
if emulatedThreadVars(m.config):
|
if emulatedThreadVars(m.config):
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@ type
|
||||||
p: BProc
|
p: BProc
|
||||||
visitorFrmt: string
|
visitorFrmt: string
|
||||||
|
|
||||||
|
const
|
||||||
|
visitorFrmt = "#nimGCvisit((void*)$1, $2);$n"
|
||||||
|
|
||||||
proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType)
|
proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType)
|
||||||
proc genCaseRange(p: BProc, branch: PNode)
|
proc genCaseRange(p: BProc, branch: PNode)
|
||||||
proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false)
|
proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false)
|
||||||
|
|
@ -75,9 +78,9 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType) =
|
||||||
getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo(), tyInt), i)
|
getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo(), tyInt), i)
|
||||||
let oldCode = p.s(cpsStmts)
|
let oldCode = p.s(cpsStmts)
|
||||||
linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
|
linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
|
||||||
i.r, arraySize.rope)
|
[i.r, arraySize])
|
||||||
let oldLen = p.s(cpsStmts).len
|
let oldLen = p.s(cpsStmts).len
|
||||||
genTraverseProc(c, ropecg(c.p.module, "$1[$2]", accessor, i.r), typ.sons[1])
|
genTraverseProc(c, ropecg(c.p.module, "$1[$2]", [accessor, i.r]), typ.sons[1])
|
||||||
if p.s(cpsStmts).len == oldLen:
|
if p.s(cpsStmts).len == oldLen:
|
||||||
# do not emit dummy long loops for faster debug builds:
|
# do not emit dummy long loops for faster debug builds:
|
||||||
p.s(cpsStmts) = oldCode
|
p.s(cpsStmts) = oldCode
|
||||||
|
|
@ -92,22 +95,22 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType) =
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
let typ = getUniqueType(typ)
|
let typ = getUniqueType(typ)
|
||||||
for i in countup(0, sonsLen(typ) - 1):
|
for i in countup(0, sonsLen(typ) - 1):
|
||||||
genTraverseProc(c, ropecg(c.p.module, "$1.Field$2", accessor, i.rope), typ.sons[i])
|
genTraverseProc(c, ropecg(c.p.module, "$1.Field$2", [accessor, i]), typ.sons[i])
|
||||||
of tyRef:
|
of tyRef:
|
||||||
lineCg(p, cpsStmts, c.visitorFrmt, accessor)
|
lineCg(p, cpsStmts, visitorFrmt, [accessor, c.visitorFrmt])
|
||||||
of tySequence:
|
of tySequence:
|
||||||
if tfHasAsgn notin typ.flags:
|
if tfHasAsgn notin typ.flags:
|
||||||
lineCg(p, cpsStmts, c.visitorFrmt, accessor)
|
lineCg(p, cpsStmts, visitorFrmt, [accessor, c.visitorFrmt])
|
||||||
elif containsGarbageCollectedRef(typ.lastSon):
|
elif containsGarbageCollectedRef(typ.lastSon):
|
||||||
# destructor based seqs are themselves not traced but their data is, if
|
# destructor based seqs are themselves not traced but their data is, if
|
||||||
# they contain a GC'ed type:
|
# they contain a GC'ed type:
|
||||||
genTraverseProcSeq(c, accessor, typ)
|
genTraverseProcSeq(c, accessor, typ)
|
||||||
of tyString:
|
of tyString:
|
||||||
if tfHasAsgn notin typ.flags:
|
if tfHasAsgn notin typ.flags:
|
||||||
lineCg(p, cpsStmts, c.visitorFrmt, accessor)
|
lineCg(p, cpsStmts, visitorFrmt, [accessor, c.visitorFrmt])
|
||||||
of tyProc:
|
of tyProc:
|
||||||
if typ.callConv == ccClosure:
|
if typ.callConv == ccClosure:
|
||||||
lineCg(p, cpsStmts, c.visitorFrmt, ropecg(c.p.module, "$1.ClE_0", accessor))
|
lineCg(p, cpsStmts, visitorFrmt, [ropecg(c.p.module, "$1.ClE_0", [accessor]), c.visitorFrmt])
|
||||||
else:
|
else:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
|
@ -145,7 +148,7 @@ proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash): Rope =
|
||||||
lineF(p, cpsInit, "a = ($1)p;$n", [t])
|
lineF(p, cpsInit, "a = ($1)p;$n", [t])
|
||||||
|
|
||||||
c.p = p
|
c.p = p
|
||||||
c.visitorFrmt = "#nimGCvisit((void*)$1, op);$n"
|
c.visitorFrmt = "op" # "#nimGCvisit((void*)$1, op);$n"
|
||||||
|
|
||||||
assert typ.kind != tyTypeDesc
|
assert typ.kind != tyTypeDesc
|
||||||
if typ.kind == tySequence:
|
if typ.kind == tySequence:
|
||||||
|
|
@ -180,7 +183,7 @@ proc genTraverseProcForGlobal(m: BModule, s: PSym; info: TLineInfo): Rope =
|
||||||
accessThreadLocalVar(p, s)
|
accessThreadLocalVar(p, s)
|
||||||
sLoc = "NimTV_->" & sLoc
|
sLoc = "NimTV_->" & sLoc
|
||||||
|
|
||||||
c.visitorFrmt = "#nimGCvisit((void*)$1, 0);$n"
|
c.visitorFrmt = "0" # "#nimGCvisit((void*)$1, 0);$n"
|
||||||
c.p = p
|
c.p = p
|
||||||
let header = "static N_NIMCALL(void, $1)(void)" % [result]
|
let header = "static N_NIMCALL(void, $1)(void)" % [result]
|
||||||
genTraverseProc(c, sLoc, s.loc.t)
|
genTraverseProc(c, sLoc, s.loc.t)
|
||||||
|
|
|
||||||
|
|
@ -559,7 +559,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope,
|
||||||
appcg(m, result, " : public $1 {$n",
|
appcg(m, result, " : public $1 {$n",
|
||||||
[getTypeDescAux(m, typ.sons[0].skipTypes(skipPtrs), check)])
|
[getTypeDescAux(m, typ.sons[0].skipTypes(skipPtrs), check)])
|
||||||
if typ.isException:
|
if typ.isException:
|
||||||
appcg(m, result, "virtual void raise() { throw *this; }$n") # required for polymorphic exceptions
|
appcg(m, result, "virtual void raise() { throw *this; }$n", []) # required for polymorphic exceptions
|
||||||
if typ.sym.magic == mException:
|
if typ.sym.magic == mException:
|
||||||
# Add cleanup destructor to Exception base class
|
# Add cleanup destructor to Exception base class
|
||||||
appcg(m, result, "~$1();$n", [name])
|
appcg(m, result, "~$1();$n", [name])
|
||||||
|
|
@ -751,10 +751,14 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
|
||||||
" NI len; $2_Content* p;$n" &
|
" NI len; $2_Content* p;$n" &
|
||||||
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
||||||
else:
|
else:
|
||||||
appcg(m, m.s[cfsSeqTypes],
|
if m.compileToCpp:
|
||||||
(if m.compileToCpp: cppSeq else: cSeq) &
|
appcg(m, m.s[cfsSeqTypes],
|
||||||
" $1 data[SEQ_DECL_SIZE];$n" &
|
cppSeq & " $1 data[SEQ_DECL_SIZE];$n" &
|
||||||
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
||||||
|
else:
|
||||||
|
appcg(m, m.s[cfsSeqTypes],
|
||||||
|
cSeq & " $1 data[SEQ_DECL_SIZE];$n" &
|
||||||
|
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
||||||
elif m.config.selectedGC == gcDestructors:
|
elif m.config.selectedGC == gcDestructors:
|
||||||
internalError(m.config, "cannot map the empty seq type to a C type")
|
internalError(m.config, "cannot map the empty seq type to a C type")
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -101,23 +101,54 @@ proc getModuleDllPath(m: BModule): Rope =
|
||||||
proc getModuleDllPath(m: BModule, s: PSym): Rope =
|
proc getModuleDllPath(m: BModule, s: PSym): Rope =
|
||||||
return getModuleDllPath(findPendingModule(m, s))
|
return getModuleDllPath(findPendingModule(m, s))
|
||||||
|
|
||||||
|
import macros
|
||||||
|
|
||||||
|
proc cgFormatValue(result: var string; value: Rope): void =
|
||||||
|
for str in leaves(value):
|
||||||
|
result.add str
|
||||||
|
|
||||||
|
proc cgFormatValue(result: var string; value: string): void =
|
||||||
|
result.add value
|
||||||
|
|
||||||
|
proc cgFormatValue(result: var string; value: BiggestInt): void =
|
||||||
|
result.add value
|
||||||
|
|
||||||
# TODO: please document
|
# TODO: please document
|
||||||
proc ropecg(m: BModule, frmt: FormatStr, args: varargs[Rope]): Rope =
|
macro ropecg(m: BModule, frmt: static[FormatStr], args: untyped): Rope =
|
||||||
assert m != nil
|
args.expectKind nnkBracket
|
||||||
|
# echo "ropecg ", newLit(frmt).repr, ", ", args.repr
|
||||||
var i = 0
|
var i = 0
|
||||||
var length = len(frmt)
|
var length = len(frmt)
|
||||||
result = nil
|
result = nnkStmtListExpr.newTree()
|
||||||
|
|
||||||
|
result.add quote do:
|
||||||
|
assert `m` != nil
|
||||||
|
|
||||||
|
let resVar = genSym(nskVar, "res")
|
||||||
|
# during `koch boot` the median of all generates strings from this
|
||||||
|
# macro is around 40 bytes in length.
|
||||||
|
result.add newVarStmt(resVar, newCall(bindSym"newStringOfCap", newLit(80)))
|
||||||
|
let formatValue = bindSym"cgFormatValue"
|
||||||
|
|
||||||
var num = 0
|
var num = 0
|
||||||
|
var strLit = ""
|
||||||
|
|
||||||
|
template flushStrLit() =
|
||||||
|
if strLit != "":
|
||||||
|
result.add newCall(ident "add", resVar, newLit(strLit))
|
||||||
|
strLit.setLen 0
|
||||||
|
|
||||||
while i < length:
|
while i < length:
|
||||||
if frmt[i] == '$':
|
if frmt[i] == '$':
|
||||||
inc(i) # skip '$'
|
inc(i) # skip '$'
|
||||||
case frmt[i]
|
case frmt[i]
|
||||||
of '$':
|
of '$':
|
||||||
add(result, "$")
|
strLit.add '$'
|
||||||
inc(i)
|
inc(i)
|
||||||
of '#':
|
of '#':
|
||||||
|
flushStrLit()
|
||||||
inc(i)
|
inc(i)
|
||||||
add(result, args[num])
|
result.add newCall(formatValue, resVar, args[num])
|
||||||
inc(num)
|
inc(num)
|
||||||
of '0'..'9':
|
of '0'..'9':
|
||||||
var j = 0
|
var j = 0
|
||||||
|
|
@ -126,71 +157,83 @@ proc ropecg(m: BModule, frmt: FormatStr, args: varargs[Rope]): Rope =
|
||||||
inc(i)
|
inc(i)
|
||||||
if i >= length or not (frmt[i] in {'0'..'9'}): break
|
if i >= length or not (frmt[i] in {'0'..'9'}): break
|
||||||
num = j
|
num = j
|
||||||
if j > high(args) + 1:
|
if j > len(args):
|
||||||
internalError(m.config, "ropes: invalid format string $" & $j)
|
error("ropes: invalid format string " & newLit(frmt).repr & " args.len: " & $args.len)
|
||||||
add(result, args[j-1])
|
|
||||||
|
flushStrLit()
|
||||||
|
result.add newCall(formatValue, resVar, args[j-1])
|
||||||
of 'n':
|
of 'n':
|
||||||
if optLineDir notin m.config.options: add(result, "\L")
|
flushStrLit()
|
||||||
|
result.add quote do:
|
||||||
|
if optLineDir notin `m`.config.options:
|
||||||
|
add(`resVar`, "\L")
|
||||||
inc(i)
|
inc(i)
|
||||||
of 'N':
|
of 'N':
|
||||||
add(result, "\L")
|
strLit.add "\L"
|
||||||
inc(i)
|
inc(i)
|
||||||
else: internalError(m.config, "ropes: invalid format string $" & frmt[i])
|
else:
|
||||||
|
error("ropes: invalid format string $" & frmt[i])
|
||||||
elif frmt[i] == '#' and frmt[i+1] in IdentStartChars:
|
elif frmt[i] == '#' and frmt[i+1] in IdentStartChars:
|
||||||
inc(i)
|
inc(i)
|
||||||
var j = i
|
var j = i
|
||||||
while frmt[j] in IdentChars: inc(j)
|
while frmt[j] in IdentChars: inc(j)
|
||||||
var ident = substr(frmt, i, j-1)
|
var ident = newLit(substr(frmt, i, j-1))
|
||||||
i = j
|
i = j
|
||||||
add(result, cgsym(m, ident))
|
flushStrLit()
|
||||||
|
result.add newCall(formatValue, resVar, newCall(ident"cgsym", m, ident))
|
||||||
elif frmt[i] == '#' and frmt[i+1] == '$':
|
elif frmt[i] == '#' and frmt[i+1] == '$':
|
||||||
inc(i, 2)
|
inc(i, 2)
|
||||||
var j = 0
|
var j = 0
|
||||||
while frmt[i] in Digits:
|
while frmt[i] in Digits:
|
||||||
j = (j * 10) + ord(frmt[i]) - ord('0')
|
j = (j * 10) + ord(frmt[i]) - ord('0')
|
||||||
inc(i)
|
inc(i)
|
||||||
add(result, cgsym(m, $args[j-1]))
|
let ident = args[j-1]
|
||||||
|
flushStrLit()
|
||||||
|
result.add newCall(formatValue, resVar, newCall(ident"cgsym", m, ident))
|
||||||
var start = i
|
var start = i
|
||||||
while i < length:
|
while i < length:
|
||||||
if frmt[i] != '$' and frmt[i] != '#': inc(i)
|
if frmt[i] != '$' and frmt[i] != '#': inc(i)
|
||||||
else: break
|
else: break
|
||||||
if i - 1 >= start:
|
if i - 1 >= start:
|
||||||
add(result, substr(frmt, start, i - 1))
|
add(strLit, substr(frmt, start, i - 1))
|
||||||
|
|
||||||
|
flushStrLit()
|
||||||
|
result.add newCall(ident"rope", resVar)
|
||||||
|
|
||||||
proc indentLine(p: BProc, r: Rope): Rope =
|
proc indentLine(p: BProc, r: Rope): Rope =
|
||||||
result = r
|
result = r
|
||||||
for i in countup(0, p.blocks.len-1):
|
for i in countup(0, p.blocks.len-1):
|
||||||
prepend(result, "\t".rope)
|
prepend(result, "\t".rope)
|
||||||
|
|
||||||
proc appcg(m: BModule, c: var Rope, frmt: FormatStr,
|
template appcg(m: BModule, c: var Rope, frmt: FormatStr,
|
||||||
args: varargs[Rope]) =
|
args: varargs[untyped]) =
|
||||||
add(c, ropecg(m, frmt, args))
|
add(c, ropecg(m, frmt, args))
|
||||||
|
|
||||||
proc appcg(m: BModule, s: TCFileSection, frmt: FormatStr,
|
template appcg(m: BModule, sec: TCFileSection, frmt: FormatStr,
|
||||||
args: varargs[Rope]) =
|
args: varargs[untyped]) =
|
||||||
add(m.s[s], ropecg(m, frmt, args))
|
add(m.s[sec], ropecg(m, frmt, args))
|
||||||
|
|
||||||
proc appcg(p: BProc, s: TCProcSection, frmt: FormatStr,
|
template appcg(p: BProc, sec: TCProcSection, frmt: FormatStr,
|
||||||
args: varargs[Rope]) =
|
args: varargs[untyped]) =
|
||||||
add(p.s(s), ropecg(p.module, frmt, args))
|
add(p.s(sec), ropecg(p.module, frmt, args))
|
||||||
|
|
||||||
proc line(p: BProc, s: TCProcSection, r: Rope) =
|
template line(p: BProc, sec: TCProcSection, r: Rope) =
|
||||||
add(p.s(s), indentLine(p, r))
|
add(p.s(sec), indentLine(p, r))
|
||||||
|
|
||||||
proc line(p: BProc, s: TCProcSection, r: string) =
|
template line(p: BProc, sec: TCProcSection, r: string) =
|
||||||
add(p.s(s), indentLine(p, r.rope))
|
add(p.s(sec), indentLine(p, r.rope))
|
||||||
|
|
||||||
proc lineF(p: BProc, s: TCProcSection, frmt: FormatStr,
|
template lineF(p: BProc, sec: TCProcSection, frmt: FormatStr,
|
||||||
args: openarray[Rope]) =
|
args: openarray[Rope]) =
|
||||||
add(p.s(s), indentLine(p, frmt % args))
|
add(p.s(sec), indentLine(p, frmt % args))
|
||||||
|
|
||||||
proc lineCg(p: BProc, s: TCProcSection, frmt: FormatStr,
|
template lineCg(p: BProc, sec: TCProcSection, frmt: FormatStr,
|
||||||
args: varargs[Rope]) =
|
args: untyped) =
|
||||||
add(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
|
add(p.s(sec), indentLine(p, ropecg(p.module, frmt, args)))
|
||||||
|
|
||||||
proc linefmt(p: BProc, s: TCProcSection, frmt: FormatStr,
|
template linefmt(p: BProc, sec: TCProcSection, frmt: FormatStr,
|
||||||
args: varargs[Rope]) =
|
args: untyped) =
|
||||||
add(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
|
add(p.s(sec), indentLine(p, ropecg(p.module, frmt, args)))
|
||||||
|
|
||||||
proc safeLineNm(info: TLineInfo): int =
|
proc safeLineNm(info: TLineInfo): int =
|
||||||
result = toLinenumber(info)
|
result = toLinenumber(info)
|
||||||
|
|
@ -222,13 +265,13 @@ proc genLineDir(p: BProc, t: PNode) =
|
||||||
(p.prc == nil or sfPure notin p.prc.flags):
|
(p.prc == nil or sfPure notin p.prc.flags):
|
||||||
if freshLineInfo(p, t.info):
|
if freshLineInfo(p, t.info):
|
||||||
linefmt(p, cpsStmts, "#endb($1, $2);$N",
|
linefmt(p, cpsStmts, "#endb($1, $2);$N",
|
||||||
line.rope, makeCString(toFilename(p.config, t.info)))
|
[line, makeCString(toFilename(p.config, t.info))])
|
||||||
elif ({optLineTrace, optStackTrace} * p.options ==
|
elif ({optLineTrace, optStackTrace} * p.options ==
|
||||||
{optLineTrace, optStackTrace}) and
|
{optLineTrace, optStackTrace}) and
|
||||||
(p.prc == nil or sfPure notin p.prc.flags) and t.info.fileIndex != InvalidFileIDX:
|
(p.prc == nil or sfPure notin p.prc.flags) and t.info.fileIndex != InvalidFileIDX:
|
||||||
if freshLineInfo(p, t.info):
|
if freshLineInfo(p, t.info):
|
||||||
linefmt(p, cpsStmts, "nimln_($1, $2);$n",
|
linefmt(p, cpsStmts, "nimln_($1, $2);$n",
|
||||||
line.rope, quotedFilename(p.config, t.info))
|
[line, quotedFilename(p.config, t.info)])
|
||||||
|
|
||||||
proc postStmtActions(p: BProc) {.inline.} =
|
proc postStmtActions(p: BProc) {.inline.} =
|
||||||
add(p.s(cpsStmts), p.module.injectStmt)
|
add(p.s(cpsStmts), p.module.injectStmt)
|
||||||
|
|
@ -291,7 +334,7 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
|
||||||
if p.module.compileToCpp and t.isException and not isDefined(p.config, "noCppExceptions"):
|
if p.module.compileToCpp and t.isException and not isDefined(p.config, "noCppExceptions"):
|
||||||
# init vtable in Exception object for polymorphic exceptions
|
# init vtable in Exception object for polymorphic exceptions
|
||||||
includeHeader(p.module, "<new>")
|
includeHeader(p.module, "<new>")
|
||||||
linefmt(p, section, "new ($1) $2;$n", rdLoc(a), getTypeDesc(p.module, t))
|
linefmt(p, section, "new ($1) $2;$n", [rdLoc(a), getTypeDesc(p.module, t)])
|
||||||
|
|
||||||
#if optNimV2 in p.config.globalOptions: return
|
#if optNimV2 in p.config.globalOptions: return
|
||||||
case analyseObjectWithTypeField(t)
|
case analyseObjectWithTypeField(t)
|
||||||
|
|
@ -305,14 +348,14 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
|
||||||
while s.kind == tyObject and s.sons[0] != nil:
|
while s.kind == tyObject and s.sons[0] != nil:
|
||||||
add(r, ".Sup")
|
add(r, ".Sup")
|
||||||
s = skipTypes(s.sons[0], skipPtrs)
|
s = skipTypes(s.sons[0], skipPtrs)
|
||||||
linefmt(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t, a.lode.info))
|
linefmt(p, section, "$1.m_type = $2;$n", [r, genTypeInfo(p.module, t, a.lode.info)])
|
||||||
of frEmbedded:
|
of frEmbedded:
|
||||||
if optNimV2 in p.config.globalOptions:
|
if optNimV2 in p.config.globalOptions:
|
||||||
localError(p.config, p.prc.info,
|
localError(p.config, p.prc.info,
|
||||||
"complex object initialization is not supported with --newruntime")
|
"complex object initialization is not supported with --newruntime")
|
||||||
# worst case for performance:
|
# worst case for performance:
|
||||||
var r = if takeAddr: addrLoc(p.config, a) else: rdLoc(a)
|
var r = if takeAddr: addrLoc(p.config, a) else: rdLoc(a)
|
||||||
linefmt(p, section, "#objectInit($1, $2);$n", r, genTypeInfo(p.module, t, a.lode.info))
|
linefmt(p, section, "#objectInit($1, $2);$n", [r, genTypeInfo(p.module, t, a.lode.info)])
|
||||||
|
|
||||||
type
|
type
|
||||||
TAssignmentFlag = enum
|
TAssignmentFlag = enum
|
||||||
|
|
@ -332,7 +375,7 @@ proc resetLoc(p: BProc, loc: var TLoc) =
|
||||||
if isImportedCppType(typ): return
|
if isImportedCppType(typ): return
|
||||||
if p.config.selectedGc == gcDestructors and typ.kind in {tyString, tySequence}:
|
if p.config.selectedGc == gcDestructors and typ.kind in {tyString, tySequence}:
|
||||||
assert rdLoc(loc) != nil
|
assert rdLoc(loc) != nil
|
||||||
linefmt(p, cpsStmts, "$1.len = 0; $1.p = NIM_NIL;$n", rdLoc(loc))
|
linefmt(p, cpsStmts, "$1.len = 0; $1.p = NIM_NIL;$n", [rdLoc(loc)])
|
||||||
elif not isComplexValueType(typ):
|
elif not isComplexValueType(typ):
|
||||||
if containsGcRef:
|
if containsGcRef:
|
||||||
var nilLoc: TLoc
|
var nilLoc: TLoc
|
||||||
|
|
@ -340,13 +383,13 @@ proc resetLoc(p: BProc, loc: var TLoc) =
|
||||||
nilLoc.r = rope("NIM_NIL")
|
nilLoc.r = rope("NIM_NIL")
|
||||||
genRefAssign(p, loc, nilLoc)
|
genRefAssign(p, loc, nilLoc)
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "$1 = 0;$n", rdLoc(loc))
|
linefmt(p, cpsStmts, "$1 = 0;$n", [rdLoc(loc)])
|
||||||
else:
|
else:
|
||||||
if optNilCheck in p.options:
|
if optNilCheck in p.options:
|
||||||
linefmt(p, cpsStmts, "#chckNil((void*)$1);$n", addrLoc(p.config, loc))
|
linefmt(p, cpsStmts, "#chckNil((void*)$1);$n", [addrLoc(p.config, loc)])
|
||||||
if loc.storage != OnStack and containsGcRef:
|
if loc.storage != OnStack and containsGcRef:
|
||||||
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
|
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
|
||||||
addrLoc(p.config, loc), genTypeInfo(p.module, loc.t, loc.lode.info))
|
[addrLoc(p.config, loc), genTypeInfo(p.module, loc.t, loc.lode.info)])
|
||||||
# XXX: generated reset procs should not touch the m_type
|
# XXX: generated reset procs should not touch the m_type
|
||||||
# field, so disabling this should be safe:
|
# field, so disabling this should be safe:
|
||||||
genObjectInit(p, cpsStmts, loc.t, loc, true)
|
genObjectInit(p, cpsStmts, loc.t, loc, true)
|
||||||
|
|
@ -354,7 +397,7 @@ proc resetLoc(p: BProc, loc: var TLoc) =
|
||||||
# array passed as argument decayed into pointer, bug #7332
|
# array passed as argument decayed into pointer, bug #7332
|
||||||
# so we use getTypeDesc here rather than rdLoc(loc)
|
# so we use getTypeDesc here rather than rdLoc(loc)
|
||||||
linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n",
|
linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n",
|
||||||
addrLoc(p.config, loc), getTypeDesc(p.module, loc.t))
|
[addrLoc(p.config, loc), getTypeDesc(p.module, loc.t)])
|
||||||
# XXX: We can be extra clever here and call memset only
|
# XXX: We can be extra clever here and call memset only
|
||||||
# on the bytes following the m_type field?
|
# on the bytes following the m_type field?
|
||||||
genObjectInit(p, cpsStmts, loc.t, loc, true)
|
genObjectInit(p, cpsStmts, loc.t, loc, true)
|
||||||
|
|
@ -362,17 +405,17 @@ proc resetLoc(p: BProc, loc: var TLoc) =
|
||||||
proc constructLoc(p: BProc, loc: TLoc, isTemp = false) =
|
proc constructLoc(p: BProc, loc: TLoc, isTemp = false) =
|
||||||
let typ = loc.t
|
let typ = loc.t
|
||||||
if p.config.selectedGc == gcDestructors and skipTypes(typ, abstractInst).kind in {tyString, tySequence}:
|
if p.config.selectedGc == gcDestructors and skipTypes(typ, abstractInst).kind in {tyString, tySequence}:
|
||||||
linefmt(p, cpsStmts, "$1.len = 0; $1.p = NIM_NIL;$n", rdLoc(loc))
|
linefmt(p, cpsStmts, "$1.len = 0; $1.p = NIM_NIL;$n", [rdLoc(loc)])
|
||||||
elif not isComplexValueType(typ):
|
elif not isComplexValueType(typ):
|
||||||
linefmt(p, cpsStmts, "$1 = ($2)0;$n", rdLoc(loc),
|
linefmt(p, cpsStmts, "$1 = ($2)0;$n", [rdLoc(loc),
|
||||||
getTypeDesc(p.module, typ))
|
getTypeDesc(p.module, typ)])
|
||||||
else:
|
else:
|
||||||
if not isTemp or containsGarbageCollectedRef(loc.t):
|
if not isTemp or containsGarbageCollectedRef(loc.t):
|
||||||
# don't use nimZeroMem for temporary values for performance if we can
|
# don't use nimZeroMem for temporary values for performance if we can
|
||||||
# avoid it:
|
# avoid it:
|
||||||
if not isImportedCppType(typ):
|
if not isImportedCppType(typ):
|
||||||
linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n",
|
linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n",
|
||||||
addrLoc(p.config, loc), getTypeDesc(p.module, typ))
|
[addrLoc(p.config, loc), getTypeDesc(p.module, typ)])
|
||||||
genObjectInit(p, cpsStmts, loc.t, loc, true)
|
genObjectInit(p, cpsStmts, loc.t, loc, true)
|
||||||
|
|
||||||
proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) =
|
proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) =
|
||||||
|
|
@ -390,7 +433,7 @@ proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) =
|
||||||
proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) =
|
proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) =
|
||||||
inc(p.labels)
|
inc(p.labels)
|
||||||
result.r = "T" & rope(p.labels) & "_"
|
result.r = "T" & rope(p.labels) & "_"
|
||||||
linefmt(p, cpsLocals, "$1 $2;$n", getTypeDesc(p.module, t), result.r)
|
linefmt(p, cpsLocals, "$1 $2;$n", [getTypeDesc(p.module, t), result.r])
|
||||||
result.k = locTemp
|
result.k = locTemp
|
||||||
result.lode = lodeTyp t
|
result.lode = lodeTyp t
|
||||||
result.storage = OnStack
|
result.storage = OnStack
|
||||||
|
|
@ -400,7 +443,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) =
|
||||||
proc getIntTemp(p: BProc, result: var TLoc) =
|
proc getIntTemp(p: BProc, result: var TLoc) =
|
||||||
inc(p.labels)
|
inc(p.labels)
|
||||||
result.r = "T" & rope(p.labels) & "_"
|
result.r = "T" & rope(p.labels) & "_"
|
||||||
linefmt(p, cpsLocals, "NI $1;$n", result.r)
|
linefmt(p, cpsLocals, "NI $1;$n", [result.r])
|
||||||
result.k = locTemp
|
result.k = locTemp
|
||||||
result.storage = OnStack
|
result.storage = OnStack
|
||||||
result.lode = lodeTyp getSysType(p.module.g.graph, unknownLineInfo(), tyInt)
|
result.lode = lodeTyp getSysType(p.module.g.graph, unknownLineInfo(), tyInt)
|
||||||
|
|
@ -412,7 +455,7 @@ proc initGCFrame(p: BProc): Rope =
|
||||||
proc deinitGCFrame(p: BProc): Rope =
|
proc deinitGCFrame(p: BProc): Rope =
|
||||||
if p.gcFrameId > 0:
|
if p.gcFrameId > 0:
|
||||||
result = ropecg(p.module,
|
result = ropecg(p.module,
|
||||||
"if (((NU)&GCFRAME_) < 4096) #nimGCFrame(&GCFRAME_);$n")
|
"if (((NU)&GCFRAME_) < 4096) #nimGCFrame(&GCFRAME_);$n", [])
|
||||||
|
|
||||||
proc localDebugInfo(p: BProc, s: PSym, retType: PType) =
|
proc localDebugInfo(p: BProc, s: PSym, retType: PType) =
|
||||||
if {optStackTrace, optEndb} * p.options != {optStackTrace, optEndb}: return
|
if {optStackTrace, optEndb} * p.options != {optStackTrace, optEndb}: return
|
||||||
|
|
@ -565,29 +608,29 @@ proc initFrame(p: BProc, procname, filename: Rope): Rope =
|
||||||
FR_.line = n; FR_.filename = file;
|
FR_.line = n; FR_.filename = file;
|
||||||
"""
|
"""
|
||||||
if p.module.s[cfsFrameDefines].len == 0:
|
if p.module.s[cfsFrameDefines].len == 0:
|
||||||
appcg(p.module, p.module.s[cfsFrameDefines], frameDefines, [rope("#")])
|
appcg(p.module, p.module.s[cfsFrameDefines], frameDefines, ["#"])
|
||||||
|
|
||||||
discard cgsym(p.module, "nimFrame")
|
discard cgsym(p.module, "nimFrame")
|
||||||
if p.maxFrameLen > 0:
|
if p.maxFrameLen > 0:
|
||||||
discard cgsym(p.module, "VarSlot")
|
discard cgsym(p.module, "VarSlot")
|
||||||
result = ropecg(p.module, "\tnimfrs_($1, $2, $3, $4);$n",
|
result = ropecg(p.module, "\tnimfrs_($1, $2, $3, $4);$n",
|
||||||
procname, filename, p.maxFrameLen.rope,
|
[procname, filename, p.maxFrameLen,
|
||||||
p.blocks[0].frameLen.rope)
|
p.blocks[0].frameLen])
|
||||||
else:
|
else:
|
||||||
result = ropecg(p.module, "\tnimfr_($1, $2);$n", procname, filename)
|
result = ropecg(p.module, "\tnimfr_($1, $2);$n", [procname, filename])
|
||||||
|
|
||||||
proc initFrameNoDebug(p: BProc; frame, procname, filename: Rope; line: int): Rope =
|
proc initFrameNoDebug(p: BProc; frame, procname, filename: Rope; line: int): Rope =
|
||||||
discard cgsym(p.module, "nimFrame")
|
discard cgsym(p.module, "nimFrame")
|
||||||
addf(p.blocks[0].sections[cpsLocals], "TFrame $1;$n", [frame])
|
addf(p.blocks[0].sections[cpsLocals], "TFrame $1;$n", [frame])
|
||||||
result = ropecg(p.module, "\t$1.procname = $2; $1.filename = $3; " &
|
result = ropecg(p.module, "\t$1.procname = $2; $1.filename = $3; " &
|
||||||
" $1.line = $4; $1.len = -1; nimFrame(&$1);$n",
|
" $1.line = $4; $1.len = -1; nimFrame(&$1);$n",
|
||||||
frame, procname, filename, rope(line))
|
[frame, procname, filename, line])
|
||||||
|
|
||||||
proc deinitFrameNoDebug(p: BProc; frame: Rope): Rope =
|
proc deinitFrameNoDebug(p: BProc; frame: Rope): Rope =
|
||||||
result = ropecg(p.module, "\t#popFrameOfAddr(&$1);$n", frame)
|
result = ropecg(p.module, "\t#popFrameOfAddr(&$1);$n", [frame])
|
||||||
|
|
||||||
proc deinitFrame(p: BProc): Rope =
|
proc deinitFrame(p: BProc): Rope =
|
||||||
result = ropecg(p.module, "\t#popFrame();$n")
|
result = ropecg(p.module, "\t#popFrame();$n", [])
|
||||||
|
|
||||||
include ccgexprs
|
include ccgexprs
|
||||||
|
|
||||||
|
|
@ -766,10 +809,10 @@ proc closureSetup(p: BProc, prc: PSym) =
|
||||||
# generate cast assignment:
|
# generate cast assignment:
|
||||||
if p.config.selectedGC == gcGo:
|
if p.config.selectedGC == gcGo:
|
||||||
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, ($2) ClE_0);$n",
|
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, ($2) ClE_0);$n",
|
||||||
addrLoc(p.config, env.loc), getTypeDesc(p.module, env.typ))
|
[addrLoc(p.config, env.loc), getTypeDesc(p.module, env.typ)])
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "$1 = ($2) ClE_0;$n",
|
linefmt(p, cpsStmts, "$1 = ($2) ClE_0;$n",
|
||||||
rdLoc(env.loc), getTypeDesc(p.module, env.typ))
|
[rdLoc(env.loc), getTypeDesc(p.module, env.typ)])
|
||||||
|
|
||||||
proc containsResult(n: PNode): bool =
|
proc containsResult(n: PNode): bool =
|
||||||
if n.kind == nkSym and n.sym.kind == skResult:
|
if n.kind == nkSym and n.sym.kind == skResult:
|
||||||
|
|
@ -928,13 +971,13 @@ proc genProcAux(m: BModule, prc: PSym) =
|
||||||
var decl = localVarDecl(p, resNode)
|
var decl = localVarDecl(p, resNode)
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExprSingleUse(p, val, a)
|
initLocExprSingleUse(p, val, a)
|
||||||
linefmt(p, cpsStmts, "$1 = $2;$n", decl, rdLoc(a))
|
linefmt(p, cpsStmts, "$1 = $2;$n", [decl, rdLoc(a)])
|
||||||
else:
|
else:
|
||||||
# declare the result symbol:
|
# declare the result symbol:
|
||||||
assignLocalVar(p, resNode)
|
assignLocalVar(p, resNode)
|
||||||
assert(res.loc.r != nil)
|
assert(res.loc.r != nil)
|
||||||
initLocalVar(p, res, immediateAsgn=false)
|
initLocalVar(p, res, immediateAsgn=false)
|
||||||
returnStmt = ropecg(p.module, "\treturn $1;$n", rdLoc(res.loc))
|
returnStmt = ropecg(p.module, "\treturn $1;$n", [rdLoc(res.loc)])
|
||||||
else:
|
else:
|
||||||
fillResult(p.config, resNode)
|
fillResult(p.config, resNode)
|
||||||
assignParam(p, res, prc.typ[0])
|
assignParam(p, res, prc.typ[0])
|
||||||
|
|
@ -966,9 +1009,9 @@ proc genProcAux(m: BModule, prc: PSym) =
|
||||||
if hasDeclspec in extccomp.CC[p.config.cCompiler].props:
|
if hasDeclspec in extccomp.CC[p.config.cCompiler].props:
|
||||||
header = "__declspec(naked) " & header
|
header = "__declspec(naked) " & header
|
||||||
generatedProc = ropecg(p.module, "$N$1 {$n$2$3$4}$N$N",
|
generatedProc = ropecg(p.module, "$N$1 {$n$2$3$4}$N$N",
|
||||||
header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts))
|
[header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)])
|
||||||
else:
|
else:
|
||||||
generatedProc = ropecg(p.module, "$N$1 {$N", header)
|
generatedProc = ropecg(p.module, "$N$1 {$N", [header])
|
||||||
add(generatedProc, initGCFrame(p))
|
add(generatedProc, initGCFrame(p))
|
||||||
if optStackTrace in prc.options:
|
if optStackTrace in prc.options:
|
||||||
add(generatedProc, p.s(cpsLocals))
|
add(generatedProc, p.s(cpsLocals))
|
||||||
|
|
@ -1007,8 +1050,8 @@ proc genProcPrototype(m: BModule, sym: PSym) =
|
||||||
if getModule(sym).id != m.module.id and
|
if getModule(sym).id != m.module.id and
|
||||||
not containsOrIncl(m.declaredThings, sym.id):
|
not containsOrIncl(m.declaredThings, sym.id):
|
||||||
add(m.s[cfsVars], ropecg(m, "$1 $2 $3;$n",
|
add(m.s[cfsVars], ropecg(m, "$1 $2 $3;$n",
|
||||||
rope(if isReloadable(m, sym): "static" else: "extern"),
|
[(if isReloadable(m, sym): "static" else: "extern"),
|
||||||
getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
|
getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)]))
|
||||||
if isReloadable(m, sym):
|
if isReloadable(m, sym):
|
||||||
addf(m.s[cfsDynLibInit], "\t$1 = ($2) hcrGetProc($3, \"$1\");$n",
|
addf(m.s[cfsDynLibInit], "\t$1 = ($2) hcrGetProc($3, \"$1\");$n",
|
||||||
[mangleDynLibProc(sym), getTypeDesc(m, sym.loc.t), getModuleDllPath(m, sym)])
|
[mangleDynLibProc(sym), getTypeDesc(m, sym.loc.t), getModuleDllPath(m, sym)])
|
||||||
|
|
@ -1024,7 +1067,7 @@ proc genProcPrototype(m: BModule, sym: PSym) =
|
||||||
header.add(" __attribute__((naked))")
|
header.add(" __attribute__((naked))")
|
||||||
if sfNoReturn in sym.flags and hasAttribute in CC[m.config.cCompiler].props:
|
if sfNoReturn in sym.flags and hasAttribute in CC[m.config.cCompiler].props:
|
||||||
header.add(" __attribute__((noreturn))")
|
header.add(" __attribute__((noreturn))")
|
||||||
add(m.s[cfsProcHeaders], ropecg(m, "$1;$N", header))
|
add(m.s[cfsProcHeaders], ropecg(m, "$1;$N", [header]))
|
||||||
|
|
||||||
# TODO: figure out how to rename this - it DOES generate a forward declaration
|
# TODO: figure out how to rename this - it DOES generate a forward declaration
|
||||||
proc genProcNoForward(m: BModule, prc: PSym) =
|
proc genProcNoForward(m: BModule, prc: PSym) =
|
||||||
|
|
@ -1222,19 +1265,19 @@ proc genMainProc(m: BModule) =
|
||||||
n.info = prc.annex.path.info
|
n.info = prc.annex.path.info
|
||||||
appcg(m, result, "\tif (!($1 = #nimLoadLibrary($2)))$N" &
|
appcg(m, result, "\tif (!($1 = #nimLoadLibrary($2)))$N" &
|
||||||
"\t\t#nimLoadLibraryError($2);$N",
|
"\t\t#nimLoadLibraryError($2);$N",
|
||||||
[handle.rope, genStringLiteral(m, n)])
|
[handle, genStringLiteral(m, n)])
|
||||||
|
|
||||||
add(preMainCode, loadLib("hcr_handle", "hcrGetProc"))
|
add(preMainCode, loadLib("hcr_handle", "hcrGetProc"))
|
||||||
add(preMainCode, "\tvoid* rtl_handle;$N")
|
add(preMainCode, "\tvoid* rtl_handle;\L")
|
||||||
add(preMainCode, loadLib("rtl_handle", "nimGC_setStackBottom"))
|
add(preMainCode, loadLib("rtl_handle", "nimGC_setStackBottom"))
|
||||||
add(preMainCode, hcrGetProcLoadCode(m, "nimGC_setStackBottom", "nimrtl_", "rtl_handle", "nimGetProcAddr"))
|
add(preMainCode, hcrGetProcLoadCode(m, "nimGC_setStackBottom", "nimrtl_", "rtl_handle", "nimGetProcAddr"))
|
||||||
add(preMainCode, "\tinner = PreMain;$N")
|
add(preMainCode, "\tinner = PreMain;\L")
|
||||||
add(preMainCode, "\tinitStackBottomWith_actual((void *)&inner);$N")
|
add(preMainCode, "\tinitStackBottomWith_actual((void *)&inner);\L")
|
||||||
add(preMainCode, "\t(*inner)();$N")
|
add(preMainCode, "\t(*inner)();\L")
|
||||||
else:
|
else:
|
||||||
add(preMainCode, "\tPreMain();$N")
|
add(preMainCode, "\tPreMain();\L")
|
||||||
|
|
||||||
let
|
const
|
||||||
# not a big deal if we always compile these 3 global vars... makes the HCR code easier
|
# not a big deal if we always compile these 3 global vars... makes the HCR code easier
|
||||||
PosixCmdLine =
|
PosixCmdLine =
|
||||||
"int cmdCount;$N" &
|
"int cmdCount;$N" &
|
||||||
|
|
@ -1261,7 +1304,7 @@ proc genMainProc(m: BModule) =
|
||||||
"\tNimMain();$N"
|
"\tNimMain();$N"
|
||||||
|
|
||||||
MainProcsWithResult =
|
MainProcsWithResult =
|
||||||
MainProcs & ("\treturn " & (if m.hcrOn: "*" else: "") & "nim_program_result;$N")
|
MainProcs & ("\treturn $1nim_program_result;$N")
|
||||||
|
|
||||||
NimMainInner = "N_CDECL(void, NimMainInner)(void) {$N" &
|
NimMainInner = "N_CDECL(void, NimMainInner)(void) {$N" &
|
||||||
"$1" &
|
"$1" &
|
||||||
|
|
@ -1270,7 +1313,7 @@ proc genMainProc(m: BModule) =
|
||||||
NimMainProc =
|
NimMainProc =
|
||||||
"N_CDECL(void, NimMain)(void) {$N" &
|
"N_CDECL(void, NimMain)(void) {$N" &
|
||||||
"\tvoid (*volatile inner)(void);$N" &
|
"\tvoid (*volatile inner)(void);$N" &
|
||||||
$preMainCode &
|
"$4" &
|
||||||
"\tinner = NimMainInner;$N" &
|
"\tinner = NimMainInner;$N" &
|
||||||
"$2" &
|
"$2" &
|
||||||
"\t(*inner)();$N" &
|
"\t(*inner)();$N" &
|
||||||
|
|
@ -1331,29 +1374,12 @@ proc genMainProc(m: BModule) =
|
||||||
"\t});$N" &
|
"\t});$N" &
|
||||||
"}$N$N"
|
"}$N$N"
|
||||||
|
|
||||||
var nimMain, otherMain: FormatStr
|
|
||||||
if m.config.target.targetOS == osWindows and
|
if m.config.target.targetOS == osWindows and
|
||||||
m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}:
|
m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}:
|
||||||
if optGenGuiApp in m.config.globalOptions:
|
|
||||||
nimMain = WinNimMain
|
|
||||||
otherMain = WinCMain
|
|
||||||
else:
|
|
||||||
nimMain = WinNimDllMain
|
|
||||||
otherMain = WinCDllMain
|
|
||||||
m.includeHeader("<windows.h>")
|
m.includeHeader("<windows.h>")
|
||||||
elif m.config.target.targetOS == osGenode:
|
elif m.config.target.targetOS == osGenode:
|
||||||
nimMain = GenodeNimMain
|
|
||||||
otherMain = ComponentConstruct
|
|
||||||
m.includeHeader("<libc/component.h>")
|
m.includeHeader("<libc/component.h>")
|
||||||
elif optGenDynLib in m.config.globalOptions:
|
|
||||||
nimMain = PosixNimDllMain
|
|
||||||
otherMain = PosixCDllMain
|
|
||||||
elif m.config.target.targetOS == osStandalone:
|
|
||||||
nimMain = NimMainBody
|
|
||||||
otherMain = StandaloneCMain
|
|
||||||
else:
|
|
||||||
nimMain = NimMainBody
|
|
||||||
otherMain = PosixCMain
|
|
||||||
if optEndb in m.config.options:
|
if optEndb in m.config.options:
|
||||||
for i in 0..<m.config.m.fileInfos.len:
|
for i in 0..<m.config.m.fileInfos.len:
|
||||||
m.g.breakpoints.addf("dbgRegisterFilename($1);$N",
|
m.g.breakpoints.addf("dbgRegisterFilename($1);$N",
|
||||||
|
|
@ -1361,18 +1387,65 @@ proc genMainProc(m: BModule) =
|
||||||
|
|
||||||
let initStackBottomCall =
|
let initStackBottomCall =
|
||||||
if m.config.target.targetOS == osStandalone or m.config.selectedGC == gcNone: "".rope
|
if m.config.target.targetOS == osStandalone or m.config.selectedGC == gcNone: "".rope
|
||||||
else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N")
|
else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N", [])
|
||||||
inc(m.labels)
|
inc(m.labels)
|
||||||
appcg(m, m.s[cfsProcs], PreMainBody, [
|
appcg(m, m.s[cfsProcs], PreMainBody, [
|
||||||
m.g.mainDatInit, m.g.breakpoints, m.g.otherModsInit])
|
m.g.mainDatInit, m.g.breakpoints, m.g.otherModsInit])
|
||||||
|
|
||||||
appcg(m, m.s[cfsProcs], nimMain,
|
if m.config.target.targetOS == osWindows and
|
||||||
[m.g.mainModInit, initStackBottomCall, rope(m.labels)])
|
m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}:
|
||||||
|
if optGenGuiApp in m.config.globalOptions:
|
||||||
|
const nimMain = WinNimMain
|
||||||
|
appcg(m, m.s[cfsProcs], nimMain,
|
||||||
|
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode])
|
||||||
|
else:
|
||||||
|
const nimMain = WinNimDllMain
|
||||||
|
appcg(m, m.s[cfsProcs], nimMain,
|
||||||
|
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode])
|
||||||
|
elif m.config.target.targetOS == osGenode:
|
||||||
|
const nimMain = GenodeNimMain
|
||||||
|
appcg(m, m.s[cfsProcs], nimMain,
|
||||||
|
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode])
|
||||||
|
elif optGenDynLib in m.config.globalOptions:
|
||||||
|
const nimMain = PosixNimDllMain
|
||||||
|
appcg(m, m.s[cfsProcs], nimMain,
|
||||||
|
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode])
|
||||||
|
elif m.config.target.targetOS == osStandalone:
|
||||||
|
const nimMain = NimMainBody
|
||||||
|
appcg(m, m.s[cfsProcs], nimMain,
|
||||||
|
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode])
|
||||||
|
else:
|
||||||
|
const nimMain = NimMainBody
|
||||||
|
appcg(m, m.s[cfsProcs], nimMain,
|
||||||
|
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode])
|
||||||
|
|
||||||
|
|
||||||
if optNoMain notin m.config.globalOptions:
|
if optNoMain notin m.config.globalOptions:
|
||||||
if m.config.cppCustomNamespace.len > 0:
|
if m.config.cppCustomNamespace.len > 0:
|
||||||
m.s[cfsProcs].add closeNamespaceNim() & "using namespace " & m.config.cppCustomNamespace & ";\L"
|
m.s[cfsProcs].add closeNamespaceNim() & "using namespace " & m.config.cppCustomNamespace & ";\L"
|
||||||
|
|
||||||
appcg(m, m.s[cfsProcs], otherMain, [])
|
if m.config.target.targetOS == osWindows and
|
||||||
|
m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}:
|
||||||
|
if optGenGuiApp in m.config.globalOptions:
|
||||||
|
const otherMain = WinCMain
|
||||||
|
appcg(m, m.s[cfsProcs], otherMain, [if m.hcrOn: "*" else: ""])
|
||||||
|
else:
|
||||||
|
const otherMain = WinCDllMain
|
||||||
|
appcg(m, m.s[cfsProcs], otherMain, [])
|
||||||
|
elif m.config.target.targetOS == osGenode:
|
||||||
|
const otherMain = ComponentConstruct
|
||||||
|
appcg(m, m.s[cfsProcs], otherMain, [])
|
||||||
|
elif optGenDynLib in m.config.globalOptions:
|
||||||
|
const otherMain = PosixCDllMain
|
||||||
|
appcg(m, m.s[cfsProcs], otherMain, [])
|
||||||
|
elif m.config.target.targetOS == osStandalone:
|
||||||
|
const otherMain = StandaloneCMain
|
||||||
|
appcg(m, m.s[cfsProcs], otherMain, [])
|
||||||
|
else:
|
||||||
|
const otherMain = PosixCMain
|
||||||
|
appcg(m, m.s[cfsProcs], otherMain, [if m.hcrOn: "*" else: ""])
|
||||||
|
|
||||||
|
|
||||||
if m.config.cppCustomNamespace.len > 0:
|
if m.config.cppCustomNamespace.len > 0:
|
||||||
m.s[cfsProcs].add openNamespaceNim(m.config.cppCustomNamespace)
|
m.s[cfsProcs].add openNamespaceNim(m.config.cppCustomNamespace)
|
||||||
|
|
||||||
|
|
@ -1430,9 +1503,9 @@ proc registerModuleToMain(g: BModuleList; m: BModule) =
|
||||||
# systemDatInit and systemInit calls if any
|
# systemDatInit and systemInit calls if any
|
||||||
if sfSystemModule in m.module.flags:
|
if sfSystemModule in m.module.flags:
|
||||||
if emulatedThreadVars(m.config) and m.config.target.targetOS != osStandalone:
|
if emulatedThreadVars(m.config) and m.config.target.targetOS != osStandalone:
|
||||||
add(g.mainDatInit, ropecg(m, "\t#initThreadVarsEmulation();$N"))
|
add(g.mainDatInit, ropecg(m, "\t#initThreadVarsEmulation();$N", []))
|
||||||
if m.config.target.targetOS != osStandalone and m.config.selectedGC != gcNone:
|
if m.config.target.targetOS != osStandalone and m.config.selectedGC != gcNone:
|
||||||
add(g.mainDatInit, ropecg(m, "\t#initStackBottomWith((void *)&inner);$N"))
|
add(g.mainDatInit, ropecg(m, "\t#initStackBottomWith((void *)&inner);$N", []))
|
||||||
|
|
||||||
if m.s[cfsInitProc].len > 0:
|
if m.s[cfsInitProc].len > 0:
|
||||||
addf(g.mainModProcs, "N_LIB_PRIVATE N_NIMCALL(void, $1)(void);$N", [init])
|
addf(g.mainModProcs, "N_LIB_PRIVATE N_NIMCALL(void, $1)(void);$N", [init])
|
||||||
|
|
@ -1503,13 +1576,13 @@ proc genInitCode(m: BModule) =
|
||||||
if m.hcrOn:
|
if m.hcrOn:
|
||||||
appcg(m, m.s[cfsTypeInit1], "\t#TNimNode* $1;$N", [m.typeNodesName])
|
appcg(m, m.s[cfsTypeInit1], "\t#TNimNode* $1;$N", [m.typeNodesName])
|
||||||
appcg(m, m.s[cfsTypeInit1], "\thcrRegisterGlobal($3, \"$1_$2\", sizeof(TNimNode) * $2, NULL, (void**)&$1);$N",
|
appcg(m, m.s[cfsTypeInit1], "\thcrRegisterGlobal($3, \"$1_$2\", sizeof(TNimNode) * $2, NULL, (void**)&$1);$N",
|
||||||
[m.typeNodesName, rope(m.typeNodes), getModuleDllPath(m, m.module)])
|
[m.typeNodesName, m.typeNodes, getModuleDllPath(m, m.module)])
|
||||||
else:
|
else:
|
||||||
appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n",
|
appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n",
|
||||||
[m.typeNodesName, rope(m.typeNodes)])
|
[m.typeNodesName, m.typeNodes])
|
||||||
if m.nimTypes > 0:
|
if m.nimTypes > 0:
|
||||||
appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n",
|
appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n",
|
||||||
[m.nimTypesName, rope(m.nimTypes)])
|
[m.nimTypesName, m.nimTypes])
|
||||||
|
|
||||||
if m.hcrOn:
|
if m.hcrOn:
|
||||||
addf(prc, "\tint* nim_hcr_dummy_ = 0;$n" &
|
addf(prc, "\tint* nim_hcr_dummy_ = 0;$n" &
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue