summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-03-09 20:43:56 +0100
committerAraq <rumpf_a@web.de>2013-03-09 20:43:56 +0100
commita64d4dc35c5b93c85a512261b78a89cdf1282e8d (patch)
tree1d8906c93a3fa4f32a0ec63fb6d42f005fb2671b /compiler
parent2b4922aea0350c3a225619e7e10b74de95bfc2b7 (diff)
downloadNim-a64d4dc35c5b93c85a512261b78a89cdf1282e8d.tar.gz
documented object constrs; endb works again
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/ccgexprs.nim35
-rwxr-xr-xcompiler/ccgstmts.nim38
-rwxr-xr-xcompiler/cgen.nim26
-rw-r--r--compiler/cgendata.nim7
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