From 6efac70181f54d24627b101ede6c79b8c3e74a96 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sat, 25 Jan 2020 20:00:13 +0100 Subject: [PATCH] make goto based exceptions available for 'nim cpp' (#13244) * make goto based exceptions available for 'nim cpp' * optimize seq.add to be comparable to C++'s emplace_back --- compiler/ccgtypes.nim | 2 +- compiler/cgen.nim | 2 +- compiler/cmdlinehelper.nim | 7 +++++++ compiler/commands.nim | 10 ++++------ compiler/main.nim | 3 ++- compiler/options.nim | 1 + compiler/pragmas.nim | 4 ++-- compiler/vm.nim | 2 +- lib/system/excpt.nim | 8 ++++---- lib/system/memtracker.nim | 2 +- lib/system/seqs_v2.nim | 6 +++++- 11 files changed, 29 insertions(+), 18 deletions(-) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 24551e7e5a6c..759330a3ebe0 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 706e8e3ee207..fd14817e0dc7 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, "") linefmt(p, section, "new ($1) $2;$n", [rdLoc(a), getTypeDesc(p.module, t)]) diff --git a/compiler/cmdlinehelper.nim b/compiler/cmdlinehelper.nim index e44163d1437f..a50d47ad21bc 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 f90d79d5b007..6633c1aa2702 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 87180db0ae40..5efdd87af91e 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 2d56974c59cd..d8f6fd0b9d0f 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 ab0af80ea711..02912808673c 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 8a08de36d1e5..2e65a47f43b9 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..