Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull 25-04-18 #2

Merged
merged 13 commits into from
Apr 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,10 @@
- Added ``macros.getProjectPath`` and ``ospaths.putEnv`` procs to Nim's virtual
machine.

- The ``deadCodeElim`` option is now always turned on and the switch has no
effect anymore, but is recognized for backwards compatibility.

- ``experimental`` is now a pragma / command line switch that can enable specific
language extensions, it is not an all-or-nothing switch anymore.

### Bugfixes
8 changes: 4 additions & 4 deletions compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,8 @@ type
# variable is a thread variable
sfCompileTime, # proc can be evaluated at compile time
sfConstructor, # proc is a C++ constructor
sfDeadCodeElim, # dead code elimination for the module is turned on
sfDispatcher, # copied method symbol is the dispatcher
# deprecated and unused, except for the con
sfBorrow, # proc is borrowed
sfInfixCall, # symbol needs infix call syntax in target language;
# for interfacing with C++, JS
Expand All @@ -275,10 +276,9 @@ type
TSymFlags* = set[TSymFlag]

const
sfDispatcher* = sfDeadCodeElim # copied method symbol is the dispatcher
sfNoInit* = sfMainModule # don't generate code to init the variable

sfImmediate* = sfDeadCodeElim
sfImmediate* = sfDispatcher
# macro or template is immediately expanded
# without considering any possible overloads
sfAllUntyped* = sfVolatile # macro or template is immediately expanded \
Expand Down Expand Up @@ -1622,7 +1622,7 @@ iterator items*(n: PNode): PNode =
for i in 0..<n.safeLen: yield n.sons[i]

iterator pairs*(n: PNode): tuple[i: int, n: PNode] =
for i in 0..<n.len: yield (i, n.sons[i])
for i in 0..<n.safeLen: yield (i, n.sons[i])

