summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitignore395
-rw-r--r--compiler/ccgcalls.nim2
-rw-r--r--compiler/ccgstmts.nim7
-rw-r--r--compiler/cgen.nim21
-rw-r--r--compiler/cgendata.nim1
-rw-r--r--compiler/extccomp.nim3
-rw-r--r--compiler/nimrod.nim10
-rw-r--r--compiler/pragmas.nim8
-rw-r--r--compiler/semthreads.nim3
-rw-r--r--compiler/wordrecg.nim5
-rw-r--r--doc/idetools.txt5
-rw-r--r--doc/manual.txt18
-rw-r--r--doc/nimrodc.txt13
-rw-r--r--lib/pure/os.nim28
-rw-r--r--lib/system.nim4
-rw-r--r--lib/system/alloc.nim2
-rw-r--r--lib/system/gc.nim13
-rw-r--r--lib/system/mmdisp.nim3
-rw-r--r--lib/windows/winlean.nim30
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".}