summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgtypes.nim2
-rw-r--r--compiler/cgen.nim2
-rw-r--r--compiler/cmdlinehelper.nim7
-rw-r--r--compiler/commands.nim10
-rw-r--r--compiler/main.nim3
-rw-r--r--compiler/options.nim1
-rw-r--r--compiler/pragmas.nim4
-rw-r--r--compiler/vm.nim2
-rw-r--r--lib/system/excpt.nim8
-rw-r--r--lib/system/memtracker.nim2
-rw-r--r--lib/system/seqs_v2.nim6
11 files changed, 29 insertions, 18 deletions
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 24551e7e5..759330a3e 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -608,7 +608,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope,
     elif m.compileToCpp:
       appcg(m, result, " : public $1 {$n",
                       [getTypeDescAux(m, typ[0].skipTypes(skipPtrs), check)])
-      if typ.isException:
+      if typ.isException and m.config.exc == excCpp:
         appcg(m, result, "virtual void raise() { throw *this; }$n", []) # required for polymorphic exceptions
         if typ.sym.magic == mException:
           # Add cleanup destructor to Exception base class
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 706e8e3ee..fd14817e0 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -342,7 +342,7 @@ type
 
 proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: var TLoc,
                    mode: ObjConstrMode) =
-  if p.module.compileToCpp and t.isException and not isDefined(p.config, "noCppExceptions"):
+  if p.module.compileToCpp and t.isException and p.config.exc == excCpp:
     # init vtable in Exception object for polymorphic exceptions
     includeHeader(p.module, "<new>")
     linefmt(p, section, "new ($1) $2;$n", [rdLoc(a), getTypeDesc(p.module, t)])
diff --git a/compiler/cmdlinehelper.nim b/compiler/cmdlinehelper.nim
index e44163d14..a50d47ad2 100644
--- a/compiler/cmdlinehelper.nim
+++ b/compiler/cmdlinehelper.nim
@@ -89,6 +89,13 @@ proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: Confi
   # now process command line arguments again, because some options in the
   # command line can overwrite the config file's settings
   extccomp.initVars(conf)
+  # XXX This is hacky. We need to find a better way.
+  case conf.command
+  of "cpp", "compiletocpp":
+    conf.cmd = cmdCompileToCpp
+  else:
+    discard
+
   self.processCmdLine(passCmd2, "", conf)
   if conf.command == "":
     rawMessage(conf, errGenerated, "command missing")
diff --git a/compiler/commands.nim b/compiler/commands.nim
index f90d79d5b..6633c1aa2 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -469,9 +469,8 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
         defineSymbol(conf.symbols, "gcmarkandsweep")
       of "destructors", "arc":
         conf.selectedGC = gcArc
-        when true:
-          if conf.cmd != cmdCompileToCpp:
-            conf.exc = excGoto
+        if conf.cmd != cmdCompileToCpp:
+          conf.exc = excGoto
         defineSymbol(conf.symbols, "gcdestructors")
         defineSymbol(conf.symbols, "gcarc")
         incl conf.globalOptions, optSeqDestructors
@@ -481,9 +480,8 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
           defineSymbol(conf.symbols, "nimV2")
       of "orc":
         conf.selectedGC = gcOrc
-        when true:
-          if conf.cmd != cmdCompileToCpp:
-            conf.exc = excGoto
+        if conf.cmd != cmdCompileToCpp:
+          conf.exc = excGoto
         defineSymbol(conf.symbols, "gcdestructors")
         defineSymbol(conf.symbols, "gcorc")
         incl conf.globalOptions, optSeqDestructors
diff --git a/compiler/main.nim b/compiler/main.nim
index 87180db0a..5efdd87af 100644
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -185,11 +185,12 @@ proc mainCommand*(graph: ModuleGraph) =
   of "c", "cc", "compile", "compiletoc":
     # compile means compileToC currently
     conf.cmd = cmdCompileToC
+    if conf.exc == excNone: conf.exc = excSetjmp
     defineSymbol(graph.config.symbols, "c")
     commandCompileToC(graph)
   of "cpp", "compiletocpp":
     conf.cmd = cmdCompileToCpp
-    conf.exc = excCpp
+    if conf.exc == excNone: conf.exc = excCpp
     defineSymbol(graph.config.symbols, "cpp")
     commandCompileToC(graph)
   of "objc", "compiletooc":
diff --git a/compiler/options.nim b/compiler/options.nim
index 2d56974c5..d8f6fd0b9 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -159,6 +159,7 @@ type
     ccTcc, ccPcc, ccUcc, ccIcl, ccIcc, ccClangCl
 
   ExceptionSystem* = enum
+    excNone,   # no exception system selected yet
     excSetjmp, # setjmp based exception handling
     excCpp,    # use C++'s native exception handling
     excGoto,   # exception handling based on goto (should become the new default for C)
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index ab0af80ea..029128086 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -29,8 +29,8 @@ const
     wAsmNoStackFrame, wDiscardable, wNoInit, wCodegenDecl,
     wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
     wConstructor, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy}
-  converterPragmas* = procPragmas - {wNoDestroy}
-  methodPragmas* = procPragmas+{wBase}-{wImportCpp, wNoDestroy}
+  converterPragmas* = procPragmas
+  methodPragmas* = procPragmas+{wBase}-{wImportCpp}
   templatePragmas* = {wDeprecated, wError, wGensym, wInject, wDirty,
     wDelegator, wExportNims, wUsed, wPragma}
   macroPragmas* = declPragmas + {FirstCallConv..LastCallConv,
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 8a08de36d..2e65a47f4 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -2187,7 +2187,6 @@ proc evalConstExprAux(module: PSym;
   setupGlobalCtx(module, g)
   var c = PCtx g.vm
   let oldMode = c.mode
-  defer: c.mode = oldMode
   c.mode = mode
   let start = genExpr(c, n, requiresValue = mode!=emStaticStmt)
   if c.code[start].opcode == opcEof: return newNodeI(nkEmpty, n.info)
@@ -2198,6 +2197,7 @@ proc evalConstExprAux(module: PSym;
   #for i in 0..<c.prc.maxSlots: tos.slots[i] = newNode(nkEmpty)
   result = rawExecute(c, start, tos).regToNode
   if result.info.col < 0: result.info = n.info
+  c.mode = oldMode
 
 proc evalConstExpr*(module: PSym; g: ModuleGraph; e: PNode): PNode =
   result = evalConstExprAux(module, g, nil, e, emConst)
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 91cf9aa3e..a9c7ba02a 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -61,7 +61,7 @@ var
   currException {.threadvar.}: ref Exception
   gcFramePtr {.threadvar.}: GcFrame
 
-when defined(cpp) and not defined(noCppExceptions):
+when defined(cpp) and not defined(noCppExceptions) and not gotoBasedExceptions:
   var
     raiseCounter {.threadvar.}: uint
 
@@ -410,7 +410,7 @@ proc reportUnhandledError(e: ref Exception) {.nodestroy.} =
     discard()
 
 proc nimLeaveFinally() {.compilerRtl.} =
-  when defined(cpp) and not defined(noCppExceptions):
+  when defined(cpp) and not defined(noCppExceptions) and not gotoBasedExceptions:
     {.emit: "throw;".}
   else:
     if excHandler != nil:
@@ -439,7 +439,7 @@ proc raiseExceptionAux(e: sink(ref Exception)) {.nodestroy.} =
     if not localRaiseHook(e): return
   if globalRaiseHook != nil:
     if not globalRaiseHook(e): return
-  when defined(cpp) and not defined(noCppExceptions):
+  when defined(cpp) and not defined(noCppExceptions) and not gotoBasedExceptions:
     if e == currException:
       {.emit: "throw;".}
     else:
@@ -544,7 +544,7 @@ proc nimFrame(s: PFrame) {.compilerRtl, inl, raises: [].} =
   framePtr = s
   if s.calldepth == nimCallDepthLimit: callDepthLimitReached()
 
-when defined(cpp) and appType != "lib" and
+when defined(cpp) and appType != "lib" and not gotoBasedExceptions and
     not defined(js) and not defined(nimscript) and
     hostOS != "standalone" and not defined(noCppExceptions):
 
diff --git a/lib/system/memtracker.nim b/lib/system/memtracker.nim
index 69c8d5575..115d4a973 100644
--- a/lib/system/memtracker.nim
+++ b/lib/system/memtracker.nim
@@ -80,7 +80,7 @@ proc addEntry(entry: LogEntry) =
       #inc gLog.count
       #gLog.disabled = false
 
-proc memTrackerWrite(address: pointer; size: int; file: cstring; line: int) {.compilerProc.} =
+proc memTrackerWrite(address: pointer; size: int; file: cstring; line: int) {.compilerproc.} =
   addEntry LogEntry(op: "write", address: address,
       size: size, file: file, line: line, thread: myThreadId())
 
diff --git a/lib/system/seqs_v2.nim b/lib/system/seqs_v2.nim
index f28bcadca..3bd5e291b 100644
--- a/lib/system/seqs_v2.nim
+++ b/lib/system/seqs_v2.nim
@@ -92,7 +92,7 @@ proc grow*[T](x: var seq[T]; newLen: Natural; value: T) =
   for i in oldLen .. newLen-1:
     xu.p.data[i] = value
 
-proc add*[T](x: var seq[T]; value: sink T) {.magic: "AppendSeqElem", noSideEffect.} =
+proc add*[T](x: var seq[T]; value: sink T) {.magic: "AppendSeqElem", noSideEffect, nodestroy.} =
   ## Generic proc for adding a data item `y` to a container `x`.
   ##
   ## For containers that have an order, `add` means *append*. New generic
@@ -104,6 +104,10 @@ proc add*[T](x: var seq[T]; value: sink T) {.magic: "AppendSeqElem", noSideEffec
   if xu.p == nil or xu.p.cap < oldLen+1:
     xu.p = cast[typeof(xu.p)](prepareSeqAdd(oldLen, xu.p, 1, sizeof(T)))
   xu.len = oldLen+1
+  # .nodestroy means `xu.p.data[oldLen] = value` is compiled into a
+  # copyMem(). This is fine as know by construction that
+  # in `xu.p.data[oldLen]` there is nothing to destroy.
+  # We also save the `wasMoved + destroy` pair for the sink parameter.
   xu.p.data[oldLen] = value
 
 proc setLen[T](s: var seq[T], newlen: Natural) =