proc isAtom*(n: PNode): bool {.inline.} =
result = n.kind >= nkNone and n.kind <= nkNilLit
Expand Down
5 changes: 2 additions & 3 deletions compiler/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2264,7 +2264,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
of nkEmpty: discard
of nkWhileStmt: genWhileStmt(p, n)
of nkVarSection, nkLetSection: genVarStmt(p, n)
of nkConstSection: genConstStmt(p, n)
of nkConstSection: discard # consts generated lazily on use
of nkForStmt: internalError(n.info, "for statement not eliminated")
of nkCaseStmt: genCase(p, n, d)
of nkReturnStmt: genReturnStmt(p, n)
Expand Down Expand Up @@ -2315,8 +2315,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
# are not transformed correctly. We work around this issue (#411) here
# by ensuring it's no inner proc (owner is a module):
if prc.skipGenericOwner.kind == skModule and sfCompileTime notin prc.flags:
if (not emitLazily(prc)) or
({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or
if ({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or
(sfExportc in prc.flags and lfExportLib in prc.loc.flags) or
(prc.kind == skMethod):
# we have not only the header:
Expand Down
18 changes: 2 additions & 16 deletions compiler/ccgstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -280,20 +280,6 @@ proc genVarStmt(p: BProc, n: PNode) =
else:
genVarTuple(p, it)

proc genConstStmt(p: BProc, n: PNode) =
for it in n.sons:
if it.kind == nkCommentStmt: continue
if it.kind != nkConstDef: internalError(n.info, "genConstStmt")

let sym = it.sons[0].sym
if sym.typ.containsCompileTimeOnly or
sym.typ.kind notin ConstantDataTypes or
sym.ast.len == 0 or
emitLazily(sym):
continue

requestConstImpl(p, sym)

proc genIf(p: BProc, n: PNode, d: var TLoc) =
#
# { if (!expr1) goto L1;
Expand Down Expand Up @@ -587,7 +573,7 @@ proc genRaiseStmt(p: BProc, t: PNode) =
genLineDir(p, t)
if isImportedException(typ):
lineF(p, cpsStmts, "throw $1;$n", [e])
else:
else:
lineCg(p, cpsStmts, "#raiseException((#Exception*)$1, $2);$n",
[e, makeCString(typ.sym.name.s)])
else:
Expand Down Expand Up @@ -836,7 +822,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
else:
for j in 0..t[i].len-2:
if t[i][j].isInfixAs():
let exvar = t[i][j][2] # ex1 in `except ExceptType as ex1:`
let exvar = t[i][j][2] # ex1 in `except ExceptType as ex1:`
fillLoc(exvar.sym.loc, locTemp, exvar, mangleLocalName(p, exvar.sym), OnUnknown)
startBlock(p, "catch ($1& $2) {$n", getTypeDesc(p.module, t[i][j][1].typ), rdLoc(exvar.sym.loc))
else:
Expand Down
4 changes: 0 additions & 4 deletions compiler/ccgutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,4 @@ proc mangle*(name: string): string =
if requiresUnderscore:
result.add "_"

proc emitLazily*(s: PSym): bool {.inline.} =
result = optDeadCodeElim in gGlobalOptions or
sfDeadCodeElim in getModule(s).flags

initTypeTables()
4 changes: 0 additions & 4 deletions compiler/cgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1309,10 +1309,6 @@ proc newModule(g: BModuleList; module: PSym): BModule =
growCache g.modules, module.position
g.modules[module.position] = result

if (optDeadCodeElim in gGlobalOptions):
if (sfDeadCodeElim in module.flags):
internalError("added pending module twice: " & toFilename(FileIndex module.position))

template injectG(config) {.dirty.} =
if graph.backend == nil:
graph.backend = newModuleList(config)
Expand Down
52 changes: 29 additions & 23 deletions compiler/commands.nim
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ type
passCmd2, # second pass over the command line
passPP # preprocessor called processCommand()

proc processCommand*(switch: string, pass: TCmdLinePass)
proc processCommand*(switch: string, pass: TCmdLinePass; config: ConfigRef)
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
config: ConfigRef = nil)
config: ConfigRef)

# implementation

Expand All @@ -58,7 +58,13 @@ const

const
Usage = slurp"../doc/basicopt.txt".replace("//", "")
AdvancedUsage = slurp"../doc/advopt.txt".replace("//", "")
FeatureDesc = block:
var x = ""
for f in low(Feature)..high(Feature):
if x.len > 0: x.add "|"
x.add $f
x
AdvancedUsage = slurp"../doc/advopt.txt".replace("//", "") % FeatureDesc

proc getCommandLineDesc(): string =
result = (HelpMessage % [VersionAsString, platform.OS[platform.hostOS].name,
Expand Down Expand Up @@ -268,7 +274,6 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
of "movechecks": result = contains(gOptions, optMoveCheck)
of "linedir": result = contains(gOptions, optLineDir)
of "assertions", "a": result = contains(gOptions, optAssert)
of "deadcodeelim": result = contains(gGlobalOptions, optDeadCodeElim)
of "run", "r": result = contains(gGlobalOptions, optRun)
of "symbolfiles": result = gSymbolFiles != disabledSf
of "genscript": result = contains(gGlobalOptions, optGenScript)
Expand All @@ -277,7 +282,6 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
of "tlsemulation": result = contains(gGlobalOptions, optTlsEmulation)
of "implicitstatic": result = contains(gOptions, optImplicitStatic)
of "patterns": result = contains(gOptions, optPatterns)
of "experimental": result = gExperimentalMode
of "excessivestacktrace": result = contains(gGlobalOptions, optExcessiveStackTrace)
else: invalidCmdLineOption(passCmd1, switch, info)

Expand Down Expand Up @@ -340,7 +344,7 @@ proc dynlibOverride(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
options.inclDynlibOverride(arg)

proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
config: ConfigRef = nil) =
config: ConfigRef) =
var
theOS: TSystemOS
cpu: TSystemCPU
Expand Down Expand Up @@ -509,7 +513,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
of "movechecks": processOnOffSwitch({optMoveCheck}, arg, pass, info)
of "linedir": processOnOffSwitch({optLineDir}, arg, pass, info)
of "assertions", "a": processOnOffSwitch({optAssert}, arg, pass, info)
of "deadcodeelim": processOnOffSwitchG({optDeadCodeElim}, arg, pass, info)
of "deadcodeelim": discard # deprecated, dead code elim always on
of "threads":
processOnOffSwitchG({optThreads}, arg, pass, info)
#if optThreads in gGlobalOptions: incl(gNotes, warnGcUnsafe)
Expand Down Expand Up @@ -648,6 +652,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
of "genscript", "gendeps":
expectNoArg(switch, arg, pass, info)
incl(gGlobalOptions, optGenScript)
incl(gGlobalOptions, optCompileOnly)
of "colors": processOnOffSwitchG({optUseColors}, arg, pass, info)
of "lib":
expectArg(switch, arg, pass, info)
Expand Down Expand Up @@ -695,8 +700,13 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
# only supported for compatibility. Does nothing.
expectArg(switch, arg, pass, info)
of "experimental":
expectNoArg(switch, arg, pass, info)
gExperimentalMode = true
if arg.len == 0:
config.features.incl oldExperimentalFeatures
else:
try:
config.features.incl parseEnum[Feature](arg)
except ValueError:
localError(info, "unknown experimental feature")
of "nocppexceptions":
expectNoArg(switch, arg, pass, info)
incl(gGlobalOptions, optNoCppExceptions)
Expand All @@ -707,7 +717,8 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
config.cppDefine(arg)
of "newruntime":
expectNoArg(switch, arg, pass, info)
newDestructors = true
doAssert(config != nil)
incl(config.features, destructor)
defineSymbol("nimNewRuntime")
of "cppcompiletonamespace":
expectNoArg(switch, arg, pass, info)
Expand All @@ -717,36 +728,31 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
else: invalidCmdLineOption(pass, switch, info)

proc processCommand(switch: string, pass: TCmdLinePass) =
proc processCommand(switch: string, pass: TCmdLinePass; config: ConfigRef) =
var cmd, arg: string
splitSwitch(switch, cmd, arg, pass, gCmdLineInfo)
processSwitch(cmd, arg, pass, gCmdLineInfo)
processSwitch(cmd, arg, pass, gCmdLineInfo, config)


var
arguments* = ""
# the arguments to be passed to the program that
# should be run

proc processSwitch*(pass: TCmdLinePass; p: OptParser) =
proc processSwitch*(pass: TCmdLinePass; p: OptParser; config: ConfigRef) =
# hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off")
# we fix this here
var bracketLe = strutils.find(p.key, '[')
if bracketLe >= 0:
var key = substr(p.key, 0, bracketLe - 1)
var val = substr(p.key, bracketLe + 1) & ':' & p.val
processSwitch(key, val, pass, gCmdLineInfo)
processSwitch(key, val, pass, gCmdLineInfo, config)
else:
processSwitch(p.key, p.val, pass, gCmdLineInfo)
processSwitch(p.key, p.val, pass, gCmdLineInfo, config)

proc processArgument*(pass: TCmdLinePass; p: OptParser;
argsCount: var int): bool =
argsCount: var int; config: ConfigRef): bool =
if argsCount == 0:
# nim filename.nims is the same as "nim e filename.nims":
if p.key.endswith(".nims"):
options.command = "e"
options.gProjectName = unixToNativePath(p.key)
arguments = cmdLineRest(p)
config.arguments = cmdLineRest(p)
result = true
elif pass != passCmd2:
options.command = p.key
Expand All @@ -755,6 +761,6 @@ proc processArgument*(pass: TCmdLinePass; p: OptParser;
if argsCount == 1:
# support UNIX style filenames everywhere for portable build scripts:
options.gProjectName = unixToNativePath(p.key)
arguments = cmdLineRest(p)
config.arguments = cmdLineRest(p)
result = true
inc argsCount
3 changes: 2 additions & 1 deletion compiler/extccomp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,9 @@ proc execExternalProgram*(cmd: string, msg = hintExecuting) =

proc generateScript(projectFile: string, script: Rope) =
let (dir, name, ext) = splitFile(projectFile)
writeRope(script, dir / addFileExt("compile_" & name,
writeRope(script, getNimcacheDir() / addFileExt("compile_" & name,
platform.OS[targetOS].scriptExt))
copyFile(libpath / "nimbase.h", getNimcacheDir() / "nimbase.h")

proc getOptSpeed(c: TSystemCC): string =
result = getConfigVar(c, ".options.speed")
Expand Down
10 changes: 5 additions & 5 deletions compiler/nim.nim
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
writeCommandLineUsage()
else:
# Process command line arguments:
processCmdLine(passCmd1, "")
processCmdLine(passCmd1, "", config)
if gProjectName == "-":
gProjectName = "stdinfile"
gProjectFull = "stdinfile"
Expand Down Expand Up @@ -71,7 +71,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
# now process command line arguments again, because some options in the
# command line can overwite the config file's settings
extccomp.initVars()
processCmdLine(passCmd2, "")
processCmdLine(passCmd2, "", config)
if options.command == "":
rawMessage(errNoCommand, command)
mainCommand(newModuleGraph(config), cache)
Expand All @@ -80,7 +80,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
if msgs.gErrorCounter == 0:
when hasTinyCBackend:
if gCmd == cmdRun:
tccgen.run(commands.arguments)
tccgen.run(config.arguments)
if optRun in gGlobalOptions:
if gCmd == cmdCompileToJS:
var ex: string
Expand All @@ -89,7 +89,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
else:
ex = quoteShell(
completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
execExternalProgram(findNodeJs() & " " & ex & ' ' & commands.arguments)
execExternalProgram(findNodeJs() & " " & ex & ' ' & config.arguments)
else:
var binPath: string
if options.outFile.len > 0:
Expand All @@ -99,7 +99,7 @@ proc handleCmdLine(cache: IdentCache; config: ConfigRef) =
# Figure out ourselves a valid binary name.
binPath = changeFileExt(gProjectFull, ExeExt).prependCurDir
var ex = quoteShell(binPath)
execExternalProgram(ex & ' ' & commands.arguments)
execExternalProgram(ex & ' ' & config.arguments)

when declared(GC_setMaxPause):
GC_setMaxPause 2_000
Expand Down
4 changes: 0 additions & 4 deletions compiler/nimconf.nim
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,6 @@ proc loadConfigs*(cfg: string; cache: IdentCache; config: ConfigRef = nil) =
var projectConfig = changeFileExt(gProjectFull, "nimcfg")
if not fileExists(projectConfig):
projectConfig = changeFileExt(gProjectFull, "nim.cfg")
if not fileExists(projectConfig):
projectConfig = changeFileExt(gProjectFull, "nimrod.cfg")
if fileExists(projectConfig):
rawMessage(warnDeprecated, projectConfig)
readConfigFile(projectConfig, cache, config)

proc loadConfigs*(cfg: string; config: ConfigRef = nil) =
Expand Down
19 changes: 15 additions & 4 deletions compiler/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ type # please make sure we have under 32 options

TOptions* = set[TOption]
TGlobalOption* = enum # **keep binary compatible**
gloptNone, optForceFullMake, optDeadCodeElim,
gloptNone, optForceFullMake,
optDeadCodeElimUnused, # deprecated, always on
optListCmd, optCompileOnly, optNoLinking,
optCDebug, # turn on debugging information
optGenDynLib, # generate a dynamic library
Expand Down Expand Up @@ -102,13 +103,25 @@ type
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideMod,
ideHighlight, ideOutline, ideKnown, ideMsg

Feature* = enum ## experimental features
implicitDeref,
dotOperators,
callOperator,
parallel,
destructor

ConfigRef* = ref object ## eventually all global configuration should be moved here
cppDefines*: HashSet[string]
headerFile*: string
features*: set[Feature]
arguments*: string ## the arguments to be passed to the program that
## should be run

const oldExperimentalFeatures* = {implicitDeref, dotOperators, callOperator, parallel}

proc newConfigRef*(): ConfigRef =
result = ConfigRef(cppDefines: initSet[string](),
headerFile: "")
headerFile: "", features: {})

proc cppDefine*(c: ConfigRef; define: string) =
c.cppDefines.incl define
Expand Down Expand Up @@ -145,8 +158,6 @@ var
gListFullPaths*: bool
gPreciseStack*: bool = false
gNoNimblePath* = false
gExperimentalMode*: bool
newDestructors*: bool
gDynlibOverrideAll*: bool
useNimNamespace*: bool

Expand Down
2 changes: 1 addition & 1 deletion compiler/passes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
p: TParsers
a: TPassContextArray
s: PLLStream
fileIdx = FileIndex module.fileIdx
fileIdx = module.fileIdx
if module.id < 0:
# new module caching mechanism:
for i in 0..<gPassesLen:
Expand Down
Loading