diff options
author | Araq <rumpf_a@web.de> | 2013-03-09 20:43:56 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2013-03-09 20:43:56 +0100 |
commit | a64d4dc35c5b93c85a512261b78a89cdf1282e8d (patch) | |
tree | 1d8906c93a3fa4f32a0ec63fb6d42f005fb2671b /compiler | |
parent | 2b4922aea0350c3a225619e7e10b74de95bfc2b7 (diff) | |
download | Nim-a64d4dc35c5b93c85a512261b78a89cdf1282e8d.tar.gz |
documented object constrs; endb works again
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ccgexprs.nim | 35 | ||||
-rwxr-xr-x | compiler/ccgstmts.nim | 38 | ||||
-rwxr-xr-x | compiler/cgen.nim | 26 | ||||
-rw-r--r-- | compiler/cgendata.nim | 7 |
4 files changed, 43 insertions, 63 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index fd70834c2..a99654cbd 100755 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -709,12 +709,12 @@ proc genFieldCheck(p: BProc, e: PNode, obj: PRope, field: PSym) = rdLoc(test), strLit) proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) = - var - a: TLoc - f, field: PSym - ty: PType - r: PRope if optFieldCheck in p.options: + var + a: TLoc + f, field: PSym + ty: PType + r: PRope ty = genRecordFieldAux(p, e.sons[0], d, a) r = rdLoc(a) f = e.sons[0].sons[1].sym @@ -729,31 +729,6 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) = if field.loc.r == nil: InternalError(e.info, "genCheckedRecordField") # generate the checks: genFieldCheck(p, e, r, field) - when false: - for i in countup(1, sonsLen(e) - 1): - it = e.sons[i] - assert(it.kind in nkCallKinds) - assert(it.sons[0].kind == nkSym) - op = it.sons[0].sym - if op.magic == mNot: it = it.sons[1] - assert(it.sons[2].kind == nkSym) - initLoc(test, locNone, it.typ, OnStack) - InitLocExpr(p, it.sons[1], u) - initLoc(v, locExpr, it.sons[2].typ, OnUnknown) - v.r = ropef("$1.$2", [r, it.sons[2].sym.loc.r]) - genInExprAux(p, it, u, v, test) - id = NodeTableTestOrSet(p.module.dataCache, - newStrNode(nkStrLit, field.name.s), gBackendId) - if id == gBackendId: strLit = getStrLit(p.module, field.name.s) - else: strLit = con("TMP", toRope(id)) - if op.magic == mNot: - linefmt(p, cpsStmts, - "if ($1) #raiseFieldError(((#NimStringDesc*) &$2));$n", - rdLoc(test), strLit) - else: - linefmt(p, cpsStmts, - "if (!($1)) #raiseFieldError(((#NimStringDesc*) &$2));$n", - rdLoc(test), strLit) app(r, rfmt(nil, ".$1", field.loc.r)) putIntoDest(p, d, field.typ, r) else: diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index dd6d2bfaa..e11678861 100755 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -45,7 +45,7 @@ proc genVarTuple(p: BProc, n: PNode) = if t.kind == tyTuple: field.r = ropef("$1.Field$2", [rdLoc(tup), toRope(i)]) else: - if (t.n.sons[i].kind != nkSym): InternalError(n.info, "genVarTuple") + if t.n.sons[i].kind != nkSym: InternalError(n.info, "genVarTuple") field.r = ropef("$1.$2", [rdLoc(tup), mangleRecFieldName(t.n.sons[i].sym, t)]) putLocIntoDest(p, v.loc, field) @@ -64,19 +64,23 @@ proc startBlock(p: BProc, start: TFormatStr = "{$n", result = len(p.blocks) setlen(p.blocks, result + 1) p.blocks[result].id = p.labels - p.blocks[result].nestedTryStmts = p.nestedTryStmts.len + p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16 proc assignLabel(b: var TBlock): PRope {.inline.} = b.label = con("LA", b.id.toRope) result = b.label -proc blockBody(b: var TBlock): PRope {.inline.} = - return b.sections[cpsLocals].con(b.sections[cpsInit]).con(b.sections[cpsStmts]) +proc blockBody(b: var TBlock): PRope = + result = b.sections[cpsLocals] + if b.frameLen > 0: + result.appf("F.len+=$1;$n", b.frameLen.toRope) + result.app(b.sections[cpsInit]) + result.app(b.sections[cpsStmts]) proc endBlock(p: BProc, blockEnd: PRope) = - let topBlock = p.blocks.len - 1 + let topBlock = p.blocks.len-1 # the block is merged into the parent block - app(p.blocks[topBlock - 1].sections[cpsStmts], p.blocks[topBlock].blockBody) + app(p.blocks[topBlock-1].sections[cpsStmts], p.blocks[topBlock].blockBody) setlen(p.blocks, topBlock) # this is done after the block is popped so $n is # properly indented when pretty printing is enabled @@ -84,10 +88,13 @@ proc endBlock(p: BProc, blockEnd: PRope) = proc endBlock(p: BProc) = let topBlock = p.blocks.len - 1 - let blockEnd = if p.blocks[topBlock].label != nil: + var blockEnd = if p.blocks[topBlock].label != nil: rfmt(nil, "} $1: ;$n", p.blocks[topBlock].label) else: ~"}$n" + let frameLen = p.blocks[topBlock].frameLen + if frameLen > 0: + blockEnd.appf("F.len-=$1;$n", frameLen.toRope) endBlock(p, blockEnd) proc genSimpleBlock(p: BProc, stmts: PNode) {.inline.} = @@ -774,7 +781,7 @@ var proc genBreakPoint(p: BProc, t: PNode) = var name: string - if optEndb in p.Options: + if optEndb in p.Options: if t.kind == nkExprColonExpr: assert(t.sons[1].kind in {nkStrLit..nkTripleStrLit}) name = normalize(t.sons[1].strVal) @@ -784,7 +791,7 @@ proc genBreakPoint(p: BProc, t: PNode) = genLineDir(p, t) # BUGFIX appcg(p.module, gBreakpoints, "#dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [ - toRope(toLinenumber(t.info)), makeCString(toFilename(t.info)), + toRope(toLinenumber(t.info)), makeCString(toFilename(t.info)), makeCString(name)]) proc genWatchpoint(p: BProc, n: PNode) = @@ -796,16 +803,13 @@ proc genWatchpoint(p: BProc, n: PNode) = [a.addrLoc, makeCString(renderTree(n.sons[1])), genTypeInfo(p.module, typ)]) -proc genPragma(p: BProc, n: PNode) = - for i in countup(0, sonsLen(n) - 1): +proc genPragma(p: BProc, n: PNode) = + for i in countup(0, sonsLen(n) - 1): var it = n.sons[i] case whichPragma(it) - of wEmit: - genEmit(p, it) - of wBreakpoint: - genBreakPoint(p, it) - of wWatchpoint: - genWatchpoint(p, it) + of wEmit: genEmit(p, it) + of wBreakpoint: genBreakPoint(p, it) + of wWatchpoint: genWatchpoint(p, it) else: nil proc FieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool = diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 399785c82..d06a6cb6f 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -269,18 +269,18 @@ proc genCLineDir(r: var PRope, filename: string, line: int) = proc genCLineDir(r: var PRope, info: TLineInfo) = genCLineDir(r, info.toFullPath, info.safeLineNm) -proc genLineDir(p: BProc, t: PNode) = +proc genLineDir(p: BProc, t: PNode) = var line = t.info.safeLineNm if optEmbedOrigSrc in gGlobalOptions: app(p.s(cpsStmts), con(~"//", t.info.sourceLine, rnl)) 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): - linefmt(p, cpsStmts, "#endb($1);$n", toRope(line)) + (p.prc == nil or sfPure notin p.prc.flags): + linefmt(p, cpsStmts, "#endb($1, $2);$n", + line.toRope, makeCString(toFilename(t.info))) elif ({optLineTrace, optStackTrace} * p.Options == {optLineTrace, optStackTrace}) and (p.prc == nil or sfPure notin p.prc.flags): - linefmt(p, cpsStmts, "nimln($1, $2);$n", line.toRope, t.info.quotedFilename) @@ -470,12 +470,13 @@ proc localDebugInfo(p: BProc, s: PSym) = # 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) - if (s.kind == skParam) and ccgIntroducedPtr(s): a = s.loc.r + if s.kind == skParam and ccgIntroducedPtr(s): a = s.loc.r lineF(p, 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, + [p.maxFrameLen.toRope, makeCString(normalize(s.name.s)), a, genTypeInfo(p.module, s.loc.t)]) - inc(p.frameLen) + inc(p.maxFrameLen) + inc p.blocks[p.blocks.len-1].frameLen proc assignLocalVar(p: BProc, s: PSym) = #assert(s.loc.k == locNone) // not yet assigned @@ -488,7 +489,7 @@ proc assignLocalVar(p: BProc, s: PSym) = if sfRegister in s.flags: app(decl, " register") #elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds: # app(decl, " GC_GUARD") - if (sfVolatile in s.flags) or (p.nestedTryStmts.len > 0): + if sfVolatile in s.flags or p.nestedTryStmts.len > 0: app(decl, " volatile") appf(decl, " $1;$n", [s.loc.r]) line(p, cpsLocals, decl) @@ -693,10 +694,11 @@ proc retIsNotVoid(s: PSym): bool = proc initFrame(p: BProc, procname, filename: PRope): PRope = discard cgsym(p.module, "pushFrame") - if p.frameLen > 0: + if p.maxFrameLen > 0: discard cgsym(p.module, "TVarSlot") - result = rfmt(nil, "\tnimfrs($1, $2, $3)$N", - procname, filename, p.frameLen.toRope) + result = rfmt(nil, "\tnimfrs($1, $2, $3, $4)$N", + procname, filename, p.maxFrameLen.toRope, + p.blocks[0].frameLen.toRope) else: result = rfmt(nil, "\tnimfr($1, $2)$N", procname, filename) diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index 32e9fb4ce..ad17194df 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -54,9 +54,10 @@ type id*: int # the ID of the label; positive means that it label*: PRope # generated text for the label # nil if label is not used - nestedTryStmts*: int # how many try statements is it nested into sections*: TCProcSections # the code beloging isLoop*: bool # whether block is a loop + nestedTryStmts*: int16 # how many try statements is it nested into + frameLen*: int16 TCProc{.final.} = object # represents C proc that is currently generated prc*: PSym # the Nimrod proc that this C proc belongs to @@ -74,9 +75,7 @@ type options*: TOptions # options that should be used for code # generation; this is the same as prc.options # unless prc == nil - frameLen*: int # current length of frame descriptor - sendClosure*: PType # closure record type that we pass - receiveClosure*: PType # closure record type that we get + maxFrameLen*: int # max length of frame descriptor module*: BModule # used to prevent excessive parameter passing withinLoop*: int # > 0 if we are within a loop gcFrameId*: natural # for the GC stack marking |