diff options
Diffstat (limited to 'compiler/cgen.nim')
-rw-r--r-- | compiler/cgen.nim | 328 |
1 files changed, 166 insertions, 162 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim index cc376d87a..ebe812e8b 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -9,7 +9,7 @@ ## This module implements the C code generator. -import +import ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options, intsets, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os, @@ -25,7 +25,7 @@ when options.hasTinyCBackend: var generatedHeader: BModule -proc addForwardedProc(m: BModule, prc: PSym) = +proc addForwardedProc(m: BModule, prc: PSym) = m.forwardedProcs.add(prc) inc(gForwardedProcsCounter) @@ -33,7 +33,7 @@ proc getCgenModule(s: PSym): BModule = result = if s.position >= 0 and s.position < gModules.len: gModules[s.position] else: nil -proc findPendingModule(m: BModule, s: PSym): BModule = +proc findPendingModule(m: BModule, s: PSym): BModule = var ms = getModule(s) result = gModules[ms.position] @@ -41,21 +41,21 @@ proc emitLazily(s: PSym): bool {.inline.} = result = optDeadCodeElim in gGlobalOptions or sfDeadCodeElim in getModule(s).flags -proc initLoc(result: var TLoc, k: TLocKind, typ: PType, s: TStorageLoc) = +proc initLoc(result: var TLoc, k: TLocKind, typ: PType, s: TStorageLoc) = result.k = k result.s = s result.t = typ result.r = nil result.flags = {} -proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: PRope, s: TStorageLoc) = +proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: PRope, s: TStorageLoc) = # fills the loc if it is not already initialized - if a.k == locNone: + if a.k == locNone: a.k = k a.t = typ a.s = s if a.r == nil: a.r = r - + proc isSimpleConst(typ: PType): bool = let t = skipTypes(typ, abstractVar) result = t.kind notin @@ -67,43 +67,43 @@ proc useStringh(m: BModule) = m.includesStringh = true discard lists.includeStr(m.headerFiles, "<string.h>") -proc useHeader(m: BModule, sym: PSym) = - if lfHeader in sym.loc.flags: +proc useHeader(m: BModule, sym: PSym) = + if lfHeader in sym.loc.flags: assert(sym.annex != nil) discard lists.includeStr(m.headerFiles, getStr(sym.annex.path)) proc cgsym(m: BModule, name: string): PRope -proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope = +proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope = var i = 0 var length = len(frmt) result = nil var num = 0 - while i < length: - if frmt[i] == '$': + while i < length: + if frmt[i] == '$': inc(i) # skip '$' case frmt[i] - of '$': + of '$': app(result, "$") inc(i) - of '#': + of '#': inc(i) app(result, args[num]) inc(num) - of '0'..'9': + of '0'..'9': var j = 0 - while true: + while true: j = (j * 10) + ord(frmt[i]) - ord('0') 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 - if j > high(args) + 1: + if j > high(args) + 1: internalError("ropes: invalid format string $" & $j) app(result, args[j-1]) of 'n': if optLineDir notin gOptions: app(result, rnl) inc(i) - of 'N': + of 'N': app(result, rnl) inc(i) else: internalError("ropes: invalid format string $" & frmt[i]) @@ -117,37 +117,37 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope = elif frmt[i] == '#' and frmt[i+1] == '$': inc(i, 2) var j = 0 - while frmt[i] in Digits: + while frmt[i] in Digits: j = (j * 10) + ord(frmt[i]) - ord('0') inc(i) app(result, cgsym(m, args[j-1].ropeToStr)) var start = i - while i < length: + while i < length: if frmt[i] != '$' and frmt[i] != '#': inc(i) - else: break - if i - 1 >= start: + else: break + if i - 1 >= start: app(result, substr(frmt, start, i - 1)) template rfmt(m: BModule, fmt: string, args: varargs[PRope]): expr = ropecg(m, fmt, args) -proc appcg(m: BModule, c: var PRope, frmt: TFormatStr, - args: varargs[PRope]) = +proc appcg(m: BModule, c: var PRope, frmt: TFormatStr, + args: varargs[PRope]) = app(c, ropecg(m, frmt, args)) -proc appcg(m: BModule, s: TCFileSection, frmt: TFormatStr, - args: varargs[PRope]) = +proc appcg(m: BModule, s: TCFileSection, frmt: TFormatStr, + args: varargs[PRope]) = app(m.s[s], ropecg(m, frmt, args)) -proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr, - args: varargs[PRope]) = +proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr, + args: varargs[PRope]) = app(p.s(s), ropecg(p.module, frmt, args)) var indent = "\t".toRope proc indentLine(p: BProc, r: PRope): PRope = result = r for i in countup(0, p.blocks.len-1): prepend(result, indent) - + proc line(p: BProc, s: TCProcSection, r: PRope) = app(p.s(s), indentLine(p, r)) @@ -180,7 +180,7 @@ proc genCLineDir(r: var PRope, filename: string, line: int) = appf(r, "$N#line $2 $1$N", [toRope(makeSingleLineCString(filename)), toRope(line)]) -proc genCLineDir(r: var PRope, info: TLineInfo) = +proc genCLineDir(r: var PRope, info: TLineInfo) = genCLineDir(r, info.toFullPath, info.safeLineNm) proc genLineDir(p: BProc, t: PNode) = @@ -261,7 +261,9 @@ proc isComplexValueType(t: PType): bool {.inline.} = proc resetLoc(p: BProc, loc: var TLoc) = let containsGcRef = containsGarbageCollectedRef(loc.t) - if not isComplexValueType(skipTypes(loc.t, abstractVarRange)): + let typ = skipTypes(loc.t, abstractVarRange) + if isImportedCppType(typ): return + if not isComplexValueType(typ): if containsGcRef: var nilLoc: TLoc initLoc(nilLoc, locTemp, loc.t, OnStack) @@ -282,35 +284,37 @@ proc resetLoc(p: BProc, loc: var TLoc) = useStringh(p.module) linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", addrLoc(loc), rdLoc(loc)) - # 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? genObjectInit(p, cpsStmts, loc.t, loc, true) proc constructLoc(p: BProc, loc: TLoc, isTemp = false) = - if not isComplexValueType(skipTypes(loc.t, abstractRange)): + let typ = skipTypes(loc.t, abstractRange) + if not isComplexValueType(typ): linefmt(p, cpsStmts, "$1 = 0;$n", rdLoc(loc)) else: if not isTemp or containsGarbageCollectedRef(loc.t): # don't use memset for temporary values for performance if we can # avoid it: - useStringh(p.module) - linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", - addrLoc(loc), rdLoc(loc)) + if not isImportedCppType(typ): + useStringh(p.module) + linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n", + addrLoc(loc), rdLoc(loc)) genObjectInit(p, cpsStmts, loc.t, loc, true) proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) = if sfNoInit notin v.flags: # we know it is a local variable and thus on the stack! # If ``not immediateAsgn`` it is not initialized in a binding like - # ``var v = X`` and thus we need to init it. + # ``var v = X`` and thus we need to init it. # If ``v`` contains a GC-ref we may pass it to ``unsureAsgnRef`` somehow # which requires initialization. However this can really only happen if - # ``var v = X()`` gets transformed into ``X(&v)``. + # ``var v = X()`` gets transformed into ``X(&v)``. # Nowadays the logic in ccgcalls deals with this case however. if not immediateAsgn: constructLoc(p, v.loc) -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) result.r = con("LOC", toRope(p.labels)) linefmt(p, cpsLocals, "$1 $2;$n", getTypeDesc(p.module, t), result.r) @@ -353,10 +357,10 @@ proc deinitGCFrame(p: BProc): PRope = if p.gcFrameId > 0: result = ropecg(p.module, "if (((NU)&GCFRAME) < 4096) #nimGCFrame(&GCFRAME);$n") - -proc allocParam(p: BProc, s: PSym) = + +proc allocParam(p: BProc, s: PSym) = assert(s.kind == skParam) - if lfParamCopy notin s.loc.flags: + if lfParamCopy notin s.loc.flags: inc(p.labels) var tmp = con("%LOC", toRope(p.labels)) incl(s.loc.flags, lfParamCopy) @@ -365,8 +369,8 @@ proc allocParam(p: BProc, s: PSym) = [tmp, s.loc.r, getTypeDesc(p.module, s.loc.t)]) s.loc.r = tmp -proc localDebugInfo(p: BProc, s: PSym) = - if {optStackTrace, optEndb} * p.options != {optStackTrace, optEndb}: return +proc localDebugInfo(p: BProc, s: PSym) = + if {optStackTrace, optEndb} * p.options != {optStackTrace, optEndb}: return # XXX work around a bug: No type information for open arrays possible: if skipTypes(s.typ, abstractVar).kind in {tyOpenArray, tyVarargs}: return var a = con("&", s.loc.r) @@ -379,7 +383,7 @@ proc localDebugInfo(p: BProc, s: PSym) = inc p.blocks[p.blocks.len-1].frameLen proc localVarDecl(p: BProc; s: PSym): PRope = - if s.loc.k == locNone: + if s.loc.k == locNone: fillLoc(s.loc, locLocalVar, s.typ, mangleName(s), OnStack) if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy) result = getTypeDesc(p.module, s.loc.t) @@ -406,22 +410,22 @@ include ccgthreadvars proc varInDynamicLib(m: BModule, sym: PSym) proc mangleDynLibProc(sym: PSym): PRope -proc assignGlobalVar(p: BProc, s: PSym) = - if s.loc.k == locNone: +proc assignGlobalVar(p: BProc, s: PSym) = + if s.loc.k == locNone: fillLoc(s.loc, locGlobalVar, s.typ, mangleName(s), OnHeap) - + if lfDynamicLib in s.loc.flags: var q = findPendingModule(p.module, s) - if q != nil and not containsOrIncl(q.declaredThings, s.id): + if q != nil and not containsOrIncl(q.declaredThings, s.id): varInDynamicLib(q, s) else: s.loc.r = mangleDynLibProc(s) return useHeader(p.module, s) if lfNoDecl in s.loc.flags: return - if sfThread in s.flags: + if sfThread in s.flags: declareThreadVar(p.module, s, sfImportc in s.flags) - else: + else: var decl: PRope = nil var td = getTypeDesc(p.module, s.loc.t) if s.constraint.isNil: @@ -437,25 +441,25 @@ proc assignGlobalVar(p: BProc, s: PSym) = # fixes tests/run/tzeroarray: resetLoc(p, s.loc) if p.module.module.options * {optStackTrace, optEndb} == - {optStackTrace, optEndb}: - appcg(p.module, p.module.s[cfsDebugInit], - "#dbgRegisterGlobal($1, &$2, $3);$n", - [makeCString(normalize(s.owner.name.s & '.' & s.name.s)), + {optStackTrace, optEndb}: + appcg(p.module, p.module.s[cfsDebugInit], + "#dbgRegisterGlobal($1, &$2, $3);$n", + [makeCString(normalize(s.owner.name.s & '.' & s.name.s)), s.loc.r, genTypeInfo(p.module, s.typ)]) - -proc assignParam(p: BProc, s: PSym) = + +proc assignParam(p: BProc, s: PSym) = assert(s.loc.r != nil) localDebugInfo(p, s) -proc fillProcLoc(sym: PSym) = - if sym.loc.k == locNone: +proc fillProcLoc(sym: PSym) = + if sym.loc.k == locNone: fillLoc(sym.loc, locProc, sym.typ, mangleName(sym), OnStack) - -proc getLabel(p: BProc): TLabel = + +proc getLabel(p: BProc): TLabel = inc(p.labels) result = con("LA", toRope(p.labels)) -proc fixLabel(p: BProc, labl: TLabel) = +proc fixLabel(p: BProc, labl: TLabel) = lineF(p, cpsStmts, "$1: ;$n", [labl]) proc genVarPrototype(m: BModule, sym: PSym) @@ -487,12 +491,12 @@ include ccgcalls, "ccgstmts.nim", "ccgexprs.nim" proc isGetProcAddr(lib: PLib): bool = let n = lib.path - result = n.kind in nkCallKinds and n.typ != nil and + result = n.kind in nkCallKinds and n.typ != nil and n.typ.kind in {tyPointer, tyProc} -proc loadDynamicLib(m: BModule, lib: PLib) = +proc loadDynamicLib(m: BModule, lib: PLib) = assert(lib != nil) - if not lib.generated: + if not lib.generated: lib.generated = true var tmp = getGlobalTempName() assert(lib.name == nil) @@ -504,14 +508,14 @@ proc loadDynamicLib(m: BModule, lib: PLib) = if gVerbosity >= 2: msgWriteln("Dependency: " & lib.path.strVal) var loadlib: PRope = nil - for i in countup(0, high(s)): + for i in countup(0, high(s)): inc(m.labels) if i > 0: app(loadlib, "||") - appcg(m, loadlib, "($1 = #nimLoadLibrary((#NimStringDesc*) &$2))$n", + appcg(m, loadlib, "($1 = #nimLoadLibrary((#NimStringDesc*) &$2))$n", [tmp, getStrLit(m, s[i])]) - appcg(m, m.s[cfsDynLibInit], - "if (!($1)) #nimLoadLibraryError((#NimStringDesc*) &$2);$n", - [loadlib, getStrLit(m, lib.path.strVal)]) + appcg(m, m.s[cfsDynLibInit], + "if (!($1)) #nimLoadLibraryError((#NimStringDesc*) &$2);$n", + [loadlib, getStrLit(m, lib.path.strVal)]) else: var p = newProc(nil, m) p.options = p.options - {optStackTrace, optEndb} @@ -520,20 +524,20 @@ proc loadDynamicLib(m: BModule, lib: PLib) = app(m.s[cfsVars], p.s(cpsLocals)) app(m.s[cfsDynLibInit], p.s(cpsInit)) app(m.s[cfsDynLibInit], p.s(cpsStmts)) - appcg(m, m.s[cfsDynLibInit], - "if (!($1 = #nimLoadLibrary($2))) #nimLoadLibraryError($2);$n", + appcg(m, m.s[cfsDynLibInit], + "if (!($1 = #nimLoadLibrary($2))) #nimLoadLibraryError($2);$n", [tmp, rdLoc(dest)]) - + if lib.name == nil: internalError("loadDynamicLib") - + proc mangleDynLibProc(sym: PSym): PRope = - if sfCompilerProc in sym.flags: + if sfCompilerProc in sym.flags: # NOTE: sym.loc.r is the external name! result = toRope(sym.name.s) else: result = ropef("Dl_$1", [toRope(sym.id)]) - -proc symInDynamicLib(m: BModule, sym: PSym) = + +proc symInDynamicLib(m: BModule, sym: PSym) = var lib = sym.annex let isCall = isGetProcAddr(lib) var extname = sym.loc.r @@ -565,13 +569,13 @@ proc symInDynamicLib(m: BModule, sym: PSym) = else: internalError(sym.info, "wrong index: " & idx) else: - appcg(m, m.s[cfsDynLibInit], - "\t$1 = ($2) #nimGetProcAddr($3, $4);$n", - [tmp, getTypeDesc(m, sym.typ), + appcg(m, m.s[cfsDynLibInit], + "\t$1 = ($2) #nimGetProcAddr($3, $4);$n", + [tmp, getTypeDesc(m, sym.typ), lib.name, makeCString(ropeToStr(extname))]) appf(m.s[cfsVars], "$2 $1;$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)]) -proc varInDynamicLib(m: BModule, sym: PSym) = +proc varInDynamicLib(m: BModule, sym: PSym) = var lib = sym.annex var extname = sym.loc.r loadDynamicLib(m, lib) @@ -579,9 +583,9 @@ proc varInDynamicLib(m: BModule, sym: PSym) = var tmp = mangleDynLibProc(sym) sym.loc.r = tmp # from now on we only need the internal name inc(m.labels, 2) - appcg(m, m.s[cfsDynLibInit], - "$1 = ($2*) #nimGetProcAddr($3, $4);$n", - [tmp, getTypeDesc(m, sym.typ), + appcg(m, m.s[cfsDynLibInit], + "$1 = ($2*) #nimGetProcAddr($3, $4);$n", + [tmp, getTypeDesc(m, sym.typ), lib.name, makeCString(ropeToStr(extname))]) appf(m.s[cfsVars], "$2* $1;$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)]) @@ -590,9 +594,9 @@ proc symInDynamicLibPartial(m: BModule, sym: PSym) = sym.loc.r = mangleDynLibProc(sym) sym.typ.sym = nil # generate a new name -proc cgsym(m: BModule, name: string): PRope = +proc cgsym(m: BModule, name: string): PRope = var sym = magicsys.getCompilerProc(name) - if sym != nil: + if sym != nil: case sym.kind of skProc, skMethod, skConverter, skIterators: genProc(m, sym) of skVar, skResult, skLet: genVarPrototype(m, sym) @@ -604,18 +608,18 @@ proc cgsym(m: BModule, name: string): PRope = # we're picky here for the system module too: rawMessage(errSystemNeeds, name) result = sym.loc.r - + proc generateHeaders(m: BModule) = app(m.s[cfsHeaders], tnl & "#include \"nimbase.h\"" & tnl) var it = PStrEntry(m.headerFiles.head) while it != nil: - if it.data[0] notin {'\"', '<'}: + if it.data[0] notin {'\"', '<'}: appf(m.s[cfsHeaders], "$N#include \"$1\"$N", [toRope(it.data)]) else: appf(m.s[cfsHeaders], "$N#include $1$N", [toRope(it.data)]) it = PStrEntry(it.next) -proc retIsNotVoid(s: PSym): bool = +proc retIsNotVoid(s: PSym): bool = result = (s.typ.sons[0] != nil) and not isInvalidReturnType(s.typ.sons[0]) proc initFrame(p: BProc, procname, filename: PRope): PRope = @@ -663,11 +667,11 @@ proc genProcAux(m: BModule, prc: PSym) = else: fillResult(res) assignParam(p, res) - if skipTypes(res.typ, abstractInst).kind == tyArray: + if skipTypes(res.typ, abstractInst).kind == tyArray: incl(res.loc.flags, lfIndirect) res.loc.s = OnUnknown - - for i in countup(1, sonsLen(prc.typ.n) - 1): + + for i in countup(1, sonsLen(prc.typ.n) - 1): var param = prc.typ.n.sons[i].sym if param.typ.isCompileTimeOnly: continue assignParam(p, param) @@ -682,11 +686,11 @@ proc genProcAux(m: BModule, prc: PSym) = else: generatedProc = rfmt(nil, "$N$1 {$N", header) app(generatedProc, initGCFrame(p)) - if optStackTrace in prc.options: + if optStackTrace in prc.options: app(generatedProc, p.s(cpsLocals)) var procname = makeCString(prc.name.s) app(generatedProc, initFrame(p, procname, prc.info.quotedFilename)) - else: + else: app(generatedProc, p.s(cpsLocals)) if optProfiler in prc.options: # invoke at proc entry for recursion: @@ -706,12 +710,12 @@ proc crossesCppBoundary(m: BModule; sym: PSym): bool {.inline.} = sfCompileToCpp notin sym.getModule().flags and gCmd != cmdCompileToCpp -proc genProcPrototype(m: BModule, sym: PSym) = +proc genProcPrototype(m: BModule, sym: PSym) = useHeader(m, sym) - if lfNoDecl in sym.loc.flags: return + if lfNoDecl in sym.loc.flags: return if lfDynamicLib in sym.loc.flags: if getModule(sym).id != m.module.id and - not containsOrIncl(m.declaredThings, sym.id): + not containsOrIncl(m.declaredThings, sym.id): app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n", getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym))) elif not containsOrIncl(m.declaredProtos, sym.id): @@ -722,13 +726,13 @@ proc genProcPrototype(m: BModule, sym: PSym) = header.app(" __attribute__((naked))") app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header)) -proc genProcNoForward(m: BModule, prc: PSym) = +proc genProcNoForward(m: BModule, prc: PSym) = fillProcLoc(prc) useHeader(m, prc) if lfImportCompilerProc in prc.loc.flags: # dependency to a compilerproc: discard cgsym(m, prc.name.s) - return + return genProcPrototype(m, prc) if lfNoDecl in prc.loc.flags: discard elif prc.typ.callConv == ccInline: @@ -738,13 +742,13 @@ proc genProcNoForward(m: BModule, prc: PSym) = if not containsOrIncl(m.declaredThings, prc.id): genProcAux(m, prc) elif lfDynamicLib in prc.loc.flags: var q = findPendingModule(m, prc) - if q != nil and not containsOrIncl(q.declaredThings, prc.id): + if q != nil and not containsOrIncl(q.declaredThings, prc.id): symInDynamicLib(q, prc) else: symInDynamicLibPartial(m, prc) elif sfImportc notin prc.flags: var q = findPendingModule(m, prc) - if q != nil and not containsOrIncl(q.declaredThings, prc.id): + if q != nil and not containsOrIncl(q.declaredThings, prc.id): genProcAux(q, prc) proc requestConstImpl(p: BProc, sym: PSym) = @@ -770,7 +774,7 @@ proc requestConstImpl(p: BProc, sym: PSym) = proc isActivated(prc: PSym): bool = prc.typ != nil -proc genProc(m: BModule, prc: PSym) = +proc genProc(m: BModule, prc: PSym) = if sfBorrow in prc.flags or not isActivated(prc): return fillProcLoc(prc) if sfForward in prc.flags: addForwardedProc(m, prc) @@ -780,19 +784,19 @@ proc genProc(m: BModule, prc: PSym) = generatedHeader != nil and lfNoDecl notin prc.loc.flags: genProcPrototype(generatedHeader, prc) if prc.typ.callConv == ccInline: - if not containsOrIncl(generatedHeader.declaredThings, prc.id): + if not containsOrIncl(generatedHeader.declaredThings, prc.id): genProcAux(generatedHeader, prc) -proc genVarPrototypeAux(m: BModule, sym: PSym) = +proc genVarPrototypeAux(m: BModule, sym: PSym) = assert(sfGlobal in sym.flags) useHeader(m, sym) fillLoc(sym.loc, locGlobalVar, sym.typ, mangleName(sym), OnHeap) - if (lfNoDecl in sym.loc.flags) or containsOrIncl(m.declaredThings, sym.id): - return - if sym.owner.id != m.module.id: + if (lfNoDecl in sym.loc.flags) or containsOrIncl(m.declaredThings, sym.id): + return + if sym.owner.id != m.module.id: # else we already have the symbol generated! assert(sym.loc.r != nil) - if sfThread in sym.flags: + if sfThread in sym.flags: declareThreadVar(m, sym, true) else: app(m.s[cfsVars], "extern ") @@ -838,7 +842,7 @@ proc genFilenames(m: BModule): PRope = result.appf("dbgRegisterFilename($1);$N", fileInfos[i].projPath.makeCString) proc genMainProc(m: BModule) = - const + const # The use of a volatile function pointer to call Pre/NimMainInner # prevents inlining of the NimMainInner function and dependent # functions, which might otherwise merge their stack frames. @@ -859,7 +863,7 @@ proc genMainProc(m: BModule) = MainProcs = "\tNimMain();$N" - + MainProcsWithResult = MainProcs & "\treturn nim_program_result;$N" @@ -880,7 +884,7 @@ proc genMainProc(m: BModule) = "char** cmdLine;$N" & "char** gEnv;$N" & NimMainBody - + PosixCMain = "int main(int argc, char** args, char** env) {$N" & "\tcmdLine = args;$N" & @@ -888,20 +892,20 @@ proc genMainProc(m: BModule) = "\tgEnv = env;$N" & MainProcsWithResult & "}$N$N" - + StandaloneCMain = "int main(void) {$N" & MainProcs & "\treturn 0;$N" & "}$N$N" - + WinNimMain = NimMainBody - + WinCMain = "N_STDCALL(int, WinMain)(HINSTANCE hCurInstance, $N" & " HINSTANCE hPrevInstance, $N" & " LPSTR lpCmdLine, int nCmdShow) {$N" & MainProcsWithResult & "}$N$N" - + WinNimDllMain = "N_LIB_EXPORT " & NimMainBody WinCDllMain = @@ -911,7 +915,7 @@ proc genMainProc(m: BModule) = "\treturn 1;$N}$N$N" PosixNimDllMain = WinNimDllMain - + PosixCDllMain = "void NIM_POSIX_INIT NimMainInit(void) {$N" & MainProcs & @@ -919,11 +923,11 @@ proc genMainProc(m: BModule) = var nimMain, otherMain: TFormatStr if platform.targetOS == osWindows and - gGlobalOptions * {optGenGuiApp, optGenDynLib} != {}: - if optGenGuiApp in gGlobalOptions: + gGlobalOptions * {optGenGuiApp, optGenDynLib} != {}: + if optGenGuiApp in gGlobalOptions: nimMain = WinNimMain otherMain = WinCMain - else: + else: nimMain = WinNimDllMain otherMain = WinCDllMain discard lists.includeStr(m.headerFiles, "<windows.h>") @@ -939,7 +943,7 @@ proc genMainProc(m: BModule) = if gBreakpoints != nil: discard cgsym(m, "dbgRegisterBreakpoint") if optEndb in gOptions: gBreakpoints.app(m.genFilenames) - + let initStackBottomCall = if platform.targetOS == osStandalone: "".toRope else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N") @@ -964,11 +968,11 @@ proc getSomeInitName(m: PSym, suffix: string): PRope = result.app "_" result.app m.name.s result.app suffix - + proc getInitName(m: PSym): PRope = getSomeInitName(m, "Init") proc getDatInitName(m: PSym): PRope = getSomeInitName(m, "DatInit") -proc registerModuleToMain(m: PSym) = +proc registerModuleToMain(m: PSym) = var init = m.getInitName datInit = m.getDatInitName @@ -981,19 +985,19 @@ proc registerModuleToMain(m: PSym) = app(mainModInit, initCall) else: app(otherModsInit, initCall) - -proc genInitCode(m: BModule) = + +proc genInitCode(m: BModule) = var initname = getInitName(m.module) var prc = ropef("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N", [initname]) - if m.typeNodes > 0: - appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n", + if m.typeNodes > 0: + appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n", [m.typeNodesName, toRope(m.typeNodes)]) - if m.nimTypes > 0: - appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n", + if m.nimTypes > 0: + appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n", [m.nimTypesName, toRope(m.nimTypes)]) - + app(prc, initGCFrame(m.initProc)) - + app(prc, genSectionStart(cpsLocals)) app(prc, m.preInitProc.s(cpsLocals)) app(prc, m.initProc.s(cpsLocals)) @@ -1009,7 +1013,7 @@ proc genInitCode(m: BModule) = app(prc, initFrame(m.initProc, procname, m.module.info.quotedFilename)) else: app(prc, ~"\tTFrame F; F.len = 0;$N") - + app(prc, genSectionStart(cpsInit)) app(prc, m.preInitProc.s(cpsInit)) app(prc, m.initProc.s(cpsInit)) @@ -1033,27 +1037,27 @@ proc genInitCode(m: BModule) = app(prc, genSectionStart(i)) app(prc, m.s[i]) app(prc, genSectionEnd(i)) - + appf(prc, "}$N$N") # we cannot simply add the init proc to ``m.s[cfsProcs]`` anymore because # that would lead to a *nesting* of merge sections which the merger does # not support. So we add it to another special section: ``cfsInitProc`` app(m.s[cfsInitProc], prc) - + for i, el in pairs(m.extensionLoaders): if el != nil: let ex = ropef("N_NIMCALL(void, nimLoadProcs$1)(void) {$2}$N$N", (i.ord - '0'.ord).toRope, el) app(m.s[cfsInitProc], ex) -proc genModule(m: BModule, cfile: string): PRope = +proc genModule(m: BModule, cfile: string): PRope = result = getFileHeader(cfile) result.app(genMergeInfo(m)) - + generateHeaders(m) generateThreadLocalStorage(m) - for i in countup(cfsHeaders, cfsProcs): + for i in countup(cfsHeaders, cfsProcs): app(result, genSectionStart(i)) app(result, m.s[i]) app(result, genSectionEnd(i)) @@ -1069,7 +1073,7 @@ proc newPostInitProc(m: BModule): BProc = # little hack so that unique temporaries are generated: result.labels = 200_000 -proc initProcOptions(m: BModule): TOptions = +proc initProcOptions(m: BModule): TOptions = if sfSystemModule in m.module.flags: gOptions-{optStackTrace} else: gOptions proc rawNewModule(module: PSym, filename: string): BModule = @@ -1124,11 +1128,11 @@ proc resetModule*(m: BModule) = m.typeNodes = 0 m.nimTypes = 0 nullify m.extensionLoaders - + # indicate that this is now cached module # the cache will be invalidated by nullifying gModules m.fromCache = true - + # we keep only the "merge info" information for the module # and the properties that can't change: # m.filename @@ -1155,11 +1159,11 @@ proc newModule(module: PSym): BModule = growCache gModules, module.position gModules[module.position] = result - if (optDeadCodeElim in gGlobalOptions): - if (sfDeadCodeElim in module.flags): + if (optDeadCodeElim in gGlobalOptions): + if (sfDeadCodeElim in module.flags): internalError("added pending module twice: " & module.filename) -proc myOpen(module: PSym): PPassContext = +proc myOpen(module: PSym): PPassContext = result = newModule(module) if optGenIndex in gGlobalOptions and generatedHeader == nil: let f = if headerFile.len > 0: headerFile else: gProjectFull @@ -1175,12 +1179,12 @@ proc writeHeader(m: BModule) = generateHeaders(m) generateThreadLocalStorage(m) - for i in countup(cfsHeaders, cfsProcs): + for i in countup(cfsHeaders, cfsProcs): app(result, genSectionStart(i)) app(result, m.s[i]) app(result, genSectionEnd(i)) app(result, m.s[cfsInitProc]) - + if optGenDynLib in gGlobalOptions: result.app("N_LIB_IMPORT ") result.appf("N_CDECL(void, NimMain)(void);$n") @@ -1200,20 +1204,20 @@ proc myOpenCached(module: PSym, rd: PRodReader): PPassContext = readMergeInfo(getCFile(m), m) result = m -proc myProcess(b: PPassContext, n: PNode): PNode = +proc myProcess(b: PPassContext, n: PNode): PNode = result = n if b == nil or passes.skipCodegen(n): return var m = BModule(b) m.initProc.options = initProcOptions(m) genStmts(m.initProc, n) -proc finishModule(m: BModule) = +proc finishModule(m: BModule) = var i = 0 - while i <= high(m.forwardedProcs): + while i <= high(m.forwardedProcs): # Note: ``genProc`` may add to ``m.forwardedProcs``, so we cannot use # a ``for`` loop here var prc = m.forwardedProcs[i] - if sfForward in prc.flags: + if sfForward in prc.flags: internalError(prc.info, "still forwarded: " & prc.name.s) genProcNoForward(m, prc) inc(i) @@ -1221,13 +1225,13 @@ proc finishModule(m: BModule) = dec(gForwardedProcsCounter, i) setLen(m.forwardedProcs, 0) -proc shouldRecompile(code: PRope, cfile: string): bool = +proc shouldRecompile(code: PRope, cfile: string): bool = result = true if optForceFullMake notin gGlobalOptions: var objFile = toObjFile(cfile) - if writeRopeIfNotEqual(code, cfile): return + if writeRopeIfNotEqual(code, cfile): return if existsFile(objFile) and os.fileNewer(objFile, cfile): result = false - else: + else: writeRope(code, cfile) # We need 2 different logics here: pending modules (including @@ -1240,15 +1244,15 @@ proc writeModule(m: BModule, pending: bool) = # generate code for the init statements of the module: var cfile = getCFile(m) var cfilenoext = changeFileExt(cfile, "") - + if not m.fromCache or optForceFullMake in gGlobalOptions: genInitCode(m) finishTypeDescriptions(m) - if sfMainModule in m.module.flags: + if sfMainModule in m.module.flags: # generate main file: app(m.s[cfsProcHeaders], mainModProcs) generateThreadVarsSize(m) - + var code = genModule(m, cfile) when hasTinyCBackend: if gCmd == cmdRun: @@ -1269,13 +1273,13 @@ proc writeModule(m: BModule, pending: bool) = # ``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(cfile) - + addFileToLink(cfilenoext) proc updateCachedModule(m: BModule) = let cfile = getCFile(m) let cfilenoext = changeFileExt(cfile, "") - + if mergeRequired(m) and sfMainModule notin m.module.flags: mergeFiles(cfile, m) genInitCode(m) @@ -1286,17 +1290,17 @@ proc updateCachedModule(m: BModule) = addFileToLink(cfilenoext) -proc myClose(b: PPassContext, n: PNode): PNode = +proc myClose(b: PPassContext, n: PNode): PNode = result = n - if b == nil or passes.skipCodegen(n): return + if b == nil or passes.skipCodegen(n): return var m = BModule(b) - if n != nil: + if n != nil: m.initProc.options = initProcOptions(m) genStmts(m.initProc, n) - # cached modules need to registered too: + # cached modules need to registered too: registerModuleToMain(m.module) - if sfMainModule in m.module.flags: + if sfMainModule in m.module.flags: m.objHasKidsValid = true var disp = generateMethodDispatchers() for i in 0..sonsLen(disp)-1: genProcAux(m, disp.sons[i].sym) |