diff options
Diffstat (limited to 'compiler/cgen.nim')
-rwxr-xr-x | compiler/cgen.nim | 116 |
1 files changed, 55 insertions, 61 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim index de91205e2..e8073b555 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -151,7 +151,7 @@ proc appcg(m: BModule, s: TCFileSection, frmt: TFormatStr, proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr, args: openarray[PRope]) = - app(p.s[s], ropecg(p.module, frmt, args)) + app(p.s(s), ropecg(p.module, frmt, args)) proc safeLineNm(info: TLineInfo): int = result = toLinenumber(info) @@ -168,14 +168,14 @@ proc genCLineDir(r: var PRope, info: TLineInfo) = proc genLineDir(p: BProc, t: PNode) = var line = t.info.safeLineNm - genCLineDir(p.s[cpsStmts], t.info.toFullPath, line) + genCLineDir(p.s(cpsStmts), t.info.toFullPath, line) if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and (p.prc == nil or sfPure notin p.prc.flags): appcg(p, cpsStmts, "#endb($1);$n", [toRope(line)]) elif ({optLineTrace, optStackTrace} * p.Options == {optLineTrace, optStackTrace}) and (p.prc == nil or sfPure notin p.prc.flags): - appf(p.s[cpsStmts], "F.line = $1;F.filename = $2;$n", + appf(p.s(cpsStmts), "F.line = $1;F.filename = $2;$n", [toRope(line), makeCString(toFilename(t.info).extractFilename)]) include "ccgtypes.nim" @@ -229,45 +229,37 @@ proc isComplexValueType(t: PType): bool {.inline.} = result = t.kind in {tyArray, tyArrayConstr, tySet, tyTuple, tyObject} or (t.kind == tyProc and t.callConv == ccClosure) -proc zeroVar(p: BProc, loc: TLoc, containsGCref: bool) = +proc resetLoc(p: BProc, loc: var TLoc) = + let containsGcRef = containsGarbageCollectedRef(loc.t) if not isComplexValueType(skipTypes(loc.t, abstractVarRange)): - if containsGcref and p.WithInLoop > 0: - appf(p.s[cpsInit], "$1 = 0;$n", [rdLoc(loc)]) + if containsGcRef: var nilLoc: TLoc initLoc(nilLoc, locTemp, loc.t, onStack) nilLoc.r = toRope("NIM_NIL") - # puts ``unsureAsgnRef`` etc to ``p.s[cpsStmts]``: genRefAssign(p, loc, nilLoc, {afSrcIsNil}) else: - appf(p.s[cpsStmts], "$1 = 0;$n", [rdLoc(loc)]) + appf(p.s(cpsStmts), "$1 = 0;$n", [rdLoc(loc)]) else: - if containsGcref and p.WithInLoop > 0: - appf(p.s[cpsInit], "memset((void*)$1, 0, sizeof($2));$n", - [addrLoc(loc), rdLoc(loc)]) - genObjectInit(p, cpsInit, loc.t, loc, true) - appcg(p, cpsStmts, "#genericReset((void*)$1, $2);$n", - [addrLoc(loc), genTypeInfo(p.module, loc.t)]) + if loc.s != OnStack: + appcg(p, cpsStmts, "#genericReset((void*)$1, $2);$n", + [addrLoc(loc), genTypeInfo(p.module, loc.t)]) + # XXX: generated reset procs should not touch the m_type + # field, so disabling this should be safe: + genObjectInit(p, cpsStmts, loc.t, loc, true) else: - appf(p.s[cpsStmts], "memset((void*)$1, 0, sizeof($2));$n", - [addrLoc(loc), rdLoc(loc)]) + appf(p.s(cpsStmts), "memset((void*)$1, 0, sizeof($2));$n", + [addrLoc(loc), rdLoc(loc)]) + # 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 zeroTemp(p: BProc, loc: TLoc) = +proc constructLoc(p: BProc, loc: TLoc, section = cpsStmts) = if not isComplexValueType(skipTypes(loc.t, abstractVarRange)): - appf(p.s[cpsStmts], "$1 = 0;$n", [rdLoc(loc)]) - when false: - var nilLoc: TLoc - initLoc(nilLoc, locTemp, loc.t, onStack) - nilLoc.r = toRope("NIM_NIL") - # puts ``unsureAsgnRef`` etc to ``p.s[cpsStmts]``: - genRefAssign(p, loc, nilLoc, {afSrcIsNil}) + appf(p.s(section), "$1 = 0;$n", [rdLoc(loc)]) else: - appf(p.s[cpsStmts], "memset((void*)$1, 0, sizeof($2));$n", - [addrLoc(loc), rdLoc(loc)]) - # XXX no object init necessary for temporaries? - when false: - appcg(p, cpsStmts, "#genericReset((void*)$1, $2);$n", - [addrLoc(loc), genTypeInfo(p.module, loc.t)]) + appf(p.s(section), "memset((void*)$1, 0, sizeof($2));$n", + [addrLoc(loc), rdLoc(loc)]) + genObjectInit(p, section, loc.t, loc, true) proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) = if sfNoInit notin v.flags: @@ -279,11 +271,13 @@ proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) = # ``var v = X()`` gets transformed into ``X(&v)``. # Nowadays the logic in ccgcalls deals with this case however. if not immediateAsgn: - zeroVar(p, v.loc, containsGarbageCollectedRef(v.typ)) - -proc initTemp(p: BProc, tmp: var TLoc) = + constructLoc(p, v.loc) + +proc initTemp(p: BProc, tmp: var TLoc) = + # XXX: This is still suspicious. + # Objects should always be constructed? if containsGarbageCollectedRef(tmp.t) or isInvalidReturnType(tmp.t): - zeroTemp(p, tmp) + constructLoc(p, tmp) proc getTemp(p: BProc, t: PType, result: var TLoc) = inc(p.labels) @@ -291,7 +285,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc) = result.r = con("%LOC", toRope(p.labels)) else: result.r = con("LOC", toRope(p.labels)) - appf(p.s[cpsLocals], "$1 $2;$n", [getTypeDesc(p.module, t), result.r]) + appf(p.s(cpsLocals), "$1 $2;$n", [getTypeDesc(p.module, t), result.r]) result.k = locTemp result.a = - 1 result.t = getUniqueType(t) @@ -361,7 +355,7 @@ proc allocParam(p: BProc, s: PSym) = var tmp = con("%LOC", toRope(p.labels)) incl(s.loc.flags, lfParamCopy) incl(s.loc.flags, lfIndirect) - appf(p.s[cpsInit], "$1 = alloca $3$n" & "store $3 $2, $3* $1$n", + appf(p.s(cpsInit), "$1 = alloca $3$n" & "store $3 $2, $3* $1$n", [tmp, s.loc.r, getTypeDesc(p.module, s.loc.t)]) s.loc.r = tmp @@ -371,7 +365,7 @@ proc localDebugInfo(p: BProc, s: PSym) = if skipTypes(s.typ, abstractVar).kind == tyOpenArray: return var a = con("&", s.loc.r) if (s.kind == skParam) and ccgIntroducedPtr(s): a = s.loc.r - appf(p.s[cpsInit], + appf(p.s(cpsInit), "F.s[$1].address = (void*)$3; F.s[$1].typ = $4; F.s[$1].name = $2;$n", [toRope(p.frameLen), makeCString(normalize(s.name.s)), a, genTypeInfo(p.module, s.loc.t)]) @@ -384,13 +378,13 @@ proc assignLocalVar(p: BProc, s: PSym) = if s.loc.k == locNone: fillLoc(s.loc, locLocalVar, s.typ, mangleName(s), OnStack) if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy) - app(p.s[cpsLocals], getTypeDesc(p.module, s.loc.t)) - if sfRegister in s.flags: app(p.s[cpsLocals], " register") + app(p.s(cpsLocals), getTypeDesc(p.module, s.loc.t)) + if sfRegister in s.flags: app(p.s(cpsLocals), " register") #elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds: # app(p.s[cpsLocals], " GC_GUARD") if (sfVolatile in s.flags) or (p.nestedTryStmts.len > 0): - app(p.s[cpsLocals], " volatile") - appf(p.s[cpsLocals], " $1;$n", [s.loc.r]) + app(p.s(cpsLocals), " volatile") + appf(p.s(cpsLocals), " $1;$n", [s.loc.r]) localDebugInfo(p, s) include ccgthreadvars @@ -410,7 +404,7 @@ proc assignGlobalVar(p: BProc, s: PSym) = appf(p.module.s[cfsVars], " $1;$n", [s.loc.r]) if p.withinLoop > 0: # fixes tests/run/tzeroarray: - initLocalVar(p, s, false) + resetLoc(p, s.loc) if p.module.module.options * {optStackTrace, optEndb} == {optStackTrace, optEndb}: appcg(p.module, p.module.s[cfsDebugInit], @@ -433,7 +427,7 @@ proc getLabel(p: BProc): TLabel = result = con("LA", toRope(p.labels)) proc fixLabel(p: BProc, labl: TLabel) = - appf(p.s[cpsStmts], "$1: ;$n", [labl]) + appf(p.s(cpsStmts), "$1: ;$n", [labl]) proc genVarPrototype(m: BModule, sym: PSym) proc requestConstImpl(p: BProc, sym: PSym) @@ -481,9 +475,9 @@ proc loadDynamicLib(m: BModule, lib: PLib) = var p = newProc(nil, m) var dest: TLoc initLocExpr(p, lib.path, dest) - app(m.s[cfsVars], p.s[cpsLocals]) - app(m.s[cfsDynLibInit], p.s[cpsInit]) - app(m.s[cfsDynLibInit], p.s[cpsStmts]) + 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", [tmp, rdLoc(dest)]) @@ -551,13 +545,13 @@ proc getFrameDecl(p: BProc) = [toRope(p.frameLen)]) else: slots = nil - appff(p.s[cpsLocals], "volatile struct {TFrame* prev;" & + appff(p.s(cpsLocals), "volatile struct {TFrame* prev;" & "NCSTRING procname;NI line;NCSTRING filename;" & "NI len;$n$1} F;$n", "%TF = type {%TFrame*, i8*, %NI, %NI$1}$n" & "%F = alloca %TF$n", [slots]) inc(p.labels) - prepend(p.s[cpsInit], ropeff("F.len = $1;$n", + prepend(p.s(cpsInit), ropeff("F.len = $1;$n", "%LOC$2 = getelementptr %TF %F, %NI 4$n" & "store %NI $1, %NI* %LOC$2$n", [toRope(p.frameLen), toRope(p.labels)])) @@ -613,32 +607,32 @@ proc genProcAux(m: BModule, prc: PSym) = var generatedProc: PRope if sfPure in prc.flags: generatedProc = ropeff("$1 {$n$2$3$4}$n", "define $1 {$n$2$3$4}$n", - [header, p.s[cpsLocals], p.s[cpsInit], p.s[cpsStmts]]) + [header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)]) else: generatedProc = ropeff("$1 {$n", "define $1 {$n", [header]) app(generatedProc, initGCFrame(p)) if optStackTrace in prc.options: getFrameDecl(p) - app(generatedProc, p.s[cpsLocals]) + app(generatedProc, p.s(cpsLocals)) var procname = CStringLit(p, generatedProc, prc.name.s) var filename = CStringLit(p, generatedProc, toFilename(prc.info)) app(generatedProc, initFrame(p, procname, filename)) else: - app(generatedProc, p.s[cpsLocals]) + app(generatedProc, p.s(cpsLocals)) if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM): if gProcProfile >= 64 * 1024: InternalError(prc.info, "too many procedures for profiling") discard cgsym(m, "profileData") - appf(p.s[cpsLocals], "ticks NIM_profilingStart;$n") + appf(p.s(cpsLocals), "ticks NIM_profilingStart;$n") if prc.loc.a < 0: appf(m.s[cfsDebugInit], "profileData[$1].procname = $2;$n", [ toRope(gProcProfile), makeCString(prc.name.s)]) prc.loc.a = gProcProfile inc(gProcProfile) - prepend(p.s[cpsInit], ropef("NIM_profilingStart = getticks();$n")) - app(generatedProc, p.s[cpsInit]) - app(generatedProc, p.s[cpsStmts]) + prepend(p.s(cpsInit), ropef("NIM_profilingStart = getticks();$n")) + app(generatedProc, p.s(cpsInit)) + app(generatedProc, p.s(cpsStmts)) if p.beforeRetNeeded: appf(generatedProc, "BeforeRet: $n;") app(generatedProc, deinitGCFrame(p)) if optStackTrace in prc.options: app(generatedProc, deinitFrame(p)) @@ -858,8 +852,8 @@ proc genInitCode(m: BModule) = app(prc, initGCFrame(m.initProc)) app(prc, genSectionStart(cpsLocals)) - app(prc, m.initProc.s[cpsLocals]) - app(prc, m.preInitProc.s[cpsLocals]) + app(prc, m.initProc.s(cpsLocals)) + app(prc, m.preInitProc.s(cpsLocals)) app(prc, genSectionEnd(cpsLocals)) app(prc, genSectionStart(cfsTypeInit1)) @@ -876,13 +870,13 @@ proc genInitCode(m: BModule) = app(prc, genSectionEnd(i)) app(prc, genSectionStart(cpsInit)) - app(prc, m.preInitProc.s[cpsInit]) - app(prc, m.initProc.s[cpsInit]) + app(prc, m.preInitProc.s(cpsInit)) + app(prc, m.initProc.s(cpsInit)) app(prc, genSectionEnd(cpsInit)) app(prc, genSectionStart(cpsStmts)) - app(prc, m.preInitProc.s[cpsStmts]) - app(prc, m.initProc.s[cpsStmts]) + app(prc, m.preInitProc.s(cpsStmts)) + app(prc, m.initProc.s(cpsStmts)) if optStackTrace in m.initProc.options and not m.PreventStackTrace: app(prc, deinitFrame(m.initProc)) app(prc, genSectionEnd(cpsStmts)) |