diff options
-rw-r--r-- | .gitignore | 395 | ||||
-rw-r--r-- | compiler/ccgcalls.nim | 2 | ||||
-rw-r--r-- | compiler/ccgstmts.nim | 7 | ||||
-rw-r--r-- | compiler/cgen.nim | 21 | ||||
-rw-r--r-- | compiler/cgendata.nim | 1 | ||||
-rw-r--r-- | compiler/extccomp.nim | 3 | ||||
-rw-r--r-- | compiler/nimrod.nim | 10 | ||||
-rw-r--r-- | compiler/pragmas.nim | 8 | ||||
-rw-r--r-- | compiler/semthreads.nim | 3 | ||||
-rw-r--r-- | compiler/wordrecg.nim | 5 | ||||
-rw-r--r-- | doc/idetools.txt | 5 | ||||
-rw-r--r-- | doc/manual.txt | 18 | ||||
-rw-r--r-- | doc/nimrodc.txt | 13 | ||||
-rw-r--r-- | lib/pure/os.nim | 28 | ||||
-rw-r--r-- | lib/system.nim | 4 | ||||
-rw-r--r-- | lib/system/alloc.nim | 2 | ||||
-rw-r--r-- | lib/system/gc.nim | 13 | ||||
-rw-r--r-- | lib/system/mmdisp.nim | 3 | ||||
-rw-r--r-- | lib/windows/winlean.nim | 30 |
19 files changed, 532 insertions, 39 deletions
diff --git a/.gitignore b/.gitignore index f576baf17..f5719848b 100644 --- a/.gitignore +++ b/.gitignore @@ -66,6 +66,7 @@ examples/cross_calculator/android/tags /examples/cgi/cgi_stacktrace /examples/cgi/example /examples/curlex +/examples/debugging /examples/docstrings /examples/filterex /examples/fizzbuzz @@ -91,6 +92,12 @@ examples/cross_calculator/android/tags /examples/pythonex /examples/sdlex /examples/statcsv +/examples/talk/dsl +/examples/talk/formatoptimizer +/examples/talk/hoisting +/examples/talk/lazyeval +/examples/talk/quasiquote +/examples/talk/tags /examples/tclex /examples/transff /examples/tunit @@ -98,10 +105,13 @@ examples/cross_calculator/android/tags /examples/x11ex /lib/libnimrtl.dylib /lib/libserver.dylib +/lib/packages/docutils/highlite /lib/pure/actors /lib/pure/algorithm /lib/pure/asyncio /lib/pure/base64 +/lib/pure/basic2d +/lib/pure/basic3d /lib/pure/browsers /lib/pure/cgi /lib/pure/collections/sequtils @@ -113,6 +123,7 @@ examples/cross_calculator/android/tags /lib/pure/encodings /lib/pure/endians /lib/pure/events +/lib/pure/fsmonitor /lib/pure/ftpclient /lib/pure/gentabs /lib/pure/hashes @@ -129,19 +140,23 @@ examples/cross_calculator/android/tags /lib/pure/math /lib/pure/md5 /lib/pure/memfiles +/lib/pure/mersenne /lib/pure/mimetypes /lib/pure/nimprof +/lib/pure/numeric /lib/pure/oids /lib/pure/os /lib/pure/osproc /lib/pure/parsecfg /lib/pure/parsecsv /lib/pure/parseopt +/lib/pure/parseopt2 /lib/pure/parsesql /lib/pure/parseurl /lib/pure/parseutils /lib/pure/parsexml /lib/pure/pegs +/lib/pure/poly /lib/pure/redis /lib/pure/romans /lib/pure/ropes @@ -169,9 +184,9 @@ examples/cross_calculator/android/tags /run.json /testresults.html /testresults.json -/tests/caas/SymbolProcRun.*/ /tests/caas/absurd_nesting /tests/caas/completion_dot_syntax_main +/tests/caasdriver /tests/caas/forward_declarations /tests/caas/idetools_api /tests/caas/imported @@ -180,6 +195,380 @@ examples/cross_calculator/android/tags /tests/caas/issue_477_dynamic_dispatch /tests/caas/its_full_of_procs /tests/caas/main -/tests/caasdriver -/tools/nimgrep +/tests/caas/SymbolProcRun.*/ +/tests/ccg/tmissingbracket +/tests/compile/talias +/tests/compile/tambsym2 +/tests/compile/tarrindx +/tests/compile/tassign +/tests/compile/tbindoverload +/tests/compile/tcan_alias_generic +/tests/compile/tcan_alias_specialised_generic +/tests/compile/tcan_inherit_generic +/tests/compile/tcan_specialise_generic +/tests/compile/tccgen1 +/tests/compile/tclosure4 +/tests/compile/tclosurebug2 +/tests/compile/tcmdline +/tests/compile/tcodegenbug1 +/tests/compile/tcolonisproc +/tests/compile/tcolors +/tests/compile/tcommontype +/tests/compile/tcompiles +/tests/compile/tcomputedgoto +/tests/compile/tconsteval +/tests/compile/tconstraints +/tests/compile/tconvcolors +/tests/compile/tcputime +/tests/compile/tdefaultprocparam +/tests/compile/tdictdestruct +/tests/compile/tdiscardable +/tests/compile/tdllvar +/tests/compile/tdumpast +/tests/compile/tdumpast2 +/tests/compile/techo +/tests/compile/teffects1 +/tests/compile/temptyecho +/tests/compile/tendian +/tests/compile/tenum +/tests/compile/tenum2 +/tests/compile/tenum3 +/tests/compile/teval1 +/tests/compile/texport +/tests/compile/tfib +/tests/compile/tforwardgeneric +/tests/compile/tforwty +/tests/compile/tforwty2 +/tests/compile/tgeneric +/tests/compile/tgeneric2 +/tests/compile/tgeneric3 +/tests/compile/tgeneric4 +/tests/compile/tgenericmatcher +/tests/compile/tgenericmatcher2 +/tests/compile/tgenericprocvar +/tests/compile/tgenericprop +/tests/compile/tgenericrefs +/tests/compile/tgenerictmpl +/tests/compile/tgenericvariant +/tests/compile/tgensymgeneric +/tests/compile/tgetstartmilsecs +/tests/compile/tglobalforvar +/tests/compile/thallo +/tests/compile/theaproots +/tests/compile/thexrange +/tests/compile/thygienictempl +/tests/compile/tident +/tests/compile/timplicititems +/tests/compile/timplictderef +/tests/compile/tinheritref +/tests/compile/tio +/tests/compile/tircbot +/tests/compile/titer +/tests/compile/titer2 +/tests/compile/titer_no_tuple_unpack +/tests/compile/titerovl +/tests/compile/tlastmod +/tests/compile/tlinearscanend +/tests/compile/tloops +/tests/compile/tmacro1 +/tests/compile/tmacro2 +/tests/compile/tmacroaspragma +/tests/compile/tmacrostmt +/tests/compile/tmandelbrot +/tests/compile/tmarshal +/tests/compile/tmath +/tests/compile/tmatrix1 +/tests/compile/tmatrix2 +/tests/compile/tmongo +/tests/compile/tnamedparamanonproc +/tests/compile/tnamedparams +/tests/compile/tnestedproc +/tests/compile/tnew +/tests/compile/tnewsets +/tests/compile/tnewuns +/tests/compile/tnoargopenarray +/tests/compile/tnoforward +/tests/compile/tobjconstr2 +/tests/compile/tobjcov +/tests/compile/tobject2 +/tests/compile/tobject3 +/tests/compile/tobjects +/tests/compile/toop +/tests/compile/toptions +/tests/compile/tos +/tests/compile/toverprc +/tests/compile/tparedef +/tests/compile/tparscfg +/tests/compile/tparsefloat +/tests/compile/tparsopt +/tests/compile/tposix +/tests/compile/tprep +/tests/compile/tprocvars +/tests/compile/tpush +/tests/compile/tquicksort +/tests/compile/tquit +/tests/compile/tradix +/tests/compile/treadln +/tests/compile/treadx +/tests/compile/trecmod +/tests/compile/trecmod2 +/tests/compile/trectuple +/tests/compile/trectuples +/tests/compile/tredef +/tests/compile/trepr +/tests/compile/tsecondarrayproperty +/tests/compile/tseq2 +/tests/compile/tseqcon2 +/tests/compile/tshadow_magic_type +/tests/compile/tsizeof +/tests/compile/tslurp +/tests/compile/tsockets +/tests/compile/tsortcall +/tests/compile/tspecialised_is_equivalent +/tests/compile/tstrace +/tests/compile/tstrdesc +/tests/compile/tstrdist +/tests/compile/tstreams +/tests/compile/tstrset +/tests/compile/tstrtabs +/tests/compile/ttableconstr +/tests/compile/ttempl +/tests/compile/ttempl3 +/tests/compile/ttempl4 +/tests/compile/ttempl5 +/tests/compile/ttemplreturntype +/tests/compile/tthread_generic +/tests/compile/ttime +/tests/compile/ttuple1 +/tests/compile/ttypeclasses +/tests/compile/ttypeconverter1 +/tests/compile/tuserpragma +/tests/compile/tvoid +/tests/compile/twalker +/tests/compile/typalias +/tests/dll/client +/tests/gc/closureleak +/tests/gc/cycleleak +/tests/gc/gcbench +/tests/gc/gcleak +/tests/gc/gcleak2 +/tests/gc/gcleak3 +/tests/gc/gctest +/tests/gc/weakrefs +/tests/manyloc/argument_parser/ex_wget +/tests/manyloc/nake/nakefile +/tests/manyloc/packages/noconflicts +/tests/manyloc/standalone/barebone +/tests/patterns/targlist +/tests/patterns/tcse +/tests/patterns/thoist +/tests/patterns/tmatrix +/tests/patterns/tnoalias +/tests/patterns/tnoendlessrec +/tests/patterns/tor +/tests/patterns/tpartial +/tests/patterns/tstar +/tests/patterns/tstmtlist +/tests/reject/t99bott +/tests/reject/tcheckedfield1 +/tests/reject/tdeprecated +/tests/reject/tdisallowif +/tests/reject/tuninit1 +/tests/rodfiles/aconv +/tests/rodfiles/bconv +/tests/rodfiles/bmethods +/tests/rodfiles/bmethods2 +/tests/rodfiles/deada +/tests/rodfiles/deada2 +/tests/rodfiles/hallo +/tests/rodfiles/hallo2 +/tests/rodfiles/tgeneric1 +/tests/rodfiles/tgeneric2 +/tests/run/tack +/tests/run/tactiontable +/tests/run/tambsym2 +/tests/run/tambsys +/tests/run/tanontuples +/tests/run/tarray +/tests/run/tarray2 +/tests/run/tarray3 +/tests/run/tarraycons +/tests/run/tassert +/tests/run/tastoverload1 +/tests/run/tasynciossl +/tests/run/tasyncudp +/tests/run/tbind1 +/tests/run/tbind3 +/tests/run/tbintre2 +/tests/run/tbintree +/tests/run/tborrow +/tests/run/tbug499771 +/tests/run/tbug511622 +/tests/run/tcase_setconstr +/tests/run/tcasestm +/tests/run/tcgbug +/tests/run/tclosure2 +/tests/run/tclosure3 +/tests/run/tcnstseq +/tests/run/tcnstseq2 +/tests/run/tcnstseq3 +/tests/run/tconcat +/tests/run/tconstr2 +/tests/run/tcontinue +/tests/run/tcontinuexc +/tests/run/tcopy +/tests/run/tcountup +/tests/run/tcritbits +/tests/run/tcurrncy +/tests/run/tdestructor +/tests/run/tdrdobbs_examples +/tests/run/temit +/tests/run/tenumhole +/tests/run/tenumitems +/tests/run/teventemitter +/tests/run/tevents +/tests/run/texceptions +/tests/run/texcpt1 +/tests/run/texcsub +/tests/run/texplicitgeneric1 +/tests/run/tfieldindex +/tests/run/tfielditerator +/tests/run/tfielditerator2 +/tests/run/tfilter +/tests/run/tfinally +/tests/run/tfinally2 +/tests/run/tfinally3 +/tests/run/tfinalobj +/tests/run/tfloat1 +/tests/run/tfloat2 +/tests/run/tfloat3 +/tests/run/tformat +/tests/run/tfriends +/tests/run/tgenericassign +/tests/run/tgenericassigntuples +/tests/run/tgenericconverter +/tests/run/tgenericprocvar +/tests/run/tgenerics1 +/tests/run/tgensym +/tests/run/tglobal +/tests/run/thashes +/tests/run/thexlit +/tests/run/thintoff +/tests/run/tidgen +/tests/run/tindent1 +/tests/run/tinit +/tests/run/tinterf +/tests/run/tints +/tests/run/tisopr +/tests/run/titer3 +/tests/run/titer5 +/tests/run/titer6 +/tests/run/titer7 +/tests/run/titer8 +/tests/run/titer9 +/tests/run/titerslice +/tests/run/titervaropenarray +/tests/run/tkoeniglookup +/tests/run/tlet +/tests/run/tlists +/tests/run/tlocals +/tests/run/tlowhigh +/tests/run/tmacro2 +/tests/run/tmacro3 +/tests/run/tmacro4 +/tests/run/tmacros1 +/tests/run/tmath +/tests/run/tmatrix +/tests/run/tmemoization +/tests/run/tmethods1 +/tests/run/tmixin +/tests/run/tmoditer +/tests/run/tmultim1 +/tests/run/tmultim2 +/tests/run/tmultim3 +/tests/run/tmultim4 +/tests/run/tmultim6 +/tests/run/tnamedenumfields +/tests/run/tnestif +/tests/run/tnestprc +/tests/run/tnewderef +/tests/run/tnodeadlocks +/tests/run/tobjasgn +/tests/run/tobjconstr +/tests/run/tobject +/tests/run/tofopr +/tests/run/tonraise +/tests/run/toop1 +/tests/run/topenarrayrepr +/tests/run/topenlen +/tests/run/toprprec +/tests/run/toverflw +/tests/run/toverflw2 +/tests/run/toverl2 +/tests/run/toverl3 +/tests/run/toverwr +/tests/run/tovfint +/tests/run/tpatterns +/tests/run/tpegs +/tests/run/tpos +/tests/run/tprecedence +/tests/run/tprintf +/tests/run/tprocvar +/tests/run/tquotewords +/tests/run/tregex +/tests/run/treguse +/tests/run/trepr +/tests/run/treraise +/tests/run/tromans +/tests/run/tseqcon +/tests/run/tseqtuple +/tests/run/tsequtils +/tests/run/tsets +/tests/run/tsets2 +/tests/run/tsidee2 +/tests/run/tsidee3 +/tests/run/tsimmeth +/tests/run/tsimplesort +/tests/run/tslices +/tests/run/tsortdev +/tests/run/tsplit +/tests/run/tstempl +/tests/run/tstmtexprs +/tests/run/tstrange +/tests/run/tstringinterp +/tests/run/tstrlits +/tests/run/tstrutil +/tests/run/tsubrange +/tests/run/tsubrange2 +/tests/run/ttables +/tests/run/ttables2 +/tests/run/ttoseq +/tests/run/ttypedesc1 +/tests/run/tunhandledexc +/tests/run/tunidecode +/tests/run/tunittests +/tests/run/tuserassert +/tests/run/tvarargs_vs_generic +/tests/run/tvardecl +/tests/run/tvariantasgn +/tests/run/tvariantstack +/tests/run/tvarious1 +/tests/run/tvarnums +/tests/run/tvarres1 +/tests/run/tvarres2 +/tests/run/tvartup +/tests/run/tvtable +/tests/run/twrongexc +/tests/run/txmlgen +/tests/run/txmltree +/tests/run/tzeroarray +/tests/system/helpers/readall_echo +/tests/system/io /tests/system/params +/tests/tester +/tests/threads/tactors +/tests/threads/tactors2 +/tests/threads/tthreadanalysis2 +/tests/threads/tthreadanalysis3 +/tests/threads/tthreadheapviolation1 +/tools/nimgrep diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 1d6df3c15..07fba95a3 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -290,6 +290,7 @@ proc genCall(p: BProc, e: PNode, d: var TLoc) = genNamedParamCall(p, e, d) else: genPrefixCall(p, nil, e, d) + postStmtActions(p) when false: if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d) @@ -303,6 +304,7 @@ proc genAsgnCall(p: BProc, le, ri: PNode, d: var TLoc) = genNamedParamCall(p, ri, d) else: genPrefixCall(p, le, ri, d) + postStmtActions(p) when false: if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 75cabf414..ac4bbb79f 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -906,7 +906,12 @@ proc genPragma(p: BProc, n: PNode) = of wEmit: genEmit(p, it) of wBreakpoint: genBreakPoint(p, it) of wWatchpoint: genWatchpoint(p, it) - else: nil + of wInjectStmt: + var p = newProc(nil, p.module) + p.options = p.options - {optLineTrace, optStackTrace} + genStmts(p, it.sons[1]) + p.module.injectStmt = p.s(cpsStmts) + else: discard proc FieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool = if optFieldCheck in p.options: diff --git a/compiler/cgen.nim b/compiler/cgen.nim index b0c90de76..6ccef5fde 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -289,6 +289,9 @@ proc genLineDir(p: BProc, t: PNode) = linefmt(p, cpsStmts, "nimln($1, $2);$n", line.toRope, t.info.quotedFilename) +proc postStmtActions(p: BProc) {.inline.} = + app(p.s(cpsStmts), p.module.injectStmt) + proc accessThreadLocalVar(p: BProc, s: PSym) proc emulatedThreadVars(): bool {.inline.} @@ -1119,6 +1122,9 @@ proc newPostInitProc(m: BModule): BProc = # little hack so that unique temporaries are generated: result.labels = 200_000 +proc initProcOptions(m: BModule): TOptions = + if sfSystemModule in m.module.flags: gOptions-{optStackTrace} else: gOptions + proc rawNewModule(module: PSym, filename: string): BModule = new(result) InitLinkedList(result.headerFiles) @@ -1131,7 +1137,7 @@ proc rawNewModule(module: PSym, filename: string): BModule = result.module = module result.typeInfoMarker = initIntSet() result.initProc = newProc(nil, result) - result.initProc.options = gOptions + result.initProc.options = initProcOptions(result) result.preInitProc = newPreInitProc(result) result.postInitProc = newPostInitProc(result) initNodeTable(result.dataCache) @@ -1139,7 +1145,12 @@ proc rawNewModule(module: PSym, filename: string): BModule = result.forwardedProcs = @[] result.typeNodesName = getTempName() result.nimTypesName = getTempName() - result.PreventStackTrace = sfSystemModule in module.flags + # no line tracing for the init sections of the system module so that we + # don't generate a TFrame which can confuse the stack botton initialization: + if sfSystemModule in module.flags: + result.PreventStackTrace = true + excl(result.preInitProc.options, optStackTrace) + excl(result.postInitProc.options, optStackTrace) proc nullify[T](arr: var T) = for i in low(arr)..high(arr): @@ -1152,7 +1163,7 @@ proc resetModule*(m: var BModule) = m.declaredProtos = initIntSet() initIdTable(m.forwTypeCache) m.initProc = newProc(nil, m) - m.initProc.options = gOptions + m.initProc.options = initProcOptions(m) m.preInitProc = newPreInitProc(m) m.postInitProc = newPostInitProc(m) initNodeTable(m.dataCache) @@ -1242,7 +1253,7 @@ proc myProcess(b: PPassContext, n: PNode): PNode = result = n if b == nil or passes.skipCodegen(n): return var m = BModule(b) - m.initProc.options = gOptions + m.initProc.options = initProcOptions(m) genStmts(m.initProc, n) proc finishModule(m: BModule) = @@ -1329,7 +1340,7 @@ proc myClose(b: PPassContext, n: PNode): PNode = if b == nil or passes.skipCodegen(n): return var m = BModule(b) if n != nil: - m.initProc.options = gOptions + m.initProc.options = initProcOptions(m) genStmts(m.initProc, n) # cached modules need to registered too: registerModuleToMain(m.module) diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index c156c40fe..a803c0ba1 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -111,6 +111,7 @@ type labels*: natural # for generating unique module-scope names extensionLoaders*: array['0'..'9', PRope] # special procs for the # OpenGL wrapper + injectStmt*: PRope var mainModProcs*, mainModInit*, mainDatInit*: PRope # parts of the main module diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index fe1bea3ff..d3b3cee75 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -616,7 +616,8 @@ proc CallCCompiler*(projectfile: string) = if options.outFile.len > 0: exefile = options.outFile if not noAbsolutePaths(): - exefile = joinPath(splitFile(projectFile).dir, exefile) + if not exeFile.isAbsolute(): + exefile = joinPath(splitFile(projectFile).dir, exefile) exefile = quoteShell(exefile) let linkOptions = getLinkOptions() linkCmd = quoteShell(linkCmd % ["builddll", builddll, diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim index 8e3c0e61e..2bc94e3f8 100644 --- a/compiler/nimrod.nim +++ b/compiler/nimrod.nim @@ -65,8 +65,14 @@ proc HandleCmdLine() = completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir)) execExternalProgram("node " & ex & ' ' & service.arguments) else: - var ex = quoteShell( - changeFileExt(gProjectFull, exeExt).prependCurDir) + var binPath: string + if options.outFile.len > 0: + # If the user specified an outFile path, use that directly. + binPath = options.outFile.prependCurDir + else: + # Figure out ourselves a valid binary name. + binPath = changeFileExt(gProjectFull, exeExt).prependCurDir + var ex = quoteShell(binPath) execExternalProgram(ex & ' ' & service.arguments) when defined(GC_setMaxPause): diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 8c2425de3..6f1e7af25 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -43,7 +43,8 @@ const wFatal, wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop, wBreakpoint, wWatchpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated, wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, - wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto} + wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto, + wInjectStmt} lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame, @@ -722,6 +723,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, of wOperator: if sym == nil: invalidPragma(it) else: sym.position = expectIntLit(c, it) + of wInjectStmt: + if it.kind != nkExprColonExpr: + localError(it.info, errExprExpected) + else: + it.sons[1] = c.semExpr(c, it.sons[1]) else: invalidPragma(it) else: invalidPragma(it) else: processNote(c, it) diff --git a/compiler/semthreads.nim b/compiler/semthreads.nim index 595ab0454..eded99325 100644 --- a/compiler/semthreads.nim +++ b/compiler/semthreads.nim @@ -380,7 +380,8 @@ proc analyseThreadProc*(prc: PSym) = var formals = skipTypes(prc.typ, abstractInst).n for i in 1 .. formals.len-1: var formal = formals.sons[i].sym - c.mapping[formal.id] = toTheirs # thread receives foreign data! + # the input is copied and belongs to the thread: + c.mapping[formal.id] = toMine discard analyse(c, prc.getBody) proc needsGlobalAnalysis*: bool = diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index b37a7bb4f..39b19646e 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -60,7 +60,7 @@ type wPassc, wPassl, wBorrow, wDiscardable, wFieldChecks, wWatchPoint, wSubsChar, - wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, + wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, wInjectStmt, wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit, wNoStackFrame, wImplicitStatic, wGlobal, wCodegenDecl, @@ -142,7 +142,8 @@ const "compiletime", "noinit", "passc", "passl", "borrow", "discardable", "fieldchecks", "watchpoint", - "subschar", "acyclic", "shallow", "unroll", "linearscanend", "computedgoto", + "subschar", "acyclic", "shallow", "unroll", "linearscanend", + "computedgoto", "injectstmt", "write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit", "nostackframe", "implicitstatic", "global", "codegendecl", diff --git a/doc/idetools.txt b/doc/idetools.txt index fdc4ebde6..7e51669f2 100644 --- a/doc/idetools.txt +++ b/doc/idetools.txt @@ -8,6 +8,11 @@ .. contents:: +.. raw:: html + <blockquote><p> + "yes, I'm the creator" -- Araq, 2013-07-26 19:28:32. + </p></blockquote> + Nimrod differs from many other compilers in that it is really fast, and being so fast makes it suited to provide external queries for text editors about the source code being written. Through the diff --git a/doc/manual.txt b/doc/manual.txt index dabff3d69..0a9aec8d0 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -4708,7 +4708,11 @@ fatal pragma ------------ The `fatal`:idx: pragma is used to make the compiler output an error message with the given content. In contrast to the ``error`` pragma, compilation -is guaranteed to be aborted by this pragma. +is guaranteed to be aborted by this pragma. Example: + +.. code-block:: nimrod + when not defined(objc): + {.fatal: "Compile this program with the objc command!".} warning pragma -------------- @@ -5053,6 +5057,18 @@ Note that this pragma is somewhat of a misnomer: Other backends will provide the same feature under the same name. +Extern pragma +------------- +Like ``exportc`` or ``importc`` the `extern`:idx: pragma affects name +mangling. The string literal passed to ``extern`` can be a format string: + +.. code-block:: Nimrod + proc p(s: string) {.extern: "prefix$1".} = + echo s + +In the example the external name of ``p`` is set to ``prefixp``. + + Bycopy pragma ------------- diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt index d494a0922..f5fbf3ebb 100644 --- a/doc/nimrodc.txt +++ b/doc/nimrodc.txt @@ -468,6 +468,19 @@ proc is declared in the generated code: proc myinterrupt() {.codegenDecl: "__interrupt $# $#$#".} = echo "realistic interrupt handler" + + +InjectStmt pragma +----------------- + +The `injectStmt`:idx: pragma can be used to inject a statement before every +other statement in the current module. It is only supposed to be used for +debugging: + +.. code-block:: nimrod + {.injectStmt: gcInvariants().} + + # ... complex code here that produces crashes ... LineDir option diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 71639d821..d74cb1fb9 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -970,17 +970,37 @@ proc moveFile*(source, dest: string) {.rtl, extern: "nos$1", if crename(source, dest) != 0'i32: raise newException(EOS, $strerror(errno)) -when not defined(ENOENT): +when not defined(ENOENT) and not defined(Windows): var ENOENT {.importc, header: "<errno.h>".}: cint +when defined(Windows): + when useWinUnicode: + template DeleteFile(file: expr): expr {.immediate.} = DeleteFileW(file) + template SetFileAttributes(file, attrs: expr): expr {.immediate.} = + SetFileAttributesW(file, attrs) + else: + template DeleteFile(file: expr): expr {.immediate.} = DeleteFileA(file) + template SetFileAttributes(file, attrs: expr): expr {.immediate.} = + SetFileAttributesA(file, attrs) + proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = ## Removes the `file`. If this fails, `EOS` is raised. This does not fail ## if the file never existed in the first place. ## On Windows, ignores the read-only attribute. when defined(Windows): - setFilePermissions(file, {fpUserWrite}) - if cremove(file) != 0'i32 and errno != ENOENT: - raise newException(EOS, $strerror(errno)) + when useWinUnicode: + let f = newWideCString(file) + else: + let f = file + if DeleteFile(f) == 0: + if GetLastError() == ERROR_ACCESS_DENIED: + if SetFileAttributes(f, FILE_ATTRIBUTE_NORMAL) == 0: + OSError(OSLastError()) + if DeleteFile(f) == 0: + OSError(OSLastError()) + else: + if cremove(file) != 0'i32 and errno != ENOENT: + raise newException(EOS, $strerror(errno)) proc execShellCmd*(command: string): int {.rtl, extern: "nos$1", tags: [FExecIO].} = diff --git a/lib/system.nim b/lib/system.nim index 3fccb4e8b..106eb04a3 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -923,6 +923,10 @@ proc quit*(errorcode: int = QuitSuccess) {. ## The proc ``quit(QuitSuccess)`` is called implicitly when your nimrod ## program finishes without incident. A raised unhandled exception is ## equivalent to calling ``quit(QuitFailure)``. + ## + ## Note that this is a *runtime* call and using ``quit`` inside a macro won't + ## have any compile time effect. If you need to stop the compiler inside a + ## macro, use the ``error`` or ``fatal`` pragmas. template sysAssert(cond: bool, msg: string) = when defined(useSysAssert): diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 2bab79212..17258cf68 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -760,7 +760,7 @@ proc getOccupiedMem(a: TMemRegion): int {.inline.} = # ---------------------- thread memory region ------------------------------- template InstantiateForRegion(allocator: expr) = - when false: + when defined(fulldebug): proc interiorAllocatedPtr*(p: pointer): pointer = result = interiorAllocatedPtr(allocator, p) diff --git a/lib/system/gc.nim b/lib/system/gc.nim index d2b065d6b..68e8b423d 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -345,8 +345,9 @@ proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) = proc forAllChildren(cell: PCell, op: TWalkOp) = gcAssert(cell != nil, "forAllChildren: 1") - gcAssert(cell.typ != nil, "forAllChildren: 2") - gcAssert cell.typ.kind in {tyRef, tySequence, tyString}, "forAllChildren: 3" + gcAssert(isAllocatedPtr(gch.region, cell), "forAllChildren: 2") + gcAssert(cell.typ != nil, "forAllChildren: 3") + gcAssert cell.typ.kind in {tyRef, tySequence, tyString}, "forAllChildren: 4" let marker = cell.typ.marker if marker != nil: marker(cellToUsr(cell), op.int) @@ -361,7 +362,7 @@ proc forAllChildren(cell: PCell, op: TWalkOp) = for i in 0..s.len-1: forAllChildrenAux(cast[pointer](d +% i *% cell.typ.base.size +% GenericSeqSize), cell.typ.base, op) - else: nil + else: discard proc addNewObjToZCT(res: PCell, gch: var TGcHeap) {.inline.} = # we check the last 8 entries (cache line) for a slot that could be reused. @@ -408,8 +409,10 @@ proc addNewObjToZCT(res: PCell, gch: var TGcHeap) {.inline.} = add(gch.zct, res) {.push stackTrace: off, profiler:off.} -proc gcInvariant*(msg: string) = - sysAssert(allocInv(gch.region), msg) +proc gcInvariant*() = + sysAssert(allocInv(gch.region), "injected") + when defined(markForDebug): + markForDebug(gch) {.pop.} proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap): pointer = diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index 118272ee3..942b6778e 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -18,7 +18,8 @@ const logGC = false traceGC = false # extensive debugging alwaysCycleGC = false - alwaysGC = false # collect after every memory allocation (for debugging) + alwaysGC = defined(fulldebug) # collect after every memory + # allocation (for debugging) leakDetector = false overwriteFree = false trackAllocationSource = leakDetector diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 56d279db6..264285d09 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -416,17 +416,17 @@ var SOMAXCONN* {.importc, header: "Winsock2.h".}: cint INVALID_SOCKET* {.importc, header: "Winsock2.h".}: TSocketHandle SOL_SOCKET* {.importc, header: "Winsock2.h".}: cint - SO_DEBUG* {.importc, header: "Winsock2.h".}: cint ## turn on debugging info recording - SO_ACCEPTCONN* {.importc, header: "Winsock2.h".}: cint # socket has had listen() - SO_REUSEADDR* {.importc, header: "Winsock2.h".}: cint # allow local address reuse - SO_KEEPALIVE* {.importc, header: "Winsock2.h".}: cint # keep connections alive - SO_DONTROUTE* {.importc, header: "Winsock2.h".}: cint # just use interface addresses - SO_BROADCAST* {.importc, header: "Winsock2.h".}: cint # permit sending of broadcast msgs - SO_USELOOPBACK* {.importc, header: "Winsock2.h".}: cint # bypass hardware when possible - SO_LINGER* {.importc, header: "Winsock2.h".}: cint # linger on close if data present - SO_OOBINLINE* {.importc, header: "Winsock2.h".}: cint # leave received OOB data in line - - SO_DONTLINGER* {.importc, header: "Winsock2.h".}: cint + SO_DEBUG* {.importc, header: "Winsock2.h".}: cint ## turn on debugging info recording + SO_ACCEPTCONN* {.importc, header: "Winsock2.h".}: cint # socket has had listen() + SO_REUSEADDR* {.importc, header: "Winsock2.h".}: cint # allow local address reuse + SO_KEEPALIVE* {.importc, header: "Winsock2.h".}: cint # keep connections alive + SO_DONTROUTE* {.importc, header: "Winsock2.h".}: cint # just use interface addresses + SO_BROADCAST* {.importc, header: "Winsock2.h".}: cint # permit sending of broadcast msgs + SO_USELOOPBACK* {.importc, header: "Winsock2.h".}: cint # bypass hardware when possible + SO_LINGER* {.importc, header: "Winsock2.h".}: cint # linger on close if data present + SO_OOBINLINE* {.importc, header: "Winsock2.h".}: cint # leave received OOB data in line + + SO_DONTLINGER* {.importc, header: "Winsock2.h".}: cint SO_EXCLUSIVEADDRUSE* {.importc, header: "Winsock2.h".}: cint # disallow local address reuse proc `==`*(x, y: TSocketHandle): bool {.borrow.} @@ -553,18 +553,26 @@ const FILE_FLAG_BACKUP_SEMANTICS* = 33554432'i32 +# Error Constants +const + ERROR_ACCESS_DENIED* = 5 + when useWinUnicode: proc CreateFileW*(lpFileName: widecstring, dwDesiredAccess, dwShareMode: DWORD, lpSecurityAttributes: pointer, dwCreationDisposition, dwFlagsAndAttributes: DWORD, hTemplateFile: THANDLE): THANDLE {. stdcall, dynlib: "kernel32", importc: "CreateFileW".} + proc DeleteFileW*(pathName: widecstring): int32 {. + importc: "DeleteFileW", dynlib: "kernel32", stdcall.} else: proc CreateFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD, lpSecurityAttributes: pointer, dwCreationDisposition, dwFlagsAndAttributes: DWORD, hTemplateFile: THANDLE): THANDLE {. stdcall, dynlib: "kernel32", importc: "CreateFileA".} + proc DeleteFileA*(pathName: cstring): int32 {. + importc: "DeleteFileA", dynlib: "kernel32", stdcall.} proc SetEndOfFile*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32", importc: "SetEndOfFile".} |