reintroduce thread analysis but disable it for backwards compatibility
This commit is contained in:
parent
da7d6c8446
commit
4075159933
7 changed files with 26 additions and 17 deletions
|
|
@ -168,6 +168,7 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
|
||||||
of "forcebuild", "f": result = contains(gGlobalOptions, optForceFullMake)
|
of "forcebuild", "f": result = contains(gGlobalOptions, optForceFullMake)
|
||||||
of "warnings", "w": result = contains(gOptions, optWarns)
|
of "warnings", "w": result = contains(gOptions, optWarns)
|
||||||
of "hints": result = contains(gOptions, optHints)
|
of "hints": result = contains(gOptions, optHints)
|
||||||
|
of "threadanalysis": result = contains(gGlobalOptions, optThreadAnalysis)
|
||||||
of "stacktrace": result = contains(gOptions, optStackTrace)
|
of "stacktrace": result = contains(gOptions, optStackTrace)
|
||||||
of "linetrace": result = contains(gOptions, optLineTrace)
|
of "linetrace": result = contains(gOptions, optLineTrace)
|
||||||
of "debugger": result = contains(gOptions, optEndb)
|
of "debugger": result = contains(gOptions, optEndb)
|
||||||
|
|
@ -329,6 +330,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
|
||||||
of "warning": processSpecificNote(arg, wWarning, pass, info)
|
of "warning": processSpecificNote(arg, wWarning, pass, info)
|
||||||
of "hint": processSpecificNote(arg, wHint, pass, info)
|
of "hint": processSpecificNote(arg, wHint, pass, info)
|
||||||
of "hints": processOnOffSwitch({optHints}, arg, pass, info)
|
of "hints": processOnOffSwitch({optHints}, arg, pass, info)
|
||||||
|
of "threadanalysis": processOnOffSwitchG({optThreadAnalysis}, arg, pass, info)
|
||||||
of "stacktrace": processOnOffSwitch({optStackTrace}, arg, pass, info)
|
of "stacktrace": processOnOffSwitch({optStackTrace}, arg, pass, info)
|
||||||
of "linetrace": processOnOffSwitch({optLineTrace}, arg, pass, info)
|
of "linetrace": processOnOffSwitch({optLineTrace}, arg, pass, info)
|
||||||
of "debugger":
|
of "debugger":
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
const
|
const
|
||||||
genPrefix* = ":tmp" # prefix for generated names
|
genPrefix* = ":tmp" # prefix for generated names
|
||||||
|
|
||||||
import ast, astalgo, types, idents, magicsys, msgs
|
import ast, astalgo, types, idents, magicsys, msgs, options
|
||||||
|
|
||||||
proc newTupleAccess*(tup: PNode, i: int): PNode =
|
proc newTupleAccess*(tup: PNode, i: int): PNode =
|
||||||
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(
|
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(
|
||||||
|
|
@ -151,8 +151,9 @@ proc wrapProcForSpawn*(owner: PSym; n: PNode): PNode =
|
||||||
if n.kind notin nkCallKinds or not n.typ.isEmptyType:
|
if n.kind notin nkCallKinds or not n.typ.isEmptyType:
|
||||||
localError(n.info, "'spawn' takes a call expression of type void")
|
localError(n.info, "'spawn' takes a call expression of type void")
|
||||||
return
|
return
|
||||||
if {tfThread, tfNoSideEffect} * n[0].typ.flags == {}:
|
if optThreadAnalysis in gGlobalOptions:
|
||||||
localError(n.info, "'spawn' takes a GC safe call expression")
|
if {tfThread, tfNoSideEffect} * n[0].typ.flags == {}:
|
||||||
|
localError(n.info, "'spawn' takes a GC safe call expression")
|
||||||
var
|
var
|
||||||
threadParam = newSym(skParam, getIdent"thread", owner, n.info)
|
threadParam = newSym(skParam, getIdent"thread", owner, n.info)
|
||||||
argsParam = newSym(skParam, getIdent"args", owner, n.info)
|
argsParam = newSym(skParam, getIdent"args", owner, n.info)
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ type # please make sure we have under 32 options
|
||||||
optContext, # ideTools: 'context'
|
optContext, # ideTools: 'context'
|
||||||
optDef, # ideTools: 'def'
|
optDef, # ideTools: 'def'
|
||||||
optUsages, # ideTools: 'usages'
|
optUsages, # ideTools: 'usages'
|
||||||
|
optThreadAnalysis, # thread analysis pass
|
||||||
optTaintMode, # taint mode turned on
|
optTaintMode, # taint mode turned on
|
||||||
optTlsEmulation, # thread var emulation turned on
|
optTlsEmulation, # thread var emulation turned on
|
||||||
optGenIndex # generate index file for documentation;
|
optGenIndex # generate index file for documentation;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nimrod Compiler
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2014 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -689,10 +689,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
incl(sym.flags, sfProcvar)
|
incl(sym.flags, sfProcvar)
|
||||||
if sym.typ != nil: incl(sym.typ.flags, tfThread)
|
if sym.typ != nil: incl(sym.typ.flags, tfThread)
|
||||||
of wGcSafe:
|
of wGcSafe:
|
||||||
noVal(it)
|
if optThreadAnalysis in gGlobalOptions:
|
||||||
if sym.kind != skType: incl(sym.flags, sfThread)
|
noVal(it)
|
||||||
if sym.typ != nil: incl(sym.typ.flags, tfGcSafe)
|
if sym.kind != skType: incl(sym.flags, sfThread)
|
||||||
else: invalidPragma(it)
|
if sym.typ != nil: incl(sym.typ.flags, tfGcSafe)
|
||||||
|
else: invalidPragma(it)
|
||||||
of wPacked:
|
of wPacked:
|
||||||
noVal(it)
|
noVal(it)
|
||||||
if sym.typ == nil: invalidPragma(it)
|
if sym.typ == nil: invalidPragma(it)
|
||||||
|
|
|
||||||
|
|
@ -705,11 +705,12 @@ proc trackProc*(s: PSym, body: PNode) =
|
||||||
checkRaisesSpec(usesSpec, t.uses,
|
checkRaisesSpec(usesSpec, t.uses,
|
||||||
"uses an unlisted global variable: ", hints=on, symbolPredicate)
|
"uses an unlisted global variable: ", hints=on, symbolPredicate)
|
||||||
effects.sons[usesEffects] = usesSpec
|
effects.sons[usesEffects] = usesSpec
|
||||||
if sfThread in s.flags and t.gcUnsafe:
|
if optThreadAnalysis in gGlobalOptions:
|
||||||
localError(s.info, warnGcUnsafe2, s.name.s)
|
if sfThread in s.flags and t.gcUnsafe:
|
||||||
#localError(s.info, "'$1' is not GC-safe" % s.name.s)
|
localError(s.info, warnGcUnsafe2, s.name.s)
|
||||||
if not t.gcUnsafe: s.typ.flags.incl tfGcSafe
|
#localError(s.info, "'$1' is not GC-safe" % s.name.s)
|
||||||
|
if not t.gcUnsafe: s.typ.flags.incl tfGcSafe
|
||||||
|
|
||||||
proc trackTopLevelStmt*(module: PSym; n: PNode) =
|
proc trackTopLevelStmt*(module: PSym; n: PNode) =
|
||||||
if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef,
|
if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef,
|
||||||
nkTypeSection, nkConverterDef, nkMethodDef, nkIteratorDef}:
|
nkTypeSection, nkConverterDef, nkMethodDef, nkIteratorDef}:
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ Advanced options:
|
||||||
--lineDir:on|off generation of #line directive on|off
|
--lineDir:on|off generation of #line directive on|off
|
||||||
--embedsrc embeds the original source code as comments
|
--embedsrc embeds the original source code as comments
|
||||||
in the generated output
|
in the generated output
|
||||||
|
--threadanalysis:on|off turn thread analysis on|off
|
||||||
--tlsEmulation:on|off turn thread local storage emulation on|off
|
--tlsEmulation:on|off turn thread local storage emulation on|off
|
||||||
--taintMode:on|off turn taint mode on|off
|
--taintMode:on|off turn taint mode on|off
|
||||||
--symbolFiles:on|off turn symbol files on|off (experimental)
|
--symbolFiles:on|off turn symbol files on|off (experimental)
|
||||||
|
|
|
||||||
|
|
@ -615,11 +615,13 @@ elif not defined(useNimRtl):
|
||||||
optionPoStdErrToStdOut: bool
|
optionPoStdErrToStdOut: bool
|
||||||
|
|
||||||
when not defined(useFork):
|
when not defined(useFork):
|
||||||
proc startProcessAuxSpawn(data: TStartProcessData): TPid {.tags: [FExecIO, FReadEnv].}
|
proc startProcessAuxSpawn(data: TStartProcessData): TPid {.
|
||||||
proc startProcessAuxFork(data: TStartProcessData): TPid {.tags: [FExecIO, FReadEnv].}
|
tags: [FExecIO, FReadEnv], gcsafe.}
|
||||||
|
proc startProcessAuxFork(data: TStartProcessData): TPid {.
|
||||||
|
tags: [FExecIO, FReadEnv], gcsafe.}
|
||||||
{.push stacktrace: off, profiler: off.}
|
{.push stacktrace: off, profiler: off.}
|
||||||
proc startProcessAfterFork(data: ptr TStartProcessData) {.
|
proc startProcessAfterFork(data: ptr TStartProcessData) {.
|
||||||
tags: [FExecIO, FReadEnv], cdecl.}
|
tags: [FExecIO, FReadEnv], cdecl, gcsafe.}
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
proc startProcess(command: string,
|
proc startProcess(command: string,
|
||||||
|
|
@ -946,7 +948,7 @@ elif not defined(useNimRtl):
|
||||||
proc execCmdEx*(command: string, options: set[TProcessOption] = {
|
proc execCmdEx*(command: string, options: set[TProcessOption] = {
|
||||||
poStdErrToStdOut, poUsePath}): tuple[
|
poStdErrToStdOut, poUsePath}): tuple[
|
||||||
output: TaintedString,
|
output: TaintedString,
|
||||||
exitCode: int] {.tags: [FExecIO, FReadIO].} =
|
exitCode: int] {.tags: [FExecIO, FReadIO], gcsafe.} =
|
||||||
## a convenience proc that runs the `command`, grabs all its output and
|
## a convenience proc that runs the `command`, grabs all its output and
|
||||||
## exit code and returns both.
|
## exit code and returns both.
|
||||||
var p = startCmd(command, options)
|
var p = startCmd(command, options)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue