Merge pull request #11771 from nim-lang/araq-remove-unused-imports
[refactoring] remove unused imports in the compiler and in some stdli…
This commit is contained in:
commit
4becd5a2a8
76 changed files with 531 additions and 558 deletions
|
|
@ -10,8 +10,7 @@
|
||||||
# abstract syntax tree + symbol table
|
# abstract syntax tree + symbol table
|
||||||
|
|
||||||
import
|
import
|
||||||
lineinfos, hashes, nversion, options, strutils, std / sha1, ropes, idents,
|
lineinfos, hashes, options, ropes, idents, idgen
|
||||||
intsets, idgen
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TCallingConvention* = enum
|
TCallingConvention* = enum
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
## is needed for incremental compilation.
|
## is needed for incremental compilation.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, ropes, options, strutils, nimlexbase, msgs, cgendata, rodutils,
|
ast, ropes, options, strutils, nimlexbase, cgendata, rodutils,
|
||||||
intsets, platform, llstream, tables, sighashes, modulegraphs, pathutils
|
intsets, llstream, tables, modulegraphs, pathutils
|
||||||
|
|
||||||
# Careful! Section marks need to contain a tabulator so that they cannot
|
# Careful! Section marks need to contain a tabulator so that they cannot
|
||||||
# be part of C string literals.
|
# be part of C string literals.
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
# This module declares some helpers for the C code generator.
|
# This module declares some helpers for the C code generator.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, ropes, hashes, strutils, types, msgs, wordrecg,
|
ast, hashes, strutils, msgs, wordrecg,
|
||||||
platform, trees, options
|
platform, trees, options
|
||||||
|
|
||||||
proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode =
|
proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode =
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, hashes, trees, platform, magicsys, extccomp, options, intsets,
|
ast, astalgo, hashes, trees, platform, magicsys, extccomp, options, intsets,
|
||||||
nversion, nimsets, msgs, std / sha1, bitsets, idents, types,
|
nversion, nimsets, msgs, bitsets, idents, types,
|
||||||
ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth,
|
ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth,
|
||||||
condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases,
|
condsyms, rodutils, renderer, cgendata, ccgmerge, aliases,
|
||||||
lowerings, tables, sets, ndi, lineinfos, pathutils, transf, enumtostr
|
lowerings, tables, sets, ndi, lineinfos, pathutils, transf, enumtostr
|
||||||
|
|
||||||
when not defined(leanCompiler):
|
when not defined(leanCompiler):
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## This module contains the data structures for the C code generation phase.
|
## This module contains the data structures for the C code generation phase.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, ropes, passes, options, intsets, platform, sighashes,
|
ast, ropes, passes, options, intsets,
|
||||||
tables, ndi, lineinfos, pathutils, modulegraphs
|
tables, ndi, lineinfos, pathutils, modulegraphs
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## This module implements code generation for multi methods.
|
## This module implements code generation for multi methods.
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, options, ast, astalgo, msgs, idents, renderer, types, magicsys,
|
intsets, options, ast, msgs, idents, renderer, types, magicsys,
|
||||||
sempass2, strutils, modulegraphs, lineinfos
|
sempass2, strutils, modulegraphs, lineinfos
|
||||||
|
|
||||||
proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =
|
proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =
|
||||||
|
|
|
||||||
|
|
@ -131,8 +131,8 @@
|
||||||
# break :stateLoop
|
# break :stateLoop
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, idents,
|
ast, msgs, idents,
|
||||||
renderer, types, magicsys, lowerings, lambdalifting, modulegraphs, lineinfos
|
renderer, magicsys, lowerings, lambdalifting, modulegraphs, lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
Ctx = object
|
Ctx = object
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ bootSwitch(usedNoGC, defined(nogc), "--gc:none")
|
||||||
|
|
||||||
import
|
import
|
||||||
os, msgs, options, nversion, condsyms, strutils, extccomp, platform,
|
os, msgs, options, nversion, condsyms, strutils, extccomp, platform,
|
||||||
wordrecg, parseutils, nimblecmd, idents, parseopt, sequtils, lineinfos,
|
wordrecg, parseutils, nimblecmd, parseopt, sequtils, lineinfos,
|
||||||
pathutils, strtabs
|
pathutils, strtabs
|
||||||
|
|
||||||
# but some have deps to imported modules. Yay.
|
# but some have deps to imported modules. Yay.
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
# This module handles the conditional symbols.
|
# This module handles the conditional symbols.
|
||||||
|
|
||||||
import
|
import
|
||||||
strtabs, platform, strutils, idents
|
strtabs
|
||||||
|
|
||||||
from options import Feature
|
from options import Feature
|
||||||
from lineinfos import HintsToStr, WarningsToStr
|
from lineinfos import HintsToStr, WarningsToStr
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@
|
||||||
# This module implements a dependency file generator.
|
# This module implements a dependency file generator.
|
||||||
|
|
||||||
import
|
import
|
||||||
os, options, ast, astalgo, msgs, ropes, idents, passes, modulepaths,
|
options, ast, ropes, idents, passes, modulepaths, pathutils
|
||||||
pathutils
|
|
||||||
|
|
||||||
from modulegraphs import ModuleGraph, PPassContext
|
from modulegraphs import ModuleGraph, PPassContext
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
## "A Graph–Free Approach to Data–Flow Analysis" by Markus Mohnen.
|
## "A Graph–Free Approach to Data–Flow Analysis" by Markus Mohnen.
|
||||||
## https://link.springer.com/content/pdf/10.1007/3-540-45937-5_6.pdf
|
## https://link.springer.com/content/pdf/10.1007/3-540-45937-5_6.pdf
|
||||||
|
|
||||||
import ast, astalgo, types, intsets, tables, msgs, options, lineinfos, renderer
|
import ast, types, intsets, lineinfos, renderer
|
||||||
|
|
||||||
from patterns import sameTrees
|
from patterns import sameTrees
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import
|
||||||
wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast,
|
wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast,
|
||||||
packages/docutils/rst, packages/docutils/rstgen,
|
packages/docutils/rst, packages/docutils/rstgen,
|
||||||
packages/docutils/highlite, json, xmltree, cgi, trees, types,
|
packages/docutils/highlite, json, xmltree, cgi, trees, types,
|
||||||
typesrenderer, astalgo, modulepaths, lineinfos, sequtils, intsets,
|
typesrenderer, astalgo, modulepaths, lineinfos, intsets,
|
||||||
pathutils, trees
|
pathutils, trees
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@
|
||||||
# semantic checking.
|
# semantic checking.
|
||||||
|
|
||||||
import
|
import
|
||||||
os, options, ast, astalgo, msgs, ropes, idents, passes, docgen, lineinfos,
|
options, ast, msgs, idents, passes, docgen, lineinfos, pathutils
|
||||||
pathutils
|
|
||||||
|
|
||||||
from modulegraphs import ModuleGraph, PPassContext
|
from modulegraphs import ModuleGraph, PPassContext
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@
|
||||||
## Template evaluation engine. Now hygienic.
|
## Template evaluation engine. Now hygienic.
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, options, ast, astalgo, msgs, os, idents, wordrecg, renderer,
|
strutils, options, ast, astalgo, msgs, renderer, lineinfos
|
||||||
lineinfos
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TemplCtx = object
|
TemplCtx = object
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
# This module implements Nim's standard template filter.
|
# This module implements Nim's standard template filter.
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
|
llstream, strutils, ast, msgs, options,
|
||||||
renderer, filters, lineinfos, pathutils
|
filters, lineinfos, pathutils
|
||||||
|
|
||||||
type
|
type
|
||||||
TParseState = enum
|
TParseState = enum
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
# This module implements Nim's simple filters and helpers for filters.
|
# This module implements Nim's simple filters and helpers for filters.
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
|
llstream, idents, strutils, ast, msgs, options,
|
||||||
renderer, pathutils
|
renderer, pathutils
|
||||||
|
|
||||||
proc invalidPragma(conf: ConfigRef; n: PNode) =
|
proc invalidPragma(conf: ConfigRef; n: PNode) =
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## Module that implements ``gorge`` for the compiler.
|
## Module that implements ``gorge`` for the compiler.
|
||||||
|
|
||||||
import msgs, std / sha1, os, osproc, streams, strutils, options,
|
import msgs, std / sha1, os, osproc, streams, options,
|
||||||
lineinfos, pathutils
|
lineinfos, pathutils
|
||||||
|
|
||||||
proc readOutput(p: Process): (string, int) =
|
proc readOutput(p: Process): (string, int) =
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
# id. This module is essential for the compiler's performance.
|
# id. This module is essential for the compiler's performance.
|
||||||
|
|
||||||
import
|
import
|
||||||
hashes, strutils, wordrecg
|
hashes, wordrecg
|
||||||
|
|
||||||
type
|
type
|
||||||
TIdObj* = object of RootObj
|
TIdObj* = object of RootObj
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## This module contains a simple persistent id generator.
|
## This module contains a simple persistent id generator.
|
||||||
|
|
||||||
import idents, strutils, os, options, pathutils
|
import idents, strutils, options, pathutils
|
||||||
|
|
||||||
var gFrontEndId*: int
|
var gFrontEndId*: int
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
## This module implements the symbol importing mechanism.
|
## This module implements the symbol importing mechanism.
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, strutils, os, ast, astalgo, msgs, options, idents, lookups,
|
intsets, ast, astalgo, msgs, options, idents, lookups,
|
||||||
semdata, passes, renderer, modulepaths, sigmatch, lineinfos
|
semdata, modulepaths, sigmatch, lineinfos
|
||||||
|
|
||||||
proc readExceptSet*(c: PContext, n: PNode): IntSet =
|
proc readExceptSet*(c: PContext, n: PNode): IntSet =
|
||||||
assert n.kind in {nkImportExceptStmt, nkExportExceptStmt}
|
assert n.kind in {nkImportExceptStmt, nkExportExceptStmt}
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
|
|
||||||
const nimIncremental* = defined(nimIncremental)
|
const nimIncremental* = defined(nimIncremental)
|
||||||
|
|
||||||
import options, lineinfos, pathutils
|
import options, lineinfos
|
||||||
|
|
||||||
when nimIncremental:
|
when nimIncremental:
|
||||||
import ast, msgs, intsets, btrees, db_sqlite, std / sha1
|
import ast, msgs, intsets, btrees, db_sqlite, std / sha1, pathutils
|
||||||
from strutils import parseInt
|
from strutils import parseInt
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ to do it.
|
||||||
]#
|
]#
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
|
intsets, ast, msgs, renderer, magicsys, types, idents,
|
||||||
strutils, options, dfa, lowerings, tables, modulegraphs, msgs,
|
strutils, options, dfa, lowerings, tables, modulegraphs, msgs,
|
||||||
lineinfos, parampatterns, sighashes
|
lineinfos, parampatterns, sighashes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,11 @@ implements the required case distinction.
|
||||||
|
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options,
|
ast, strutils, trees, magicsys, options,
|
||||||
nversion, nimsets, msgs, std / sha1, bitsets, idents, types, os, tables,
|
nversion, msgs, idents, types, tables,
|
||||||
times, ropes, math, passes, ccgutils, wordrecg, renderer,
|
ropes, math, passes, ccgutils, wordrecg, renderer,
|
||||||
intsets, cgmeth, lowerings, sighashes, modulegraphs, lineinfos, rodutils,
|
intsets, cgmeth, lowerings, sighashes, modulegraphs, lineinfos, rodutils,
|
||||||
pathutils, transf
|
transf
|
||||||
|
|
||||||
|
|
||||||
from modulegraphs import ModuleGraph, PPassContext
|
from modulegraphs import ModuleGraph, PPassContext
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
# This file implements lambda lifting for the transformator.
|
# This file implements lambda lifting for the transformator.
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, strutils, options, ast, astalgo, trees, treetab, msgs,
|
intsets, strutils, options, ast, astalgo, msgs,
|
||||||
idents, renderer, types, magicsys, lowerings, tables, modulegraphs, lineinfos,
|
idents, renderer, types, magicsys, lowerings, tables, modulegraphs, lineinfos,
|
||||||
transf, liftdestructors
|
transf, liftdestructors
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
# Todo:
|
# Todo:
|
||||||
# - use openArray instead of array to avoid over-specializations
|
# - use openArray instead of array to avoid over-specializations
|
||||||
|
|
||||||
import modulegraphs, lineinfos, idents, ast, astalgo, renderer, semdata,
|
import modulegraphs, lineinfos, idents, ast, renderer, semdata,
|
||||||
sighashes, lowerings, options, types, msgs, magicsys, tables
|
sighashes, lowerings, options, types, msgs, magicsys, tables
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## This module implements the '.liftLocals' pragma.
|
## This module implements the '.liftLocals' pragma.
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, strutils, options, ast, astalgo, msgs,
|
strutils, options, ast, msgs,
|
||||||
idents, renderer, types, lowerings, lineinfos
|
idents, renderer, types, lowerings, lineinfos
|
||||||
|
|
||||||
from pragmas import getPragmaVal
|
from pragmas import getPragmaVal
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,9 @@
|
||||||
|
|
||||||
## This module implements the style checker.
|
## This module implements the style checker.
|
||||||
|
|
||||||
import
|
import strutils
|
||||||
strutils, os, intsets, strtabs
|
|
||||||
|
|
||||||
import options, ast, astalgo, msgs, semdata, ropes, idents,
|
import options, ast, msgs, idents, lineinfos, wordrecg
|
||||||
lineinfos, pathutils, wordrecg
|
|
||||||
|
|
||||||
const
|
const
|
||||||
Letters* = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'}
|
Letters* = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## Low-level streams for high performance.
|
## Low-level streams for high performance.
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, pathutils
|
pathutils
|
||||||
|
|
||||||
# support '-d:useGnuReadline' for backwards compatibility:
|
# support '-d:useGnuReadline' for backwards compatibility:
|
||||||
when not defined(windows) and (defined(useGnuReadline) or defined(useLinenoise)):
|
when not defined(windows) and (defined(useGnuReadline) or defined(useLinenoise)):
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, ast, astalgo, idents, semdata, types, msgs, options,
|
intsets, ast, astalgo, idents, semdata, types, msgs, options,
|
||||||
renderer, wordrecg, idgen, nimfix/prettybase, lineinfos, strutils
|
renderer, nimfix/prettybase, lineinfos, strutils
|
||||||
|
|
||||||
proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope)
|
proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ const
|
||||||
|
|
||||||
import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs,
|
import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs,
|
||||||
lineinfos
|
lineinfos
|
||||||
from trees import getMagic
|
|
||||||
|
|
||||||
proc newDeref*(n: PNode): PNode {.inline.} =
|
proc newDeref*(n: PNode): PNode {.inline.} =
|
||||||
result = newNodeIT(nkHiddenDeref, n.info, n.typ.sons[0])
|
result = newNodeIT(nkHiddenDeref, n.info, n.typ.sons[0])
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## This module implements helpers for the macro cache.
|
## This module implements helpers for the macro cache.
|
||||||
|
|
||||||
import lineinfos, ast, modulegraphs, vmdef, magicsys
|
import lineinfos, ast, modulegraphs, vmdef
|
||||||
|
|
||||||
proc recordInc*(c: PCtx; info: TLineInfo; key: string; by: BiggestInt) =
|
proc recordInc*(c: PCtx; info: TLineInfo; key: string; by: BiggestInt) =
|
||||||
var recorded = newNodeI(nkCommentStmt, info)
|
var recorded = newNodeI(nkCommentStmt, info)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
# Built-in types and compilerprocs are registered here.
|
# Built-in types and compilerprocs are registered here.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, hashes, msgs, platform, nversion, times, idents,
|
ast, astalgo, msgs, platform, idents,
|
||||||
modulegraphs, lineinfos
|
modulegraphs, lineinfos
|
||||||
|
|
||||||
export createMagic
|
export createMagic
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,12 @@ when not defined(nimcore):
|
||||||
{.error: "nimcore MUST be defined for Nim's core tooling".}
|
{.error: "nimcore MUST be defined for Nim's core tooling".}
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs,
|
llstream, strutils, ast, lexer, syntaxes, options, msgs,
|
||||||
os, condsyms, times,
|
condsyms, times,
|
||||||
wordrecg, sem, semdata, idents, passes, extccomp,
|
sem, idents, passes, extccomp,
|
||||||
cgen, json, nversion,
|
cgen, json, nversion,
|
||||||
platform, nimconf, importer, passaux, depends, vm, vmdef, types, idgen,
|
platform, nimconf, passaux, depends, vm, idgen,
|
||||||
parser, modules, ccgutils, sigmatch, ropes,
|
parser, modules,
|
||||||
modulegraphs, tables, rod, lineinfos, pathutils
|
modulegraphs, tables, rod, lineinfos, pathutils
|
||||||
|
|
||||||
when not defined(leanCompiler):
|
when not defined(leanCompiler):
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import ast, renderer, strutils, msgs, options, idents, os, lineinfos,
|
import ast, renderer, strutils, msgs, options, idents, os, lineinfos,
|
||||||
pathutils, nimblecmd
|
pathutils
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
## Implements the module handling, including the caching of modules.
|
## Implements the module handling, including the caching of modules.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, magicsys, std / sha1, msgs, cgendata, sigmatch, options,
|
ast, astalgo, magicsys, msgs, options,
|
||||||
idents, os, lexer, idgen, passes, syntaxes, llstream, modulegraphs, rod,
|
idents, lexer, idgen, passes, syntaxes, llstream, modulegraphs, rod,
|
||||||
lineinfos, pathutils, tables
|
lineinfos, pathutils, tables
|
||||||
|
|
||||||
proc resetSystemArtifacts*(g: ModuleGraph) =
|
proc resetSystemArtifacts*(g: ModuleGraph) =
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import
|
import
|
||||||
options, strutils, os, tables, ropes, platform, terminal, macros,
|
options, strutils, os, tables, ropes, terminal, macros,
|
||||||
lineinfos, pathutils
|
lineinfos, pathutils
|
||||||
|
|
||||||
proc toCChar*(c: char; result: var string) =
|
proc toCChar*(c: char; result: var string) =
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@ when defined(i386) and defined(windows) and defined(vcc):
|
||||||
{.link: "../icons/nim-i386-windows-vcc.res".}
|
{.link: "../icons/nim-i386-windows-vcc.res".}
|
||||||
|
|
||||||
import
|
import
|
||||||
commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes,
|
commands, options, msgs,
|
||||||
extccomp, strutils, os, osproc, platform, main, parseopt,
|
extccomp, strutils, os, main, parseopt,
|
||||||
scriptconfig, idents, modulegraphs, lineinfos, cmdlinehelper,
|
idents, lineinfos, cmdlinehelper,
|
||||||
pathutils
|
pathutils
|
||||||
|
|
||||||
include nodejs
|
include nodejs
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
# This module handles the reading of the config file.
|
# This module handles the reading of the config file.
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, lexer,
|
llstream, commands, os, strutils, msgs, lexer,
|
||||||
options, idents, wordrecg, strtabs, lineinfos, pathutils
|
options, idents, wordrecg, strtabs, lineinfos, pathutils
|
||||||
|
|
||||||
# ---------------- configuration file parser -----------------------------
|
# ---------------- configuration file parser -----------------------------
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import strutils except Letters
|
import strutils except Letters
|
||||||
import lexbase, streams
|
|
||||||
import ".." / [ast, msgs, lineinfos, idents, options, linter]
|
import ".." / [ast, msgs, lineinfos, idents, options, linter]
|
||||||
from os import splitFile
|
|
||||||
|
|
||||||
proc replaceDeprecated*(conf: ConfigRef; info: TLineInfo; oldSym, newSym: PIdent) =
|
proc replaceDeprecated*(conf: ConfigRef; info: TLineInfo; oldSym, newSym: PIdent) =
|
||||||
let line = sourceLine(conf, info)
|
let line = sourceLine(conf, info)
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@
|
||||||
# this unit handles Nim sets; it implements symbolic sets
|
# this unit handles Nim sets; it implements symbolic sets
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, trees, nversion, lineinfos, platform, bitsets, types, renderer,
|
ast, astalgo, lineinfos, bitsets, types, options
|
||||||
options
|
|
||||||
|
|
||||||
proc inSet*(s: PNode, elem: PNode): bool =
|
proc inSet*(s: PNode, elem: PNode): bool =
|
||||||
assert s.kind == nkCurly
|
assert s.kind == nkCurly
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import
|
import
|
||||||
os, strutils, strtabs, osproc, sets, lineinfos, platform,
|
os, strutils, strtabs, sets, lineinfos, platform,
|
||||||
prefixmatches, pathutils
|
prefixmatches, pathutils
|
||||||
|
|
||||||
from terminal import isatty
|
from terminal import isatty
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## This module implements the pattern matching features for term rewriting
|
## This module implements the pattern matching features for term rewriting
|
||||||
## macro support.
|
## macro support.
|
||||||
|
|
||||||
import strutils, ast, astalgo, types, msgs, idents, renderer, wordrecg, trees,
|
import strutils, ast, types, msgs, idents, renderer, wordrecg, trees,
|
||||||
options
|
options
|
||||||
|
|
||||||
# we precompile the pattern here for efficiency into some internal
|
# we precompile the pattern here for efficiency into some internal
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ when isMainModule:
|
||||||
outp.close
|
outp.close
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, lexer, idents, strutils, ast, astalgo, msgs, options, lineinfos,
|
llstream, lexer, idents, strutils, ast, msgs, options, lineinfos,
|
||||||
pathutils
|
pathutils
|
||||||
|
|
||||||
when defined(nimpretty):
|
when defined(nimpretty):
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## implements some little helper passes
|
## implements some little helper passes
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, ast, astalgo, passes, idents, msgs, options, idgen, lineinfos
|
ast, passes, idents, msgs, options, idgen, lineinfos
|
||||||
|
|
||||||
from modulegraphs import ModuleGraph, PPassContext
|
from modulegraphs import ModuleGraph, PPassContext
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@
|
||||||
## `TPass` interface.
|
## `TPass` interface.
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, options, ast, astalgo, llstream, msgs, platform, os,
|
options, ast, llstream, msgs,
|
||||||
condsyms, idents, renderer, types, extccomp, math, magicsys, nversion,
|
idents,
|
||||||
nimsets, syntaxes, times, idgen, modulegraphs, reorder, rod,
|
syntaxes, idgen, modulegraphs, reorder, rod,
|
||||||
lineinfos, pathutils
|
lineinfos, pathutils
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## Path handling utilities for Nim. Strictly typed code in order
|
## Path handling utilities for Nim. Strictly typed code in order
|
||||||
## to avoid the never ending time sink in getting path handling right.
|
## to avoid the never ending time sink in getting path handling right.
|
||||||
|
|
||||||
import os, strutils, pathnorm
|
import os, pathnorm
|
||||||
|
|
||||||
type
|
type
|
||||||
AbsoluteFile* = distinct string
|
AbsoluteFile* = distinct string
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@
|
||||||
## macro support.
|
## macro support.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, types, semdata, sigmatch, msgs, idents, aliases, parampatterns,
|
ast, types, semdata, sigmatch, idents, aliases, parampatterns, trees
|
||||||
trees
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TPatternContext = object
|
TPatternContext = object
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,7 @@
|
||||||
|
|
||||||
## Plugin to transform an inline iterator into a data structure.
|
## Plugin to transform an inline iterator into a data structure.
|
||||||
|
|
||||||
import ".." / [ast, astalgo,
|
import ".." / [ast, lookups, semdata, lambdalifting, msgs]
|
||||||
magicsys, lookups, semdata,
|
|
||||||
lambdalifting, msgs]
|
|
||||||
|
|
||||||
proc iterToProcImpl*(c: PContext, n: PNode): PNode =
|
proc iterToProcImpl*(c: PContext, n: PNode): PNode =
|
||||||
result = newNodeI(nkStmtList, n.info)
|
result = newNodeI(nkStmtList, n.info)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## The builtin 'system.locals' implemented as a plugin.
|
## The builtin 'system.locals' implemented as a plugin.
|
||||||
|
|
||||||
import ".." / [pluginsupport, ast, astalgo,
|
import ".." / [ast, astalgo,
|
||||||
magicsys, lookups, semdata, lowerings]
|
magicsys, lookups, semdata, lowerings]
|
||||||
|
|
||||||
proc semLocals*(c: PContext, n: PNode): PNode =
|
proc semLocals*(c: PContext, n: PNode): PNode =
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, ast, idents, algorithm, renderer, parser, os, strutils,
|
intsets, ast, idents, algorithm, renderer, os, strutils,
|
||||||
sequtils, msgs, modulegraphs, syntaxes, options, modulepaths, tables,
|
msgs, modulegraphs, syntaxes, options, modulepaths,
|
||||||
lineinfos
|
lineinfos
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## This module implements the canonalization for the various caching mechanisms.
|
## This module implements the canonalization for the various caching mechanisms.
|
||||||
|
|
||||||
import ast, idgen, lineinfos, msgs, incremental, modulegraphs, pathutils
|
import ast, idgen, lineinfos, incremental, modulegraphs, pathutils
|
||||||
|
|
||||||
when not nimIncremental:
|
when not nimIncremental:
|
||||||
template setupModuleCache*(g: ModuleGraph) = discard
|
template setupModuleCache*(g: ModuleGraph) = discard
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,10 @@
|
||||||
## language.
|
## language.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, modules, idents, passes, passaux, condsyms,
|
ast, modules, idents, passes, condsyms,
|
||||||
options, nimconf, sem, semdata, llstream, vm, vmdef, commands, msgs,
|
options, sem, llstream, vm, vmdef, commands, msgs,
|
||||||
os, times, osproc, wordrecg, strtabs, modulegraphs, lineinfos, pathutils
|
os, times, osproc, wordrecg, strtabs, modulegraphs,
|
||||||
|
lineinfos, pathutils
|
||||||
|
|
||||||
# we support 'cmpIgnoreStyle' natively for efficiency:
|
# we support 'cmpIgnoreStyle' natively for efficiency:
|
||||||
from strutils import cmpIgnoreStyle, contains
|
from strutils import cmpIgnoreStyle, contains
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@
|
||||||
# This module implements the semantic checking pass.
|
# This module implements the semantic checking pass.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, strutils, hashes, options, lexer, astalgo, trees, treetab,
|
ast, strutils, options, astalgo, trees,
|
||||||
wordrecg, ropes, msgs, os, condsyms, idents, renderer, types, platform, math,
|
wordrecg, ropes, msgs, idents, renderer, types, platform, math,
|
||||||
magicsys, parser, nversion, nimsets, semfold, modulepaths, importer,
|
magicsys, nversion, nimsets, semfold, modulepaths, importer,
|
||||||
procfind, lookups, pragmas, passes, semdata, semtypinst, sigmatch,
|
procfind, lookups, pragmas, passes, semdata, semtypinst, sigmatch,
|
||||||
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
|
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
|
||||||
evaltempl, patterns, parampatterns, sempass2, linter, semmacrosanity,
|
evaltempl, patterns, parampatterns, sempass2, linter, semmacrosanity,
|
||||||
lowerings, pluginsupport, plugins/active, rod, lineinfos, strtabs, int128
|
lowerings, plugins/active, rod, lineinfos, strtabs, int128
|
||||||
|
|
||||||
from modulegraphs import ModuleGraph, PPassContext, onUse, onDef, onDefResolveForward
|
from modulegraphs import ModuleGraph, PPassContext, onUse, onDef, onDefResolveForward
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,8 @@
|
||||||
## This module contains the data structures for the semantic checking phase.
|
## This module contains the data structures for the semantic checking phase.
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, intsets, options, lexer, ast, astalgo, trees, treetab,
|
intsets, options, ast, astalgo, msgs, idents, renderer,
|
||||||
wordrecg,
|
magicsys, passes, vmdef, modulegraphs, lineinfos
|
||||||
ropes, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math,
|
|
||||||
magicsys, nversion, nimsets, parser, times, passes, vmdef,
|
|
||||||
modulegraphs, lineinfos
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TOptionEntry* = object # entries to put on a stack for pragma parsing
|
TOptionEntry* = object # entries to put on a stack for pragma parsing
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@
|
||||||
# and evaluation phase
|
# and evaluation phase
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, options, ast, astalgo, trees, treetab, nimsets,
|
strutils, options, ast, trees, nimsets,
|
||||||
nversion, platform, math, msgs, os, condsyms, idents, renderer, types,
|
platform, math, msgs, idents, renderer, types,
|
||||||
commands, magicsys, modulegraphs, strtabs, lineinfos
|
commands, magicsys, modulegraphs, strtabs, lineinfos
|
||||||
|
|
||||||
proc newIntNodeT*(intVal: BiggestInt, n: PNode; g: ModuleGraph): PNode =
|
proc newIntNodeT*(intVal: BiggestInt, n: PNode; g: ModuleGraph): PNode =
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## Implements type sanity checking for ASTs resulting from macros. Lots of
|
## Implements type sanity checking for ASTs resulting from macros. Lots of
|
||||||
## room for improvement here.
|
## room for improvement here.
|
||||||
|
|
||||||
import ast, astalgo, msgs, types, options
|
import ast, msgs, types, options
|
||||||
|
|
||||||
proc ithField(n: PNode, field: var int): PSym =
|
proc ithField(n: PNode, field: var int): PSym =
|
||||||
result = nil
|
result = nil
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
import
|
import
|
||||||
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
|
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
|
||||||
wordrecg, strutils, options, guards, lineinfos, semfold, semdata,
|
wordrecg, strutils, options, guards, lineinfos, semfold, semdata,
|
||||||
modulegraphs, lowerings, sigmatch, tables
|
modulegraphs
|
||||||
|
|
||||||
when not defined(leanCompiler):
|
when not defined(leanCompiler):
|
||||||
import writetracking
|
import writetracking
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,7 @@
|
||||||
|
|
||||||
import ast, tables, ropes, md5, modulegraphs
|
import ast, tables, ropes, md5, modulegraphs
|
||||||
from hashes import Hash
|
from hashes import Hash
|
||||||
from astalgo import debug
|
|
||||||
import types
|
import types
|
||||||
from strutils import startsWith, contains
|
|
||||||
|
|
||||||
proc `&=`(c: var MD5Context, s: string) = md5Update(c, s, s.len)
|
proc `&=`(c: var MD5Context, s: string) = md5Update(c, s, s.len)
|
||||||
proc `&=`(c: var MD5Context, ch: char) = md5Update(c, unsafeAddr ch, 1)
|
proc `&=`(c: var MD5Context, ch: char) = md5Update(c, unsafeAddr ch, 1)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
|
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
|
||||||
magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees,
|
magicsys, idents, lexer, options, parampatterns, strutils, trees,
|
||||||
linter, lineinfos, lowerings, modulegraphs
|
linter, lineinfos, lowerings, modulegraphs
|
||||||
|
|
||||||
when (defined(booting) or defined(nimsuggest)) and not defined(leanCompiler):
|
when (defined(booting) or defined(nimsuggest)) and not defined(leanCompiler):
|
||||||
|
|
|
||||||
|
|
@ -1,428 +1,428 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nim Compiler
|
# The Nim Compiler
|
||||||
# (c) Copyright 2015 Andreas Rumpf
|
# (c) Copyright 2015 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.
|
||||||
#
|
#
|
||||||
|
|
||||||
## This module implements threadpool's ``spawn``.
|
## This module implements threadpool's ``spawn``.
|
||||||
|
|
||||||
import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs,
|
import ast, types, idents, magicsys, msgs, options, modulegraphs,
|
||||||
lineinfos, lowerings
|
lowerings
|
||||||
from trees import getMagic
|
from trees import getMagic
|
||||||
|
|
||||||
proc callProc(a: PNode): PNode =
|
proc callProc(a: PNode): PNode =
|
||||||
result = newNodeI(nkCall, a.info)
|
result = newNodeI(nkCall, a.info)
|
||||||
result.add a
|
result.add a
|
||||||
result.typ = a.typ.sons[0]
|
result.typ = a.typ.sons[0]
|
||||||
|
|
||||||
# we have 4 cases to consider:
|
# we have 4 cases to consider:
|
||||||
# - a void proc --> nothing to do
|
# - a void proc --> nothing to do
|
||||||
# - a proc returning GC'ed memory --> requires a flowVar
|
# - a proc returning GC'ed memory --> requires a flowVar
|
||||||
# - a proc returning non GC'ed memory --> pass as hidden 'var' parameter
|
# - a proc returning non GC'ed memory --> pass as hidden 'var' parameter
|
||||||
# - not in a parallel environment --> requires a flowVar for memory safety
|
# - not in a parallel environment --> requires a flowVar for memory safety
|
||||||
type
|
type
|
||||||
TSpawnResult* = enum
|
TSpawnResult* = enum
|
||||||
srVoid, srFlowVar, srByVar
|
srVoid, srFlowVar, srByVar
|
||||||
TFlowVarKind = enum
|
TFlowVarKind = enum
|
||||||
fvInvalid # invalid type T for 'FlowVar[T]'
|
fvInvalid # invalid type T for 'FlowVar[T]'
|
||||||
fvGC # FlowVar of a GC'ed type
|
fvGC # FlowVar of a GC'ed type
|
||||||
fvBlob # FlowVar of a blob type
|
fvBlob # FlowVar of a blob type
|
||||||
|
|
||||||
proc spawnResult*(t: PType; inParallel: bool): TSpawnResult =
|
proc spawnResult*(t: PType; inParallel: bool): TSpawnResult =
|
||||||
if t.isEmptyType: srVoid
|
if t.isEmptyType: srVoid
|
||||||
elif inParallel and not containsGarbageCollectedRef(t): srByVar
|
elif inParallel and not containsGarbageCollectedRef(t): srByVar
|
||||||
else: srFlowVar
|
else: srFlowVar
|
||||||
|
|
||||||
proc flowVarKind(t: PType): TFlowVarKind =
|
proc flowVarKind(t: PType): TFlowVarKind =
|
||||||
if t.skipTypes(abstractInst).kind in {tyRef, tyString, tySequence}: fvGC
|
if t.skipTypes(abstractInst).kind in {tyRef, tyString, tySequence}: fvGC
|
||||||
elif containsGarbageCollectedRef(t): fvInvalid
|
elif containsGarbageCollectedRef(t): fvInvalid
|
||||||
else: fvBlob
|
else: fvBlob
|
||||||
|
|
||||||
proc typeNeedsNoDeepCopy(t: PType): bool =
|
proc typeNeedsNoDeepCopy(t: PType): bool =
|
||||||
var t = t.skipTypes(abstractInst)
|
var t = t.skipTypes(abstractInst)
|
||||||
# for the tconvexhull example (and others) we're a bit lax here and pretend
|
# for the tconvexhull example (and others) we're a bit lax here and pretend
|
||||||
# seqs and strings are *by value* only and 'shallow' doesn't exist!
|
# seqs and strings are *by value* only and 'shallow' doesn't exist!
|
||||||
if t.kind == tyString: return true
|
if t.kind == tyString: return true
|
||||||
# note that seq[T] is fine, but 'var seq[T]' is not, so we need to skip 'var'
|
# note that seq[T] is fine, but 'var seq[T]' is not, so we need to skip 'var'
|
||||||
# for the stricter check and likewise we can skip 'seq' for a less
|
# for the stricter check and likewise we can skip 'seq' for a less
|
||||||
# strict check:
|
# strict check:
|
||||||
if t.kind in {tyVar, tyLent, tySequence}: t = t.lastSon
|
if t.kind in {tyVar, tyLent, tySequence}: t = t.lastSon
|
||||||
result = not containsGarbageCollectedRef(t)
|
result = not containsGarbageCollectedRef(t)
|
||||||
|
|
||||||
proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; owner: PSym; typ: PType;
|
proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; owner: PSym; typ: PType;
|
||||||
v: PNode; useShallowCopy=false): PSym =
|
v: PNode; useShallowCopy=false): PSym =
|
||||||
result = newSym(skTemp, getIdent(g.cache, genPrefix), owner, varSection.info,
|
result = newSym(skTemp, getIdent(g.cache, genPrefix), owner, varSection.info,
|
||||||
owner.options)
|
owner.options)
|
||||||
result.typ = typ
|
result.typ = typ
|
||||||
incl(result.flags, sfFromGeneric)
|
incl(result.flags, sfFromGeneric)
|
||||||
|
|
||||||
var vpart = newNodeI(nkIdentDefs, varSection.info, 3)
|
var vpart = newNodeI(nkIdentDefs, varSection.info, 3)
|
||||||
vpart.sons[0] = newSymNode(result)
|
vpart.sons[0] = newSymNode(result)
|
||||||
vpart.sons[1] = newNodeI(nkEmpty, varSection.info)
|
vpart.sons[1] = newNodeI(nkEmpty, varSection.info)
|
||||||
vpart.sons[2] = if varInit.isNil: v else: vpart[1]
|
vpart.sons[2] = if varInit.isNil: v else: vpart[1]
|
||||||
varSection.add vpart
|
varSection.add vpart
|
||||||
if varInit != nil:
|
if varInit != nil:
|
||||||
if useShallowCopy and typeNeedsNoDeepCopy(typ):
|
if useShallowCopy and typeNeedsNoDeepCopy(typ):
|
||||||
varInit.add newFastAsgnStmt(newSymNode(result), v)
|
varInit.add newFastAsgnStmt(newSymNode(result), v)
|
||||||
else:
|
else:
|
||||||
let deepCopyCall = newNodeI(nkCall, varInit.info, 3)
|
let deepCopyCall = newNodeI(nkCall, varInit.info, 3)
|
||||||
deepCopyCall.sons[0] = newSymNode(getSysMagic(g, varSection.info, "deepCopy", mDeepCopy))
|
deepCopyCall.sons[0] = newSymNode(getSysMagic(g, varSection.info, "deepCopy", mDeepCopy))
|
||||||
deepCopyCall.sons[1] = newSymNode(result)
|
deepCopyCall.sons[1] = newSymNode(result)
|
||||||
deepCopyCall.sons[2] = v
|
deepCopyCall.sons[2] = v
|
||||||
varInit.add deepCopyCall
|
varInit.add deepCopyCall
|
||||||
|
|
||||||
discard """
|
discard """
|
||||||
We generate roughly this:
|
We generate roughly this:
|
||||||
|
|
||||||
proc f_wrapper(thread, args) =
|
proc f_wrapper(thread, args) =
|
||||||
barrierEnter(args.barrier) # for parallel statement
|
barrierEnter(args.barrier) # for parallel statement
|
||||||
var a = args.a # thread transfer; deepCopy or shallowCopy or no copy
|
var a = args.a # thread transfer; deepCopy or shallowCopy or no copy
|
||||||
# depending on whether we're in a 'parallel' statement
|
# depending on whether we're in a 'parallel' statement
|
||||||
var b = args.b
|
var b = args.b
|
||||||
var fv = args.fv
|
var fv = args.fv
|
||||||
|
|
||||||
fv.owner = thread # optional
|
fv.owner = thread # optional
|
||||||
nimArgsPassingDone() # signal parent that the work is done
|
nimArgsPassingDone() # signal parent that the work is done
|
||||||
#
|
#
|
||||||
args.fv.blob = f(a, b, ...)
|
args.fv.blob = f(a, b, ...)
|
||||||
nimFlowVarSignal(args.fv)
|
nimFlowVarSignal(args.fv)
|
||||||
|
|
||||||
# - or -
|
# - or -
|
||||||
f(a, b, ...)
|
f(a, b, ...)
|
||||||
barrierLeave(args.barrier) # for parallel statement
|
barrierLeave(args.barrier) # for parallel statement
|
||||||
|
|
||||||
stmtList:
|
stmtList:
|
||||||
var scratchObj
|
var scratchObj
|
||||||
scratchObj.a = a
|
scratchObj.a = a
|
||||||
scratchObj.b = b
|
scratchObj.b = b
|
||||||
|
|
||||||
nimSpawn(f_wrapper, addr scratchObj)
|
nimSpawn(f_wrapper, addr scratchObj)
|
||||||
scratchObj.fv # optional
|
scratchObj.fv # optional
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc createWrapperProc(g: ModuleGraph; f: PNode; threadParam, argsParam: PSym;
|
proc createWrapperProc(g: ModuleGraph; f: PNode; threadParam, argsParam: PSym;
|
||||||
varSection, varInit, call, barrier, fv: PNode;
|
varSection, varInit, call, barrier, fv: PNode;
|
||||||
spawnKind: TSpawnResult): PSym =
|
spawnKind: TSpawnResult): PSym =
|
||||||
var body = newNodeI(nkStmtList, f.info)
|
var body = newNodeI(nkStmtList, f.info)
|
||||||
body.flags.incl nfTransf # do not transform further
|
body.flags.incl nfTransf # do not transform further
|
||||||
|
|
||||||
var threadLocalBarrier: PSym
|
var threadLocalBarrier: PSym
|
||||||
if barrier != nil:
|
if barrier != nil:
|
||||||
var varSection2 = newNodeI(nkVarSection, barrier.info)
|
var varSection2 = newNodeI(nkVarSection, barrier.info)
|
||||||
threadLocalBarrier = addLocalVar(g, varSection2, nil, argsParam.owner,
|
threadLocalBarrier = addLocalVar(g, varSection2, nil, argsParam.owner,
|
||||||
barrier.typ, barrier)
|
barrier.typ, barrier)
|
||||||
body.add varSection2
|
body.add varSection2
|
||||||
body.add callCodegenProc(g, "barrierEnter", threadLocalBarrier.info,
|
body.add callCodegenProc(g, "barrierEnter", threadLocalBarrier.info,
|
||||||
threadLocalBarrier.newSymNode)
|
threadLocalBarrier.newSymNode)
|
||||||
var threadLocalProm: PSym
|
var threadLocalProm: PSym
|
||||||
if spawnKind == srByVar:
|
if spawnKind == srByVar:
|
||||||
threadLocalProm = addLocalVar(g, varSection, nil, argsParam.owner, fv.typ, fv)
|
threadLocalProm = addLocalVar(g, varSection, nil, argsParam.owner, fv.typ, fv)
|
||||||
elif fv != nil:
|
elif fv != nil:
|
||||||
internalAssert g.config, fv.typ.kind == tyGenericInst
|
internalAssert g.config, fv.typ.kind == tyGenericInst
|
||||||
threadLocalProm = addLocalVar(g, varSection, nil, argsParam.owner, fv.typ, fv)
|
threadLocalProm = addLocalVar(g, varSection, nil, argsParam.owner, fv.typ, fv)
|
||||||
body.add varSection
|
body.add varSection
|
||||||
body.add varInit
|
body.add varInit
|
||||||
if fv != nil and spawnKind != srByVar:
|
if fv != nil and spawnKind != srByVar:
|
||||||
# generate:
|
# generate:
|
||||||
# fv.owner = threadParam
|
# fv.owner = threadParam
|
||||||
body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode,
|
body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode,
|
||||||
"owner", fv.info, g.cache), threadParam.newSymNode)
|
"owner", fv.info, g.cache), threadParam.newSymNode)
|
||||||
|
|
||||||
body.add callCodegenProc(g, "nimArgsPassingDone", threadParam.info,
|
body.add callCodegenProc(g, "nimArgsPassingDone", threadParam.info,
|
||||||
threadParam.newSymNode)
|
threadParam.newSymNode)
|
||||||
if spawnKind == srByVar:
|
if spawnKind == srByVar:
|
||||||
body.add newAsgnStmt(genDeref(threadLocalProm.newSymNode), call)
|
body.add newAsgnStmt(genDeref(threadLocalProm.newSymNode), call)
|
||||||
elif fv != nil:
|
elif fv != nil:
|
||||||
let fk = fv.typ.sons[1].flowVarKind
|
let fk = fv.typ.sons[1].flowVarKind
|
||||||
if fk == fvInvalid:
|
if fk == fvInvalid:
|
||||||
localError(g.config, f.info, "cannot create a flowVar of type: " &
|
localError(g.config, f.info, "cannot create a flowVar of type: " &
|
||||||
typeToString(fv.typ.sons[1]))
|
typeToString(fv.typ.sons[1]))
|
||||||
body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode,
|
body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode,
|
||||||
if fk == fvGC: "data" else: "blob", fv.info, g.cache), call)
|
if fk == fvGC: "data" else: "blob", fv.info, g.cache), call)
|
||||||
if fk == fvGC:
|
if fk == fvGC:
|
||||||
let incRefCall = newNodeI(nkCall, fv.info, 2)
|
let incRefCall = newNodeI(nkCall, fv.info, 2)
|
||||||
incRefCall.sons[0] = newSymNode(getSysMagic(g, fv.info, "GCref", mGCref))
|
incRefCall.sons[0] = newSymNode(getSysMagic(g, fv.info, "GCref", mGCref))
|
||||||
incRefCall.sons[1] = indirectAccess(threadLocalProm.newSymNode,
|
incRefCall.sons[1] = indirectAccess(threadLocalProm.newSymNode,
|
||||||
"data", fv.info, g.cache)
|
"data", fv.info, g.cache)
|
||||||
body.add incRefCall
|
body.add incRefCall
|
||||||
if barrier == nil:
|
if barrier == nil:
|
||||||
# by now 'fv' is shared and thus might have beeen overwritten! we need
|
# by now 'fv' is shared and thus might have beeen overwritten! we need
|
||||||
# to use the thread-local view instead:
|
# to use the thread-local view instead:
|
||||||
body.add callCodegenProc(g, "nimFlowVarSignal", threadLocalProm.info,
|
body.add callCodegenProc(g, "nimFlowVarSignal", threadLocalProm.info,
|
||||||
threadLocalProm.newSymNode)
|
threadLocalProm.newSymNode)
|
||||||
else:
|
else:
|
||||||
body.add call
|
body.add call
|
||||||
if barrier != nil:
|
if barrier != nil:
|
||||||
body.add callCodegenProc(g, "barrierLeave", threadLocalBarrier.info,
|
body.add callCodegenProc(g, "barrierLeave", threadLocalBarrier.info,
|
||||||
threadLocalBarrier.newSymNode)
|
threadLocalBarrier.newSymNode)
|
||||||
|
|
||||||
var params = newNodeI(nkFormalParams, f.info)
|
var params = newNodeI(nkFormalParams, f.info)
|
||||||
params.add newNodeI(nkEmpty, f.info)
|
params.add newNodeI(nkEmpty, f.info)
|
||||||
params.add threadParam.newSymNode
|
params.add threadParam.newSymNode
|
||||||
params.add argsParam.newSymNode
|
params.add argsParam.newSymNode
|
||||||
|
|
||||||
var t = newType(tyProc, threadParam.owner)
|
var t = newType(tyProc, threadParam.owner)
|
||||||
t.rawAddSon nil
|
t.rawAddSon nil
|
||||||
t.rawAddSon threadParam.typ
|
t.rawAddSon threadParam.typ
|
||||||
t.rawAddSon argsParam.typ
|
t.rawAddSon argsParam.typ
|
||||||
t.n = newNodeI(nkFormalParams, f.info)
|
t.n = newNodeI(nkFormalParams, f.info)
|
||||||
t.n.add newNodeI(nkEffectList, f.info)
|
t.n.add newNodeI(nkEffectList, f.info)
|
||||||
t.n.add threadParam.newSymNode
|
t.n.add threadParam.newSymNode
|
||||||
t.n.add argsParam.newSymNode
|
t.n.add argsParam.newSymNode
|
||||||
|
|
||||||
let name = (if f.kind == nkSym: f.sym.name.s else: genPrefix) & "Wrapper"
|
let name = (if f.kind == nkSym: f.sym.name.s else: genPrefix) & "Wrapper"
|
||||||
result = newSym(skProc, getIdent(g.cache, name), argsParam.owner, f.info,
|
result = newSym(skProc, getIdent(g.cache, name), argsParam.owner, f.info,
|
||||||
argsParam.options)
|
argsParam.options)
|
||||||
let emptyNode = newNodeI(nkEmpty, f.info)
|
let emptyNode = newNodeI(nkEmpty, f.info)
|
||||||
result.ast = newProcNode(nkProcDef, f.info, body = body,
|
result.ast = newProcNode(nkProcDef, f.info, body = body,
|
||||||
params = params, name = newSymNode(result), pattern = emptyNode,
|
params = params, name = newSymNode(result), pattern = emptyNode,
|
||||||
genericParams = emptyNode, pragmas = emptyNode,
|
genericParams = emptyNode, pragmas = emptyNode,
|
||||||
exceptions = emptyNode)
|
exceptions = emptyNode)
|
||||||
result.typ = t
|
result.typ = t
|
||||||
|
|
||||||
proc createCastExpr(argsParam: PSym; objType: PType): PNode =
|
proc createCastExpr(argsParam: PSym; objType: PType): PNode =
|
||||||
result = newNodeI(nkCast, argsParam.info)
|
result = newNodeI(nkCast, argsParam.info)
|
||||||
result.add newNodeI(nkEmpty, argsParam.info)
|
result.add newNodeI(nkEmpty, argsParam.info)
|
||||||
result.add newSymNode(argsParam)
|
result.add newSymNode(argsParam)
|
||||||
result.typ = newType(tyPtr, objType.owner)
|
result.typ = newType(tyPtr, objType.owner)
|
||||||
result.typ.rawAddSon(objType)
|
result.typ.rawAddSon(objType)
|
||||||
|
|
||||||
proc setupArgsForConcurrency(g: ModuleGraph; n: PNode; objType: PType; scratchObj: PSym,
|
proc setupArgsForConcurrency(g: ModuleGraph; n: PNode; objType: PType; scratchObj: PSym,
|
||||||
castExpr, call,
|
castExpr, call,
|
||||||
varSection, varInit, result: PNode) =
|
varSection, varInit, result: PNode) =
|
||||||
let formals = n[0].typ.n
|
let formals = n[0].typ.n
|
||||||
let tmpName = getIdent(g.cache, genPrefix)
|
let tmpName = getIdent(g.cache, genPrefix)
|
||||||
for i in 1 ..< n.len:
|
for i in 1 ..< n.len:
|
||||||
# we pick n's type here, which hopefully is 'tyArray' and not
|
# we pick n's type here, which hopefully is 'tyArray' and not
|
||||||
# 'tyOpenArray':
|
# 'tyOpenArray':
|
||||||
var argType = n[i].typ.skipTypes(abstractInst)
|
var argType = n[i].typ.skipTypes(abstractInst)
|
||||||
if i < formals.len and formals[i].typ.kind in {tyVar, tyLent}:
|
if i < formals.len and formals[i].typ.kind in {tyVar, tyLent}:
|
||||||
localError(g.config, n[i].info, "'spawn'ed function cannot have a 'var' parameter")
|
localError(g.config, n[i].info, "'spawn'ed function cannot have a 'var' parameter")
|
||||||
#elif containsTyRef(argType):
|
#elif containsTyRef(argType):
|
||||||
# localError(n[i].info, "'spawn'ed function cannot refer to 'ref'/closure")
|
# localError(n[i].info, "'spawn'ed function cannot refer to 'ref'/closure")
|
||||||
|
|
||||||
let fieldname = if i < formals.len: formals[i].sym.name else: tmpName
|
let fieldname = if i < formals.len: formals[i].sym.name else: tmpName
|
||||||
var field = newSym(skField, fieldname, objType.owner, n.info, g.config.options)
|
var field = newSym(skField, fieldname, objType.owner, n.info, g.config.options)
|
||||||
field.typ = argType
|
field.typ = argType
|
||||||
objType.addField(field, g.cache)
|
objType.addField(field, g.cache)
|
||||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[i])
|
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[i])
|
||||||
|
|
||||||
let temp = addLocalVar(g, varSection, varInit, objType.owner, argType,
|
let temp = addLocalVar(g, varSection, varInit, objType.owner, argType,
|
||||||
indirectAccess(castExpr, field, n.info))
|
indirectAccess(castExpr, field, n.info))
|
||||||
call.add(newSymNode(temp))
|
call.add(newSymNode(temp))
|
||||||
|
|
||||||
proc getRoot*(n: PNode): PSym =
|
proc getRoot*(n: PNode): PSym =
|
||||||
## ``getRoot`` takes a *path* ``n``. A path is an lvalue expression
|
## ``getRoot`` takes a *path* ``n``. A path is an lvalue expression
|
||||||
## like ``obj.x[i].y``. The *root* of a path is the symbol that can be
|
## like ``obj.x[i].y``. The *root* of a path is the symbol that can be
|
||||||
## determined as the owner; ``obj`` in the example.
|
## determined as the owner; ``obj`` in the example.
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
if n.sym.kind in {skVar, skResult, skTemp, skLet, skForVar}:
|
if n.sym.kind in {skVar, skResult, skTemp, skLet, skForVar}:
|
||||||
result = n.sym
|
result = n.sym
|
||||||
of nkDotExpr, nkBracketExpr, nkHiddenDeref, nkDerefExpr,
|
of nkDotExpr, nkBracketExpr, nkHiddenDeref, nkDerefExpr,
|
||||||
nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
|
nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
|
||||||
result = getRoot(n.sons[0])
|
result = getRoot(n.sons[0])
|
||||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||||
result = getRoot(n.sons[1])
|
result = getRoot(n.sons[1])
|
||||||
of nkCallKinds:
|
of nkCallKinds:
|
||||||
if getMagic(n) == mSlice: result = getRoot(n.sons[1])
|
if getMagic(n) == mSlice: result = getRoot(n.sons[1])
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType; scratchObj: PSym;
|
proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType; scratchObj: PSym;
|
||||||
castExpr, call,
|
castExpr, call,
|
||||||
varSection, varInit, result: PNode) =
|
varSection, varInit, result: PNode) =
|
||||||
let formals = n[0].typ.n
|
let formals = n[0].typ.n
|
||||||
let tmpName = getIdent(g.cache, genPrefix)
|
let tmpName = getIdent(g.cache, genPrefix)
|
||||||
# we need to copy the foreign scratch object fields into local variables
|
# we need to copy the foreign scratch object fields into local variables
|
||||||
# for correctness: These are called 'threadLocal' here.
|
# for correctness: These are called 'threadLocal' here.
|
||||||
for i in 1 ..< n.len:
|
for i in 1 ..< n.len:
|
||||||
let n = n[i]
|
let n = n[i]
|
||||||
let argType = skipTypes(if i < formals.len: formals[i].typ else: n.typ,
|
let argType = skipTypes(if i < formals.len: formals[i].typ else: n.typ,
|
||||||
abstractInst)
|
abstractInst)
|
||||||
#if containsTyRef(argType):
|
#if containsTyRef(argType):
|
||||||
# localError(n.info, "'spawn'ed function cannot refer to 'ref'/closure")
|
# localError(n.info, "'spawn'ed function cannot refer to 'ref'/closure")
|
||||||
|
|
||||||
let fieldname = if i < formals.len: formals[i].sym.name else: tmpName
|
let fieldname = if i < formals.len: formals[i].sym.name else: tmpName
|
||||||
var field = newSym(skField, fieldname, objType.owner, n.info, g.config.options)
|
var field = newSym(skField, fieldname, objType.owner, n.info, g.config.options)
|
||||||
|
|
||||||
if argType.kind in {tyVarargs, tyOpenArray}:
|
if argType.kind in {tyVarargs, tyOpenArray}:
|
||||||
# important special case: we always create a zero-copy slice:
|
# important special case: we always create a zero-copy slice:
|
||||||
let slice = newNodeI(nkCall, n.info, 4)
|
let slice = newNodeI(nkCall, n.info, 4)
|
||||||
slice.typ = n.typ
|
slice.typ = n.typ
|
||||||
slice.sons[0] = newSymNode(createMagic(g, "slice", mSlice))
|
slice.sons[0] = newSymNode(createMagic(g, "slice", mSlice))
|
||||||
slice.sons[0].typ = getSysType(g, n.info, tyInt) # fake type
|
slice.sons[0].typ = getSysType(g, n.info, tyInt) # fake type
|
||||||
var fieldB = newSym(skField, tmpName, objType.owner, n.info, g.config.options)
|
var fieldB = newSym(skField, tmpName, objType.owner, n.info, g.config.options)
|
||||||
fieldB.typ = getSysType(g, n.info, tyInt)
|
fieldB.typ = getSysType(g, n.info, tyInt)
|
||||||
objType.addField(fieldB, g.cache)
|
objType.addField(fieldB, g.cache)
|
||||||
|
|
||||||
if getMagic(n) == mSlice:
|
if getMagic(n) == mSlice:
|
||||||
let a = genAddrOf(n[1])
|
let a = genAddrOf(n[1])
|
||||||
field.typ = a.typ
|
field.typ = a.typ
|
||||||
objType.addField(field, g.cache)
|
objType.addField(field, g.cache)
|
||||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
|
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
|
||||||
|
|
||||||
var fieldA = newSym(skField, tmpName, objType.owner, n.info, g.config.options)
|
var fieldA = newSym(skField, tmpName, objType.owner, n.info, g.config.options)
|
||||||
fieldA.typ = getSysType(g, n.info, tyInt)
|
fieldA.typ = getSysType(g, n.info, tyInt)
|
||||||
objType.addField(fieldA, g.cache)
|
objType.addField(fieldA, g.cache)
|
||||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldA), n[2])
|
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldA), n[2])
|
||||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), n[3])
|
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), n[3])
|
||||||
|
|
||||||
let threadLocal = addLocalVar(g, varSection,nil, objType.owner, fieldA.typ,
|
let threadLocal = addLocalVar(g, varSection,nil, objType.owner, fieldA.typ,
|
||||||
indirectAccess(castExpr, fieldA, n.info),
|
indirectAccess(castExpr, fieldA, n.info),
|
||||||
useShallowCopy=true)
|
useShallowCopy=true)
|
||||||
slice.sons[2] = threadLocal.newSymNode
|
slice.sons[2] = threadLocal.newSymNode
|
||||||
else:
|
else:
|
||||||
let a = genAddrOf(n)
|
let a = genAddrOf(n)
|
||||||
field.typ = a.typ
|
field.typ = a.typ
|
||||||
objType.addField(field, g.cache)
|
objType.addField(field, g.cache)
|
||||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
|
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
|
||||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), genHigh(g, n))
|
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), genHigh(g, n))
|
||||||
|
|
||||||
slice.sons[2] = newIntLit(g, n.info, 0)
|
slice.sons[2] = newIntLit(g, n.info, 0)
|
||||||
# the array itself does not need to go through a thread local variable:
|
# the array itself does not need to go through a thread local variable:
|
||||||
slice.sons[1] = genDeref(indirectAccess(castExpr, field, n.info))
|
slice.sons[1] = genDeref(indirectAccess(castExpr, field, n.info))
|
||||||
|
|
||||||
let threadLocal = addLocalVar(g, varSection,nil, objType.owner, fieldB.typ,
|
let threadLocal = addLocalVar(g, varSection,nil, objType.owner, fieldB.typ,
|
||||||
indirectAccess(castExpr, fieldB, n.info),
|
indirectAccess(castExpr, fieldB, n.info),
|
||||||
useShallowCopy=true)
|
useShallowCopy=true)
|
||||||
slice.sons[3] = threadLocal.newSymNode
|
slice.sons[3] = threadLocal.newSymNode
|
||||||
call.add slice
|
call.add slice
|
||||||
elif (let size = computeSize(g.config, argType); size < 0 or size > 16) and
|
elif (let size = computeSize(g.config, argType); size < 0 or size > 16) and
|
||||||
n.getRoot != nil:
|
n.getRoot != nil:
|
||||||
# it is more efficient to pass a pointer instead:
|
# it is more efficient to pass a pointer instead:
|
||||||
let a = genAddrOf(n)
|
let a = genAddrOf(n)
|
||||||
field.typ = a.typ
|
field.typ = a.typ
|
||||||
objType.addField(field, g.cache)
|
objType.addField(field, g.cache)
|
||||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
|
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
|
||||||
let threadLocal = addLocalVar(g, varSection,nil, objType.owner, field.typ,
|
let threadLocal = addLocalVar(g, varSection,nil, objType.owner, field.typ,
|
||||||
indirectAccess(castExpr, field, n.info),
|
indirectAccess(castExpr, field, n.info),
|
||||||
useShallowCopy=true)
|
useShallowCopy=true)
|
||||||
call.add(genDeref(threadLocal.newSymNode))
|
call.add(genDeref(threadLocal.newSymNode))
|
||||||
else:
|
else:
|
||||||
# boring case
|
# boring case
|
||||||
field.typ = argType
|
field.typ = argType
|
||||||
objType.addField(field, g.cache)
|
objType.addField(field, g.cache)
|
||||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n)
|
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n)
|
||||||
let threadLocal = addLocalVar(g, varSection, varInit,
|
let threadLocal = addLocalVar(g, varSection, varInit,
|
||||||
objType.owner, field.typ,
|
objType.owner, field.typ,
|
||||||
indirectAccess(castExpr, field, n.info),
|
indirectAccess(castExpr, field, n.info),
|
||||||
useShallowCopy=true)
|
useShallowCopy=true)
|
||||||
call.add(threadLocal.newSymNode)
|
call.add(threadLocal.newSymNode)
|
||||||
|
|
||||||
proc wrapProcForSpawn*(g: ModuleGraph; owner: PSym; spawnExpr: PNode; retType: PType;
|
proc wrapProcForSpawn*(g: ModuleGraph; owner: PSym; spawnExpr: PNode; retType: PType;
|
||||||
barrier, dest: PNode = nil): PNode =
|
barrier, dest: PNode = nil): PNode =
|
||||||
# if 'barrier' != nil, then it is in a 'parallel' section and we
|
# if 'barrier' != nil, then it is in a 'parallel' section and we
|
||||||
# generate quite different code
|
# generate quite different code
|
||||||
let n = spawnExpr[^2]
|
let n = spawnExpr[^2]
|
||||||
let spawnKind = spawnResult(retType, barrier!=nil)
|
let spawnKind = spawnResult(retType, barrier!=nil)
|
||||||
case spawnKind
|
case spawnKind
|
||||||
of srVoid:
|
of srVoid:
|
||||||
internalAssert g.config, dest == nil
|
internalAssert g.config, dest == nil
|
||||||
result = newNodeI(nkStmtList, n.info)
|
result = newNodeI(nkStmtList, n.info)
|
||||||
of srFlowVar:
|
of srFlowVar:
|
||||||
internalAssert g.config, dest == nil
|
internalAssert g.config, dest == nil
|
||||||
result = newNodeIT(nkStmtListExpr, n.info, retType)
|
result = newNodeIT(nkStmtListExpr, n.info, retType)
|
||||||
of srByVar:
|
of srByVar:
|
||||||
if dest == nil: localError(g.config, n.info, "'spawn' must not be discarded")
|
if dest == nil: localError(g.config, n.info, "'spawn' must not be discarded")
|
||||||
result = newNodeI(nkStmtList, n.info)
|
result = newNodeI(nkStmtList, n.info)
|
||||||
|
|
||||||
if n.kind notin nkCallKinds:
|
if n.kind notin nkCallKinds:
|
||||||
localError(g.config, n.info, "'spawn' takes a call expression")
|
localError(g.config, n.info, "'spawn' takes a call expression")
|
||||||
return
|
return
|
||||||
if optThreadAnalysis in g.config.globalOptions:
|
if optThreadAnalysis in g.config.globalOptions:
|
||||||
if {tfThread, tfNoSideEffect} * n[0].typ.flags == {}:
|
if {tfThread, tfNoSideEffect} * n[0].typ.flags == {}:
|
||||||
localError(g.config, n.info, "'spawn' takes a GC safe call expression")
|
localError(g.config, n.info, "'spawn' takes a GC safe call expression")
|
||||||
var
|
var
|
||||||
threadParam = newSym(skParam, getIdent(g.cache, "thread"), owner, n.info, g.config.options)
|
threadParam = newSym(skParam, getIdent(g.cache, "thread"), owner, n.info, g.config.options)
|
||||||
argsParam = newSym(skParam, getIdent(g.cache, "args"), owner, n.info, g.config.options)
|
argsParam = newSym(skParam, getIdent(g.cache, "args"), owner, n.info, g.config.options)
|
||||||
block:
|
block:
|
||||||
let ptrType = getSysType(g, n.info, tyPointer)
|
let ptrType = getSysType(g, n.info, tyPointer)
|
||||||
threadParam.typ = ptrType
|
threadParam.typ = ptrType
|
||||||
argsParam.typ = ptrType
|
argsParam.typ = ptrType
|
||||||
argsParam.position = 1
|
argsParam.position = 1
|
||||||
|
|
||||||
var objType = createObj(g, owner, n.info)
|
var objType = createObj(g, owner, n.info)
|
||||||
incl(objType.flags, tfFinal)
|
incl(objType.flags, tfFinal)
|
||||||
let castExpr = createCastExpr(argsParam, objType)
|
let castExpr = createCastExpr(argsParam, objType)
|
||||||
|
|
||||||
var scratchObj = newSym(skVar, getIdent(g.cache, "scratch"), owner, n.info, g.config.options)
|
var scratchObj = newSym(skVar, getIdent(g.cache, "scratch"), owner, n.info, g.config.options)
|
||||||
block:
|
block:
|
||||||
scratchObj.typ = objType
|
scratchObj.typ = objType
|
||||||
incl(scratchObj.flags, sfFromGeneric)
|
incl(scratchObj.flags, sfFromGeneric)
|
||||||
var varSectionB = newNodeI(nkVarSection, n.info)
|
var varSectionB = newNodeI(nkVarSection, n.info)
|
||||||
varSectionB.addVar(scratchObj.newSymNode)
|
varSectionB.addVar(scratchObj.newSymNode)
|
||||||
result.add varSectionB
|
result.add varSectionB
|
||||||
|
|
||||||
var call = newNodeIT(nkCall, n.info, n.typ)
|
var call = newNodeIT(nkCall, n.info, n.typ)
|
||||||
var fn = n.sons[0]
|
var fn = n.sons[0]
|
||||||
# templates and macros are in fact valid here due to the nature of
|
# templates and macros are in fact valid here due to the nature of
|
||||||
# the transformation:
|
# the transformation:
|
||||||
if fn.kind == nkClosure or (fn.typ != nil and fn.typ.callConv == ccClosure):
|
if fn.kind == nkClosure or (fn.typ != nil and fn.typ.callConv == ccClosure):
|
||||||
localError(g.config, n.info, "closure in spawn environment is not allowed")
|
localError(g.config, n.info, "closure in spawn environment is not allowed")
|
||||||
if not (fn.kind == nkSym and fn.sym.kind in {skProc, skTemplate, skMacro,
|
if not (fn.kind == nkSym and fn.sym.kind in {skProc, skTemplate, skMacro,
|
||||||
skFunc, skMethod, skConverter}):
|
skFunc, skMethod, skConverter}):
|
||||||
# for indirect calls we pass the function pointer in the scratchObj
|
# for indirect calls we pass the function pointer in the scratchObj
|
||||||
var argType = n[0].typ.skipTypes(abstractInst)
|
var argType = n[0].typ.skipTypes(abstractInst)
|
||||||
var field = newSym(skField, getIdent(g.cache, "fn"), owner, n.info, g.config.options)
|
var field = newSym(skField, getIdent(g.cache, "fn"), owner, n.info, g.config.options)
|
||||||
field.typ = argType
|
field.typ = argType
|
||||||
objType.addField(field, g.cache)
|
objType.addField(field, g.cache)
|
||||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[0])
|
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[0])
|
||||||
fn = indirectAccess(castExpr, field, n.info)
|
fn = indirectAccess(castExpr, field, n.info)
|
||||||
elif fn.kind == nkSym and fn.sym.kind == skIterator:
|
elif fn.kind == nkSym and fn.sym.kind == skIterator:
|
||||||
localError(g.config, n.info, "iterator in spawn environment is not allowed")
|
localError(g.config, n.info, "iterator in spawn environment is not allowed")
|
||||||
elif fn.typ.callConv == ccClosure:
|
elif fn.typ.callConv == ccClosure:
|
||||||
localError(g.config, n.info, "closure in spawn environment is not allowed")
|
localError(g.config, n.info, "closure in spawn environment is not allowed")
|
||||||
|
|
||||||
call.add(fn)
|
call.add(fn)
|
||||||
var varSection = newNodeI(nkVarSection, n.info)
|
var varSection = newNodeI(nkVarSection, n.info)
|
||||||
var varInit = newNodeI(nkStmtList, n.info)
|
var varInit = newNodeI(nkStmtList, n.info)
|
||||||
if barrier.isNil:
|
if barrier.isNil:
|
||||||
setupArgsForConcurrency(g, n, objType, scratchObj, castExpr, call,
|
setupArgsForConcurrency(g, n, objType, scratchObj, castExpr, call,
|
||||||
varSection, varInit, result)
|
varSection, varInit, result)
|
||||||
else:
|
else:
|
||||||
setupArgsForParallelism(g, n, objType, scratchObj, castExpr, call,
|
setupArgsForParallelism(g, n, objType, scratchObj, castExpr, call,
|
||||||
varSection, varInit, result)
|
varSection, varInit, result)
|
||||||
|
|
||||||
var barrierAsExpr: PNode = nil
|
var barrierAsExpr: PNode = nil
|
||||||
if barrier != nil:
|
if barrier != nil:
|
||||||
let typ = newType(tyPtr, owner)
|
let typ = newType(tyPtr, owner)
|
||||||
typ.rawAddSon(magicsys.getCompilerProc(g, "Barrier").typ)
|
typ.rawAddSon(magicsys.getCompilerProc(g, "Barrier").typ)
|
||||||
var field = newSym(skField, getIdent(g.cache, "barrier"), owner, n.info, g.config.options)
|
var field = newSym(skField, getIdent(g.cache, "barrier"), owner, n.info, g.config.options)
|
||||||
field.typ = typ
|
field.typ = typ
|
||||||
objType.addField(field, g.cache)
|
objType.addField(field, g.cache)
|
||||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), barrier)
|
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), barrier)
|
||||||
barrierAsExpr = indirectAccess(castExpr, field, n.info)
|
barrierAsExpr = indirectAccess(castExpr, field, n.info)
|
||||||
|
|
||||||
var fvField, fvAsExpr: PNode = nil
|
var fvField, fvAsExpr: PNode = nil
|
||||||
if spawnKind == srFlowVar:
|
if spawnKind == srFlowVar:
|
||||||
var field = newSym(skField, getIdent(g.cache, "fv"), owner, n.info, g.config.options)
|
var field = newSym(skField, getIdent(g.cache, "fv"), owner, n.info, g.config.options)
|
||||||
field.typ = retType
|
field.typ = retType
|
||||||
objType.addField(field, g.cache)
|
objType.addField(field, g.cache)
|
||||||
fvField = newDotExpr(scratchObj, field)
|
fvField = newDotExpr(scratchObj, field)
|
||||||
fvAsExpr = indirectAccess(castExpr, field, n.info)
|
fvAsExpr = indirectAccess(castExpr, field, n.info)
|
||||||
# create flowVar:
|
# create flowVar:
|
||||||
result.add newFastAsgnStmt(fvField, callProc(spawnExpr[^1]))
|
result.add newFastAsgnStmt(fvField, callProc(spawnExpr[^1]))
|
||||||
if barrier == nil:
|
if barrier == nil:
|
||||||
result.add callCodegenProc(g, "nimFlowVarCreateSemaphore", fvField.info,
|
result.add callCodegenProc(g, "nimFlowVarCreateSemaphore", fvField.info,
|
||||||
fvField)
|
fvField)
|
||||||
|
|
||||||
elif spawnKind == srByVar:
|
elif spawnKind == srByVar:
|
||||||
var field = newSym(skField, getIdent(g.cache, "fv"), owner, n.info, g.config.options)
|
var field = newSym(skField, getIdent(g.cache, "fv"), owner, n.info, g.config.options)
|
||||||
field.typ = newType(tyPtr, objType.owner)
|
field.typ = newType(tyPtr, objType.owner)
|
||||||
field.typ.rawAddSon(retType)
|
field.typ.rawAddSon(retType)
|
||||||
objType.addField(field, g.cache)
|
objType.addField(field, g.cache)
|
||||||
fvAsExpr = indirectAccess(castExpr, field, n.info)
|
fvAsExpr = indirectAccess(castExpr, field, n.info)
|
||||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), genAddrOf(dest))
|
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), genAddrOf(dest))
|
||||||
|
|
||||||
let wrapper = createWrapperProc(g, fn, threadParam, argsParam,
|
let wrapper = createWrapperProc(g, fn, threadParam, argsParam,
|
||||||
varSection, varInit, call,
|
varSection, varInit, call,
|
||||||
barrierAsExpr, fvAsExpr, spawnKind)
|
barrierAsExpr, fvAsExpr, spawnKind)
|
||||||
result.add callCodegenProc(g, "nimSpawn" & $spawnExpr.len, wrapper.info,
|
result.add callCodegenProc(g, "nimSpawn" & $spawnExpr.len, wrapper.info,
|
||||||
wrapper.newSymNode, genAddrOf(scratchObj.newSymNode), nil, spawnExpr)
|
wrapper.newSymNode, genAddrOf(scratchObj.newSymNode), nil, spawnExpr)
|
||||||
|
|
||||||
if spawnKind == srFlowVar: result.add fvField
|
if spawnKind == srFlowVar: result.add fvField
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,11 @@
|
||||||
|
|
||||||
# included from sigmatch.nim
|
# included from sigmatch.nim
|
||||||
|
|
||||||
import algorithm, prefixmatches, lineinfos, pathutils, parseutils, linter
|
import algorithm, prefixmatches, lineinfos, parseutils, linter
|
||||||
from wordrecg import wDeprecated, wError, wAddr, wYield, specialWords
|
from wordrecg import wDeprecated, wError, wAddr, wYield, specialWords
|
||||||
|
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
import passes, tables # importer
|
import passes, tables, pathutils # importer
|
||||||
|
|
||||||
const
|
const
|
||||||
sep = '\t'
|
sep = '\t'
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## Implements the dispatcher for the different parsers.
|
## Implements the dispatcher for the different parsers.
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser,
|
strutils, llstream, ast, idents, lexer, options, msgs, parser,
|
||||||
filters, filter_tmpl, renderer, lineinfos, pathutils
|
filters, filter_tmpl, renderer, lineinfos, pathutils
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@
|
||||||
# * transforms 'defer' into a 'try finally' statement
|
# * transforms 'defer' into a 'try finally' statement
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, lookups,
|
options, ast, astalgo, trees, msgs,
|
||||||
idents, renderer, types, passes, semfold, magicsys, cgmeth,
|
idents, renderer, types, passes, semfold, magicsys, cgmeth,
|
||||||
sempass2, lowerings, injectdestructors, liftlocals,
|
lowerings, injectdestructors, liftlocals,
|
||||||
modulegraphs, lineinfos
|
modulegraphs, lineinfos
|
||||||
|
|
||||||
proc transformBody*(g: ModuleGraph, prc: PSym, cache = true;
|
proc transformBody*(g: ModuleGraph, prc: PSym, cache = true;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
# tree helper routines
|
# tree helper routines
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, lexer, msgs, strutils, wordrecg, idents
|
ast, wordrecg, idents
|
||||||
|
|
||||||
proc cyclicTreeAux(n: PNode, visited: var seq[PNode]): bool =
|
proc cyclicTreeAux(n: PNode, visited: var seq[PNode]): bool =
|
||||||
if n == nil: return
|
if n == nil: return
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
import renderer, strutils, ast, msgs, types, astalgo
|
import renderer, strutils, ast, types
|
||||||
|
|
||||||
const defaultParamSeparator* = ","
|
const defaultParamSeparator* = ","
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
import ast except getstr
|
import ast except getstr
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, astalgo, msgs, vmdef, vmgen, nimsets, types, passes,
|
strutils, msgs, vmdef, vmgen, nimsets, types, passes,
|
||||||
parser, vmdeps, idents, trees, renderer, options, transf, parseutils,
|
parser, vmdeps, idents, trees, renderer, options, transf, parseutils,
|
||||||
vmmarshal, gorgeimpl, lineinfos, tables, btrees, macrocacheimpl,
|
vmmarshal, gorgeimpl, lineinfos, tables, btrees, macrocacheimpl,
|
||||||
modulegraphs, sighashes
|
modulegraphs, sighashes
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@
|
||||||
## This module contains the type definitions for the new evaluation engine.
|
## This module contains the type definitions for the new evaluation engine.
|
||||||
## An instruction is 1-3 int32s in memory, it is a register based VM.
|
## An instruction is 1-3 int32s in memory, it is a register based VM.
|
||||||
|
|
||||||
import ast, passes, msgs, idents, intsets, options, modulegraphs, lineinfos,
|
import ast, passes, idents, intsets, options, modulegraphs, lineinfos
|
||||||
tables, btrees
|
|
||||||
|
|
||||||
const
|
const
|
||||||
byteExcess* = 128 # we use excess-K for immediates
|
byteExcess* = 128 # we use excess-K for immediates
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
import ast, types, msgs, os, streams, options, idents, lineinfos
|
import ast, types, msgs, os, options, idents, lineinfos
|
||||||
|
|
||||||
proc opSlurp*(file: string, info: TLineInfo, module: PSym; conf: ConfigRef): string =
|
proc opSlurp*(file: string, info: TLineInfo, module: PSym; conf: ConfigRef): string =
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,8 @@
|
||||||
# this copy depends on the involved types.
|
# this copy depends on the involved types.
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, ast, astalgo, types, msgs, renderer, vmdef,
|
strutils, ast, types, msgs, renderer, vmdef,
|
||||||
trees, intsets, magicsys, options, lowerings, lineinfos, transf
|
intsets, magicsys, options, lowerings, lineinfos, transf
|
||||||
import platform
|
|
||||||
from os import splitFile
|
|
||||||
|
|
||||||
const
|
const
|
||||||
debugEchoCode* = defined(nimVMDebug)
|
debugEchoCode* = defined(nimVMDebug)
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,7 @@
|
||||||
## * Computing an aliasing relation based on the assignments. This relation
|
## * Computing an aliasing relation based on the assignments. This relation
|
||||||
## is then used to compute the 'writes' and 'escapes' effects.
|
## is then used to compute the 'writes' and 'escapes' effects.
|
||||||
|
|
||||||
import intsets, idents, ast, astalgo, trees, renderer, msgs, types, options,
|
import intsets, idents, ast, trees, msgs, types, options, lineinfos
|
||||||
lineinfos
|
|
||||||
|
|
||||||
const
|
const
|
||||||
debug = false
|
debug = false
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
|
|
||||||
import
|
import
|
||||||
hashes, math
|
hashes
|
||||||
|
|
||||||
type
|
type
|
||||||
BitScalar = uint
|
BitScalar = uint
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,8 @@
|
||||||
|
|
||||||
include "system/inclrtl"
|
include "system/inclrtl"
|
||||||
|
|
||||||
import strutils, os
|
|
||||||
|
|
||||||
when not defined(windows):
|
when not defined(windows):
|
||||||
import posix
|
import strutils, posix, os
|
||||||
|
|
||||||
when defined(linux):
|
when defined(linux):
|
||||||
import linux
|
import linux
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,6 @@
|
||||||
## * `std/sha1 module <sha1.html>`_ for a sha1 encoder and decoder
|
## * `std/sha1 module <sha1.html>`_ for a sha1 encoder and decoder
|
||||||
## * `tables module <tables.html>`_ for hash tables
|
## * `tables module <tables.html>`_ for hash tables
|
||||||
|
|
||||||
|
|
||||||
import
|
|
||||||
strutils
|
|
||||||
|
|
||||||
type
|
type
|
||||||
Hash* = int ## A hash value. Hash tables using these values should
|
Hash* = int ## A hash value. Hash tables using these values should
|
||||||
## always have a size of a power of two and can use the ``and``
|
## always have a size of a power of two and can use the ``and``
|
||||||
|
|
|
||||||
|
|
@ -142,8 +142,8 @@ runnableExamples:
|
||||||
doAssert $(%* Foo()) == """{"a1":0,"a2":0,"a0":0,"a3":0,"a4":0}"""
|
doAssert $(%* Foo()) == """{"a1":0,"a2":0,"a0":0,"a3":0,"a4":0}"""
|
||||||
|
|
||||||
import
|
import
|
||||||
hashes, tables, strutils, lexbase, streams, unicode, macros, parsejson,
|
hashes, tables, strutils, lexbase, streams, macros, parsejson,
|
||||||
typetraits, options
|
options
|
||||||
|
|
||||||
export
|
export
|
||||||
tables.`$`
|
tables.`$`
|
||||||
|
|
|
||||||
|
|
@ -1849,7 +1849,7 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
|
||||||
break
|
break
|
||||||
# getFullPathName doesn't do case corrections, so we have to use this convoluted
|
# getFullPathName doesn't do case corrections, so we have to use this convoluted
|
||||||
# way of retrieving the true filename
|
# way of retrieving the true filename
|
||||||
for x in walkFiles(result.string):
|
for x in walkFiles(result):
|
||||||
result = x
|
result = x
|
||||||
if not existsFile(result) and not existsDir(result):
|
if not existsFile(result) and not existsDir(result):
|
||||||
raise newException(OSError, "file '" & result & "' does not exist")
|
raise newException(OSError, "file '" & result & "' does not exist")
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
import macros
|
import macros
|
||||||
import strformat
|
import strformat
|
||||||
from strutils import toLowerAscii, `%`
|
from strutils import toLowerAscii, `%`
|
||||||
import colors, tables
|
import colors
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
import winlean
|
import winlean
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue