diff options
-rw-r--r-- | compiler/ccgtypes.nim | 2 | ||||
-rw-r--r-- | compiler/cgen.nim | 2 | ||||
-rw-r--r-- | compiler/cmdlinehelper.nim | 7 | ||||
-rw-r--r-- | compiler/commands.nim | 10 | ||||
-rw-r--r-- | compiler/main.nim | 3 | ||||
-rw-r--r-- | compiler/options.nim | 1 | ||||
-rw-r--r-- | compiler/pragmas.nim | 4 | ||||
-rw-r--r-- | compiler/vm.nim | 2 | ||||
-rw-r--r-- | lib/system/excpt.nim | 8 | ||||
-rw-r--r-- | lib/system/memtracker.nim | 2 | ||||
-rw-r--r-- | lib/system/seqs_v2.nim | 6 |
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) = |