mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-15 23:54:19 +00:00
implemented mixed mode codegen
This commit is contained in:
@@ -291,6 +291,8 @@ const
|
||||
|
||||
sfNoRoot* = sfBorrow # a local variable is provably no root so it doesn't
|
||||
# require RC ops
|
||||
sfCompileToCpp* = sfInfixCall # compile the module as C++ code
|
||||
sfCompileToObjc* = sfNamedParamCall # compile the module as Objective-C code
|
||||
|
||||
const
|
||||
# getting ready for the future expr/stmt merge
|
||||
|
||||
@@ -103,9 +103,9 @@ proc openArrayLoc(p: BProc, n: PNode): PRope =
|
||||
result = ropef("$1, $1Len0", [rdLoc(a)])
|
||||
of tyString, tySequence:
|
||||
if skipTypes(n.typ, abstractInst).kind == tyVar:
|
||||
result = ropef("(*$1)->data, (*$1)->$2", [a.rdLoc, lenField()])
|
||||
result = ropef("(*$1)->data, (*$1)->$2", [a.rdLoc, lenField(p)])
|
||||
else:
|
||||
result = ropef("$1->data, $1->$2", [a.rdLoc, lenField()])
|
||||
result = ropef("$1->data, $1->$2", [a.rdLoc, lenField(p)])
|
||||
of tyArray, tyArrayConstr:
|
||||
result = ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])
|
||||
else: internalError("openArrayLoc: " & typeToString(a.t))
|
||||
|
||||
@@ -721,7 +721,7 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||
internalError(e.info, "genRecordField")
|
||||
field = lookupInRecord(ty.n, f.name)
|
||||
if field != nil: break
|
||||
if gCmd != cmdCompileToCpp: app(r, ".Sup")
|
||||
if not p.module.compileToCpp: app(r, ".Sup")
|
||||
ty = getUniqueType(ty.sons[0])
|
||||
if field == nil: internalError(e.info, "genRecordField 2 ")
|
||||
if field.loc.r == nil: internalError(e.info, "genRecordField 3")
|
||||
@@ -773,7 +773,7 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||
assert(ty.kind in {tyTuple, tyObject})
|
||||
field = lookupInRecord(ty.n, f.name)
|
||||
if field != nil: break
|
||||
if gCmd != cmdCompileToCpp: app(r, ".Sup")
|
||||
if not p.module.compileToCpp: app(r, ".Sup")
|
||||
ty = getUniqueType(ty.sons[0])
|
||||
if field == nil: internalError(e.info, "genCheckedRecordField")
|
||||
if field.loc.r == nil:
|
||||
@@ -840,11 +840,11 @@ proc genSeqElem(p: BProc, e: PNode, d: var TLoc) =
|
||||
if ty.kind == tyString:
|
||||
linefmt(p, cpsStmts,
|
||||
"if ((NU)($1) > (NU)($2->$3)) #raiseIndexError();$n",
|
||||
rdLoc(b), rdLoc(a), lenField())
|
||||
rdLoc(b), rdLoc(a), lenField(p))
|
||||
else:
|
||||
linefmt(p, cpsStmts,
|
||||
"if ((NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n",
|
||||
rdLoc(b), rdLoc(a), lenField())
|
||||
rdLoc(b), rdLoc(a), lenField(p))
|
||||
if d.k == locNone: d.s = OnHeap
|
||||
d.heapRoot = a.r
|
||||
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
|
||||
@@ -937,7 +937,7 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
|
||||
if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
|
||||
inc(L, len(e.sons[i + 1].strVal))
|
||||
else:
|
||||
appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
|
||||
appf(lens, "$1->$2 + ", [rdLoc(a), lenField(p)])
|
||||
app(appends, rfmt(p.module, "#appendString($1, $2);$n", tmp.r, rdLoc(a)))
|
||||
linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", tmp.r, lens, toRope(L))
|
||||
app(p.s(cpsStmts), appends)
|
||||
@@ -977,7 +977,7 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||
if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}:
|
||||
inc(L, len(e.sons[i + 2].strVal))
|
||||
else:
|
||||
appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
|
||||
appf(lens, "$1->$2 + ", [rdLoc(a), lenField(p)])
|
||||
app(appends, rfmt(p.module, "#appendString($1, $2);$n",
|
||||
rdLoc(dest), rdLoc(a)))
|
||||
linefmt(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
|
||||
@@ -990,7 +990,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||
# seq &= x -->
|
||||
# seq = (typeof seq) incrSeq(&seq->Sup, sizeof(x));
|
||||
# seq->data[seq->len-1] = x;
|
||||
let seqAppendPattern = if gCmd != cmdCompileToCpp:
|
||||
let seqAppendPattern = if not p.module.compileToCpp:
|
||||
"$1 = ($2) #incrSeq(&($1)->Sup, sizeof($3));$n"
|
||||
else:
|
||||
"$1 = ($2) #incrSeq($1, sizeof($3));$n"
|
||||
@@ -1003,7 +1003,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||
getTypeDesc(p.module, skipTypes(e.sons[2].typ, abstractVar))])
|
||||
keepAlive(p, a)
|
||||
initLoc(dest, locExpr, b.t, OnHeap)
|
||||
dest.r = rfmt(nil, "$1->data[$1->$2-1]", rdLoc(a), lenField())
|
||||
dest.r = rfmt(nil, "$1->data[$1->$2-1]", rdLoc(a), lenField(p))
|
||||
genAssignment(p, dest, b, {needToCopy, afDestIsNil})
|
||||
gcUsage(e)
|
||||
|
||||
@@ -1097,7 +1097,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||
while ty != nil:
|
||||
field = lookupInRecord(ty.n, it.sons[0].sym.name)
|
||||
if field != nil: break
|
||||
if gCmd != cmdCompileToCpp: app(tmp2.r, ".Sup")
|
||||
if not p.module.compileToCpp: app(tmp2.r, ".Sup")
|
||||
ty = getUniqueType(ty.sons[0])
|
||||
if field == nil or field.loc.r == nil: internalError(e.info, "genObjConstr")
|
||||
if it.len == 3 and optFieldCheck in p.options:
|
||||
@@ -1198,8 +1198,8 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||
if t.kind != tyVar: nilCheck = r
|
||||
r = rfmt(nil, "(*$1)", r)
|
||||
t = skipTypes(t.lastSon, typedescInst)
|
||||
if gCmd != cmdCompileToCpp:
|
||||
while (t.kind == tyObject) and (t.sons[0] != nil):
|
||||
if not p.module.compileToCpp:
|
||||
while t.kind == tyObject and t.sons[0] != nil:
|
||||
app(r, ~".Sup")
|
||||
t = skipTypes(t.sons[0], typedescInst)
|
||||
if isObjLackingTypeField(t):
|
||||
@@ -1244,7 +1244,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||
putIntoDest(p, b, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
|
||||
of tyString, tySequence:
|
||||
putIntoDest(p, b, e.typ,
|
||||
ropef("$1->data, $1->$2", [rdLoc(a), lenField()]))
|
||||
ropef("$1->data, $1->$2", [rdLoc(a), lenField(p)]))
|
||||
of tyArray, tyArrayConstr:
|
||||
putIntoDest(p, b, e.typ,
|
||||
ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
|
||||
@@ -1287,7 +1287,7 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
if op == mHigh: unaryExpr(p, e, d, "(strlen($1)-1)")
|
||||
else: unaryExpr(p, e, d, "strlen($1)")
|
||||
of tyString, tySequence:
|
||||
if gCmd != cmdCompileToCpp:
|
||||
if not p.module.compileToCpp:
|
||||
if op == mHigh: unaryExpr(p, e, d, "($1->Sup.len-1)")
|
||||
else: unaryExpr(p, e, d, "$1->Sup.len")
|
||||
else:
|
||||
@@ -1305,7 +1305,7 @@ proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
|
||||
initLocExpr(p, e.sons[1], a)
|
||||
initLocExpr(p, e.sons[2], b)
|
||||
var t = skipTypes(e.sons[1].typ, abstractVar)
|
||||
let setLenPattern = if gCmd != cmdCompileToCpp:
|
||||
let setLenPattern = if not p.module.compileToCpp:
|
||||
"$1 = ($3) #setLengthSeq(&($1)->Sup, sizeof($4), $2);$n"
|
||||
else:
|
||||
"$1 = ($3) #setLengthSeq($1, sizeof($4), $2);$n"
|
||||
@@ -1561,11 +1561,11 @@ proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
|
||||
elif (a.kind in {nkStrLit..nkTripleStrLit}) and (a.strVal == ""):
|
||||
initLocExpr(p, e.sons[2], x)
|
||||
putIntoDest(p, d, e.typ,
|
||||
rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField()))
|
||||
rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField(p)))
|
||||
elif (b.kind in {nkStrLit..nkTripleStrLit}) and (b.strVal == ""):
|
||||
initLocExpr(p, e.sons[1], x)
|
||||
putIntoDest(p, d, e.typ,
|
||||
rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField()))
|
||||
rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField(p)))
|
||||
else:
|
||||
binaryExpr(p, e, d, "#eqStrings($1, $2)")
|
||||
|
||||
@@ -1824,7 +1824,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||
if t.kind != tyVar: nilCheck = r
|
||||
r = ropef("(*$1)", [r])
|
||||
t = skipTypes(t.lastSon, abstractInst)
|
||||
if gCmd != cmdCompileToCpp:
|
||||
if not p.module.compileToCpp:
|
||||
while t.kind == tyObject and t.sons[0] != nil:
|
||||
app(r, ".Sup")
|
||||
t = skipTypes(t.sons[0], abstractInst)
|
||||
@@ -1842,7 +1842,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||
[getTypeDesc(p.module, dest), addrLoc(a)]))
|
||||
|
||||
proc downConv(p: BProc, n: PNode, d: var TLoc) =
|
||||
if gCmd == cmdCompileToCpp:
|
||||
if p.module.compileToCpp:
|
||||
expr(p, n.sons[0], d) # downcast does C++ for us
|
||||
else:
|
||||
var dest = skipTypes(n.typ, abstractPtrs)
|
||||
@@ -2028,7 +2028,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||
initLocExpr(p, n.sons[0], a)
|
||||
of nkAsmStmt: genAsmStmt(p, n)
|
||||
of nkTryStmt:
|
||||
if gCmd == cmdCompileToCpp: genTryCpp(p, n, d)
|
||||
if p.module.compileToCpp: genTryCpp(p, n, d)
|
||||
else: genTry(p, n, d)
|
||||
of nkRaiseStmt: genRaiseStmt(p, n)
|
||||
of nkTypeSection:
|
||||
|
||||
@@ -249,7 +249,7 @@ proc readMergeInfo*(cfilename: string, m: BModule) =
|
||||
break
|
||||
|
||||
type
|
||||
TMergeSections = object {.pure.}
|
||||
TMergeSections = object
|
||||
f: TCFileSections
|
||||
p: TCProcSections
|
||||
|
||||
|
||||
@@ -289,8 +289,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
||||
|
||||
var alreadyPoppedCnt = p.inExceptBlock
|
||||
for i in countup(1, howManyTrys):
|
||||
|
||||
if gCmd != cmdCompileToCpp:
|
||||
if not p.module.compileToCpp:
|
||||
# Pop safe points generated by try
|
||||
if alreadyPoppedCnt > 0:
|
||||
dec alreadyPoppedCnt
|
||||
@@ -312,7 +311,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
||||
for i in countdown(howManyTrys-1, 0):
|
||||
p.nestedTryStmts.add(stack[i])
|
||||
|
||||
if gCmd != cmdCompileToCpp:
|
||||
if not p.module.compileToCpp:
|
||||
# Pop exceptions that was handled by the
|
||||
# except-blocks we are in
|
||||
for i in countdown(howManyExcepts-1, 0):
|
||||
@@ -496,7 +495,7 @@ proc genBreakStmt(p: BProc, t: PNode) =
|
||||
lineF(p, cpsStmts, "goto $1;$n", [label])
|
||||
|
||||
proc getRaiseFrmt(p: BProc): string =
|
||||
if gCmd == cmdCompileToCpp:
|
||||
if p.module.compileToCpp:
|
||||
result = "throw NimException($1, $2);$n"
|
||||
elif getCompilerProc("Exception") != nil:
|
||||
result = "#raiseException((#Exception*)$1, $2);$n"
|
||||
@@ -517,10 +516,10 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
||||
var typ = skipTypes(t.sons[0].typ, abstractPtrs)
|
||||
genLineDir(p, t)
|
||||
lineCg(p, cpsStmts, getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)])
|
||||
else:
|
||||
else:
|
||||
genLineDir(p, t)
|
||||
# reraise the last exception:
|
||||
if gCmd == cmdCompileToCpp:
|
||||
if p.module.compileToCpp:
|
||||
line(p, cpsStmts, ~"throw;$n")
|
||||
else:
|
||||
linefmt(p, cpsStmts, "#reraiseException();$n")
|
||||
|
||||
@@ -49,8 +49,8 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, n: PNode) =
|
||||
genTraverseProc(c, ropef("$1.$2", accessor, field.loc.r), field.loc.t)
|
||||
else: internalError(n.info, "genTraverseProc()")
|
||||
|
||||
proc parentObj(accessor: PRope): PRope {.inline.} =
|
||||
if gCmd != cmdCompileToCpp:
|
||||
proc parentObj(accessor: PRope; m: BModule): PRope {.inline.} =
|
||||
if not m.compileToCpp:
|
||||
result = ropef("$1.Sup", accessor)
|
||||
else:
|
||||
result = accessor
|
||||
@@ -71,7 +71,7 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
|
||||
lineF(p, cpsStmts, "}$n")
|
||||
of tyObject:
|
||||
for i in countup(0, sonsLen(typ) - 1):
|
||||
genTraverseProc(c, accessor.parentObj, typ.sons[i])
|
||||
genTraverseProc(c, accessor.parentObj(c.p.module), typ.sons[i])
|
||||
if typ.n != nil: genTraverseProc(c, accessor, typ.n)
|
||||
of tyTuple:
|
||||
let typ = getUniqueType(typ)
|
||||
@@ -91,7 +91,7 @@ proc genTraverseProcSeq(c: var TTraversalClosure, accessor: PRope, typ: PType) =
|
||||
var i: TLoc
|
||||
getTemp(p, getSysType(tyInt), i)
|
||||
lineF(p, cpsStmts, "for ($1 = 0; $1 < $2->$3; $1++) {$n",
|
||||
i.r, accessor, toRope(if gCmd != cmdCompileToCpp: "Sup.len" else: "len"))
|
||||
i.r, accessor, toRope(if c.p.module.compileToCpp: "len" else: "Sup.len"))
|
||||
genTraverseProc(c, ropef("$1->data[$2]", accessor, i.r), typ.sons[0])
|
||||
lineF(p, cpsStmts, "}$n")
|
||||
|
||||
|
||||
@@ -342,8 +342,8 @@ proc getTypePre(m: BModule, typ: PType): PRope =
|
||||
proc structOrUnion(t: PType): PRope =
|
||||
(if tfUnion in t.flags: toRope("union") else: toRope("struct"))
|
||||
|
||||
proc getForwardStructFormat(): string =
|
||||
if gCmd == cmdCompileToCpp: result = "$1 $2;$n"
|
||||
proc getForwardStructFormat(m: BModule): string =
|
||||
if m.compileToCpp: result = "$1 $2;$n"
|
||||
else: result = "typedef $1 $2 $2;$n"
|
||||
|
||||
proc getTypeForward(m: BModule, typ: PType): PRope =
|
||||
@@ -355,7 +355,7 @@ proc getTypeForward(m: BModule, typ: PType): PRope =
|
||||
of tySequence, tyTuple, tyObject:
|
||||
result = getTypeName(typ)
|
||||
if not isImportedType(typ):
|
||||
appf(m.s[cfsForwardTypes], getForwardStructFormat(),
|
||||
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
|
||||
[structOrUnion(typ), result])
|
||||
idTablePut(m.forwTypeCache, typ, result)
|
||||
else: internalError("getTypeForward(" & $typ.kind & ')')
|
||||
@@ -442,7 +442,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: PRope,
|
||||
else:
|
||||
appcg(m, result, " {$n#TNimType* m_type;$n", [name, attribute])
|
||||
hasField = true
|
||||
elif gCmd == cmdCompileToCpp:
|
||||
elif m.compileToCpp:
|
||||
appcg(m, result, " : public $1 {$n",
|
||||
[getTypeDescAux(m, typ.sons[0], check)])
|
||||
hasField = true
|
||||
@@ -538,7 +538,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||
if result == nil:
|
||||
result = getTypeName(t)
|
||||
if not isImportedType(t):
|
||||
appf(m.s[cfsForwardTypes], getForwardStructFormat(),
|
||||
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
|
||||
[structOrUnion(t), result])
|
||||
idTablePut(m.forwTypeCache, t, result)
|
||||
assert(cacheGetType(m.typeCache, t) == nil)
|
||||
@@ -550,7 +550,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||
cSeq = "struct $2 {$n" &
|
||||
" #TGenericSeq Sup;$n"
|
||||
appcg(m, m.s[cfsSeqTypes],
|
||||
(if gCmd == cmdCompileToCpp: cppSeq else: cSeq) &
|
||||
(if m.compileToCpp: cppSeq else: cSeq) &
|
||||
" $1 data[SEQ_DECL_SIZE];$n" &
|
||||
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
||||
else:
|
||||
@@ -570,7 +570,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||
if result == nil:
|
||||
result = getTypeName(t)
|
||||
if not isImportedType(t):
|
||||
appf(m.s[cfsForwardTypes], getForwardStructFormat(),
|
||||
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
|
||||
[structOrUnion(t), result])
|
||||
idTablePut(m.forwTypeCache, t, result)
|
||||
idTablePut(m.typeCache, t, result) # always call for sideeffects:
|
||||
|
||||
@@ -171,7 +171,7 @@ proc mangle*(name: string): string =
|
||||
## Lowercases the given name and manges any non-alphanumeric characters
|
||||
## so they are represented as `HEX____`. If the name starts with a number,
|
||||
## `N` is prepended
|
||||
result = ""
|
||||
result = newStringOfCap(name.len)
|
||||
case name[0]
|
||||
of Letters:
|
||||
result.add(name[0].toLower)
|
||||
|
||||
@@ -297,6 +297,9 @@ proc accessThreadLocalVar(p: BProc, s: PSym)
|
||||
proc emulatedThreadVars(): bool {.inline.}
|
||||
proc genProc(m: BModule, prc: PSym)
|
||||
|
||||
template compileToCpp(m: BModule): expr =
|
||||
gCmd == cmdCompileToCpp or sfCompileToCpp in m.module.flags
|
||||
|
||||
include "ccgtypes.nim"
|
||||
|
||||
# ------------------------------ Manager of temporaries ------------------
|
||||
@@ -326,7 +329,7 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
|
||||
var r = rdLoc(a)
|
||||
if not takeAddr: r = ropef("(*$1)", [r])
|
||||
var s = skipTypes(t, abstractInst)
|
||||
if gCmd != cmdCompileToCpp:
|
||||
if not p.module.compileToCpp:
|
||||
while (s.kind == tyObject) and (s.sons[0] != nil):
|
||||
app(r, ".Sup")
|
||||
s = skipTypes(s.sons[0], abstractInst)
|
||||
@@ -506,7 +509,7 @@ proc assignLocalVar(p: BProc, s: PSym) =
|
||||
#elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
|
||||
# app(decl, " GC_GUARD")
|
||||
if sfVolatile in s.flags or (p.nestedTryStmts.len > 0 and
|
||||
gCmd != cmdCompileToCpp):
|
||||
not p.module.compileToCpp):
|
||||
app(decl, " volatile")
|
||||
appf(decl, " $1;$n", [s.loc.r])
|
||||
else:
|
||||
@@ -587,8 +590,8 @@ proc initLocExpr(p: BProc, e: PNode, result: var TLoc) =
|
||||
initLoc(result, locNone, e.typ, OnUnknown)
|
||||
expr(p, e, result)
|
||||
|
||||
proc lenField: PRope {.inline.} =
|
||||
result = toRope(if gCmd != cmdCompileToCpp: "Sup.len" else: "len")
|
||||
proc lenField(p: BProc): PRope =
|
||||
result = toRope(if p.module.compileToCpp: "len" else: "Sup.len")
|
||||
|
||||
include ccgcalls, "ccgstmts.nim", "ccgexprs.nim"
|
||||
|
||||
@@ -812,7 +815,12 @@ proc genProcAux(m: BModule, prc: PSym) =
|
||||
app(generatedProc, returnStmt)
|
||||
app(generatedProc, ~"}$N")
|
||||
app(m.s[cfsProcs], generatedProc)
|
||||
|
||||
|
||||
proc crossesCppBoundary(m: BModule; sym: PSym): bool {.inline.} =
|
||||
result = sfCompileToCpp in m.module.flags and
|
||||
sfCompileToCpp notin sym.getModule().flags and
|
||||
gCmd != cmdCompileToCpp
|
||||
|
||||
proc genProcPrototype(m: BModule, sym: PSym) =
|
||||
useHeader(m, sym)
|
||||
if lfNoDecl in sym.loc.flags: return
|
||||
@@ -824,6 +832,8 @@ proc genProcPrototype(m: BModule, sym: PSym) =
|
||||
if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
|
||||
elif not containsOrIncl(m.declaredProtos, sym.id):
|
||||
var header = genProcHeader(m, sym)
|
||||
if sym.typ.callConv != ccInline and crossesCppBoundary(m, sym):
|
||||
header = con("extern \"C\" ", header)
|
||||
if sfPure in sym.flags and hasNakedAttribute in CC[cCompiler].props:
|
||||
header.app(" __attribute__((naked))")
|
||||
app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header))
|
||||
@@ -915,7 +925,7 @@ proc addIntTypes(result: var PRope) {.inline.} =
|
||||
appf(result, "#define NIM_INTBITS $1", [
|
||||
platform.CPU[targetCPU].intSize.toRope])
|
||||
|
||||
proc getCopyright(cfilenoext: string): PRope =
|
||||
proc getCopyright(cfile: string): PRope =
|
||||
if optCompileOnly in gGlobalOptions:
|
||||
result = ropeff("/* Generated by Nim Compiler v$1 */$N" &
|
||||
"/* (c) 2014 Andreas Rumpf */$N" &
|
||||
@@ -935,10 +945,10 @@ proc getCopyright(cfilenoext: string): PRope =
|
||||
toRope(platform.OS[targetOS].name),
|
||||
toRope(platform.CPU[targetCPU].name),
|
||||
toRope(extccomp.CC[extccomp.cCompiler].name),
|
||||
toRope(getCompileCFileCmd(cfilenoext))])
|
||||
toRope(getCompileCFileCmd(cfile))])
|
||||
|
||||
proc getFileHeader(cfilenoext: string): PRope =
|
||||
result = getCopyright(cfilenoext)
|
||||
proc getFileHeader(cfile: string): PRope =
|
||||
result = getCopyright(cfile)
|
||||
addIntTypes(result)
|
||||
|
||||
proc genFilenames(m: BModule): PRope =
|
||||
@@ -1078,9 +1088,9 @@ proc registerModuleToMain(m: PSym) =
|
||||
var
|
||||
init = m.getInitName
|
||||
datInit = m.getDatInitName
|
||||
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N",
|
||||
appff(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N",
|
||||
"declare void $1() noinline$N", [init])
|
||||
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N",
|
||||
appff(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N",
|
||||
"declare void $1() noinline$N", [datInit])
|
||||
if sfSystemModule notin m.flags:
|
||||
appff(mainDatInit, "\t$1();$N", "call void ()* $1$n", [datInit])
|
||||
@@ -1092,7 +1102,7 @@ proc registerModuleToMain(m: PSym) =
|
||||
|
||||
proc genInitCode(m: BModule) =
|
||||
var initname = getInitName(m.module)
|
||||
var prc = ropeff("N_NOINLINE(void, $1)(void) {$N",
|
||||
var prc = ropeff("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
|
||||
"define void $1() noinline {$n", [initname])
|
||||
if m.typeNodes > 0:
|
||||
appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n",
|
||||
@@ -1135,7 +1145,7 @@ proc genInitCode(m: BModule) =
|
||||
app(prc, deinitGCFrame(m.initProc))
|
||||
appf(prc, "}$N$N")
|
||||
|
||||
prc.appff("N_NOINLINE(void, $1)(void) {$N",
|
||||
prc.appff("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
|
||||
"define void $1() noinline {$n", [getDatInitName(m.module)])
|
||||
|
||||
for i in cfsTypeInit1..cfsDynLibInit:
|
||||
@@ -1155,8 +1165,8 @@ proc genInitCode(m: BModule) =
|
||||
(i.ord - '0'.ord).toRope, el)
|
||||
app(m.s[cfsInitProc], ex)
|
||||
|
||||
proc genModule(m: BModule, cfilenoext: string): PRope =
|
||||
result = getFileHeader(cfilenoext)
|
||||
proc genModule(m: BModule, cfile: string): PRope =
|
||||
result = getFileHeader(cfile)
|
||||
result.app(genMergeInfo(m))
|
||||
|
||||
generateHeaders(m)
|
||||
@@ -1297,7 +1307,11 @@ proc writeHeader(m: BModule) =
|
||||
writeRope(result, m.filename)
|
||||
|
||||
proc getCFile(m: BModule): string =
|
||||
result = changeFileExt(completeCFilePath(m.cfilename.withPackageName), cExt)
|
||||
let ext =
|
||||
if m.compileToCpp: ".cpp"
|
||||
elif gCmd == cmdCompileToOC or sfCompileToObjC in m.module.flags: ".m"
|
||||
else: ".c"
|
||||
result = changeFileExt(completeCFilePath(m.cfilename.withPackageName), ext)
|
||||
|
||||
proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
|
||||
assert optSymbolFiles in gGlobalOptions
|
||||
@@ -1326,10 +1340,10 @@ proc finishModule(m: BModule) =
|
||||
dec(gForwardedProcsCounter, i)
|
||||
setLen(m.forwardedProcs, 0)
|
||||
|
||||
proc shouldRecompile(code: PRope, cfile, cfilenoext: string): bool =
|
||||
proc shouldRecompile(code: PRope, cfile: string): bool =
|
||||
result = true
|
||||
if optForceFullMake notin gGlobalOptions:
|
||||
var objFile = toObjFile(cfilenoext)
|
||||
var objFile = toObjFile(cfile)
|
||||
if writeRopeIfNotEqual(code, cfile): return
|
||||
if existsFile(objFile) and os.fileNewer(objFile, cfile): result = false
|
||||
else:
|
||||
@@ -1354,26 +1368,26 @@ proc writeModule(m: BModule, pending: bool) =
|
||||
app(m.s[cfsProcHeaders], mainModProcs)
|
||||
generateThreadVarsSize(m)
|
||||
|
||||
var code = genModule(m, cfilenoext)
|
||||
var code = genModule(m, cfile)
|
||||
when hasTinyCBackend:
|
||||
if gCmd == cmdRun:
|
||||
tccgen.compileCCode(ropeToStr(code))
|
||||
return
|
||||
|
||||
if shouldRecompile(code, cfile, cfilenoext):
|
||||
addFileToCompile(cfilenoext)
|
||||
if shouldRecompile(code, cfile):
|
||||
addFileToCompile(cfile)
|
||||
elif pending and mergeRequired(m) and sfMainModule notin m.module.flags:
|
||||
mergeFiles(cfile, m)
|
||||
genInitCode(m)
|
||||
finishTypeDescriptions(m)
|
||||
var code = genModule(m, cfilenoext)
|
||||
var code = genModule(m, cfile)
|
||||
writeRope(code, cfile)
|
||||
addFileToCompile(cfilenoext)
|
||||
addFileToCompile(cfile)
|
||||
elif not existsFile(toObjFile(cfilenoext)):
|
||||
# Consider: first compilation compiles ``system.nim`` and produces
|
||||
# ``system.c`` but then compilation fails due to an error. This means
|
||||
# that ``system.o`` is missing, so we need to call the C compiler for it:
|
||||
addFileToCompile(cfilenoext)
|
||||
addFileToCompile(cfile)
|
||||
|
||||
addFileToLink(cfilenoext)
|
||||
|
||||
@@ -1385,9 +1399,9 @@ proc updateCachedModule(m: BModule) =
|
||||
mergeFiles(cfile, m)
|
||||
genInitCode(m)
|
||||
finishTypeDescriptions(m)
|
||||
var code = genModule(m, cfilenoext)
|
||||
var code = genModule(m, cfile)
|
||||
writeRope(code, cfile)
|
||||
addFileToCompile(cfilenoext)
|
||||
addFileToCompile(cfile)
|
||||
|
||||
addFileToLink(cfilenoext)
|
||||
|
||||
|
||||
@@ -323,10 +323,7 @@ const
|
||||
|
||||
var
|
||||
cCompiler* = ccGcc # the used compiler
|
||||
|
||||
cExt* = ".c" # extension of generated C/C++ files
|
||||
# (can be changed to .cpp later)
|
||||
|
||||
gMixedMode*: bool # true if some module triggered C++ codegen
|
||||
cIncludes*: seq[string] = @[] # directories to search for included files
|
||||
cLibs*: seq[string] = @[] # directories to search for lib files
|
||||
cLinkedLibs*: seq[string] = @[] # libraries to link
|
||||
@@ -387,8 +384,6 @@ proc initVars*() =
|
||||
# we need to define the symbol here, because ``CC`` may have never been set!
|
||||
for i in countup(low(CC), high(CC)): undefSymbol(CC[i].name)
|
||||
defineSymbol(CC[cCompiler].name)
|
||||
if gCmd == cmdCompileToCpp: cExt = ".cpp"
|
||||
elif gCmd == cmdCompileToOC: cExt = ".m"
|
||||
addCompileOption(getConfigVar(cCompiler, ".options.always"))
|
||||
addLinkOption(getConfigVar(cCompiler, ".options.linker"))
|
||||
if len(ccompilerpath) == 0:
|
||||
@@ -397,9 +392,9 @@ proc initVars*() =
|
||||
proc completeCFilePath*(cfile: string, createSubDir: bool = true): string =
|
||||
result = completeGeneratedFilePath(cfile, createSubDir)
|
||||
|
||||
proc toObjFile*(filenameWithoutExt: string): string =
|
||||
proc toObjFile*(filename: string): string =
|
||||
# Object file for compilation
|
||||
result = changeFileExt(filenameWithoutExt, CC[cCompiler].objExt)
|
||||
result = changeFileExt(filename, CC[cCompiler].objExt)
|
||||
|
||||
proc addFileToCompile*(filename: string) =
|
||||
appendStr(toCompile, filename)
|
||||
@@ -497,6 +492,7 @@ proc getCompilerExe(compiler: TSystemCC): string =
|
||||
|
||||
proc getLinkerExe(compiler: TSystemCC): string =
|
||||
result = if CC[compiler].linkerExe.len > 0: CC[compiler].linkerExe
|
||||
elif gMixedMode and gCmd != cmdCompileToCpp: CC[compiler].cppCompiler
|
||||
else: compiler.getCompilerExe
|
||||
|
||||
proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
|
||||
@@ -507,11 +503,11 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
|
||||
|
||||
if needsExeExt(): exe = addFileExt(exe, "exe")
|
||||
if optGenDynLib in gGlobalOptions and
|
||||
ospNeedsPIC in platform.OS[targetOS].props:
|
||||
ospNeedsPIC in platform.OS[targetOS].props:
|
||||
add(options, ' ' & CC[c].pic)
|
||||
|
||||
var includeCmd, compilePattern: string
|
||||
if not noAbsolutePaths():
|
||||
if not noAbsolutePaths():
|
||||
# compute include paths:
|
||||
includeCmd = CC[c].includeCmd & quoteShell(libpath)
|
||||
|
||||
@@ -519,26 +515,27 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
|
||||
includeCmd.add([CC[c].includeCmd, includeDir.quoteShell])
|
||||
|
||||
compilePattern = joinPath(ccompilerpath, exe)
|
||||
else:
|
||||
else:
|
||||
includeCmd = ""
|
||||
compilePattern = c.getCompilerExe
|
||||
|
||||
var cfile = if noAbsolutePaths(): extractFilename(cfilename)
|
||||
var cfile = if noAbsolutePaths(): extractFilename(cfilename)
|
||||
else: cfilename
|
||||
var objfile = if not isExternal or noAbsolutePaths():
|
||||
toObjFile(cfile)
|
||||
else:
|
||||
var objfile = if not isExternal or noAbsolutePaths():
|
||||
toObjFile(cfile)
|
||||
else:
|
||||
completeCFilePath(toObjFile(cfile))
|
||||
cfile = quoteShell(addFileExt(cfile, cExt))
|
||||
objfile = quoteShell(objfile)
|
||||
result = quoteShell(compilePattern % [
|
||||
"file", cfile, "objfile", objfile, "options", options,
|
||||
"include", includeCmd, "nimrod", getPrefixDir(), "lib", libpath])
|
||||
"file", cfile, "objfile", objfile, "options", options,
|
||||
"include", includeCmd, "nimrod", getPrefixDir(),
|
||||
"nim", getPrefixDir(), "lib", libpath])
|
||||
add(result, ' ')
|
||||
addf(result, CC[c].compileTmpl, [
|
||||
"file", cfile, "objfile", objfile,
|
||||
"options", options, "include", includeCmd,
|
||||
"nimrod", quoteShell(getPrefixDir()),
|
||||
"file", cfile, "objfile", objfile,
|
||||
"options", options, "include", includeCmd,
|
||||
"nimrod", quoteShell(getPrefixDir()),
|
||||
"nim", quoteShell(getPrefixDir()),
|
||||
"lib", quoteShell(libpath)])
|
||||
|
||||
proc footprint(filename: string): TCrc32 =
|
||||
@@ -668,7 +665,7 @@ proc callCCompiler*(projectfile: string) =
|
||||
proc genMappingFiles(list: TLinkedList): PRope =
|
||||
var it = PStrEntry(list.head)
|
||||
while it != nil:
|
||||
appf(result, "--file:r\"$1\"$N", [toRope(addFileExt(it.data, cExt))])
|
||||
appf(result, "--file:r\"$1\"$N", [toRope(it.data)])
|
||||
it = PStrEntry(it.next)
|
||||
|
||||
proc writeMapping*(gSymbolMapping: PRope) =
|
||||
|
||||
@@ -272,13 +272,11 @@ proc mainCommand* =
|
||||
gCmd = cmdCompileToC
|
||||
commandCompileToC()
|
||||
of "cpp", "compiletocpp":
|
||||
extccomp.cExt = ".cpp"
|
||||
gCmd = cmdCompileToCpp
|
||||
if cCompiler == ccGcc: setCC("gcc")
|
||||
defineSymbol("cpp")
|
||||
commandCompileToC()
|
||||
of "objc", "compiletooc":
|
||||
extccomp.cExt = ".m"
|
||||
gCmd = cmdCompileToOC
|
||||
defineSymbol("objc")
|
||||
commandCompileToC()
|
||||
|
||||
@@ -128,12 +128,17 @@ proc processImportCpp(s: PSym, extname: string) =
|
||||
incl(s.flags, sfImportc)
|
||||
incl(s.flags, sfInfixCall)
|
||||
excl(s.flags, sfForward)
|
||||
let m = s.getModule()
|
||||
incl(m.flags, sfCompileToCpp)
|
||||
extccomp.gMixedMode = true
|
||||
|
||||
proc processImportObjC(s: PSym, extname: string) =
|
||||
setExternName(s, extname)
|
||||
incl(s.flags, sfImportc)
|
||||
incl(s.flags, sfNamedParamCall)
|
||||
excl(s.flags, sfForward)
|
||||
let m = s.getModule()
|
||||
incl(m.flags, sfCompileToObjC)
|
||||
|
||||
proc newEmptyStrNode(n: PNode): PNode {.noinline.} =
|
||||
result = newNodeIT(nkStrLit, n.info, getSysType(tyString))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
|
||||
Nimrod's Runtime Library
|
||||
(c) Copyright 2013 Andreas Rumpf
|
||||
Nim's Runtime Library
|
||||
(c) Copyright 2014 Andreas Rumpf
|
||||
|
||||
See the file "copying.txt", included in this
|
||||
distribution, for details about the copyright.
|
||||
@@ -384,3 +384,9 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
|
||||
"error: 'assert_numbits' declared as an array with a negative size" */
|
||||
typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define NIM_EXTERNC extern "C"
|
||||
#else
|
||||
# define NIM_EXTERNC
|
||||
#endif
|
||||
|
||||
4
todo.txt
4
todo.txt
@@ -3,8 +3,6 @@ version 0.10
|
||||
|
||||
- Test nimfix on various babel packages
|
||||
|
||||
- VM: Pegs do not work at compile-time
|
||||
- VM: ptr/ref T cannot work in general
|
||||
|
||||
version 0.9.6
|
||||
=============
|
||||
@@ -41,6 +39,8 @@ Misc
|
||||
Bugs
|
||||
====
|
||||
|
||||
- VM: Pegs do not work at compile-time
|
||||
- VM: ptr/ref T cannot work in general
|
||||
- scopes are still broken for generic instantiation!
|
||||
- bug: type conversions concerning proc types are weird
|
||||
- compilation of niminst takes way too long. looks like a regression
|
||||
|
||||
19
web/news.txt
19
web/news.txt
@@ -52,13 +52,30 @@ News
|
||||
- Recursive tuple types are not allowed anymore. Use ``object`` instead.
|
||||
|
||||
|
||||
Compiler Additions
|
||||
------------------
|
||||
|
||||
- The compiler now supports *mixed* Objective C / C++ / C code generation:
|
||||
The modules that use ``importCpp`` or ``importObjc`` are compiled to C++
|
||||
or Objective C code, any other module is compiled to C code. This
|
||||
improves interoperability.
|
||||
|
||||
|
||||
Language Additions
|
||||
------------------
|
||||
|
||||
- There is a new ``parallel`` statement for safe fork&join parallel computing.
|
||||
- ``guard`` and ``lock`` pragmas have been implemented to support safer
|
||||
concurrent programming.
|
||||
- ``system.writeFile`` can be used at compile-time.
|
||||
- The following procs are now available at compile-time::
|
||||
|
||||
math.sqrt, math.ln, math.log10, math.log2, math.exp, math.round,
|
||||
math.arccos, math.arcsin, math.arctan, math.arctan2, math.cos, math.cosh,
|
||||
math.hypot, math.sinh, math.sin, math.tan, math.tanh, math.pow,
|
||||
math.trunc, math.floor, math.ceil, math.fmod,
|
||||
os.getEnv, os.existsEnv, os.dirExists, os.fileExists,
|
||||
system.writeFile
|
||||
|
||||
|
||||
Library Additions
|
||||
-----------------
|
||||
|
||||
Reference in New Issue
Block a user