Compare commits

..

1 Commits

Author SHA1 Message Date
narimiran
727c6378d2 bump NimVersion to 1.6.0 2021-10-18 16:36:47 +02:00
562 changed files with 7520 additions and 15288 deletions

View File

@@ -2,7 +2,7 @@
name: Feature request
about: Do you want to suggest a new feature? Use this template.
title: ''
labels: ["Feature"]
labels: ''
assignees: ''
---

View File

@@ -3,102 +3,15 @@
## Changes affecting backward compatibility
- The `Math.trunc` polyfill for targeting Internet Explorer was
previously emitted for every JavaScript output file except if
the symbol `nodejs` was defined via `-d:nodejs`. Now, it is only
emitted if the symbol `nimJsMathTruncPolyfill` is defined. If you are
targeting Internet Explorer, you may choose to enable this option
or define your own `Math.trunc` polyfill using the [`emit` pragma](https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-emit-pragma). Nim uses
`Math.trunc` for the division and modulo operators for integers.
- Deprecated `std/sums`.
- Optional parameters in combination with `: body` syntax (RFC #405) are now opt-in via
`experimental:flexibleOptionalParams`.
- `std/sharedstrings` module is removed.
- Constants `colors.colPaleVioletRed` and `colors.colMediumPurple` changed to match the CSS color standard.
- `addr` is now available for all addressable locations, `unsafeAddr` is deprecated and
becomes an alias for `addr`.
- io is about to move out of system; use `-d:nimPreviewSlimSystem` and import `std/syncio`.
- The `gc:v2` option is removed.
## Standard library additions and changes
[//]: # "Changes:"
- `macros.parseExpr` and `macros.parseStmt` now accept an optional.
filename argument for more informative errors.
- Module `colors` expanded with missing colors from the CSS color standard.
- Fixed `lists.SinglyLinkedList` being broken after removing the last node ([#19353](https://github.com/nim-lang/Nim/pull/19353)).
- `md5` now works at compile time and in JavaScript.
- `std/smtp` sends `ehlo` first. If the mail server does not understand, it sends `helo` as a fallback.
- Changed mimedb to use an `OrderedTable` instead of `OrderedTableRef`, to use it in a const.
- `strutils.find` now use and default to `last=-1` for whole string searches, making limiting it to just the first char (`last=0`) valid.
[//]: # "Additions:"
- Added `IsoWeekRange`, a range type to represent the number of weeks in an ISO week-based year.
- Added `IsoYear`, a distinct int type to prevent bugs from confusing the week-based year and the regular year.
- Added `initDateTime` in `times` to create a datetime from a weekday, and ISO 8601 week number and week-based year.
- Added `getIsoWeekAndYear` in `times` to get an ISO week number along with the corresponding ISO week-based year from a datetime.
- Added `getIsoWeeksInYear` in `times` to return the number of weeks in an ISO week-based year.
- Added `std/oserrors` for OS error reporting. Added `std/envvars` for environment variables handling.
- Added `sep` parameter in `std/uri` to specify the query separator.
- Added [`Array.shift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift) for JavaScript targets.
- Added [`queueMicrotask`](https://developer.mozilla.org/en-US/docs/Web/API/queueMicrotask) for JavaScript targets.
[//]: # "Deprecations:"
- Deprecated `selfExe` for Nimscript.
[//]: # "Removals:"
- Removed deprecated `oids.oidToString`.
- Removed define `nimExperimentalAsyncjsThen` for `std/asyncjs.then` and `std/jsfetch`.
- Removed deprecated `jsre.test` and `jsre.toString`.
- Removed deprecated `math.c_frexp`.
- Removed deprecated `` httpcore.`==` ``.
- Removed deprecated `std/dom_extensions`.
- Removed deprecated `std/posix.CMSG_SPACE` and `std/posix.CMSG_LEN` that takes wrong argument types.
- Removed deprecated `osproc.poDemon`, symbol with typo.
## Language changes
- Pragma macros on type definitions can now return `nnkTypeSection` nodes as well as `nnkTypeDef`,
allowing multiple type definitions to be injected in place of the original type definition.
```nim
import macros
macro multiply(amount: static int, s: untyped): untyped =
let name = $s[0].basename
result = newNimNode(nnkTypeSection)
for i in 1 .. amount:
result.add(newTree(nnkTypeDef, ident(name & $i), s[1], s[2]))
type
Foo = object
Bar {.multiply: 3.} = object
x, y, z: int
Baz = object
# becomes
type
Foo = object
Bar1 = object
x, y, z: int
Bar2 = object
x, y, z: int
Bar3 = object
x, y, z: int
Baz = object
```
- [Case statement macros](manual.html#macros-case-statement-macros) are no longer experimental,
meaning you no longer need to enable the experimental switch `caseStmtMacros` to use them.
- Full command syntax and block arguments i.e. `foo a, b: c` are now allowed
for the right-hand side of type definitions in type sections. Previously
they would error with "invalid indentation".
## Compiler changes
@@ -108,12 +21,5 @@ becomes an alias for `addr`.
## Tool changes
- The `gc` switch has been renamed to `mm` ("memory management") in order to reflect the
reality better. (Nim moved away from all techniques based on "tracing".)
- Nim now supports Nimble version 0.14 which added support for lock-files. This is done by
a simple configuration change setting that you can do yourself too. In `$nim/config/nim.cfg`
replace `pkgs` by `pkgs2`.
- There is a new switch `--nimMainPrefix:prefix` to influence the `NimMain` that the
compiler produces. This is particularly useful for generating static libraries.

View File

@@ -1,33 +0,0 @@
# v1.xx.x - yyyy-mm-dd
## Changes affecting backward compatibility
## Standard library additions and changes
- `std/sharedlist` and `std/sharedtables` are now deprecated, see RFC [#433](https://github.com/nim-lang/RFCs/issues/433).
### New compile flag (`-d:nimNoGetRandom`) when building `std/sysrand` to remove dependency on linux `getrandom` syscall
This compile flag only affects linux builds and is necessary if either compiling on a linux kernel version < 3.17, or if code built will be executing on kernel < 3.17.
On linux kernels < 3.17 (such as kernel 3.10 in RHEL7 and CentOS7), the `getrandom` syscall was not yet introduced. Without this, the `std/sysrand` module will not build properly, and if code is built on a kernel >= 3.17 without the flag, any usage of the `std/sysrand` module will fail to execute on a kernel < 3.17 (since it attempts to perform a syscall to `getrandom`, which isn't present in the current kernel). A compile flag has been added to force the `std/sysrand` module to use /dev/urandom (available since linux kernel 1.3.30), rather than the `getrandom` syscall. This allows for use of a cryptographically secure PRNG, regardless of kernel support for the `getrandom` syscall.
When building for RHEL7/CentOS7 for example, the entire build process for nim from a source package would then be:
```sh
$ yum install devtoolset-8 # Install GCC version 8 vs the standard 4.8.5 on RHEL7/CentOS7. Alternatively use -d:nimEmulateOverflowChecks. See issue #13692 for details
$ scl enable devtoolset-8 bash # Run bash shell with default toolchain of gcc 8
$ sh build.sh # per unix install instructions
$ bin/nim c koch # per unix install instructions
$ ./koch boot -d:release # per unix install instructions
$ ./koch tools -d:nimNoGetRandom # pass the nimNoGetRandom flag to compile std/sysrand without support for getrandom syscall
```
This is necessary to pass when building nim on kernel versions < 3.17 in particular to avoid an error of "SYS_getrandom undeclared" during the build process for stdlib (sysrand in particular).
## Language changes
## Compiler changes
## Tool changes

View File

@@ -282,7 +282,7 @@
- Removed the deprecated `asyncdispatch.newAsyncNativeSocket`.
- Removed the deprecated `dom.releaseEvents` and `dom.captureEvents`.
- Removed `sharedlist.initSharedList`, was deprecated and produces undefined behaviour.
- Removed `sharedlists.initSharedList`, was deprecated and produces undefined behaviour.
- There is a new experimental feature called "strictFuncs" which makes the definition of
`.noSideEffect` stricter. [See here](manual_experimental.html#stricts-funcs)

View File

@@ -76,8 +76,6 @@ _nimBuildCsourcesIfNeeded(){
makeX=gmake
elif [ "$unamestr" = 'CROSSOS' ]; then
makeX=gmake
elif [ "$unamestr" = 'SunOS' ]; then
makeX=gmake
else
makeX=make
fi

View File

@@ -12,9 +12,6 @@
import
ast, astalgo, types, trees, intsets
when defined(nimPreviewSlimSystem):
import std/assertions
type
TAnalysisResult* = enum
arNo, arMaybe, arYes

View File

@@ -13,9 +13,6 @@ import
lineinfos, hashes, options, ropes, idents, int128, tables
from strutils import toLowerAscii
when defined(nimPreviewSlimSystem):
import std/assertions
export int128
type
@@ -504,7 +501,7 @@ type
nfHasComment # node has a comment
TNodeFlags* = set[TNodeFlag]
TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 45)
TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 43)
tfVarargs, # procedure has C styled varargs
# tyArray type represeting a varargs list
tfNoSideEffect, # procedure type does not allow side effects
@@ -676,7 +673,7 @@ type
mSwap, mIsNil, mArrToSeq,
mNewString, mNewStringOfCap, mParseBiggestFloat,
mMove, mWasMoved, mDestroy, mTrace,
mDefault, mUnown, mFinished, mIsolate, mAccessEnv, mAccessTypeField, mReset,
mDefault, mUnown, mFinished, mIsolate, mAccessEnv, mReset,
mArray, mOpenArray, mRange, mSet, mSeq, mVarargs,
mRef, mPtr, mVar, mDistinct, mVoid, mTuple,
mOrdinal, mIterableType,
@@ -1108,6 +1105,21 @@ proc getPIdent*(a: PNode): PIdent {.inline.} =
of nkIdent: a.ident
else: nil
proc getnimblePkg*(a: PSym): PSym =
result = a
while result != nil:
case result.kind
of skModule:
result = result.owner
assert result.kind == skPackage
of skPackage:
if result.owner == nil:
break
else:
result = result.owner
else:
assert false, $result.kind
const
moduleShift = when defined(cpu32): 20 else: 24
@@ -1152,7 +1164,13 @@ when false:
assert dest.ItemId.item <= src.ItemId.item
dest = src
proc getnimblePkgId*(a: PSym): int =
let b = a.getnimblePkg
result = if b == nil: -1 else: b.id
var ggDebug* {.deprecated.}: bool ## convenience switch for trying out things
#var
# gMainPackageId*: int
proc isCallExpr*(n: PNode): bool =
result = n.kind in nkCallKinds
@@ -1506,7 +1524,7 @@ proc assignType*(dest, src: PType) =
# this fixes 'type TLock = TSysLock':
if src.sym != nil:
if dest.sym != nil:
dest.sym.flags.incl src.sym.flags-{sfUsed, sfExported}
dest.sym.flags.incl src.sym.flags-{sfExported}
if dest.sym.annex == nil: dest.sym.annex = src.sym.annex
mergeLoc(dest.sym.loc, src.sym.loc)
else:
@@ -2083,11 +2101,3 @@ proc skipAddr*(n: PNode): PNode {.inline.} =
proc isNewStyleConcept*(n: PNode): bool {.inline.} =
assert n.kind == nkTypeClassTy
result = n[0].kind == nkEmpty
const
nodesToIgnoreSet* = {nkNone..pred(nkSym), succ(nkSym)..nkNilLit,
nkTypeSection, nkProcDef, nkConverterDef,
nkMethodDef, nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo,
nkFuncDef, nkConstSection, nkConstDef, nkIncludeStmt, nkImportStmt,
nkExportStmt, nkPragma, nkCommentStmt, nkBreakState,
nkTypeOfExpr, nkMixinStmt, nkBindStmt}

View File

@@ -15,9 +15,6 @@ import
ast, hashes, intsets, strutils, options, lineinfos, ropes, idents, rodutils,
msgs
when defined(nimPreviewSlimSystem):
import std/assertions
proc hashNode*(p: RootRef): Hash
proc treeToYaml*(conf: ConfigRef; n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope
# Convert a tree into its YAML representation; this is used by the

View File

@@ -10,9 +10,6 @@
# this unit handles Nim sets; it implements bit sets
# the code here should be reused in the Nim standard library
when defined(nimPreviewSlimSystem):
import std/assertions
type
ElemType = byte
TBitSet* = seq[ElemType] # we use byte here to avoid issues with
@@ -26,40 +23,53 @@ const
template modElemSize(arg: untyped): untyped = arg and 7
template divElemSize(arg: untyped): untyped = arg shr 3
proc bitSetIn*(x: TBitSet, e: BiggestInt): bool =
proc bitSetInit*(b: var TBitSet, length: int)
proc bitSetUnion*(x: var TBitSet, y: TBitSet)
proc bitSetDiff*(x: var TBitSet, y: TBitSet)
proc bitSetSymDiff*(x: var TBitSet, y: TBitSet)
proc bitSetIntersect*(x: var TBitSet, y: TBitSet)
proc bitSetIncl*(x: var TBitSet, elem: BiggestInt)
proc bitSetExcl*(x: var TBitSet, elem: BiggestInt)
proc bitSetIn*(x: TBitSet, e: BiggestInt): bool
proc bitSetEquals*(x, y: TBitSet): bool
proc bitSetContains*(x, y: TBitSet): bool
proc bitSetCard*(x: TBitSet): BiggestInt
# implementation
proc bitSetIn(x: TBitSet, e: BiggestInt): bool =
result = (x[int(e.divElemSize)] and (One shl e.modElemSize)) != Zero
proc bitSetIncl*(x: var TBitSet, elem: BiggestInt) =
proc bitSetIncl(x: var TBitSet, elem: BiggestInt) =
assert(elem >= 0)
x[int(elem.divElemSize)] = x[int(elem.divElemSize)] or
(One shl elem.modElemSize)
proc bitSetExcl*(x: var TBitSet, elem: BiggestInt) =
proc bitSetExcl(x: var TBitSet, elem: BiggestInt) =
x[int(elem.divElemSize)] = x[int(elem.divElemSize)] and
not(One shl elem.modElemSize)
proc bitSetInit*(b: var TBitSet, length: int) =
proc bitSetInit(b: var TBitSet, length: int) =
newSeq(b, length)
proc bitSetUnion*(x: var TBitSet, y: TBitSet) =
proc bitSetUnion(x: var TBitSet, y: TBitSet) =
for i in 0..high(x): x[i] = x[i] or y[i]
proc bitSetDiff*(x: var TBitSet, y: TBitSet) =
proc bitSetDiff(x: var TBitSet, y: TBitSet) =
for i in 0..high(x): x[i] = x[i] and not y[i]
proc bitSetSymDiff*(x: var TBitSet, y: TBitSet) =
proc bitSetSymDiff(x: var TBitSet, y: TBitSet) =
for i in 0..high(x): x[i] = x[i] xor y[i]
proc bitSetIntersect*(x: var TBitSet, y: TBitSet) =
proc bitSetIntersect(x: var TBitSet, y: TBitSet) =
for i in 0..high(x): x[i] = x[i] and y[i]
proc bitSetEquals*(x, y: TBitSet): bool =
proc bitSetEquals(x, y: TBitSet): bool =
for i in 0..high(x):
if x[i] != y[i]:
return false
result = true
proc bitSetContains*(x, y: TBitSet): bool =
proc bitSetContains(x, y: TBitSet): bool =
for i in 0..high(x):
if (x[i] and not y[i]) != Zero:
return false
@@ -86,6 +96,6 @@ const populationCount: array[uint8, uint8] = block:
arr
proc bitSetCard*(x: TBitSet): BiggestInt =
proc bitSetCard(x: TBitSet): BiggestInt =
for it in x:
result.inc int(populationCount[it])

View File

@@ -10,9 +10,6 @@
## BTree implementation with few features, but good enough for the
## Nim compiler's needs.
when defined(nimPreviewSlimSystem):
import std/assertions
const
M = 512 # max children per B-tree node = M-1
# (must be even and greater than 2)

View File

@@ -21,7 +21,7 @@ proc canRaiseDisp(p: BProc; n: PNode): bool =
# we have to be *very* conservative:
result = canRaiseConservative(n)
proc preventNrvo(p: BProc; dest, le, ri: PNode): bool =
proc preventNrvo(p: BProc; le, ri: PNode): bool =
proc locationEscapes(p: BProc; le: PNode; inTryStmt: bool): bool =
var n = le
while true:
@@ -54,11 +54,6 @@ proc preventNrvo(p: BProc; dest, le, ri: PNode): bool =
if canRaise(ri[0]) and
locationEscapes(p, le, p.nestedTryStmts.len > 0):
message(p.config, le.info, warnObservableStores, $le)
# bug #19613 prevent dangerous aliasing too:
if dest != nil and dest != le:
for i in 1..<ri.len:
let r = ri[i]
if isPartOf(dest, r) != arNo: return true
proc hasNoInit(call: PNode): bool {.inline.} =
result = call[0].kind == nkSym and sfNoInit in call[0].sym.flags
@@ -81,10 +76,10 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
# getUniqueType() is too expensive here:
var typ = skipTypes(ri[0].typ, abstractInst)
if typ[0] != nil:
if isInvalidReturnType(p.config, typ):
if isInvalidReturnType(p.config, typ[0]):
if params != nil: pl.add(~", ")
# beware of 'result = p(result)'. We may need to allocate a temporary:
if d.k in {locTemp, locNone} or not preventNrvo(p, d.lode, le, ri):
if d.k in {locTemp, locNone} or not preventNrvo(p, le, ri):
# Great, we can use 'd':
if d.k == locNone: getTemp(p, typ[0], d, needsInit=true)
elif d.k notin {locTemp} and not hasNoInit(ri):
@@ -219,7 +214,7 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode): Rope =
else:
var a: TLoc
initLocExpr(p, if n.kind == nkHiddenStdConv: n[1] else: n, a)
case skipTypes(a.t, abstractVar+{tyStatic}).kind
case skipTypes(a.t, abstractVar).kind
of tyOpenArray, tyVarargs:
if reifiedOpenArray(n):
if a.t.kind in {tyVar, tyLent}:
@@ -381,8 +376,8 @@ proc genParams(p: BProc, ri: PNode, typ: PType): Rope =
if not needTmp[i - 1]:
needTmp[i - 1] = potentialAlias(n, potentialWrites)
getPotentialWrites(ri[i], false, potentialWrites)
if ri[i].kind in {nkHiddenAddr, nkAddr}:
# Optimization: don't use a temp, if we would only take the address anyway
if ri[i].kind == nkHiddenAddr:
# Optimization: don't use a temp, if we would only take the adress anyway
needTmp[i - 1] = false
for i in 1..<ri.len:
@@ -444,10 +439,10 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
let rawProc = getClosureType(p.module, typ, clHalf)
let canRaise = p.config.exc == excGoto and canRaiseDisp(p, ri[0])
if typ[0] != nil:
if isInvalidReturnType(p.config, typ):
if isInvalidReturnType(p.config, typ[0]):
if ri.len > 1: pl.add(~", ")
# beware of 'result = p(result)'. We may need to allocate a temporary:
if d.k in {locTemp, locNone} or not preventNrvo(p, d.lode, le, ri):
if d.k in {locTemp, locNone} or not preventNrvo(p, le, ri):
# Great, we can use 'd':
if d.k == locNone:
getTemp(p, typ[0], d, needsInit=true)
@@ -742,7 +737,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
pl.add(~": ")
pl.add(genArg(p, ri[i], param, ri))
if typ[0] != nil:
if isInvalidReturnType(p.config, typ):
if isInvalidReturnType(p.config, typ[0]):
if ri.len > 1: pl.add(~" ")
# beware of 'result = p(result)'. We always allocate a temporary:
if d.k in {locTemp, locNone}:

View File

@@ -584,23 +584,13 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
else:
# we handle div by zero here so that we know that the compilerproc's
# result is only for overflows.
var needsOverflowCheck = true
if m in {mDivI, mModI}:
var canBeZero = true
if e[2].kind in {nkIntLit..nkUInt64Lit}:
canBeZero = e[2].intVal == 0
if e[2].kind in {nkIntLit..nkInt64Lit}:
needsOverflowCheck = e[2].intVal == -1
if canBeZero:
linefmt(p, cpsStmts, "if ($1 == 0){ #raiseDivByZero(); $2}$n",
[rdLoc(b), raiseInstr(p)])
if needsOverflowCheck:
let res = binaryArithOverflowRaw(p, t, a, b,
if t.kind == tyInt64: prc64[m] else: prc[m])
putIntoDest(p, d, e, "($#)($#)" % [getTypeDesc(p.module, e.typ), res])
else:
let res = "($1)($2 $3 $4)" % [getTypeDesc(p.module, e.typ), rdLoc(a), rope(opr[m]), rdLoc(b)]
putIntoDest(p, d, e, res)
linefmt(p, cpsStmts, "if ($1 == 0){ #raiseDivByZero(); $2}$n",
[rdLoc(b), raiseInstr(p)])
let res = binaryArithOverflowRaw(p, t, a, b,
if t.kind == tyInt64: prc64[m] else: prc[m])
putIntoDest(p, d, e, "($#)($#)" % [getTypeDesc(p.module, e.typ), res])
proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
var
@@ -988,12 +978,12 @@ proc genBoundsCheck(p: BProc; arr, a, b: TLoc) =
if reifiedOpenArray(arr.lode):
linefmt(p, cpsStmts,
"if ($2-$1 != -1 && " &
"($1 < 0 || $1 >= $3.Field1 || $2 < 0 || $2 >= $3.Field1)){ #raiseIndexError4($1, $2, $3.Field1); $4}$n",
"((NU)($1) >= (NU)($3.Field1) || (NU)($2) >= (NU)($3.Field1))){ #raiseIndexError(); $4}$n",
[rdLoc(a), rdLoc(b), rdLoc(arr), raiseInstr(p)])
else:
linefmt(p, cpsStmts,
"if ($2-$1 != -1 && ($1 < 0 || $1 >= $3Len_0 || $2 < 0 || $2 >= $3Len_0))" &
"{ #raiseIndexError4($1, $2, $3Len_0); $4}$n",
"if ($2-$1 != -1 && " &
"((NU)($1) >= (NU)($3Len_0) || (NU)($2) >= (NU)($3Len_0))){ #raiseIndexError(); $4}$n",
[rdLoc(a), rdLoc(b), rdLoc(arr), raiseInstr(p)])
of tyArray:
let first = intLiteral(firstOrd(p.config, ty))
@@ -1004,7 +994,7 @@ proc genBoundsCheck(p: BProc; arr, a, b: TLoc) =
of tySequence, tyString:
linefmt(p, cpsStmts,
"if ($2-$1 != -1 && " &
"($1 < 0 || $1 >= $3 || $2 < 0 || $2 >= $3)){ #raiseIndexError4($1, $2, $3); $4}$n",
"((NU)($1) >= (NU)$3 || (NU)($2) >= (NU)$3)){ #raiseIndexError(); $4}$n",
[rdLoc(a), rdLoc(b), lenExpr(p, arr), raiseInstr(p)])
else: discard
@@ -1015,14 +1005,14 @@ proc genOpenArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) =
if not reifiedOpenArray(x):
# emit range check:
if optBoundsCheck in p.options:
linefmt(p, cpsStmts, "if ($1 < 0 || $1 >= $2Len_0){ #raiseIndexError2($1,$2Len_0-1); $3}$n",
linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len_0)){ #raiseIndexError2($1,$2Len_0-1); $3}$n",
[rdCharLoc(b), rdLoc(a), raiseInstr(p)]) # BUGFIX: ``>=`` and not ``>``!
inheritLocation(d, a)
putIntoDest(p, d, n,
ropecg(p.module, "$1[$2]", [rdLoc(a), rdCharLoc(b)]), a.storage)
else:
if optBoundsCheck in p.options:
linefmt(p, cpsStmts, "if ($1 < 0 || $1 >= $2.Field1){ #raiseIndexError2($1,$2.Field1-1); $3}$n",
linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2.Field1)){ #raiseIndexError2($1,$2.Field1-1); $3}$n",
[rdCharLoc(b), rdLoc(a), raiseInstr(p)]) # BUGFIX: ``>=`` and not ``>``!
inheritLocation(d, a)
putIntoDest(p, d, n,
@@ -1037,7 +1027,7 @@ proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) =
ty = skipTypes(ty.lastSon, abstractVarRange) # emit range check:
if optBoundsCheck in p.options:
linefmt(p, cpsStmts,
"if ($1 < 0 || $1 >= $2){ #raiseIndexError2($1,$2-1); $3}$n",
"if ((NU)($1) >= (NU)$2){ #raiseIndexError2($1,$2-1); $3}$n",
[rdCharLoc(b), lenExpr(p, a), raiseInstr(p)])
if d.k == locNone: d.storage = OnHeap
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
@@ -1615,11 +1605,8 @@ proc genNewFinalize(p: BProc, e: PNode) =
proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo): Rope =
if optTinyRtti in p.config.globalOptions:
let ti = genTypeInfo2Name(p.module, dest)
inc p.module.labels
let cache = "Nim_OfCheck_CACHE" & p.module.labels.rope
p.module.s[cfsVars].addf("static TNimTypeV2* $#[2];$n", [cache])
result = ropecg(p.module, "#isObjWithCache($#.m_type, $#, $#)", [a, ti, cache])
result = ropecg(p.module, "#isObj($1.m_type, $2)",
[a, genTypeInfo2Name(p.module, dest)])
else:
# unfortunately 'genTypeInfoV1' sets tfObjHasKids as a side effect, so we
# have to call it here first:
@@ -1754,13 +1741,6 @@ proc genGetTypeInfoV2(p: BProc, e: PNode, d: var TLoc) =
# use the dynamic type stored at offset 0:
putIntoDest(p, d, e, rdMType(p, a, nilCheck))
proc genAccessTypeField(p: BProc; e: PNode; d: var TLoc) =
var a: TLoc
initLocExpr(p, e[1], a)
var nilCheck = Rope(nil)
# use the dynamic type stored at offset 0:
putIntoDest(p, d, e, rdMType(p, a, nilCheck))
template genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
var a: TLoc
initLocExpr(p, n[1], a)
@@ -2469,7 +2449,6 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mMove: genMove(p, e, d)
of mDestroy: genDestroy(p, e)
of mAccessEnv: unaryExpr(p, e, d, "$1.ClE_0")
of mAccessTypeField: genAccessTypeField(p, e, d)
of mSlice: genSlice(p, e, d)
of mTrace: discard "no code to generate"
else:
@@ -2945,21 +2924,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
nkFromStmt, nkTemplateDef, nkMacroDef, nkStaticStmt:
discard
of nkPragma: genPragma(p, n)
of nkPragmaBlock:
var inUncheckedAssignSection = 0
let pragmaList = n[0]
for pi in pragmaList:
if whichPragma(pi) == wCast:
case whichPragma(pi[1])
of wUncheckedAssign:
inUncheckedAssignSection = 1
else:
discard
inc p.inUncheckedAssignSection, inUncheckedAssignSection
expr(p, n.lastSon, d)
dec p.inUncheckedAssignSection, inUncheckedAssignSection
of nkPragmaBlock: expr(p, n.lastSon, d)
of nkProcDef, nkFuncDef, nkMethodDef, nkConverterDef:
if n[genericParamsPos].kind == nkEmpty:
var prc = n[namePos].sym

View File

@@ -16,7 +16,7 @@ const
# above X strings a hash-switch for strings is generated
proc getTraverseProc(p: BProc, v: PSym): Rope =
if p.config.selectedGC in {gcMarkAndSweep, gcHooks, gcRefc} and
if p.config.selectedGC in {gcMarkAndSweep, gcHooks, gcV2, gcRefc} and
optOwnedRefs notin p.config.globalOptions and
containsGarbageCollectedRef(v.loc.t):
# we register a specialized marked proc here; this has the advantage
@@ -32,20 +32,13 @@ proc registerTraverseProc(p: BProc, v: PSym, traverseProc: Rope) =
"$n\t#nimRegisterGlobalMarker($1);$n$n", [traverseProc])
proc isAssignedImmediately(conf: ConfigRef; n: PNode): bool {.inline.} =
if n.kind == nkEmpty:
result = false
elif n.kind in nkCallKinds and n[0] != nil and n[0].typ != nil and n[0].typ.skipTypes(abstractInst).kind == tyProc:
if isInvalidReturnType(conf, n[0].typ, true):
# var v = f()
# is transformed into: var v; f(addr v)
# where 'f' **does not** initialize the result!
result = false
else:
result = true
elif isInvalidReturnType(conf, n.typ, false):
result = false
else:
result = true
if n.kind == nkEmpty: return false
if isInvalidReturnType(conf, n.typ):
# var v = f()
# is transformed into: var v; f(addr v)
# where 'f' **does not** initialize the result!
return false
result = true
proc inExceptBlockLen(p: BProc): int =
for x in p.nestedTryStmts:
@@ -1363,19 +1356,8 @@ proc genTrySetjmp(p: BProc, t: PNode, d: var TLoc) =
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint])
elif isDefined(p.config, "nimSigSetjmp"):
linefmt(p, cpsStmts, "$1.status = sigsetjmp($1.context, 0);$n", [safePoint])
elif isDefined(p.config, "nimBuiltinSetjmp"):
linefmt(p, cpsStmts, "$1.status = __builtin_setjmp($1.context);$n", [safePoint])
elif isDefined(p.config, "nimRawSetjmp"):
if isDefined(p.config, "mswindows"):
# The Windows `_setjmp()` takes two arguments, with the second being an
# undocumented buffer used by the SEH mechanism for stack unwinding.
# Mingw-w64 has been trying to get it right for years, but it's still
# prone to stack corruption during unwinding, so we disable that by setting
# it to NULL.
# More details: https://github.com/status-im/nimbus-eth2/issues/3121
linefmt(p, cpsStmts, "$1.status = _setjmp($1.context, 0);$n", [safePoint])
else:
linefmt(p, cpsStmts, "$1.status = _setjmp($1.context);$n", [safePoint])
linefmt(p, cpsStmts, "$1.status = _setjmp($1.context);$n", [safePoint])
else:
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint])
lineCg(p, cpsStmts, "if ($1.status == 0) {$n", [safePoint])
@@ -1566,7 +1548,7 @@ proc asgnFieldDiscriminant(p: BProc, e: PNode) =
initLocExpr(p, e[0], a)
getTemp(p, a.t, tmp)
expr(p, e[1], tmp)
if optTinyRtti notin p.config.globalOptions and p.inUncheckedAssignSection == 0:
if optTinyRtti notin p.config.globalOptions:
let field = dotExpr[1].sym
genDiscriminantCheck(p, a, tmp, dotExpr[0].typ, field)
message(p.config, e.info, warnCaseTransition)

View File

@@ -39,7 +39,7 @@ proc mangleName(m: BModule; s: PSym): Rope =
result = s.loc.r
if result == nil:
result = s.name.s.mangle.rope
result.add "__"
result.add "_"
result.add m.g.graph.ifaces[s.itemId.module].uniqueName
result.add "_"
result.add rope s.itemId.item
@@ -215,19 +215,12 @@ proc isObjLackingTypeField(typ: PType): bool {.inline.} =
result = (typ.kind == tyObject) and ((tfFinal in typ.flags) and
(typ[0] == nil) or isPureObject(typ))
proc isInvalidReturnType(conf: ConfigRef; typ: PType, isProc = true): bool =
proc isInvalidReturnType(conf: ConfigRef; rettype: PType): bool =
# Arrays and sets cannot be returned by a C procedure, because C is
# such a poor programming language.
# We exclude records with refs too. This enhances efficiency and
# is necessary for proper code generation of assignments.
var rettype = typ
var isAllowedCall = true
if isProc:
rettype = rettype[0]
isAllowedCall = typ.callConv in {ccClosure, ccInline, ccNimCall}
if rettype == nil or (isAllowedCall and
getSize(conf, rettype) > conf.target.floatSize*3):
result = true
if rettype == nil: result = true
else:
case mapType(conf, rettype, skResult)
of ctArray:
@@ -263,11 +256,11 @@ proc addAbiCheck(m: BModule, t: PType, name: Rope) =
# see `testCodegenABICheck` for example error message it generates
proc fillResult(conf: ConfigRef; param: PNode, proctype: PType) =
proc fillResult(conf: ConfigRef; param: PNode) =
fillLoc(param.sym.loc, locParam, param, ~"Result",
OnStack)
let t = param.sym.typ
if mapReturnType(conf, t) != ctArray and isInvalidReturnType(conf, proctype):
if mapReturnType(conf, t) != ctArray and isInvalidReturnType(conf, t):
incl(param.sym.loc.flags, lfIndirect)
param.sym.loc.storage = OnUnknown
@@ -432,7 +425,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope,
check: var IntSet, declareEnvironment=true;
weakDep=false) =
params = nil
if t[0] == nil or isInvalidReturnType(m.config, t):
if t[0] == nil or isInvalidReturnType(m.config, t[0]):
rettype = ~"void"
else:
rettype = getTypeDescAux(m, t[0], check, skResult)
@@ -467,17 +460,12 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope,
params.addf(", NI $1Len_$2", [param.loc.r, j.rope])
inc(j)
arr = arr[0].skipTypes({tySink})
if t[0] != nil and isInvalidReturnType(m.config, t):
if t[0] != nil and isInvalidReturnType(m.config, t[0]):
var arr = t[0]
if params != nil: params.add(", ")
if mapReturnType(m.config, t[0]) != ctArray:
if isHeaderFile in m.flags:
# still generates types for `--header`
params.add(getTypeDescAux(m, arr, check, skResult))
params.add("*")
else:
params.add(getTypeDescWeak(m, arr, check, skResult))
params.add("*")
params.add(getTypeDescWeak(m, arr, check, skResult))
params.add("*")
else:
params.add(getTypeDescAux(m, arr, check, skResult))
params.addf(" Result", [])
@@ -594,7 +582,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope,
if typ.kind == tyObject:
if typ[0] == nil:
if lacksMTypeField(typ):
if (typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags:
appcg(m, result, " {$n", [])
else:
if optTinyRtti in m.config.globalOptions:
@@ -1483,12 +1471,12 @@ proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope =
genTupleInfo(m, x, x, result, info)
of tySequence:
genTypeInfoAux(m, t, t, result, info)
if m.config.selectedGC in {gcMarkAndSweep, gcRefc, gcGo}:
if m.config.selectedGC in {gcMarkAndSweep, gcRefc, gcV2, gcGo}:
let markerProc = genTraverseProc(m, origType, sig)
m.s[cfsTypeInit3].addf("$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc])
of tyRef:
genTypeInfoAux(m, t, t, result, info)
if m.config.selectedGC in {gcMarkAndSweep, gcRefc, gcGo}:
if m.config.selectedGC in {gcMarkAndSweep, gcRefc, gcV2, gcGo}:
let markerProc = genTraverseProc(m, origType, sig)
m.s[cfsTypeInit3].addf("$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc])
of tyPtr, tyRange, tyUncheckedArray: genTypeInfoAux(m, t, t, result, info)

View File

@@ -13,9 +13,6 @@ import
ast, types, hashes, strutils, msgs, wordrecg,
platform, trees, options, cgendata
when defined(nimPreviewSlimSystem):
import std/assertions
proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode =
case n.kind
of nkStmtList:

View File

@@ -15,10 +15,7 @@ import
ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth,
rodutils, renderer, cgendata, aliases,
lowerings, tables, sets, ndi, lineinfos, pathutils, transf,
injectdestructors, astmsgs, modulepaths
when defined(nimPreviewSlimSystem):
import std/assertions
injectdestructors, astmsgs
when not defined(leanCompiler):
import spawn, semparallel
@@ -51,13 +48,8 @@ proc addForwardedProc(m: BModule, prc: PSym) =
m.g.forwardedProcs.add(prc)
proc findPendingModule(m: BModule, s: PSym): BModule =
# TODO fixme
if m.config.symbolFiles == v2Sf:
let ms = s.itemId.module #getModule(s)
result = m.g.modules[ms]
else:
var ms = getModule(s)
result = m.g.modules[ms.position]
let ms = s.itemId.module #getModule(s)
result = m.g.modules[ms]
proc initLoc(result: var TLoc, k: TLocKind, lode: PNode, s: TStorageLoc) =
result.k = k
@@ -162,11 +154,6 @@ macro ropecg(m: BModule, frmt: static[FormatStr], args: untyped): Rope =
inc(i)
result.add newCall(formatValue, resVar, args[num])
inc(num)
of '^':
flushStrLit()
inc(i)
result.add newCall(formatValue, resVar, args[^1])
inc(num)
of '0'..'9':
var j = 0
while true:
@@ -376,8 +363,7 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: var TLoc,
else:
linefmt(p, section, "$1.m_type = $2;$n", [r, genTypeInfoV1(p.module, t, a.lode.info)])
of frEmbedded:
# inheritance in C++ does not allow struct initialization: bug #18410
if not p.module.compileToCpp and optTinyRtti in p.config.globalOptions:
if optTinyRtti in p.config.globalOptions:
var tmp: TLoc
if mode == constructRefObj:
let objType = t.skipTypes(abstractInst+{tyRef})
@@ -456,14 +442,8 @@ proc constructLoc(p: BProc, loc: var TLoc, isTemp = false) =
if optSeqDestructors in p.config.globalOptions and skipTypes(typ, abstractInst + {tyStatic}).kind in {tyString, tySequence}:
linefmt(p, cpsStmts, "$1.len = 0; $1.p = NIM_NIL;$n", [rdLoc(loc)])
elif not isComplexValueType(typ):
if containsGarbageCollectedRef(loc.t):
var nilLoc: TLoc
initLoc(nilLoc, locTemp, loc.lode, OnStack)
nilLoc.r = rope("NIM_NIL")
genRefAssign(p, loc, nilLoc)
else:
linefmt(p, cpsStmts, "$1 = ($2)0;$n", [rdLoc(loc),
getTypeDesc(p.module, typ, mapTypeChooser(loc))])
linefmt(p, cpsStmts, "$1 = ($2)0;$n", [rdLoc(loc),
getTypeDesc(p.module, typ, mapTypeChooser(loc))])
else:
if not isTemp or containsGarbageCollectedRef(loc.t):
# don't use nimZeroMem for temporary values for performance if we can
@@ -884,7 +864,7 @@ proc containsResult(n: PNode): bool =
if containsResult(n[i]): return true
const harmless = {nkConstSection, nkTypeSection, nkEmpty, nkCommentStmt, nkTemplateDef,
nkMacroDef, nkMixinStmt, nkBindStmt, nkFormalParams} +
nkMacroDef, nkMixinStmt, nkBindStmt} +
declarativeDefs
proc easyResultAsgn(n: PNode): PNode =
@@ -1042,7 +1022,7 @@ proc genProcAux(m: BModule, prc: PSym) =
internalError(m.config, prc.info, "proc has no result symbol")
let resNode = prc.ast[resultPos]
let res = resNode.sym # get result symbol
if not isInvalidReturnType(m.config, prc.typ):
if not isInvalidReturnType(m.config, prc.typ[0]):
if sfNoInit in prc.flags: incl(res.flags, sfNoInit)
if sfNoInit in prc.flags and p.module.compileToCpp and (let val = easyResultAsgn(procBody); val != nil):
var decl = localVarDecl(p, resNode)
@@ -1056,7 +1036,7 @@ proc genProcAux(m: BModule, prc: PSym) =
initLocalVar(p, res, immediateAsgn=false)
returnStmt = ropecg(p.module, "\treturn $1;$n", [rdLoc(res.loc)])
else:
fillResult(p.config, resNode, prc.typ)
fillResult(p.config, resNode)
assignParam(p, res, prc.typ[0])
# We simplify 'unsureAsgn(result, nil); unsureAsgn(result, x)'
# to 'unsureAsgn(result, x)'
@@ -1064,11 +1044,9 @@ proc genProcAux(m: BModule, prc: PSym) =
# the 'unsureAsgn' is a nop. If it points to a global variable the
# global is either 'nil' or points to valid memory and so the RC operation
# succeeds without touching not-initialized memory.
if sfNoInit in prc.flags and p.config.selectedGC notin {gcArc, gcOrc}: discard
if sfNoInit in prc.flags: discard
elif allPathsAsgnResult(procBody) == InitSkippable: discard
else:
if sfNoInit in prc.flags and p.config.selectedGC in {gcArc, gcOrc}:
message(m.config, resNode.info, warnNoInitIgnored, "")
resetLoc(p, res.loc)
if skipTypes(res.typ, abstractInst).kind == tyArray:
#incl(res.loc.flags, lfIndirect)
@@ -1307,19 +1285,17 @@ proc getFileHeader(conf: ConfigRef; cfile: Cfile): Rope =
if conf.hcrOn: result.add("#define NIM_HOT_CODE_RELOADING\L")
addNimDefines(result, conf)
proc getSomeNameForModule(conf: ConfigRef, filename: AbsoluteFile): Rope =
## Returns a mangled module name.
result.add mangleModuleName(conf, filename).mangle
proc getSomeNameForModule(m: BModule): Rope =
## Returns a mangled module name.
assert m.module.kind == skModule
assert m.module.owner.kind == skPackage
result.add mangleModuleName(m.g.config, m.filename).mangle
proc getSomeNameForModule(m: PSym): Rope =
assert m.kind == skModule
assert m.owner.kind == skPackage
if {sfSystemModule, sfMainModule} * m.flags == {}:
result = m.owner.name.s.mangle.rope
result.add "_"
result.add m.name.s.mangle
proc getSomeInitName(m: BModule, suffix: string): Rope =
if not m.hcrOn:
result = getSomeNameForModule(m)
result = getSomeNameForModule(m.module)
result.add suffix
proc getInitName(m: BModule): Rope =
@@ -1370,29 +1346,20 @@ proc genMainProc(m: BModule) =
# The use of a volatile function pointer to call Pre/NimMainInner
# prevents inlining of the NimMainInner function and dependent
# functions, which might otherwise merge their stack frames.
PreMainVolatileBody =
"\tvoid (*volatile inner)(void);$N" &
"\tinner = PreMainInner;$N" &
"$1" &
"\t(*inner)();$N"
PreMainNonVolatileBody =
"$1" &
"\tPreMainInner();$N"
PreMainBodyStart = "$N" &
PreMainBody = "$N" &
"N_LIB_PRIVATE void PreMainInner(void) {$N" &
"$2" &
"}$N$N" &
PosixCmdLine &
"N_LIB_PRIVATE void PreMain(void) {$N"
PreMainBodyEnd =
"N_LIB_PRIVATE void PreMain(void) {$N" &
"\tvoid (*volatile inner)(void);$N" &
"\tinner = PreMainInner;$N" &
"$1" &
"\t(*inner)();$N" &
"}$N$N"
MainProcs =
"\t$^NimMain();$N"
"\tNimMain();$N"
MainProcsWithResult =
MainProcs & ("\treturn $1nim_program_result;$N")
@@ -1401,32 +1368,17 @@ proc genMainProc(m: BModule) =
"$1" &
"}$N$N"
NimMainVolatileBody =
"\tvoid (*volatile inner)(void);$N" &
"$4" &
"\tinner = NimMainInner;$N" &
"$2" &
"\t(*inner)();$N"
NimMainNonVolatileBody =
"$4" &
"$2" &
"\tNimMainInner();$N"
NimMainProcStart =
"N_CDECL(void, $5NimMain)(void) {$N"
NimMainProcEnd =
NimMainProc =
"N_CDECL(void, NimMain)(void) {$N" &
"\tvoid (*volatile inner)(void);$N" &
"$4" &
"\tinner = NimMainInner;$N" &
"$2" &
"\t(*inner)();$N" &
"}$N$N"
NimMainProc = NimMainProcStart & NimMainVolatileBody & NimMainProcEnd
NimSlimMainProc = NimMainProcStart & NimMainNonVolatileBody & NimMainProcEnd
NimMainBody = NimMainInner & NimMainProc
NimSlimMainBody = NimMainInner & NimSlimMainProc
PosixCMain =
"int main(int argc, char** args, char** env) {$N" &
"\tcmdLine = args;$N" &
@@ -1487,45 +1439,38 @@ proc genMainProc(m: BModule) =
m.includeHeader("<libc/component.h>")
let initStackBottomCall =
if m.config.target.targetOS == osStandalone or m.config.selectedGC in {gcNone, gcArc, gcOrc}: "".rope
if m.config.target.targetOS == osStandalone or m.config.selectedGC == gcNone: "".rope
else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N", [])
inc(m.labels)
if m.config.selectedGC notin {gcNone, gcArc, gcOrc}:
appcg(m, m.s[cfsProcs], PreMainBodyStart & PreMainVolatileBody & PreMainBodyEnd, [m.g.mainDatInit, m.g.otherModsInit])
else:
appcg(m, m.s[cfsProcs], PreMainBodyStart & PreMainNonVolatileBody & PreMainBodyEnd, [m.g.mainDatInit, m.g.otherModsInit])
appcg(m, m.s[cfsProcs], PreMainBody, [m.g.mainDatInit, m.g.otherModsInit])
if m.config.target.targetOS == osWindows and
m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}:
if optGenGuiApp in m.config.globalOptions:
const nimMain = WinNimMain
appcg(m, m.s[cfsProcs], nimMain,
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix])
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode])
else:
const nimMain = WinNimDllMain
appcg(m, m.s[cfsProcs], nimMain,
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix])
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode])
elif m.config.target.targetOS == osGenode:
const nimMain = GenodeNimMain
appcg(m, m.s[cfsProcs], nimMain,
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix])
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode])
elif optGenDynLib in m.config.globalOptions:
const nimMain = PosixNimDllMain
appcg(m, m.s[cfsProcs], nimMain,
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix])
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode])
elif m.config.target.targetOS == osStandalone:
const nimMain = NimMainBody
appcg(m, m.s[cfsProcs], nimMain,
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix])
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode])
else:
if m.config.selectedGC notin {gcNone, gcArc, gcOrc}:
const nimMain = NimMainBody
appcg(m, m.s[cfsProcs], nimMain,
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix])
else:
const nimMain = NimSlimMainBody
appcg(m, m.s[cfsProcs], nimMain,
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix])
const nimMain = NimMainBody
appcg(m, m.s[cfsProcs], nimMain,
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode])
if optNoMain notin m.config.globalOptions:
if m.config.cppCustomNamespace.len > 0:
@@ -1535,22 +1480,23 @@ proc genMainProc(m: BModule) =
m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}:
if optGenGuiApp in m.config.globalOptions:
const otherMain = WinCMain
appcg(m, m.s[cfsProcs], otherMain, [if m.hcrOn: "*" else: "", m.config.nimMainPrefix])
appcg(m, m.s[cfsProcs], otherMain, [if m.hcrOn: "*" else: ""])
else:
const otherMain = WinCDllMain
appcg(m, m.s[cfsProcs], otherMain, [m.config.nimMainPrefix])
appcg(m, m.s[cfsProcs], otherMain, [])
elif m.config.target.targetOS == osGenode:
const otherMain = ComponentConstruct
appcg(m, m.s[cfsProcs], otherMain, [m.config.nimMainPrefix])
appcg(m, m.s[cfsProcs], otherMain, [])
elif optGenDynLib in m.config.globalOptions:
const otherMain = PosixCDllMain
appcg(m, m.s[cfsProcs], otherMain, [m.config.nimMainPrefix])
appcg(m, m.s[cfsProcs], otherMain, [])
elif m.config.target.targetOS == osStandalone:
const otherMain = StandaloneCMain
appcg(m, m.s[cfsProcs], otherMain, [m.config.nimMainPrefix])
appcg(m, m.s[cfsProcs], otherMain, [])
else:
const otherMain = PosixCMain
appcg(m, m.s[cfsProcs], otherMain, [if m.hcrOn: "*" else: "", m.config.nimMainPrefix])
appcg(m, m.s[cfsProcs], otherMain, [if m.hcrOn: "*" else: ""])
if m.config.cppCustomNamespace.len > 0:
m.s[cfsProcs].add openNamespaceNim(m.config.cppCustomNamespace)
@@ -1558,11 +1504,11 @@ proc genMainProc(m: BModule) =
proc registerInitProcs*(g: BModuleList; m: PSym; flags: set[ModuleBackendFlag]) =
## Called from the IC backend.
if HasDatInitProc in flags:
let datInit = getSomeNameForModule(g.config, g.config.toFullPath(m.info.fileIndex).AbsoluteFile) & "DatInit000"
let datInit = getSomeNameForModule(m) & "DatInit000"
g.mainModProcs.addf("N_LIB_PRIVATE N_NIMCALL(void, $1)(void);$N", [datInit])
g.mainDatInit.addf("\t$1();$N", [datInit])
if HasModuleInitProc in flags:
let init = getSomeNameForModule(g.config, g.config.toFullPath(m.info.fileIndex).AbsoluteFile) & "Init000"
let init = getSomeNameForModule(m) & "Init000"
g.mainModProcs.addf("N_LIB_PRIVATE N_NIMCALL(void, $1)(void);$N", [init])
let initCall = "\t$1();$N" % [init]
if sfMainModule in m.flags:
@@ -1932,7 +1878,7 @@ proc writeHeader(m: BModule) =
if optGenDynLib in m.config.globalOptions:
result.add("N_LIB_IMPORT ")
result.addf("N_CDECL(void, $1NimMain)(void);$n", [rope m.config.nimMainPrefix])
result.addf("N_CDECL(void, NimMain)(void);$n", [])
if m.config.cppCustomNamespace.len > 0: result.add closeNamespaceNim()
result.addf("#endif /* $1 */$n", [guard])
if not writeRope(result, m.filename):
@@ -1943,7 +1889,7 @@ proc getCFile(m: BModule): AbsoluteFile =
if m.compileToCpp: ".nim.cpp"
elif m.config.backend == backendObjc or sfCompileToObjc in m.module.flags: ".nim.m"
else: ".nim.c"
result = changeFileExt(completeCfilePath(m.config, mangleModuleName(m.config, m.cfilename).AbsoluteFile), ext)
result = changeFileExt(completeCfilePath(m.config, withPackageName(m.config, m.cfilename)), ext)
when false:
proc myOpenCached(graph: ModuleGraph; module: PSym, rd: PRodReader): PPassContext =
@@ -2096,7 +2042,7 @@ proc finalCodegenActions*(graph: ModuleGraph; m: BModule; n: PNode) =
discard cgsym(m, "rawWrite")
# raise dependencies on behalf of genMainProc
if m.config.target.targetOS != osStandalone and m.config.selectedGC notin {gcNone, gcArc, gcOrc}:
if m.config.target.targetOS != osStandalone and m.config.selectedGC != gcNone:
discard cgsym(m, "initStackBottomWith")
if emulatedThreadVars(m.config) and m.config.target.targetOS != osStandalone:
discard cgsym(m, "initThreadVarsEmulation")

View File

@@ -99,7 +99,6 @@ type
withinTryWithExcept*: int # required for goto based exception handling
withinBlockLeaveActions*: int # complex to explain
sigConflicts*: CountTable[string]
inUncheckedAssignSection*: int
TTypeSeq* = seq[PType]
TypeCache* = Table[SigHash, Rope]

View File

@@ -13,10 +13,6 @@ import
intsets, options, ast, msgs, idents, renderer, types, magicsys,
sempass2, strutils, modulegraphs, lineinfos
when defined(nimPreviewSlimSystem):
import std/assertions
proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =
var dest = skipTypes(d, abstractPtrs)
var source = skipTypes(n.typ, abstractPtrs)

View File

@@ -133,9 +133,6 @@ import
renderer, magicsys, lowerings, lambdalifting, modulegraphs, lineinfos,
tables, options
when defined(nimPreviewSlimSystem):
import std/assertions
type
Ctx = object
g: ModuleGraph
@@ -1354,15 +1351,13 @@ proc preprocess(c: var PreprocessContext; n: PNode): PNode =
case n.kind
of nkTryStmt:
let f = n.lastSon
var didAddSomething = false
if f.kind == nkFinally:
c.finallys.add f.lastSon
didAddSomething = true
for i in 0 ..< n.len:
result[i] = preprocess(c, n[i])
if didAddSomething:
if f.kind == nkFinally:
discard c.finallys.pop()
of nkWhileStmt, nkBlockStmt:
@@ -1389,7 +1384,7 @@ proc preprocess(c: var PreprocessContext; n: PNode): PNode =
result = newNodeI(nkStmtList, n.info)
for i in countdown(c.finallys.high, fin):
var vars = FreshVarsContext(tab: initTable[int, PSym](), config: c.config, info: n.info, idgen: c.idgen)
result.add freshVars(copyTree(c.finallys[i]), vars)
result.add freshVars(preprocess(c, c.finallys[i]), vars)
c.idgen = vars.idgen
result.add n
of nkSkip: discard

View File

@@ -64,8 +64,7 @@ proc loadConfigsAndProcessCmdLine*(self: NimProg, cache: IdentCache; conf: Confi
if conf.cmd == cmdNimscript: return false
# now process command line arguments again, because some options in the
# command line can overwrite the config file's settings
if conf.backend != backendJs: # bug #19059
extccomp.initVars(conf)
extccomp.initVars(conf)
self.processCmdLine(passCmd2, "", conf)
if conf.cmd == cmdNone:
rawMessage(conf, errGenerated, "command missing")

View File

@@ -31,9 +31,6 @@ import
from ast import setUseIc, eqTypeFlags, tfGcSafe, tfNoSideEffect
when defined(nimPreviewSlimSystem):
import std/assertions
# but some have deps to imported modules. Yay.
bootSwitch(usedTinyC, hasTinyCBackend, "-d:tinyc")
bootSwitch(usedFFI, hasFFI, "-d:nimHasLibFFI")
@@ -116,7 +113,7 @@ const
errInvalidCmdLineOption = "invalid command line option: '$1'"
errOnOrOffExpectedButXFound = "'on' or 'off' expected, but '$1' found"
errOnOffOrListExpectedButXFound = "'on', 'off' or 'list' expected, but '$1' found"
errOffHintsError = "'off', 'hint', 'error' or 'usages' expected, but '$1' found"
errOffHintsError = "'off', 'hint' or 'error' expected, but '$1' found"
proc invalidCmdLineOption(conf: ConfigRef; pass: TCmdLinePass, switch: string, info: TLineInfo) =
if switch == " ": localError(conf, info, errInvalidCmdLineOption % "-")
@@ -241,7 +238,7 @@ const
errNoneBoehmRefcExpectedButXFound = "'arc', 'orc', 'markAndSweep', 'boehm', 'go', 'none', 'regions', or 'refc' expected, but '$1' found"
errNoneSpeedOrSizeExpectedButXFound = "'none', 'speed' or 'size' expected, but '$1' found"
errGuiConsoleOrLibExpectedButXFound = "'gui', 'console' or 'lib' expected, but '$1' found"
errInvalidExceptionSystem = "'goto', 'setjmp', 'cpp' or 'quirky' expected, but '$1' found"
errInvalidExceptionSystem = "'goto', 'setjump', 'cpp' or 'quirky' expected, but '$1' found"
template warningOptionNoop(switch: string) =
warningDeprecated(conf, info, "'$#' is deprecated, now a noop" % switch)
@@ -251,7 +248,7 @@ template deprecatedAlias(oldName, newName: string) =
proc testCompileOptionArg*(conf: ConfigRef; switch, arg: string, info: TLineInfo): bool =
case switch.normalize
of "gc", "mm":
of "gc":
case arg.normalize
of "boehm": result = conf.selectedGC == gcBoehm
of "refc": result = conf.selectedGC == gcRefc
@@ -262,6 +259,7 @@ proc testCompileOptionArg*(conf: ConfigRef; switch, arg: string, info: TLineInfo
of "go": result = conf.selectedGC == gcGo
of "none": result = conf.selectedGC == gcNone
of "stack", "regions": result = conf.selectedGC == gcRegions
of "v2", "generational": warningOptionNoop(arg)
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
of "opt":
case arg.normalize
@@ -334,7 +332,6 @@ proc testCompileOption*(conf: ConfigRef; switch: string, info: TLineInfo): bool
result = contains(conf.options, optTrMacros)
of "excessivestacktrace": result = contains(conf.globalOptions, optExcessiveStackTrace)
of "nilseqs", "nilchecks", "taintmode": warningOptionNoop(switch)
of "panics": result = contains(conf.globalOptions, optPanics)
else: invalidCmdLineOption(conf, passCmd1, switch, info)
proc processPath(conf: ConfigRef; path: string, info: TLineInfo,
@@ -500,75 +497,6 @@ proc specialDefine(conf: ConfigRef, key: string; pass: TCmdLinePass) =
optOverflowCheck, optAssert, optStackTrace, optLineTrace, optLineDir}
conf.globalOptions.excl {optCDebug}
proc registerArcOrc(pass: TCmdLinePass, conf: ConfigRef, isOrc: bool) =
if isOrc:
conf.selectedGC = gcOrc
defineSymbol(conf.symbols, "gcorc")
else:
conf.selectedGC = gcArc
defineSymbol(conf.symbols, "gcarc")
defineSymbol(conf.symbols, "gcdestructors")
incl conf.globalOptions, optSeqDestructors
incl conf.globalOptions, optTinyRtti
if pass in {passCmd2, passPP}:
defineSymbol(conf.symbols, "nimSeqsV2")
defineSymbol(conf.symbols, "nimV2")
if conf.exc == excNone and conf.backend != backendCpp:
conf.exc = excGoto
proc unregisterArcOrc(conf: ConfigRef) =
undefSymbol(conf.symbols, "gcdestructors")
undefSymbol(conf.symbols, "gcarc")
undefSymbol(conf.symbols, "gcorc")
undefSymbol(conf.symbols, "nimSeqsV2")
undefSymbol(conf.symbols, "nimV2")
excl conf.globalOptions, optSeqDestructors
excl conf.globalOptions, optTinyRtti
proc processMemoryManagementOption(switch, arg: string, pass: TCmdLinePass,
info: TLineInfo; conf: ConfigRef) =
if conf.backend == backendJs: return # for: bug #16033
expectArg(conf, switch, arg, pass, info)
if pass in {passCmd2, passPP}:
case arg.normalize
of "boehm":
unregisterArcOrc(conf)
conf.selectedGC = gcBoehm
defineSymbol(conf.symbols, "boehmgc")
incl conf.globalOptions, optTlsEmulation # Boehm GC doesn't scan the real TLS
of "refc":
unregisterArcOrc(conf)
conf.selectedGC = gcRefc
of "markandsweep":
unregisterArcOrc(conf)
conf.selectedGC = gcMarkAndSweep
defineSymbol(conf.symbols, "gcmarkandsweep")
of "destructors", "arc":
registerArcOrc(pass, conf, false)
of "orc":
registerArcOrc(pass, conf, true)
of "hooks":
conf.selectedGC = gcHooks
defineSymbol(conf.symbols, "gchooks")
incl conf.globalOptions, optSeqDestructors
processOnOffSwitchG(conf, {optSeqDestructors}, arg, pass, info)
if pass in {passCmd2, passPP}:
defineSymbol(conf.symbols, "nimSeqsV2")
of "go":
unregisterArcOrc(conf)
conf.selectedGC = gcGo
defineSymbol(conf.symbols, "gogc")
of "none":
unregisterArcOrc(conf)
conf.selectedGC = gcNone
defineSymbol(conf.symbols, "nogc")
of "stack", "regions":
unregisterArcOrc(conf)
conf.selectedGC = gcRegions
defineSymbol(conf.symbols, "gcregions")
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
conf: ConfigRef) =
var
@@ -669,10 +597,59 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
of "project":
processOnOffSwitchG(conf, {optWholeProject, optGenIndex}, arg, pass, info)
of "gc":
warningDeprecated(conf, info, "`gc:option` is deprecated; use `mm:option` instead")
processMemoryManagementOption(switch, arg, pass, info, conf)
of "mm":
processMemoryManagementOption(switch, arg, pass, info, conf)
if conf.backend == backendJs: return # for: bug #16033
expectArg(conf, switch, arg, pass, info)
if pass in {passCmd2, passPP}:
case arg.normalize
of "boehm":
conf.selectedGC = gcBoehm
defineSymbol(conf.symbols, "boehmgc")
incl conf.globalOptions, optTlsEmulation # Boehm GC doesn't scan the real TLS
of "refc":
conf.selectedGC = gcRefc
of "markandsweep":
conf.selectedGC = gcMarkAndSweep
defineSymbol(conf.symbols, "gcmarkandsweep")
of "destructors", "arc":
conf.selectedGC = gcArc
defineSymbol(conf.symbols, "gcdestructors")
defineSymbol(conf.symbols, "gcarc")
incl conf.globalOptions, optSeqDestructors
incl conf.globalOptions, optTinyRtti
if pass in {passCmd2, passPP}:
defineSymbol(conf.symbols, "nimSeqsV2")
defineSymbol(conf.symbols, "nimV2")
if conf.exc == excNone and conf.backend != backendCpp:
conf.exc = excGoto
of "orc":
conf.selectedGC = gcOrc
defineSymbol(conf.symbols, "gcdestructors")
defineSymbol(conf.symbols, "gcorc")
incl conf.globalOptions, optSeqDestructors
incl conf.globalOptions, optTinyRtti
if pass in {passCmd2, passPP}:
defineSymbol(conf.symbols, "nimSeqsV2")
defineSymbol(conf.symbols, "nimV2")
if conf.exc == excNone and conf.backend != backendCpp:
conf.exc = excGoto
of "hooks":
conf.selectedGC = gcHooks
defineSymbol(conf.symbols, "gchooks")
incl conf.globalOptions, optSeqDestructors
processOnOffSwitchG(conf, {optSeqDestructors}, arg, pass, info)
if pass in {passCmd2, passPP}:
defineSymbol(conf.symbols, "nimSeqsV2")
of "go":
conf.selectedGC = gcGo
defineSymbol(conf.symbols, "gogc")
of "none":
conf.selectedGC = gcNone
defineSymbol(conf.symbols, "nogc")
of "stack", "regions":
conf.selectedGC = gcRegions
defineSymbol(conf.symbols, "gcregions")
of "v2": warningOptionNoop(arg)
else: localError(conf, info, errNoneBoehmRefcExpectedButXFound % arg)
of "warnings", "w":
if processOnOffSwitchOrList(conf, {optWarns}, arg, pass, info): listWarnings(conf)
of "warning": processSpecificNote(arg, wWarning, pass, info, switch, conf)
@@ -740,7 +717,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
of "linedir": processOnOffSwitch(conf, {optLineDir}, arg, pass, info)
of "assertions", "a": processOnOffSwitch(conf, {optAssert}, arg, pass, info)
of "threads":
if conf.backend == backendJs or conf.cmd == cmdNimscript: discard
if conf.backend == backendJs: discard
else: processOnOffSwitchG(conf, {optThreads}, arg, pass, info)
#if optThreads in conf.globalOptions: conf.setNote(warnGcUnsafe)
of "tlsemulation": processOnOffSwitchG(conf, {optTlsEmulation}, arg, pass, info)
@@ -908,9 +885,8 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
splitSwitch(conf, arg, key, val, pass, info)
os.putEnv(key, val)
of "cc":
if conf.backend != backendJs: # bug #19330
expectArg(conf, switch, arg, pass, info)
setCC(conf, arg, info)
expectArg(conf, switch, arg, pass, info)
setCC(conf, arg, info)
of "track":
expectArg(conf, switch, arg, pass, info)
track(conf, arg, info)
@@ -1051,10 +1027,6 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
defineSymbol(conf.symbols, "NimMajor", "1")
defineSymbol(conf.symbols, "NimMinor", "2")
conf.globalOptions.incl optNimV12Emulation
of "1.6":
defineSymbol(conf.symbols, "NimMajor", "1")
defineSymbol(conf.symbols, "NimMinor", "6")
conf.globalOptions.incl optNimV16Emulation
else:
localError(conf, info, "unknown Nim version; currently supported values are: `1.0`, `1.2`")
# always be compatible with 1.x.100:
@@ -1080,7 +1052,6 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
of "": # comes from "-" in for example: `nim c -r -` (gets stripped from -)
handleStdinInput(conf)
of "nilseqs", "nilchecks", "mainmodule", "m", "symbol", "taintmode", "cs", "deadcodeelim": warningOptionNoop(switch)
of "nimmainprefix": conf.nimMainPrefix = arg
else:
if strutils.find(switch, '.') >= 0: options.setConfigVar(conf, switch, arg)
else: invalidCmdLineOption(conf, pass, switch, info)
@@ -1117,8 +1088,6 @@ proc processArgument*(pass: TCmdLinePass; p: OptParser;
else:
if pass == passCmd1: config.commandArgs.add p.key
if argsCount == 1:
if p.key.endsWith(".nims"):
incl(config.globalOptions, optWasNimscript)
# support UNIX style filenames everywhere for portable build scripts:
if config.projectName.len == 0:
config.projectName = unixToNativePath(p.key)

View File

@@ -15,9 +15,6 @@ import ast, astalgo, semdata, lookups, lineinfos, idents, msgs, renderer, types,
from magicsys import addSonSkipIntLit
when defined(nimPreviewSlimSystem):
import std/assertions
const
logBindings = false

View File

@@ -138,5 +138,3 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimHasHintAll")
defineSymbol("nimHasTrace")
defineSymbol("nimHasEffectsOf")
defineSymbol("nimHasEnforceNoRaises")

View File

@@ -54,19 +54,3 @@ proc isCompilerDebug*(): bool =
{.undef(nimCompilerDebug).}
echo 'x'
conf0.isDefined("nimCompilerDebug")
proc enteringDebugSection*() {.exportc, dynlib.} =
## Provides a way for native debuggers to enable breakpoints, watchpoints, etc
## when code of interest is being compiled.
##
## Set your debugger to break on entering `nimCompilerIsEnteringDebugSection`
## and then execute a desired command.
discard
proc exitingDebugSection*() {.exportc, dynlib.} =
## Provides a way for native debuggers to disable breakpoints, watchpoints, etc
## when code of interest is no longer being compiled.
##
## Set your debugger to break on entering `exitingDebugSection`
## and then execute a desired command.
discard

View File

@@ -32,9 +32,6 @@
import ast, intsets, lineinfos, renderer
import std/private/asciitables
when defined(nimPreviewSlimSystem):
import std/assertions
type
InstrKind* = enum
goto, fork, def, use
@@ -608,11 +605,11 @@ proc aliases*(obj, field: PNode): AliasKind =
var n = n
while true:
case n.kind
of PathKinds0 - {nkDotExpr, nkBracketExpr}:
of PathKinds0 - {nkDotExpr, nkCheckedFieldExpr, nkBracketExpr}:
n = n[0]
of PathKinds1:
n = n[1]
of nkDotExpr, nkBracketExpr:
of nkDotExpr, nkCheckedFieldExpr, nkBracketExpr:
result.add n
n = n[0]
of nkSym:
@@ -645,6 +642,8 @@ proc aliases*(obj, field: PNode): AliasKind =
if currFieldPath.sym != currObjPath.sym: return no
of nkDotExpr:
if currFieldPath[1].sym != currObjPath[1].sym: return no
of nkCheckedFieldExpr:
if currFieldPath[0][1].sym != currObjPath[0][1].sym: return no
of nkBracketExpr:
if currFieldPath[1].kind in nkLiterals and currObjPath[1].kind in nkLiterals:
if currFieldPath[1].intVal != currObjPath[1].intVal:

View File

@@ -13,10 +13,10 @@
import
ast, strutils, strtabs, algorithm, sequtils, options, msgs, os, idents,
wordrecg, syntaxes, renderer, lexer,
packages/docutils/[rst, rstgen, dochelpers],
packages/docutils/rst, packages/docutils/rstgen,
json, xmltree, trees, types,
typesrenderer, astalgo, lineinfos, intsets,
pathutils, tables, nimpaths, renderverbatim, osproc, packages
pathutils, tables, nimpaths, renderverbatim, osproc
import packages/docutils/rstast except FileIndex, TLineInfo
from uri import encodeUrl
@@ -44,14 +44,8 @@ type
## runnableExamples).
substitutions: seq[string] ## Variable names in `doc.item`...
sortName: string ## The string used for sorting in output
info: rstast.TLineInfo ## place where symbol was defined (for messages)
anchor: string ## e.g. HTML anchor
name: string ## short name of the symbol, not unique
## (includes backticks ` if present)
detailedName: string ## longer name like `proc search(x: int): int`
ModSection = object ## Section like Procs, Types, etc.
secItems: Table[string, seq[Item]]
## Map basic name -> pre-processed items.
secItems: seq[Item] ## Pre-processed items.
finalMarkup: string ## The items, after RST pass 2 and rendering.
ModSections = array[TSymKind, ModSection]
TocItem = object ## HTML TOC item
@@ -97,22 +91,12 @@ type
thisDir*: AbsoluteDir
exampleGroups: OrderedTable[string, ExampleGroup]
wroteSupportFiles*: bool
nimToRstFid: Table[lineinfos.FileIndex, rstast.FileIndex]
## map Nim FileIndex -> RST one, it's needed because we keep them separate
PDoc* = ref TDocumentor ## Alias to type less.
proc add(dest: var ItemPre, rst: PRstNode) = dest.add ItemFragment(isRst: true, rst: rst)
proc add(dest: var ItemPre, str: string) = dest.add ItemFragment(isRst: false, str: str)
proc addRstFileIndex(d: PDoc, info: lineinfos.TLineInfo): rstast.FileIndex =
let invalid = rstast.FileIndex(-1)
result = d.nimToRstFid.getOrDefault(info.fileIndex, default = invalid)
if result == invalid:
let fname = toFullPath(d.conf, info)
result = addFilename(d.sharedState, fname)
d.nimToRstFid[info.fileIndex] = result
proc cmpDecimalsIgnoreCase(a, b: string): int =
## For sorting with correct handling of cases like 'uint8' and 'uint16'.
## Also handles leading zeros well (however note that leading zeros are
@@ -232,16 +216,13 @@ template declareClosures =
of meExpected: k = errXExpected
of meGridTableNotImplemented: k = errRstGridTableNotImplemented
of meMarkdownIllformedTable: k = errRstMarkdownIllformedTable
of meIllformedTable: k = errRstIllformedTable
of meNewSectionExpected: k = errRstNewSectionExpected
of meGeneralParseError: k = errRstGeneralParseError
of meInvalidDirective: k = errRstInvalidDirectiveX
of meInvalidField: k = errRstInvalidField
of meFootnoteMismatch: k = errRstFootnoteMismatch
of meSandboxedDirective: k = errRstSandboxedDirective
of mwRedefinitionOfLabel: k = warnRstRedefinitionOfLabel
of mwUnknownSubstitution: k = warnRstUnknownSubstitutionX
of mwAmbiguousLink: k = warnRstAmbiguousLink
of mwBrokenLink: k = warnRstBrokenLink
of mwUnsupportedLanguage: k = warnRstLanguageXNotSupported
of mwUnsupportedField: k = warnRstFieldXNotSupported
@@ -255,7 +236,7 @@ template declareClosures =
result = getCurrentDir() / s
if not fileExists(result): result = ""
proc parseRst(text: string,
proc parseRst(text, filename: string,
line, column: int,
conf: ConfigRef, sharedState: PRstSharedState): PRstNode =
declareClosures()
@@ -284,7 +265,7 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef,
result.cache = cache
result.outDir = conf.outDir.string
result.isPureRst = isPureRst
var options= {roSupportRawDirective, roSupportMarkdown, roPreferMarkdown, roSandboxDisabled}
var options= {roSupportRawDirective, roSupportMarkdown, roPreferMarkdown}
if not isPureRst: options.incl roNimFile
result.sharedState = newRstSharedState(
options, filename.string,
@@ -371,8 +352,7 @@ proc getVarIdx(varnames: openArray[string], id: string): int =
proc genComment(d: PDoc, n: PNode): PRstNode =
if n.comment.len > 0:
d.sharedState.currFileIdx = addRstFileIndex(d, n.info)
result = parseRst(n.comment,
result = parseRst(n.comment, toFullPath(d.conf, n.info),
toLinenumber(n.info),
toColumn(n.info) + DocColOffset,
d.conf, d.sharedState)
@@ -414,6 +394,9 @@ proc getPlainDocstring(n: PNode): string =
result = getPlainDocstring(n[i])
if result.len > 0: return
proc belongsToPackage(conf: ConfigRef; module: PSym): bool =
result = module.kind == skModule and module.getnimblePkgId == conf.mainPackageId
proc externalDep(d: PDoc; module: PSym): string =
if optWholeProject in d.conf.globalOptions or d.conf.docRoot.len > 0:
let full = AbsoluteFile toFullPath(d.conf, FileIndex module.position)
@@ -469,7 +452,7 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var string;
"\\spanIdentifier{$1}", [escLit, procLink])
elif s != nil and s.kind in {skType, skVar, skLet, skConst} and
sfExported in s.flags and s.owner != nil and
belongsToProjectPackage(d.conf, s.owner) and d.target == outHtml:
belongsToPackage(d.conf, s.owner) and d.target == outHtml:
let external = externalDep(d, s.owner)
result.addf "<a href=\"$1#$2\"><span class=\"Identifier\">$3</span></a>",
[changeFileExt(external, "html"), literal,
@@ -902,64 +885,6 @@ proc genSeeSrc(d: PDoc, path: string, line: int): string =
"path", path.string, "line", $line, "url", gitUrl,
"commit", commit, "devel", develBranch]])
proc symbolPriority(k: TSymKind): int =
result = case k
of skMacro: -3
of skTemplate: -2
of skIterator: -1
else: 0 # including skProc which have higher priority
# documentation itself has even higher priority 1
proc toLangSymbol(k: TSymKind, n: PNode, baseName: string): LangSymbol =
## Converts symbol info (names/types/parameters) in `n` into format
## `LangSymbol` convenient for ``rst.nim``/``dochelpers.nim``.
result.name = baseName.nimIdentNormalize
result.symKind = k.toHumanStr
if k in routineKinds:
var
paramTypes: seq[string]
renderParamTypes(paramTypes, n[paramsPos], toNormalize=true)
let paramNames = renderParamNames(n[paramsPos], toNormalize=true)
# In some rare cases (system.typeof) parameter type is not set for default:
doAssert paramTypes.len <= paramNames.len
for i in 0 ..< paramNames.len:
if i < paramTypes.len:
result.parameters.add (paramNames[i], paramTypes[i])
else:
result.parameters.add (paramNames[i], "")
result.parametersProvided = true
result.outType = renderOutType(n[paramsPos], toNormalize=true)
if k in {skProc, skFunc, skType, skIterator}:
# Obtain `result.generics`
# Use `n[miscPos]` since n[genericParamsPos] does not contain constraints
var genNode: PNode = nil
if k == skType:
genNode = n[1] # FIXME: what is index 1?
else:
if n[miscPos].kind != nkEmpty:
genNode = n[miscPos][1] # FIXME: what is index 1?
if genNode != nil:
var literal = ""
var r: TSrcGen
initTokRender(r, genNode, {renderNoBody, renderNoComments,
renderNoPragmas, renderNoProcDefs})
var kind = tkEof
while true:
getNextTok(r, kind, literal)
if kind == tkEof:
break
if kind != tkSpaces:
result.generics.add(literal.nimIdentNormalize)
if k == skType:
case n[2].kind
of nkEnumTy: result.symTypeKind = "enum"
of nkObjectTy: result.symTypeKind = "object"
of nkTupleTy: result.symTypeKind = "tuple"
else: discard
proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) =
if (docFlags != kForceExport) and not isVisible(d, nameNode): return
let
@@ -990,8 +915,6 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) =
inc(d.id)
let
plainNameEsc = esc(d.target, plainName.strip)
detailedName = k.toHumanStr & " " & (
if k in routineKinds: plainName else: name)
uniqueName = if k in routineKinds: plainNameEsc else: name
sortName = if k in routineKinds: plainName.strip else: name
cleanPlainSymbol = renderPlainSymbolName(nameNode)
@@ -1000,32 +923,20 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) =
symbolOrId = d.newUniquePlainSymbol(complexSymbol)
symbolOrIdEnc = encodeUrl(symbolOrId, usePlus = false)
deprecationMsg = genDeprecationMsg(d, pragmaNode)
rstLangSymbol = toLangSymbol(k, n, cleanPlainSymbol)
# we generate anchors automatically for subsequent use in doc comments
let lineinfo = rstast.TLineInfo(
line: nameNode.info.line, col: nameNode.info.col,
fileIndex: addRstFileIndex(d, nameNode.info))
addAnchorNim(d.sharedState, refn = symbolOrId, tooltip = detailedName,
rstLangSymbol, priority = symbolPriority(k), info = lineinfo)
nodeToHighlightedHtml(d, n, result, {renderNoBody, renderNoComments,
renderDocComments, renderSyms}, symbolOrIdEnc)
let seeSrc = genSeeSrc(d, toFullPath(d.conf, n.info), n.info.line.int)
d.section[k].secItems.mgetOrPut(cleanPlainSymbol, newSeq[Item]()).add Item(
d.section[k].secItems.add Item(
descRst: comm,
sortName: sortName,
info: lineinfo,
anchor: symbolOrId,
detailedName: detailedName,
name: name,
substitutions: @[
"uniqueName", uniqueName,
"name", name, "uniqueName", uniqueName,
"header", result, "itemID", $d.id,
"header_plain", plainNameEsc, "itemSym", cleanPlainSymbol,
"itemSymEnc", plainSymbolEnc,
"itemSymOrID", symbolOrId, "itemSymEnc", plainSymbolEnc,
"itemSymOrIDEnc", symbolOrIdEnc, "seeSrc", seeSrc,
"deprecationMsg", deprecationMsg])
@@ -1129,7 +1040,7 @@ proc traceDeps(d: PDoc, it: PNode) =
for x in it[2]:
a[2] = x
traceDeps(d, a)
elif it.kind == nkSym and belongsToProjectPackage(d.conf, it.sym):
elif it.kind == nkSym and belongsToPackage(d.conf, it.sym):
let external = externalDep(d, it.sym)
if d.section[k].finalMarkup != "": d.section[k].finalMarkup.add(", ")
dispA(d.conf, d.section[k].finalMarkup,
@@ -1139,7 +1050,7 @@ proc traceDeps(d: PDoc, it: PNode) =
proc exportSym(d: PDoc; s: PSym) =
const k = exportSection
if s.kind == skModule and belongsToProjectPackage(d.conf, s):
if s.kind == skModule and belongsToPackage(d.conf, s):
let external = externalDep(d, s)
if d.section[k].finalMarkup != "": d.section[k].finalMarkup.add(", ")
dispA(d.conf, d.section[k].finalMarkup,
@@ -1148,7 +1059,7 @@ proc exportSym(d: PDoc; s: PSym) =
changeFileExt(external, "html")])
elif s.kind != skModule and s.owner != nil:
let module = originatingModule(s)
if belongsToProjectPackage(d.conf, module):
if belongsToPackage(d.conf, module):
let
complexSymbol = complexName(s.kind, s.ast, s.name.s)
symbolOrId = d.newUniquePlainSymbol(complexSymbol)
@@ -1273,11 +1184,6 @@ proc generateDoc*(d: PDoc, n, orig: PNode, docFlags: DocFlags = kDefault) =
if comm.len != 0: d.modDescPre.add(comm)
else: discard
proc overloadGroupName(s: string, k: TSymKind): string =
## Turns a name like `f` into anchor `f-procs-all`
#s & " " & k.toHumanStr & "s all"
s & "-" & k.toHumanStr & "s-all"
proc finishGenerateDoc*(d: var PDoc) =
## Perform 2nd RST pass for resolution of links/footnotes/headings...
# copy file map `filenames` to ``rstgen.nim`` for its warnings
@@ -1291,22 +1197,6 @@ proc finishGenerateDoc*(d: var PDoc) =
break
preparePass2(d.sharedState, firstRst)
# add anchors to overload groups before RST resolution
for k in TSymKind:
if k in routineKinds:
for plainName, overloadChoices in d.section[k].secItems:
if overloadChoices.len > 1:
let refn = overloadGroupName(plainName, k)
let tooltip = "$1 ($2 overloads)" % [
k.toHumanStr & " " & plainName, $overloadChoices.len]
addAnchorNim(d.sharedState, refn, tooltip,
LangSymbol(symKind: k.toHumanStr,
name: nimIdentBackticksNormalize(plainName),
isGroup: true),
priority = symbolPriority(k),
# select index `0` just to have any meaningful warning:
info = overloadChoices[0].info)
# Finalize fragments of ``.nim`` or ``.rst`` file
proc renderItemPre(d: PDoc, fragments: ItemPre, result: var string) =
for f in fragments:
@@ -1317,33 +1207,14 @@ proc finishGenerateDoc*(d: var PDoc) =
of false: result &= f.str
proc cmp(x, y: Item): int = cmpDecimalsIgnoreCase(x.sortName, y.sortName)
for k in TSymKind:
# add symbols to section for each `k`, while optionally wrapping
# overloadable items with the same basic name by ``doc.item2``
let overloadableNames = toSeq(keys(d.section[k].secItems))
for plainName in overloadableNames.sorted(cmpDecimalsIgnoreCase):
var overloadChoices = d.section[k].secItems[plainName]
overloadChoices.sort(cmp)
var nameContent = ""
for item in overloadChoices:
var itemDesc: string
renderItemPre(d, item.descRst, itemDesc)
nameContent.add(
getConfigVar(d.conf, "doc.item") % (
item.substitutions & @[
"desc", itemDesc,
"name", item.name,
"itemSymOrID", item.anchor]))
if k in routineKinds:
let plainNameEsc1 = esc(d.target, plainName.strip)
let plainNameEsc2 = esc(d.target, plainName.strip, escMode=emUrl)
d.section[k].finalMarkup.add(
getConfigVar(d.conf, "doc.item2") % (
@["header_plain", plainNameEsc1,
"overloadGroupName", overloadGroupName(plainNameEsc2, k),
"content", nameContent]))
else:
d.section[k].finalMarkup.add(nameContent)
d.section[k].secItems.clear
for item in d.section[k].secItems.sorted(cmp):
var itemDesc: string
renderItemPre(d, item.descRst, itemDesc)
d.section[k].finalMarkup.add(
getConfigVar(d.conf, "doc.item") % (
item.substitutions & @["desc", itemDesc]))
itemDesc = ""
d.section[k].secItems.setLen 0
renderItemPre(d, d.modDescPre, d.modDescFinal)
d.modDescPre.setLen 0
d.hasToc = d.hasToc or d.sharedState.hasToc
@@ -1497,10 +1368,7 @@ proc genOutFile(d: PDoc, groupedToc = false): string =
# Extract the title. Non API modules generate an entry in the index table.
if d.meta[metaTitle].len != 0:
title = d.meta[metaTitle]
let external = AbsoluteFile(d.destFile)
.relativeTo(d.conf.outDir, '/')
.changeFileExt(HtmlExt)
.string
let external = presentationPath(d.conf, AbsoluteFile d.filename).changeFileExt(HtmlExt).string.nativeToUnixPath
setIndexTerm(d[], external, "", title)
else:
# Modules get an automatic title for the HTML, but no entry in the index.
@@ -1574,11 +1442,7 @@ proc writeOutput*(d: PDoc, useWarning = false, groupedToc = false) =
outfile.string)
if not d.wroteSupportFiles: # nimdoc.css + dochack.js
let nimr = $d.conf.getPrefixDir()
case d.target
of outHtml:
copyFile(docCss.interp(nimr = nimr), $d.conf.outDir / nimdocOutCss)
of outLatex:
copyFile(docCls.interp(nimr = nimr), $d.conf.outDir / nimdocOutCls)
copyFile(docCss.interp(nimr = nimr), $d.conf.outDir / nimdocOutCss)
if optGenIndex in d.conf.globalOptions:
let docHackJs2 = getDocHacksJs(nimr, nim = getAppFilename())
copyFile(docHackJs2, $d.conf.outDir / docHackJs2.lastPathPart)
@@ -1629,7 +1493,7 @@ proc commandRstAux(cache: IdentCache, conf: ConfigRef;
filename: AbsoluteFile, outExt: string) =
var filen = addFileExt(filename, "txt")
var d = newDocumentor(filen, cache, conf, outExt, isPureRst = true)
let rst = parseRst(readFile(filen.string),
let rst = parseRst(readFile(filen.string), filen.string,
line=LineRstInit, column=ColRstInit,
conf, d.sharedState)
d.modDescPre = @[ItemFragment(isRst: true, rst: rst)]

View File

@@ -11,7 +11,7 @@
# semantic checking.
import
options, ast, msgs, passes, docgen, lineinfos, pathutils, packages
options, ast, msgs, passes, docgen, lineinfos, pathutils
from modulegraphs import ModuleGraph, PPassContext
@@ -23,7 +23,7 @@ type
PGen = ref TGen
proc shouldProcess(g: PGen): bool =
(optWholeProject in g.doc.conf.globalOptions and g.doc.conf.belongsToProjectPackage(g.module)) or
(optWholeProject in g.doc.conf.globalOptions and g.module.getnimblePkgId == g.doc.conf.mainPackageId) or
sfMainModule in g.module.flags or g.config.projectMainIdx == g.module.info.fileIndex
template closeImpl(body: untyped) {.dirty.} =

View File

@@ -1,10 +1,6 @@
import ast, idents, lineinfos, modulegraphs, magicsys
when defined(nimPreviewSlimSystem):
import std/assertions
proc genEnumToStrProc*(t: PType; info: TLineInfo; g: ModuleGraph; idgen: IdGenerator): PSym =
result = newSym(skProc, getIdent(g.cache, "$"), nextSymId idgen, t.owner, info)

View File

@@ -12,9 +12,6 @@
import ast, renderer, options, strutils, types
when defined(nimPreviewSlimSystem):
import std/assertions
type
ErrorKind* = enum ## expand as you need.
RawTypeMismatchError

View File

@@ -12,13 +12,10 @@
# from a lineinfos file, to provide generalized procedures to compile
# nim files.
import ropes, platform, condsyms, options, msgs, lineinfos, pathutils, modulepaths
import ropes, platform, condsyms, options, msgs, lineinfos, pathutils
import std/[os, strutils, osproc, sha1, streams, sequtils, times, strtabs, json, jsonutils, sugar]
when defined(nimPreviewSlimSystem):
import std/syncio
type
TInfoCCProp* = enum # properties of the C compiler:
hasSwitchRange, # CC allows ranges in switch statements (GNU C)
@@ -370,7 +367,6 @@ proc initVars*(conf: ConfigRef) =
proc completeCfilePath*(conf: ConfigRef; cfile: AbsoluteFile,
createSubDir: bool = true): AbsoluteFile =
## Generate the absolute file path to the generated modules.
result = completeGeneratedFilePath(conf, cfile, createSubDir)
proc toObjFile*(conf: ConfigRef; filename: AbsoluteFile): AbsoluteFile =
@@ -381,7 +377,7 @@ proc addFileToCompile*(conf: ConfigRef; cf: Cfile) =
conf.toCompile.add(cf)
proc addLocalCompileOption*(conf: ConfigRef; option: string; nimfile: AbsoluteFile) =
let key = completeCfilePath(conf, mangleModuleName(conf, nimfile).AbsoluteFile).string
let key = completeCfilePath(conf, withPackageName(conf, nimfile)).string
var value = conf.cfileSpecificOptions.getOrDefault(key)
if strutils.find(value, option, 0) < 0:
addOpt(value, option)
@@ -434,13 +430,7 @@ proc noAbsolutePaths(conf: ConfigRef): bool {.inline.} =
# really: Cross compilation from Linux to Linux for example is entirely
# reasonable.
# `optGenMapping` is included here for niminst.
# We use absolute paths for vcc / cl, see issue #19883.
let options =
if conf.cCompiler == ccVcc:
{optGenMapping}
else:
{optGenScript, optGenMapping}
result = conf.globalOptions * options != {}
result = conf.globalOptions * {optGenScript, optGenMapping} != {}
proc cFileSpecificOptions(conf: ConfigRef; nimname, fullNimFile: string): string =
result = conf.compileOptions
@@ -644,7 +634,7 @@ proc footprint(conf: ConfigRef; cfile: Cfile): SecureHash =
proc externalFileChanged(conf: ConfigRef; cfile: Cfile): bool =
if conf.backend == backendJs: return false # pre-existing behavior, but not sure it's good
let hashFile = toGeneratedFile(conf, conf.mangleModuleName(cfile.cname).AbsoluteFile, "sha1")
let hashFile = toGeneratedFile(conf, conf.withPackageName(cfile.cname), "sha1")
let currentHash = footprint(conf, cfile)
var f: File
if open(f, hashFile.string, fmRead):
@@ -659,10 +649,8 @@ proc externalFileChanged(conf: ConfigRef; cfile: Cfile): bool =
close(f)
proc addExternalFileToCompile*(conf: ConfigRef; c: var Cfile) =
# we want to generate the hash file unconditionally
let extFileChanged = externalFileChanged(conf, c)
if optForceFullMake notin conf.globalOptions and fileExists(c.obj) and
not extFileChanged:
not externalFileChanged(conf, c):
c.flags.incl CfileFlag.Cached
else:
# make sure Nim keeps recompiling the external file on reruns
@@ -852,9 +840,9 @@ proc hcrLinkTargetName(conf: ConfigRef, objFile: string, isMain = false): Absolu
proc displayProgressCC(conf: ConfigRef, path, compileCmd: string): string =
if conf.hasHint(hintCC):
if optListCmd in conf.globalOptions or conf.verbosity > 1:
result = MsgKindToStr[hintCC] % (demangleModuleName(path.splitFile.name) & ": " & compileCmd)
result = MsgKindToStr[hintCC] % (demanglePackageName(path.splitFile.name) & ": " & compileCmd)
else:
result = MsgKindToStr[hintCC] % demangleModuleName(path.splitFile.name)
result = MsgKindToStr[hintCC] % demanglePackageName(path.splitFile.name)
proc callCCompiler*(conf: ConfigRef) =
var
@@ -927,7 +915,7 @@ proc callCCompiler*(conf: ConfigRef) =
objfiles.add(' ')
objfiles.add(quoteShell(objFile))
let mainOutput = if optGenScript notin conf.globalOptions: conf.prepareToWriteOutput
else: AbsoluteFile(conf.outFile)
else: AbsoluteFile(conf.projectName)
linkCmd = getLinkCmd(conf, mainOutput, objfiles, removeStaticFile = true)
extraCmds = getExtraCmds(conf, mainOutput)

View File

@@ -12,9 +12,6 @@
import msgs, std / sha1, os, osproc, streams, options,
lineinfos, pathutils
when defined(nimPreviewSlimSystem):
import std/syncio
proc readOutput(p: Process): (string, int) =
result[0] = ""
var output = p.outputStream

View File

@@ -12,9 +12,6 @@
import ast, astalgo, msgs, magicsys, nimsets, trees, types, renderer, idents,
saturate, modulegraphs, options, lineinfos, int128
when defined(nimPreviewSlimSystem):
import std/assertions
const
someEq = {mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc,
mEqStr, mEqSet, mEqCString}

View File

@@ -9,9 +9,6 @@
# This include implements the high level optimization pass.
when defined(nimPreviewSlimSystem):
import std/assertions
proc hlo(c: PContext, n: PNode): PNode
proc evalPattern(c: PContext, n, orig: PNode): PNode =

View File

@@ -3,9 +3,6 @@
import hashes, rodfiles
when defined(nimPreviewSlimSystem):
import std/assertions
type
LitId* = distinct uint32

View File

@@ -20,11 +20,8 @@
import std/packedsets, algorithm, tables
when defined(nimPreviewSlimSystem):
import std/assertions
import ".."/[ast, options, lineinfos, modulegraphs, cgendata, cgen,
pathutils, extccomp, msgs, modulepaths]
pathutils, extccomp, msgs]
import packed_ast, ic, dce, rodfiles
@@ -64,8 +61,7 @@ proc addFileToLink(config: ConfigRef; m: PSym) =
if config.backend == backendCpp: ".nim.cpp"
elif config.backend == backendObjc: ".nim.m"
else: ".nim.c"
let cfile = changeFileExt(completeCfilePath(config,
mangleModuleName(config, filename).AbsoluteFile), ext)
let cfile = changeFileExt(completeCfilePath(config, withPackageName(config, filename)), ext)
let objFile = completeCfilePath(config, toObjFile(config, cfile))
if fileExists(objFile):
var cf = Cfile(nimname: m.name.s, cname: cfile,

View File

@@ -10,10 +10,6 @@
## Dead code elimination (=DCE) for IC.
import std/[intsets, tables]
when defined(nimPreviewSlimSystem):
import std/assertions
import ".." / [ast, options, lineinfos, types]
import packed_ast, ic, bitabs

View File

@@ -10,13 +10,10 @@
import hashes, tables, intsets, std/sha1
import packed_ast, bitabs, rodfiles
import ".." / [ast, idents, lineinfos, msgs, ropes, options,
pathutils, condsyms, packages, modulepaths]
pathutils, condsyms]
#import ".." / [renderer, astalgo]
from os import removeFile, isAbsolute
when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
type
PackedConfig* = object
backend: TBackend
@@ -551,10 +548,6 @@ proc loadError(err: RodFileError; filename: AbsoluteFile; config: ConfigRef;) =
rawMessage(config, warnCannotOpenFile, filename.string & " reason: " & $err)
#echo "Error: ", $err, " loading file: ", filename.string
proc toRodFile*(conf: ConfigRef; f: AbsoluteFile; ext = RodExt): AbsoluteFile =
result = changeFileExt(completeGeneratedFilePath(conf,
mangleModuleName(conf, f).AbsoluteFile), ext)
proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef;
ignoreConfig = false): RodFileError =
var f = rodfiles.open(filename.string)
@@ -934,6 +927,17 @@ proc loadType(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int; t
result = g[si].types[t.item]
assert result.itemId.item > 0
proc newPackage(config: ConfigRef; cache: IdentCache; fileIdx: FileIndex): PSym =
let filename = AbsoluteFile toFullPath(config, fileIdx)
let name = getIdent(cache, splitFile(filename).name)
let info = newLineInfo(fileIdx, 1, 1)
let
pck = getPackageName(config, filename.string)
pck2 = if pck.len > 0: pck else: "unknown"
pack = getIdent(cache, pck2)
result = newSym(skPackage, getIdent(cache, pck2),
ItemId(module: PackageModuleId, item: int32(fileIdx)), nil, info)
proc setupLookupTables(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
fileIdx: FileIndex; m: var LoadedModule) =
m.iface = initTable[PIdent, seq[PackedItemId]]()
@@ -961,7 +965,7 @@ proc setupLookupTables(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCa
name: getIdent(cache, splitFile(filename).name),
info: newLineInfo(fileIdx, 1, 1),
position: int(fileIdx))
m.module.owner = getPackage(conf, cache, fileIdx)
m.module.owner = newPackage(conf, cache, fileIdx)
m.module.flags = m.fromDisk.moduleFlags
proc loadToReplayNodes(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;

View File

@@ -11,10 +11,6 @@
## The set must cover a complete Nim project.
import sets
when defined(nimPreviewSlimSystem):
import std/assertions
import ".." / [ast, modulegraphs]
import packed_ast, bitabs, ic

View File

@@ -16,9 +16,6 @@ import sets
from os import nil
from std/private/miscdollars import toLocation
when defined(nimPreviewSlimSystem):
import std/assertions
import ".." / [ast, modulegraphs, msgs, options]
import packed_ast, bitabs, ic

View File

@@ -16,9 +16,6 @@ import hashes, tables, strtabs
import bitabs
import ".." / [ast, options]
when defined(nimPreviewSlimSystem):
import std/assertions
type
SymId* = distinct int32
ModuleId* = distinct int32

View File

@@ -16,9 +16,6 @@ import ".." / [ast, modulegraphs, trees, extccomp, btrees,
import tables
when defined(nimPreviewSlimSystem):
import std/assertions
import packed_ast, ic, bitabs
proc replayStateChanges*(module: PSym; g: ModuleGraph) =

View File

@@ -16,9 +16,6 @@
from typetraits import supportsCopyMem
when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
## Overview
## ========
## `RodFile` represents a Rod File (versioned binary format), and the

View File

@@ -14,9 +14,6 @@
import
hashes, wordrecg
when defined(nimPreviewSlimSystem):
import std/assertions
type
PIdent* = ref TIdent
TIdent*{.acyclic.} = object

View File

@@ -15,9 +15,6 @@ import
modulegraphs, wordrecg, tables
from strutils import `%`
when defined(nimPreviewSlimSystem):
import std/assertions
proc readExceptSet*(c: PContext, n: PNode): IntSet =
assert n.kind in {nkImportExceptStmt, nkExportExceptStmt}
result = initIntSet()
@@ -188,13 +185,11 @@ template addUnnamedIt(c: PContext, fromMod: PSym; filter: untyped) {.dirty.} =
for it in mitems c.graph.ifaces[fromMod.position].converters:
if filter:
loadPackedSym(c.graph, it)
if sfExported in it.sym.flags:
addConverter(c, it)
addConverter(c, it)
for it in mitems c.graph.ifaces[fromMod.position].patterns:
if filter:
loadPackedSym(c.graph, it)
if sfExported in it.sym.flags:
addPattern(c, it)
addPattern(c, it)
for it in mitems c.graph.ifaces[fromMod.position].pureEnums:
if filter:
loadPackedSym(c.graph, it)
@@ -202,7 +197,7 @@ template addUnnamedIt(c: PContext, fromMod: PSym; filter: untyped) {.dirty.} =
proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: IntSet) =
c.addImport ImportedModule(m: fromMod, mode: importExcept, exceptSet: exceptSet)
addUnnamedIt(c, fromMod, it.sym.name.id notin exceptSet)
addUnnamedIt(c, fromMod, it.sym.id notin exceptSet)
proc importAllSymbols*(c: PContext, fromMod: PSym) =
c.addImport ImportedModule(m: fromMod, mode: importAll)

View File

@@ -19,9 +19,6 @@ import
lineinfos, parampatterns, sighashes, liftdestructors, optimizer,
varpartitions
when defined(nimPreviewSlimSystem):
import std/assertions
from trees import exprStructuralEquivalent, getRoot
type

View File

@@ -5,9 +5,6 @@
from math import trunc
when defined(nimPreviewSlimSystem):
import std/assertions
type
Int128* = object
udata: array[4, uint32]

View File

@@ -13,9 +13,6 @@
import
ast, types, renderer, intsets
when defined(nimPreviewSlimSystem):
import std/assertions
proc canAlias(arg, ret: PType; marker: var IntSet): bool
proc canAliasN(arg: PType; n: PNode; marker: var IntSet): bool =
@@ -74,23 +71,12 @@ proc isValueOnlyType(t: PType): bool =
proc canAlias*(arg, ret: PType): bool =
if isValueOnlyType(arg):
# can alias only with addr(arg.x) and we don't care if it is not safe
# can alias only with unsafeAddr(arg.x) and we don't care if it is not safe
result = false
else:
var marker = initIntSet()
result = canAlias(arg, ret, marker)
proc containsVariable(n: PNode): bool =
case n.kind
of nodesToIgnoreSet:
result = false
of nkSym:
result = n.sym.kind in {skForVar, skParam, skVar, skLet, skConst, skResult, skTemp}
else:
for ch in n:
if containsVariable(ch): return true
result = false
proc checkIsolate*(n: PNode): bool =
if types.containsTyRef(n.typ):
# XXX Maybe require that 'n.typ' is acyclic. This is not much
@@ -110,11 +96,7 @@ proc checkIsolate*(n: PNode): bool =
else:
let argType = n[i].typ
if argType != nil and not isCompileTimeOnly(argType) and containsTyRef(argType):
if argType.canAlias(n.typ) or containsVariable(n[i]):
# bug #19013: Alias information is not enough, we need to check for potential
# "overlaps". I claim the problem can only happen by reading again from a location
# that materialized which is only possible if a variable that contains a `ref`
# is involved.
if argType.canAlias(n.typ):
return false
result = true
of nkIfStmt, nkIfExpr:

View File

@@ -178,7 +178,7 @@ const
proc mapType(typ: PType): TJSTypeKind =
let t = skipTypes(typ, abstractInst)
case t.kind
of tyVar, tyRef, tyPtr:
of tyVar, tyRef, tyPtr, tyLent:
if skipTypes(t.lastSon, abstractInst).kind in MappedToObject:
result = etyObject
else:
@@ -186,8 +186,7 @@ proc mapType(typ: PType): TJSTypeKind =
of tyPointer:
# treat a tyPointer like a typed pointer to an array of bytes
result = etyBaseIndex
of tyRange, tyDistinct, tyOrdinal, tyProxy, tyLent:
# tyLent is no-op as JS has pass-by-reference semantics
of tyRange, tyDistinct, tyOrdinal, tyProxy:
result = mapType(t[0])
of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt
of tyBool: result = etyBool
@@ -771,6 +770,9 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
if catchBranchesExist:
p.body.add("++excHandler;\L")
var tmpFramePtr = rope"F"
if optStackTrace notin p.options:
tmpFramePtr = p.getTemp(true)
line(p, tmpFramePtr & " = framePtr;\L")
lineF(p, "try {$n", [])
var a: TCompRes
gen(p, n[0], a)
@@ -779,8 +781,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
if catchBranchesExist:
p.body.addf("--excHandler;$n} catch (EXCEPTION) {$n var prevJSError = lastJSError;$n" &
" lastJSError = EXCEPTION;$n --excHandler;$n", [])
if hasFrameInfo(p):
line(p, "framePtr = $1;$n" % [tmpFramePtr])
line(p, "framePtr = $1;$n" % [tmpFramePtr])
while i < n.len and n[i].kind == nkExceptBranch:
if n[i].len == 1:
# general except section:
@@ -839,8 +840,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
line(p, "}\L")
lineF(p, "lastJSError = prevJSError;$n")
line(p, "} finally {\L")
if hasFrameInfo(p):
line(p, "framePtr = $1;$n" % [tmpFramePtr])
line(p, "framePtr = $1;$n" % [tmpFramePtr])
if i < n.len and n[i].kind == nkFinally:
genStmt(p, n[i][0])
line(p, "}\L")
@@ -1060,14 +1060,14 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
xtyp = etySeq
case xtyp
of etySeq:
if x.typ.kind in {tyVar, tyLent} or (needsNoCopy(p, y) and needsNoCopy(p, x)) or noCopyNeeded:
if (needsNoCopy(p, y) and needsNoCopy(p, x)) or noCopyNeeded:
lineF(p, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
else:
useMagic(p, "nimCopy")
lineF(p, "$1 = nimCopy(null, $2, $3);$n",
[a.rdLoc, b.res, genTypeInfo(p, y.typ)])
of etyObject:
if x.typ.kind in {tyVar, tyLent} or (needsNoCopy(p, y) and needsNoCopy(p, x)) or noCopyNeeded:
if x.typ.kind in {tyVar} or (needsNoCopy(p, y) and needsNoCopy(p, x)) or noCopyNeeded:
lineF(p, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
else:
useMagic(p, "nimCopy")
@@ -1092,18 +1092,10 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
lineF(p, "$# = [$#, $#];$n", [a.res, b.address, b.res])
lineF(p, "$1 = $2;$n", [a.address, b.res])
lineF(p, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
elif a.typ == etyBaseIndex:
# array indexing may not map to var type
if b.address != nil:
lineF(p, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
else:
lineF(p, "$1 = $2;$n", [a.address, b.res])
else:
internalError(p.config, x.info, $("genAsgn", b.typ, a.typ))
elif b.address != nil:
lineF(p, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
else:
lineF(p, "$1 = $2;$n", [a.address, b.res])
lineF(p, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
else:
lineF(p, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
@@ -1296,89 +1288,75 @@ template isIndirect(x: PSym): bool =
v.kind notin {skProc, skFunc, skConverter, skMethod, skIterator,
skConst, skTemp, skLet})
proc genSymAddr(p: PProc, n: PNode, typ: PType, r: var TCompRes) =
let s = n.sym
if s.loc.r == nil: internalError(p.config, n.info, "genAddr: 3")
case s.kind
of skParam:
r.res = s.loc.r
r.address = nil
r.typ = etyNone
of skVar, skLet, skResult:
r.kind = resExpr
let jsType = mapType(p):
if typ.isNil:
n.typ
else:
typ
if jsType == etyObject:
# make addr() a no-op:
r.typ = etyNone
if isIndirect(s):
r.res = s.loc.r & "[0]"
else:
r.res = s.loc.r
r.address = nil
elif {sfGlobal, sfAddrTaken} * s.flags != {} or jsType == etyBaseIndex:
# for ease of code generation, we do not distinguish between
# sfAddrTaken and sfGlobal.
r.typ = etyBaseIndex
r.address = s.loc.r
r.res = rope("0")
else:
# 'var openArray' for instance produces an 'addr' but this is harmless:
gen(p, n, r)
#internalError(p.config, n.info, "genAddr: 4 " & renderTree(n))
else: internalError(p.config, n.info, $("genAddr: 2", s.kind))
proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
if n.kind == nkSym:
genSymAddr(p, n, nil, r)
else:
case n[0].kind
of nkSym:
genSymAddr(p, n[0], n.typ, r)
of nkCheckedFieldExpr:
genCheckedFieldOp(p, n[0], n.typ, r)
of nkDotExpr:
if mapType(p, n.typ) == etyBaseIndex:
genFieldAddr(p, n[0], r)
case n[0].kind
of nkSym:
let s = n[0].sym
if s.loc.r == nil: internalError(p.config, n.info, "genAddr: 3")
case s.kind
of skParam:
r.res = s.loc.r
r.address = nil
r.typ = etyNone
of skVar, skLet, skResult:
r.kind = resExpr
let jsType = mapType(p, n.typ)
if jsType == etyObject:
# make addr() a no-op:
r.typ = etyNone
if isIndirect(s):
r.res = s.loc.r & "[0]"
else:
r.res = s.loc.r
r.address = nil
elif {sfGlobal, sfAddrTaken} * s.flags != {} or jsType == etyBaseIndex:
# for ease of code generation, we do not distinguish between
# sfAddrTaken and sfGlobal.
r.typ = etyBaseIndex
r.address = s.loc.r
r.res = rope("0")
else:
genFieldAccess(p, n[0], r)
of nkBracketExpr:
var ty = skipTypes(n[0].typ, abstractVarRange)
if ty.kind in MappedToObject:
gen(p, n[0], r)
else:
let kindOfIndexedExpr = skipTypes(n[0][0].typ, abstractVarRange).kind
case kindOfIndexedExpr
of tyArray, tyOpenArray, tySequence, tyString, tyCstring, tyVarargs:
genArrayAddr(p, n[0], r)
of tyTuple:
genFieldAddr(p, n[0], r)
of tyGenericBody:
genAddr(p, n[^1], r)
else: internalError(p.config, n[0].info, "expr(nkBracketExpr, " & $kindOfIndexedExpr & ')')
of nkObjDownConv:
gen(p, n[0], r)
of nkHiddenDeref:
gen(p, n[0], r)
of nkHiddenAddr:
gen(p, n[0], r)
of nkConv:
genAddr(p, n[0], r)
of nkStmtListExpr:
if n.len == 1: gen(p, n[0], r)
else: internalError(p.config, n[0].info, "genAddr for complex nkStmtListExpr")
of nkCallKinds:
if n[0].typ.kind == tyOpenArray:
# 'var openArray' for instance produces an 'addr' but this is harmless:
# namely toOpenArray(a, 1, 3)
gen(p, n[0], r)
else:
internalError(p.config, n[0].info, "genAddr: " & $n[0].kind)
#internalError(p.config, n.info, "genAddr: 4 " & renderTree(n))
else: internalError(p.config, n.info, $("genAddr: 2", s.kind))
of nkCheckedFieldExpr:
genCheckedFieldOp(p, n[0], n.typ, r)
of nkDotExpr:
if mapType(p, n.typ) == etyBaseIndex:
genFieldAddr(p, n[0], r)
else:
genFieldAccess(p, n[0], r)
of nkBracketExpr:
var ty = skipTypes(n[0].typ, abstractVarRange)
if ty.kind in MappedToObject:
gen(p, n[0], r)
else:
let kindOfIndexedExpr = skipTypes(n[0][0].typ, abstractVarRange).kind
case kindOfIndexedExpr
of tyArray, tyOpenArray, tySequence, tyString, tyCstring, tyVarargs:
genArrayAddr(p, n[0], r)
of tyTuple:
genFieldAddr(p, n[0], r)
else: internalError(p.config, n[0].info, "expr(nkBracketExpr, " & $kindOfIndexedExpr & ')')
of nkObjDownConv:
gen(p, n[0], r)
of nkHiddenDeref:
gen(p, n[0], r)
of nkHiddenAddr:
gen(p, n[0], r)
of nkStmtListExpr:
if n.len == 1: gen(p, n[0], r)
else: internalError(p.config, n[0].info, "genAddr for complex nkStmtListExpr")
of nkCallKinds:
if n[0].typ.kind == tyOpenArray:
# 'var openArray' for instance produces an 'addr' but this is harmless:
# namely toOpenArray(a, 1, 3)
gen(p, n[0], r)
else:
internalError(p.config, n[0].info, "genAddr: " & $n[0].kind)
else:
internalError(p.config, n[0].info, "genAddr: " & $n[0].kind)
proc attachProc(p: PProc; content: Rope; s: PSym) =
p.g.code.add(content)
@@ -1464,17 +1442,13 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) =
else:
if s.loc.r == nil:
internalError(p.config, n.info, "symbol has no generated name: " & s.name.s)
if mapType(p, s.typ) == etyBaseIndex:
r.address = s.loc.r
r.res = s.loc.r & "_Idx"
else:
r.res = s.loc.r
r.res = s.loc.r
r.kind = resVal
proc genDeref(p: PProc, n: PNode, r: var TCompRes) =
let it = n[0]
let t = mapType(p, it.typ)
if t == etyObject or it.typ.kind == tyLent:
if t == etyObject:
gen(p, it, r)
else:
var a: TCompRes
@@ -1715,7 +1689,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
result = putToSeq("0", indirect)
of tyFloat..tyFloat128:
result = putToSeq("0.0", indirect)
of tyRange, tyGenericInst, tyAlias, tySink, tyOwned, tyLent:
of tyRange, tyGenericInst, tyAlias, tySink, tyOwned:
result = createVar(p, lastSon(typ), indirect)
of tySet:
result = putToSeq("{}", indirect)
@@ -1757,7 +1731,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
createObjInitList(p, t, initIntSet(), initList)
result = ("({$1})") % [initList]
if indirect: result = "[$1]" % [result]
of tyVar, tyPtr, tyRef, tyPointer:
of tyVar, tyPtr, tyLent, tyRef, tyPointer:
if mapType(p, t) == etyBaseIndex:
result = putToSeq("[null, 0]", indirect)
else:
@@ -2392,7 +2366,6 @@ proc optionalLine(p: Rope): Rope =
return p & "\L"
proc genProc(oldProc: PProc, prc: PSym): Rope =
## Generate a JS procedure ('function').
var
resultSym: PSym
a: TCompRes
@@ -2407,17 +2380,16 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
if prc.typ[0] != nil and sfPure notin prc.flags:
resultSym = prc.ast[resultPos].sym
let mname = mangleName(p.module, resultSym)
let returnAddress = not isIndirect(resultSym) and
if not isIndirect(resultSym) and
resultSym.typ.kind in {tyVar, tyPtr, tyLent, tyRef, tyOwned} and
mapType(p, resultSym.typ) == etyBaseIndex
if returnAddress:
mapType(p, resultSym.typ) == etyBaseIndex:
resultAsgn = p.indentLine(("var $# = null;$n") % [mname])
resultAsgn.add p.indentLine("var $#_Idx = 0;$n" % [mname])
else:
let resVar = createVar(p, resultSym.typ, isIndirect(resultSym))
resultAsgn = p.indentLine(("var $# = $#;$n") % [mname, resVar])
gen(p, prc.ast[resultPos], a)
if returnAddress:
if mapType(p, resultSym.typ) == etyBaseIndex:
returnStmt = "return [$#, $#];$n" % [a.address, a.res]
else:
returnStmt = "return $#;$n" % [a.res]
@@ -2593,15 +2565,8 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
of nkObjConstr: genObjConstr(p, n, r)
of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, n, r)
of nkAddr, nkHiddenAddr:
if n.typ.kind in {tyLent}:
gen(p, n[0], r)
else:
genAddr(p, n, r)
of nkDerefExpr, nkHiddenDeref:
if n.typ.kind in {tyLent}:
gen(p, n[0], r)
else:
genDeref(p, n, r)
genAddr(p, n, r)
of nkDerefExpr, nkHiddenDeref: genDeref(p, n, r)
of nkBracketExpr: genArrayAccess(p, n, r)
of nkDotExpr: genFieldAccess(p, n, r)
of nkCheckedFieldExpr: genCheckedFieldOp(p, n, nil, r)
@@ -2674,7 +2639,6 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
else: internalError(p.config, n.info, "gen: unknown node type: " & $n.kind)
proc newModule(g: ModuleGraph; module: PSym): BModule =
## Create a new JS backend module node.
new(result)
result.module = module
result.sigConflicts = initCountTable[SigHash]()
@@ -2686,7 +2650,6 @@ proc newModule(g: ModuleGraph; module: PSym): BModule =
PGlobals(g.backend).inSystem = true
proc genHeader(): Rope =
## Generate the JS header.
result = rope("""/* Generated by the Nim Compiler v$1 */
var framePtr = null;
var excHandler = 0;
@@ -2717,8 +2680,6 @@ proc addHcrInitGuards(p: PProc, n: PNode,
genStmt(p, n)
proc genModule(p: PProc, n: PNode) =
## Generate the JS module code.
## Called for each top level node in a Nim module.
if optStackTrace in p.options:
p.body.add(frameCreate(p,
makeJSString("module " & p.module.module.name.s),
@@ -2747,7 +2708,6 @@ proc genModule(p: PProc, n: PNode) =
p.body.add(frameDestroy(p))
proc myProcess(b: PPassContext, n: PNode): PNode =
## Generate JS code for a node.
result = n
let m = BModule(b)
if passes.skipCodegen(m.config, n): return n
@@ -2760,7 +2720,6 @@ proc myProcess(b: PPassContext, n: PNode): PNode =
p.g.code.add(p.body)
proc wholeCode(graph: ModuleGraph; m: BModule): Rope =
## Combine source code from all nodes.
let globals = PGlobals(graph.backend)
for prc in globals.forwarded:
if not globals.generatedSyms.containsOrIncl(prc.id):
@@ -2786,41 +2745,26 @@ proc getClassName(t: PType): Rope =
else: result = rope(s.name.s)
proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
## Finalize JS code generation of a Nim module.
## Param `n` may contain nodes returned from the last module close call.
result = myProcess(b, n)
var m = BModule(b)
if sfMainModule in m.module.flags:
# Add global destructors to the module.
# This must come before the last call to `myProcess`.
for i in countdown(high(graph.globalDestructors), 0):
n.add graph.globalDestructors[i]
# Process any nodes left over from the last call to `myClose`.
result = myProcess(b, n)
# Some codegen is different (such as no stacktraces; see `initProcOptions`)
# when `std/system` is being processed.
for destructorCall in graph.globalDestructors:
n.add destructorCall
if sfSystemModule in m.module.flags:
PGlobals(graph.backend).inSystem = false
# Check if codegen should continue before any files are generated.
# It may bail early is if too many errors have been raised.
if passes.skipCodegen(m.config, n): return n
# Nim modules are compiled into a single JS file.
# If this is the main module, then this is the final call to `myClose`.
if sfMainModule in m.module.flags:
var code = genHeader() & wholeCode(graph, m)
let outFile = m.config.prepareToWriteOutput()
# Generate an optional source map.
if optSourcemap in m.config.globalOptions:
var map: SourceMap
(code, map) = genSourceMap($(code), outFile.string)
writeFile(outFile.string & ".map", $(%map))
# Check if the generated JS code matches the output file, or else
# write it to the file.
if not equalsFile(code, outFile):
if not writeRope(code, outFile):
rawMessage(m.config, errCannotOpenFile, outFile.string)
discard writeRopeIfNotEqual(code, outFile)
proc myOpen(graph: ModuleGraph; s: PSym; idgen: IdGenerator): PPassContext =
## Create the JS backend pass context `BModule` for a Nim module.
result = newModule(graph, s)
result.idgen = idgen

View File

@@ -14,9 +14,6 @@ import
idents, renderer, types, magicsys, lowerings, tables, modulegraphs, lineinfos,
transf, liftdestructors, typeallowed
when defined(nimPreviewSlimSystem):
import std/assertions
discard """
The basic approach is that captured vars need to be put on the heap and
that the calling chain needs to be explicitly modelled. Things to consider:
@@ -275,11 +272,16 @@ proc liftIterSym*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PN
proc freshVarForClosureIter*(g: ModuleGraph; s: PSym; idgen: IdGenerator; owner: PSym): PNode =
let envParam = getHiddenParam(g, owner)
let obj = envParam.typ.skipTypes({tyOwned, tyRef, tyPtr})
let field = addField(obj, s, g.cache, idgen)
addField(obj, s, g.cache, idgen)
var access = newSymNode(envParam)
assert obj.kind == tyObject
result = rawIndirectAccess(access, field, s.info)
let field = getFieldFromObj(obj, s)
if field != nil:
result = rawIndirectAccess(access, field, s.info)
else:
localError(g.config, s.info, "internal error: cannot generate fresh variable")
result = access
# ------------------ new stuff -------------------------------------------
@@ -288,8 +290,7 @@ proc markAsClosure(g: ModuleGraph; owner: PSym; n: PNode) =
if illegalCapture(s):
localError(g.config, n.info,
("'$1' is of type <$2> which cannot be captured as it would violate memory" &
" safety, declared here: $3; using '-d:nimNoLentIterators' helps in some cases." &
" Consider using a <ref $2> which can be captured.") %
" safety, declared here: $3; using '-d:nimNoLentIterators' helps in some cases") %
[s.name.s, typeToString(s.typ), g.config$s.info])
elif not (owner.typ.callConv == ccClosure or owner.typ.callConv == ccNimCall and tfExplicitCallConv notin owner.typ.flags):
localError(g.config, n.info, "illegal capture '$1' because '$2' has the calling convention: <$3>" %
@@ -448,7 +449,7 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
if s.name.id == getIdent(c.graph.cache, ":state").id:
obj.n[0].sym.itemId = ItemId(module: s.itemId.module, item: -s.itemId.item)
else:
discard addField(obj, s, c.graph.cache, c.idgen)
addField(obj, s, c.graph.cache, c.idgen)
# direct or indirect dependency:
elif (innerProc and s.typ.callConv == ccClosure) or interestingVar(s):
discard """
@@ -470,7 +471,7 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
if interestingVar(s) and not c.capturedVars.containsOrIncl(s.id):
let obj = c.getEnvTypeForOwner(ow, n.info).skipTypes({tyOwned, tyRef, tyPtr})
#getHiddenParam(owner).typ.skipTypes({tyOwned, tyRef, tyPtr})
discard addField(obj, s, c.graph.cache, c.idgen)
addField(obj, s, c.graph.cache, c.idgen)
# create required upFields:
var w = owner.skipGenericOwner
if isInnerProc(w) or owner.isIterator:

View File

@@ -19,9 +19,6 @@ import
hashes, options, msgs, strutils, platform, idents, nimlexbase, llstream,
wordrecg, lineinfos, pathutils, parseutils
when defined(nimPreviewSlimSystem):
import std/assertions
const
MaxLineLength* = 80 # lines longer than this lead to a warning
numChars*: set[char] = {'0'..'9', 'a'..'z', 'A'..'Z'}

View File

@@ -15,9 +15,6 @@ import modulegraphs, lineinfos, idents, ast, renderer, semdata,
from trees import isCaseObj
when defined(nimPreviewSlimSystem):
import std/assertions
type
TLiftCtx = object
g: ModuleGraph
@@ -944,12 +941,6 @@ proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp
incl result.flags, sfFromGeneric
incl result.flags, sfGeneratedOp
proc genTypeFieldCopy(c: var TLiftCtx; t: PType; body, x, y: PNode) =
let xx = genBuiltin(c, mAccessTypeField, "accessTypeField", x)
let yy = genBuiltin(c, mAccessTypeField, "accessTypeField", y)
xx.typ = getSysType(c.g, c.info, tyPointer)
yy.typ = xx.typ
body.add newAsgnStmt(xx, yy)
proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
info: TLineInfo; idgen: IdGenerator): PSym =
@@ -989,10 +980,6 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
fillStrOp(a, typ, result.ast[bodyPos], d, src)
else:
fillBody(a, typ, result.ast[bodyPos], d, src)
if tk == tyObject and a.kind in {attachedAsgn, attachedSink, attachedDeepCopy} and not lacksMTypeField(typ):
# bug #19205: Do not forget to also copy the hidden type field:
genTypeFieldCopy(a, typ, result.ast[bodyPos], d, src)
if not a.canRaise: incl result.flags, sfNeverRaises
completePartialOp(g, idgen.module, typ, kind, result)

View File

@@ -34,13 +34,11 @@ type
errXExpected,
errRstGridTableNotImplemented,
errRstMarkdownIllformedTable,
errRstIllformedTable,
errRstNewSectionExpected,
errRstGeneralParseError,
errRstInvalidDirectiveX,
errRstInvalidField,
errRstFootnoteMismatch,
errRstSandboxedDirective,
errProveInit, # deadcode
errGenerated,
errUser,
@@ -52,7 +50,6 @@ type
warnSmallLshouldNotBeUsed = "SmallLshouldNotBeUsed", warnUnknownMagic = "UnknownMagic",
warnRstRedefinitionOfLabel = "RedefinitionOfLabel",
warnRstUnknownSubstitutionX = "UnknownSubstitutionX",
warnRstAmbiguousLink = "AmbiguousLink",
warnRstBrokenLink = "BrokenLink",
warnRstLanguageXNotSupported = "LanguageXNotSupported",
warnRstFieldXNotSupported = "FieldXNotSupported",
@@ -78,7 +75,6 @@ type
warnAnyEnumConv = "AnyEnumConv",
warnHoleEnumConv = "HoleEnumConv",
warnCstringConv = "CStringConv",
warnNoInitIgnored = "NoInitIgnored"
warnEffect = "Effect",
warnUser = "User",
# hints
@@ -108,13 +104,11 @@ const
errXExpected: "'$1' expected",
errRstGridTableNotImplemented: "grid table is not implemented",
errRstMarkdownIllformedTable: "illformed delimiter row of a markdown table",
errRstIllformedTable: "Illformed table: $1",
errRstNewSectionExpected: "new section expected $1",
errRstGeneralParseError: "general parse error",
errRstInvalidDirectiveX: "invalid directive: '$1'",
errRstInvalidField: "invalid field: $1",
errRstFootnoteMismatch: "number of footnotes and their references don't match: $1",
errRstSandboxedDirective: "disabled directive: '$1'",
errProveInit: "Cannot prove that '$1' is initialized.", # deadcode
errGenerated: "$1",
errUser: "$1",
@@ -129,7 +123,6 @@ const
warnUnknownMagic: "unknown magic '$1' might crash the compiler",
warnRstRedefinitionOfLabel: "redefinition of label '$1'",
warnRstUnknownSubstitutionX: "unknown substitution '$1'",
warnRstAmbiguousLink: "ambiguous doc link $1",
warnRstBrokenLink: "broken link '$1'",
warnRstLanguageXNotSupported: "language '$1' not supported",
warnRstFieldXNotSupported: "field '$1' not supported",
@@ -171,7 +164,6 @@ const
warnAnyEnumConv: "$1",
warnHoleEnumConv: "$1",
warnCstringConv: "$1",
warnNoInitIgnored: "noinit pragma is ignored",
warnEffect: "$1",
warnUser: "$1",
hintSuccess: "operation successful: $#",

View File

@@ -12,9 +12,6 @@
import
pathutils
when defined(nimPreviewSlimSystem):
import std/syncio
# support `useGnuReadline`, `useLinenoise` for backwards compatibility
const hasRstdin = (defined(nimUseLinenoise) or defined(useLinenoise) or defined(useGnuReadline)) and
not defined(windows)

View File

@@ -9,10 +9,6 @@
# This module implements lookup helpers.
import std/[algorithm, strutils]
when defined(nimPreviewSlimSystem):
import std/assertions
import
intsets, ast, astalgo, idents, semdata, types, msgs, options,
renderer, nimfix/prettybase, lineinfos, modulegraphs, astmsgs

View File

@@ -15,9 +15,6 @@ const
import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs,
lineinfos
when defined(nimPreviewSlimSystem):
import std/assertions
proc newDeref*(n: PNode): PNode {.inline.} =
result = newNodeIT(nkHiddenDeref, n.info, n.typ[0])
result.add n
@@ -74,20 +71,14 @@ proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: P
let value = n.lastSon
result = newNodeI(nkStmtList, n.info)
var tempAsNode: PNode
let avoidTemp = value.kind == nkSym
if avoidTemp:
tempAsNode = value
else:
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), nextSymId(idgen),
owner, value.info, g.config.options)
temp.typ = skipTypes(value.typ, abstractInst)
incl(temp.flags, sfFromGeneric)
tempAsNode = newSymNode(temp)
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), nextSymId(idgen),
owner, value.info, g.config.options)
temp.typ = skipTypes(value.typ, abstractInst)
incl(temp.flags, sfFromGeneric)
var v = newNodeI(nkVarSection, value.info)
if not avoidTemp:
v.addVar(tempAsNode, value)
let tempAsNode = newSymNode(temp)
v.addVar(tempAsNode, value)
result.add(v)
for i in 0..<n.len-2:
@@ -230,7 +221,7 @@ proc lookupInRecord(n: PNode, id: ItemId): PSym =
if n.sym.itemId.module == id.module and n.sym.itemId.item == -abs(id.item): result = n.sym
else: discard
proc addField*(obj: PType; s: PSym; cache: IdentCache; idgen: IdGenerator): PSym =
proc addField*(obj: PType; s: PSym; cache: IdentCache; idgen: IdGenerator) =
# because of 'gensym' support, we have to mangle the name with its ID.
# This is hacky but the clean solution is much more complex than it looks.
var field = newSym(skField, getIdent(cache, s.name.s & $obj.n.len),
@@ -244,7 +235,6 @@ proc addField*(obj: PType; s: PSym; cache: IdentCache; idgen: IdGenerator): PSym
field.flags = s.flags * {sfCursor}
obj.n.add newSymNode(field)
fieldCheck()
result = field
proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache; idgen: IdGenerator): PSym {.discardable.} =
result = lookupInRecord(obj.n, s.itemId)

View File

@@ -22,10 +22,6 @@ import
modules,
modulegraphs, lineinfos, pathutils, vmprofiler
when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
import ic / [cbackend, integrity, navigator]
from ic / ic import rodViewer
@@ -62,11 +58,6 @@ proc commandCheck(graph: ModuleGraph) =
let conf = graph.config
conf.setErrorMaxHighMaybe
defineSymbol(conf.symbols, "nimcheck")
if optWasNimscript in conf.globalOptions:
defineSymbol(conf.symbols, "nimscript")
defineSymbol(conf.symbols, "nimconfig")
elif conf.backend == backendJs:
setTarget(conf.target, osJS, cpuJS)
semanticPasses(graph) # use an empty backend for semantic checking only
compileProject(graph)
@@ -372,8 +363,7 @@ proc mainCommand*(graph: ModuleGraph) =
msgWriteln(conf, "-- end of list --", {msgStdout, msgSkipHook})
for it in conf.searchPaths: msgWriteln(conf, it.string)
of cmdCheck:
commandCheck(graph)
of cmdCheck: commandCheck(graph)
of cmdParse:
wantMainModule(conf)
discard parseFile(conf.projectMainIdx, cache, conf)

View File

@@ -1,297 +0,0 @@
#
#
# Nim's Runtime Library
# (c) Copyright 2010 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
# `std/md5` without VM and JavaScript support, to circumvent a bug with
# openarrays on Nim < 1.4.
when defined(nimHasStyleChecks):
{.push styleChecks: off.}
type
MD5State = array[0..3, uint32]
MD5Block = array[0..15, uint32]
MD5CBits = array[0..7, uint8]
MD5Digest* = array[0..15, uint8]
## MD5 checksum of a string, obtained with the `toMD5 proc <#toMD5,string>`_.
MD5Buffer = array[0..63, uint8]
MD5Context* {.final.} = object
state: MD5State
count: array[0..1, uint32]
buffer: MD5Buffer
const
padding: array[0..63, uint8] = [
0x80'u8, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
]
proc F(x, y, z: uint32): uint32 {.inline.} =
result = (x and y) or ((not x) and z)
proc G(x, y, z: uint32): uint32 {.inline.} =
result = (x and z) or (y and (not z))
proc H(x, y, z: uint32): uint32 {.inline.} =
result = x xor y xor z
proc I(x, y, z: uint32): uint32 {.inline.} =
result = y xor (x or (not z))
proc rot(x: var uint32, n: uint8) {.inline.} =
x = (x shl n) or (x shr (32'u32 - n))
proc FF(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) =
a = a + F(b, c, d) + x + ac
rot(a, s)
a = a + b
proc GG(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) =
a = a + G(b, c, d) + x + ac
rot(a, s)
a = a + b
proc HH(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) =
a = a + H(b, c, d) + x + ac
rot(a, s)
a = a + b
proc II(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) =
a = a + I(b, c, d) + x + ac
rot(a, s)
a = a + b
proc encode(dest: var MD5Block, src: openArray[uint8]) =
var j = 0
for i in 0..high(dest):
dest[i] = uint32(ord(src[j])) or
uint32(ord(src[j+1])) shl 8 or
uint32(ord(src[j+2])) shl 16 or
uint32(ord(src[j+3])) shl 24
inc(j, 4)
proc decode(dest: var openArray[uint8], src: openArray[uint32]) =
var i = 0
for j in 0..high(src):
dest[i] = uint8(src[j] and 0xff'u32)
dest[i+1] = uint8(src[j] shr 8 and 0xff'u32)
dest[i+2] = uint8(src[j] shr 16 and 0xff'u32)
dest[i+3] = uint8(src[j] shr 24 and 0xff'u32)
inc(i, 4)
template slice(s: string | cstring, a, b): openArray[uint8] =
s.toOpenArrayByte(a, b)
template slice(s: openArray[uint8], a, b): openArray[uint8] =
s.toOpenArray(a, b)
proc transform(buffer: openArray[uint8], state: var MD5State) =
var
myBlock: MD5Block
encode(myBlock, buffer)
var a = state[0]
var b = state[1]
var c = state[2]
var d = state[3]
FF(a, b, c, d, myBlock[0], 7'u8, 0xD76AA478'u32)
FF(d, a, b, c, myBlock[1], 12'u8, 0xE8C7B756'u32)
FF(c, d, a, b, myBlock[2], 17'u8, 0x242070DB'u32)
FF(b, c, d, a, myBlock[3], 22'u8, 0xC1BDCEEE'u32)
FF(a, b, c, d, myBlock[4], 7'u8, 0xF57C0FAF'u32)
FF(d, a, b, c, myBlock[5], 12'u8, 0x4787C62A'u32)
FF(c, d, a, b, myBlock[6], 17'u8, 0xA8304613'u32)
FF(b, c, d, a, myBlock[7], 22'u8, 0xFD469501'u32)
FF(a, b, c, d, myBlock[8], 7'u8, 0x698098D8'u32)
FF(d, a, b, c, myBlock[9], 12'u8, 0x8B44F7AF'u32)
FF(c, d, a, b, myBlock[10], 17'u8, 0xFFFF5BB1'u32)
FF(b, c, d, a, myBlock[11], 22'u8, 0x895CD7BE'u32)
FF(a, b, c, d, myBlock[12], 7'u8, 0x6B901122'u32)
FF(d, a, b, c, myBlock[13], 12'u8, 0xFD987193'u32)
FF(c, d, a, b, myBlock[14], 17'u8, 0xA679438E'u32)
FF(b, c, d, a, myBlock[15], 22'u8, 0x49B40821'u32)
GG(a, b, c, d, myBlock[1], 5'u8, 0xF61E2562'u32)
GG(d, a, b, c, myBlock[6], 9'u8, 0xC040B340'u32)
GG(c, d, a, b, myBlock[11], 14'u8, 0x265E5A51'u32)
GG(b, c, d, a, myBlock[0], 20'u8, 0xE9B6C7AA'u32)
GG(a, b, c, d, myBlock[5], 5'u8, 0xD62F105D'u32)
GG(d, a, b, c, myBlock[10], 9'u8, 0x02441453'u32)
GG(c, d, a, b, myBlock[15], 14'u8, 0xD8A1E681'u32)
GG(b, c, d, a, myBlock[4], 20'u8, 0xE7D3FBC8'u32)
GG(a, b, c, d, myBlock[9], 5'u8, 0x21E1CDE6'u32)
GG(d, a, b, c, myBlock[14], 9'u8, 0xC33707D6'u32)
GG(c, d, a, b, myBlock[3], 14'u8, 0xF4D50D87'u32)
GG(b, c, d, a, myBlock[8], 20'u8, 0x455A14ED'u32)
GG(a, b, c, d, myBlock[13], 5'u8, 0xA9E3E905'u32)
GG(d, a, b, c, myBlock[2], 9'u8, 0xFCEFA3F8'u32)
GG(c, d, a, b, myBlock[7], 14'u8, 0x676F02D9'u32)
GG(b, c, d, a, myBlock[12], 20'u8, 0x8D2A4C8A'u32)
HH(a, b, c, d, myBlock[5], 4'u8, 0xFFFA3942'u32)
HH(d, a, b, c, myBlock[8], 11'u8, 0x8771F681'u32)
HH(c, d, a, b, myBlock[11], 16'u8, 0x6D9D6122'u32)
HH(b, c, d, a, myBlock[14], 23'u8, 0xFDE5380C'u32)
HH(a, b, c, d, myBlock[1], 4'u8, 0xA4BEEA44'u32)
HH(d, a, b, c, myBlock[4], 11'u8, 0x4BDECFA9'u32)
HH(c, d, a, b, myBlock[7], 16'u8, 0xF6BB4B60'u32)
HH(b, c, d, a, myBlock[10], 23'u8, 0xBEBFBC70'u32)
HH(a, b, c, d, myBlock[13], 4'u8, 0x289B7EC6'u32)
HH(d, a, b, c, myBlock[0], 11'u8, 0xEAA127FA'u32)
HH(c, d, a, b, myBlock[3], 16'u8, 0xD4EF3085'u32)
HH(b, c, d, a, myBlock[6], 23'u8, 0x04881D05'u32)
HH(a, b, c, d, myBlock[9], 4'u8, 0xD9D4D039'u32)
HH(d, a, b, c, myBlock[12], 11'u8, 0xE6DB99E5'u32)
HH(c, d, a, b, myBlock[15], 16'u8, 0x1FA27CF8'u32)
HH(b, c, d, a, myBlock[2], 23'u8, 0xC4AC5665'u32)
II(a, b, c, d, myBlock[0], 6'u8, 0xF4292244'u32)
II(d, a, b, c, myBlock[7], 10'u8, 0x432AFF97'u32)
II(c, d, a, b, myBlock[14], 15'u8, 0xAB9423A7'u32)
II(b, c, d, a, myBlock[5], 21'u8, 0xFC93A039'u32)
II(a, b, c, d, myBlock[12], 6'u8, 0x655B59C3'u32)
II(d, a, b, c, myBlock[3], 10'u8, 0x8F0CCC92'u32)
II(c, d, a, b, myBlock[10], 15'u8, 0xFFEFF47D'u32)
II(b, c, d, a, myBlock[1], 21'u8, 0x85845DD1'u32)
II(a, b, c, d, myBlock[8], 6'u8, 0x6FA87E4F'u32)
II(d, a, b, c, myBlock[15], 10'u8, 0xFE2CE6E0'u32)
II(c, d, a, b, myBlock[6], 15'u8, 0xA3014314'u32)
II(b, c, d, a, myBlock[13], 21'u8, 0x4E0811A1'u32)
II(a, b, c, d, myBlock[4], 6'u8, 0xF7537E82'u32)
II(d, a, b, c, myBlock[11], 10'u8, 0xBD3AF235'u32)
II(c, d, a, b, myBlock[2], 15'u8, 0x2AD7D2BB'u32)
II(b, c, d, a, myBlock[9], 21'u8, 0xEB86D391'u32)
state[0] = state[0] + a
state[1] = state[1] + b
state[2] = state[2] + c
state[3] = state[3] + d
proc md5Init*(c: var MD5Context) {.raises: [], tags: [], gcsafe.}
proc md5Update*(c: var MD5Context, input: openArray[uint8]) {.raises: [],
tags: [], gcsafe.}
proc md5Final*(c: var MD5Context, digest: var MD5Digest) {.raises: [], tags: [], gcsafe.}
proc md5Update*(c: var MD5Context, input: cstring, len: int) {.raises: [],
tags: [], gcsafe.} =
## Updates the `MD5Context` with the `input` data of length `len`.
##
## If you use the `toMD5 proc <#toMD5,string>`_, there's no need to call this
## function explicitly.
md5Update(c, input.slice(0, len - 1))
proc toMD5*(s: string): MD5Digest =
## Computes the `MD5Digest` value for a string `s`.
##
## **See also:**
## * `getMD5 proc <#getMD5,string>`_ which returns a string representation
## of the `MD5Digest`
## * `$ proc <#$,MD5Digest>`_ for converting MD5Digest to string
runnableExamples:
assert $toMD5("abc") == "900150983cd24fb0d6963f7d28e17f72"
var c: MD5Context
md5Init(c)
md5Update(c, s.slice(0, s.len - 1))
md5Final(c, result)
proc `$`*(d: MD5Digest): string =
## Converts a `MD5Digest` value into its string representation.
const digits = "0123456789abcdef"
result = ""
for i in 0..15:
add(result, digits[(d[i].int shr 4) and 0xF])
add(result, digits[d[i].int and 0xF])
proc getMD5*(s: string): string =
## Computes an MD5 value of `s` and returns its string representation.
##
## **See also:**
## * `toMD5 proc <#toMD5,string>`_ which returns the `MD5Digest` of a string
runnableExamples:
assert getMD5("abc") == "900150983cd24fb0d6963f7d28e17f72"
var
c: MD5Context
d: MD5Digest
md5Init(c)
md5Update(c, s.slice(0, s.len - 1))
md5Final(c, d)
result = $d
proc `==`*(D1, D2: MD5Digest): bool =
## Checks if two `MD5Digest` values are identical.
for i in 0..15:
if D1[i] != D2[i]: return false
return true
proc clearBuffer(c: var MD5Context) {.inline.} =
zeroMem(addr(c.buffer), sizeof(MD5Buffer))
proc md5Init*(c: var MD5Context) =
## Initializes an `MD5Context`.
##
## If you use the `toMD5 proc <#toMD5,string>`_, there's no need to call this
## function explicitly.
c.state[0] = 0x67452301'u32
c.state[1] = 0xEFCDAB89'u32
c.state[2] = 0x98BADCFE'u32
c.state[3] = 0x10325476'u32
c.count[0] = 0'u32
c.count[1] = 0'u32
clearBuffer(c)
proc writeBuffer(c: var MD5Context, index: int,
input: openArray[uint8], inputIndex, len: int) {.inline.} =
copyMem(addr(c.buffer[index]), unsafeAddr(input[inputIndex]), len)
proc md5Update*(c: var MD5Context, input: openArray[uint8]) =
## Updates the `MD5Context` with the `input` data.
##
## If you use the `toMD5 proc <#toMD5,string>`_, there's no need to call this
## function explicitly.
var Index = int((c.count[0] shr 3) and 0x3F)
c.count[0] = c.count[0] + (uint32(input.len) shl 3)
if c.count[0] < (uint32(input.len) shl 3): c.count[1] = c.count[1] + 1'u32
c.count[1] = c.count[1] + (uint32(input.len) shr 29)
var PartLen = 64 - Index
if input.len >= PartLen:
writeBuffer(c, Index, input, 0, PartLen)
transform(c.buffer, c.state)
var i = PartLen
while i + 63 < input.len:
transform(input.slice(i, i + 63), c.state)
inc(i, 64)
if i < input.len:
writeBuffer(c, 0, input, i, input.len - i)
elif input.len > 0:
writeBuffer(c, Index, input, 0, input.len)
proc md5Final*(c: var MD5Context, digest: var MD5Digest) =
## Finishes the `MD5Context` and stores the result in `digest`.
##
## If you use the `toMD5 proc <#toMD5,string>`_, there's no need to call this
## function explicitly.
var
Bits: MD5CBits
PadLen: int
decode(Bits, c.count)
var Index = int((c.count[0] shr 3) and 0x3F)
if Index < 56: PadLen = 56 - Index
else: PadLen = 120 - Index
md5Update(c, padding.slice(0, PadLen - 1))
md5Update(c, Bits)
decode(digest, c.state)
clearBuffer(c)
when defined(nimHasStyleChecks):
{.pop.} #{.push styleChecks: off.}

View File

@@ -11,13 +11,10 @@
## represents a complete Nim project. Single modules can either be kept in RAM
## or stored in a rod-file.
import intsets, tables, hashes, md5_old, sequtils
import ast, astalgo, options, lineinfos,idents, btrees, ropes, msgs, pathutils, packages
import intsets, tables, hashes, md5
import ast, astalgo, options, lineinfos,idents, btrees, ropes, msgs, pathutils
import ic / [packed_ast, ic]
when defined(nimPreviewSlimSystem):
import std/assertions
type
SigHash* = distinct MD5Digest
@@ -67,6 +64,7 @@ type
startupPackedConfig*: PackedConfig
packageSyms*: TStrTable
modulesPerPackage*: Table[ItemId, TStrTable]
deps*: IntSet # the dependency graph or potentially its transitive closure.
importDeps*: Table[FileIndex, seq[FileIndex]] # explicit import module dependencies
suggestMode*: bool # whether we are in nimsuggest mode or not.
@@ -83,8 +81,6 @@ type
doStopCompile*: proc(): bool {.closure.}
usageSym*: PSym # for nimsuggest
owners*: seq[PSym]
suggestSymbols*: Table[FileIndex, seq[tuple[sym: PSym, info: TLineInfo]]]
suggestErrors*: Table[FileIndex, seq[Suggest]]
methods*: seq[tuple[methods: seq[PSym], dispatcher: PSym]] # needs serialization!
systemModule*: PSym
sysTypes*: array[TTypeKind, PType]
@@ -387,19 +383,9 @@ when defined(nimfind):
c.graph.onDefinitionResolveForward(c.graph, s, info)
else:
when defined(nimsuggest):
template onUse*(info: TLineInfo; s: PSym) = discard
template onDef*(info: TLineInfo; s: PSym) =
let c = getPContext()
if c.graph.config.suggestVersion == 3:
suggestSym(c.graph, info, s, c.graph.usageSym)
template onDefResolveForward*(info: TLineInfo; s: PSym) = discard
else:
template onUse*(info: TLineInfo; s: PSym) = discard
template onDef*(info: TLineInfo; s: PSym) = discard
template onDefResolveForward*(info: TLineInfo; s: PSym) = discard
template onUse*(info: TLineInfo; s: PSym) = discard
template onDef*(info: TLineInfo; s: PSym) = discard
template onDefResolveForward*(info: TLineInfo; s: PSym) = discard
proc stopCompile*(g: ModuleGraph): bool {.inline.} =
result = g.doStopCompile != nil and g.doStopCompile()
@@ -446,7 +432,8 @@ proc initOperators*(g: ModuleGraph): Operators =
result.opNot = createMagic(g, "not", mNot)
result.opContains = createMagic(g, "contains", mInSet)
proc initModuleGraphFields(result: ModuleGraph) =
proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
result = ModuleGraph()
# A module ID of -1 means that the symbol is not attached to a module at all,
# but to the module graph:
result.idgen = IdGenerator(module: -1'i32, symId: 0'i32, typeId: 0'i32)
@@ -456,9 +443,9 @@ proc initModuleGraphFields(result: ModuleGraph) =
result.ifaces = @[]
result.importStack = @[]
result.inclToMod = initTable[FileIndex, FileIndex]()
result.config = config
result.cache = cache
result.owners = @[]
result.suggestSymbols = initTable[FileIndex, seq[tuple[sym: PSym, info: TLineInfo]]]()
result.suggestErrors = initTable[FileIndex, seq[Suggest]]()
result.methods = @[]
initStrTable(result.compilerprocs)
initStrTable(result.exposed)
@@ -472,12 +459,6 @@ proc initModuleGraphFields(result: ModuleGraph) =
result.operators = initOperators(result)
result.emittedTypeInfo = initTable[string, FileIndex]()
proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
result = ModuleGraph()
result.config = config
result.cache = cache
initModuleGraphFields(result)
proc resetAllModules*(g: ModuleGraph) =
initStrTable(g.packageSyms)
g.deps = initIntSet()
@@ -489,7 +470,6 @@ proc resetAllModules*(g: ModuleGraph) =
g.methods = @[]
initStrTable(g.compilerprocs)
initStrTable(g.exposed)
initModuleGraphFields(g)
proc getModule*(g: ModuleGraph; fileIdx: FileIndex): PSym =
if fileIdx.int32 >= 0:
@@ -568,19 +548,7 @@ proc transitiveClosure(g: var IntSet; n: int) =
proc markDirty*(g: ModuleGraph; fileIdx: FileIndex) =
let m = g.getModule fileIdx
if m != nil:
g.suggestSymbols.del(fileIdx)
g.suggestErrors.del(fileIdx)
incl m.flags, sfDirty
proc unmarkAllDirty*(g: ModuleGraph) =
for i in 0i32..<g.ifaces.len.int32:
let m = g.ifaces[i].module
if m != nil:
m.flags.excl sfDirty
proc isDirty*(g: ModuleGraph; m: PSym): bool =
result = g.suggestMode and sfDirty in m.flags
if m != nil: incl m.flags, sfDirty
proc markClientsDirty*(g: ModuleGraph; fileIdx: FileIndex) =
# we need to mark its dependent modules D as dirty right away because after
@@ -590,28 +558,14 @@ proc markClientsDirty*(g: ModuleGraph; fileIdx: FileIndex) =
g.invalidTransitiveClosure = false
transitiveClosure(g.deps, g.ifaces.len)
# every module that *depends* on this file is also dirty:
for i in 0i32..<g.ifaces.len.int32:
if g.deps.contains(i.dependsOn(fileIdx.int)):
g.markDirty(FileIndex(i))
proc needsCompilation*(g: ModuleGraph): bool =
# every module that *depends* on this file is also dirty:
for i in 0i32..<g.ifaces.len.int32:
let m = g.ifaces[i].module
if m != nil:
if sfDirty in m.flags:
return true
if m != nil and g.deps.contains(i.dependsOn(fileIdx.int)):
incl m.flags, sfDirty
proc needsCompilation*(g: ModuleGraph, fileIdx: FileIndex): bool =
let module = g.getModule(fileIdx)
if module != nil and g.isDirty(module):
return true
for i in 0i32..<g.ifaces.len.int32:
let m = g.ifaces[i].module
if m != nil and g.isDirty(m) and g.deps.contains(fileIdx.int32.dependsOn(i)):
return true
proc isDirty*(g: ModuleGraph; m: PSym): bool =
result = g.suggestMode and sfDirty in m.flags
proc getBody*(g: ModuleGraph; s: PSym): PNode {.inline.} =
result = s.ast[bodyPos]
@@ -640,28 +594,3 @@ proc onProcessing*(graph: ModuleGraph, fileIdx: FileIndex, moduleStatus: string,
let fromModule2 = if fromModule != nil: $fromModule.name.s else: "(toplevel)"
let mode = if isNimscript: "(nims) " else: ""
rawMessage(conf, hintProcessing, "$#$# $#: $#: $#" % [mode, indent, fromModule2, moduleStatus, path])
proc getPackage*(graph: ModuleGraph; fileIdx: FileIndex): PSym =
## Returns a package symbol for yet to be defined module for fileIdx.
## The package symbol is added to the graph if it doesn't exist.
let pkgSym = getPackage(graph.config, graph.cache, fileIdx)
# check if the package is already in the graph
result = graph.packageSyms.strTableGet(pkgSym.name)
if result == nil:
# the package isn't in the graph, so create and add it
result = pkgSym
graph.packageSyms.strTableAdd(pkgSym)
func belongsToStdlib*(graph: ModuleGraph, sym: PSym): bool =
## Check if symbol belongs to the 'stdlib' package.
sym.getPackageSymbol.getPackageId == graph.systemModule.getPackageId
iterator suggestSymbolsIter*(g: ModuleGraph): tuple[sym: PSym, info: TLineInfo] =
for xs in g.suggestSymbols.values:
for x in xs.deduplicate:
yield x
iterator suggestErrorsIter*(g: ModuleGraph): Suggest =
for xs in g.suggestErrors.values:
for x in xs:
yield x

View File

@@ -10,6 +10,100 @@
import ast, renderer, strutils, msgs, options, idents, os, lineinfos,
pathutils
when false:
const
considerParentDirs = not defined(noParentProjects)
considerNimbleDirs = not defined(noNimbleDirs)
proc findInNimbleDir(pkg, subdir, dir: string): string =
var best = ""
var bestv = ""
for k, p in os.walkDir(dir, relative=true):
if k == pcDir and p.len > pkg.len+1 and
p[pkg.len] == '-' and p.startsWith(pkg):
let (_, a, _) = getPathVersionChecksum(p)
if bestv.len == 0 or bestv < a:
bestv = a
best = dir / p
if best.len > 0:
var f: File
if open(f, best / changeFileExt(pkg, ".nimble-link")):
# the second line contains what we're interested in, see:
# https://github.com/nim-lang/nimble#nimble-link
var override = ""
discard readLine(f, override)
discard readLine(f, override)
close(f)
if not override.isAbsolute():
best = best / override
else:
best = override
let f = if subdir.len == 0: pkg else: subdir
let res = addFileExt(best / f, "nim")
if best.len > 0 and fileExists(res):
result = res
when false:
proc resolveDollar(project, source, pkg, subdir: string; info: TLineInfo): string =
template attempt(a) =
let x = addFileExt(a, "nim")
if fileExists(x): return x
case pkg
of "stdlib":
if subdir.len == 0:
return options.libpath
else:
for candidate in stdlibDirs:
attempt(options.libpath / candidate / subdir)
of "root":
let root = project.splitFile.dir
if subdir.len == 0:
return root
else:
attempt(root / subdir)
else:
when considerParentDirs:
var p = parentDir(source.splitFile.dir)
# support 'import $karax':
let f = if subdir.len == 0: pkg else: subdir
while p.len > 0:
let dir = p / pkg
if dirExists(dir):
attempt(dir / f)
# 2nd attempt: try to use 'karax/karax'
attempt(dir / pkg / f)
# 3rd attempt: try to use 'karax/src/karax'
attempt(dir / "src" / f)
attempt(dir / "src" / pkg / f)
p = parentDir(p)
when considerNimbleDirs:
if not options.gNoNimblePath:
var nimbleDir = getEnv("NIMBLE_DIR")
if nimbleDir.len == 0: nimbleDir = getHomeDir() / ".nimble"
result = findInNimbleDir(pkg, subdir, nimbleDir / "pkgs")
if result.len > 0: return result
when not defined(windows):
result = findInNimbleDir(pkg, subdir, "/opt/nimble/pkgs")
if result.len > 0: return result
proc scriptableImport(pkg, sub: string; info: TLineInfo): string =
resolveDollar(gProjectFull, info.toFullPath(), pkg, sub, info)
proc lookupPackage(pkg, subdir: PNode): string =
let sub = if subdir != nil: renderTree(subdir, {renderNoComments}).replace(" ") else: ""
case pkg.kind
of nkStrLit, nkRStrLit, nkTripleStrLit:
result = scriptableImport(pkg.strVal, sub, pkg.info)
of nkIdent:
result = scriptableImport(pkg.ident.s, sub, pkg.info)
else:
localError(pkg.info, "package name must be an identifier or string literal")
result = ""
proc getModuleName*(conf: ConfigRef; n: PNode): string =
# This returns a short relative module name without the nim extension
# e.g. like "system", "importer" or "somepath/module"
@@ -69,18 +163,3 @@ proc checkModuleName*(conf: ConfigRef; n: PNode; doLocalError=true): FileIndex =
result = InvalidFileIdx
else:
result = fileInfoIdx(conf, fullPath)
proc mangleModuleName*(conf: ConfigRef; path: AbsoluteFile): string =
## Mangle a relative module path to avoid path and symbol collisions.
##
## Used by backends that need to generate intermediary files from Nim modules.
## This is needed because the compiler uses a flat cache file hierarchy.
##
## Example:
## `foo-#head/../bar` becomes `@foo-@hhead@s..@sbar`
"@m" & relativeTo(path, conf.projectPath).string.multiReplace(
{$os.DirSep: "@s", $os.AltSep: "@s", "#": "@h", "@": "@@", ":": "@c"})
proc demangleModuleName*(path: string): string =
## Demangle a relative module path.
result = path.multiReplace({"@@": "@", "@h": "#", "@s": "/", "@m": "", "@c": ":"})

View File

@@ -12,10 +12,7 @@
import
ast, astalgo, magicsys, msgs, options,
idents, lexer, passes, syntaxes, llstream, modulegraphs,
lineinfos, pathutils, tables, packages
when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
lineinfos, pathutils, tables
import ic / replayer
@@ -25,11 +22,56 @@ proc resetSystemArtifacts*(g: ModuleGraph) =
template getModuleIdent(graph: ModuleGraph, filename: AbsoluteFile): PIdent =
getIdent(graph.cache, splitFile(filename).name)
template packageId(): untyped {.dirty.} = ItemId(module: PackageModuleId, item: int32(fileIdx))
proc getPackage(graph: ModuleGraph; fileIdx: FileIndex): PSym =
## returns package symbol (skPackage) for yet to be defined module for fileIdx
let filename = AbsoluteFile toFullPath(graph.config, fileIdx)
let name = getModuleIdent(graph, filename)
let info = newLineInfo(fileIdx, 1, 1)
let
pck = getPackageName(graph.config, filename.string)
pck2 = if pck.len > 0: pck else: "unknown"
pack = getIdent(graph.cache, pck2)
result = graph.packageSyms.strTableGet(pack)
if result == nil:
result = newSym(skPackage, getIdent(graph.cache, pck2), packageId(), nil, info)
#initStrTable(packSym.tab)
graph.packageSyms.strTableAdd(result)
else:
let modules = graph.modulesPerPackage.getOrDefault(result.itemId)
let existing = if modules.data.len > 0: strTableGet(modules, name) else: nil
if existing != nil and existing.info.fileIndex != info.fileIndex:
when false:
# we used to produce an error:
localError(graph.config, info,
"module names need to be unique per Nimble package; module clashes with " &
toFullPath(graph.config, existing.info.fileIndex))
else:
# but starting with version 0.20 we now produce a fake Nimble package instead
# to resolve the conflicts:
let pck3 = fakePackageName(graph.config, filename)
# this makes the new `result`'s owner be the original `result`
result = newSym(skPackage, getIdent(graph.cache, pck3), packageId(), result, info)
#initStrTable(packSym.tab)
graph.packageSyms.strTableAdd(result)
proc partialInitModule(result: PSym; graph: ModuleGraph; fileIdx: FileIndex; filename: AbsoluteFile) =
let packSym = getPackage(graph, fileIdx)
result.owner = packSym
result.position = int fileIdx
#initStrTable(result.tab(graph))
when false:
strTableAdd(result.tab, result) # a module knows itself
# This is now implemented via
# c.moduleScope.addSym(module) # a module knows itself
# in sem.nim, around line 527
if graph.modulesPerPackage.getOrDefault(packSym.itemId).data.len == 0:
graph.modulesPerPackage[packSym.itemId] = newStrTable()
graph.modulesPerPackage[packSym.itemId].strTableAdd(result)
proc newModule(graph: ModuleGraph; fileIdx: FileIndex): PSym =
let filename = AbsoluteFile toFullPath(graph.config, fileIdx)
# We cannot call ``newSym`` here, because we have to circumvent the ID
@@ -91,7 +133,7 @@ proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PSym =
# localError(result.info, errAttemptToRedefine, result.name.s)
# restore the notes for outer module:
graph.config.notes =
if graph.config.belongsToProjectPackage(s) or isDefined(graph.config, "booting"): graph.config.mainPackageNotes
if s.getnimblePkgId == graph.config.mainPackageId or isDefined(graph.config, "booting"): graph.config.mainPackageNotes
else: graph.config.foreignPackageNotes
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PNode =
@@ -126,7 +168,7 @@ proc compileProject*(graph: ModuleGraph; projectFileIdx = InvalidFileIdx) =
conf.projectMainIdx2 = projectFile
let packSym = getPackage(graph, projectFile)
graph.config.mainPackageId = packSym.getPackageId
graph.config.mainPackageId = packSym.getnimblePkgId
graph.importStack.add projectFile
if projectFile == systemFileIdx:

View File

@@ -12,10 +12,6 @@ import
std/private/miscdollars,
options, ropes, lineinfos, pathutils, strutils2
when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
type InstantiationInfo* = typeof(instantiationInfo())
template instLoc*(): InstantiationInfo = instantiationInfo(-2, fullPaths = true)

View File

@@ -12,9 +12,6 @@
import ast, msgs, ropes, options, pathutils
when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
type
NdiFile* = object
enabled: bool

View File

@@ -10,9 +10,6 @@
import ast, renderer, intsets, tables, msgs, options, lineinfos, strformat, idents, treetab, hashes
import sequtils, strutils, sets
when defined(nimPreviewSlimSystem):
import std/assertions
# IMPORTANT: notes not up to date, i'll update this comment again
#
# notes:

View File

@@ -8,10 +8,6 @@
#
import std/[os, strutils, parseopt]
when defined(nimPreviewSlimSystem):
import std/assertions
when defined(windows) and not defined(nimKochBootstrap):
# remove workaround pending bootstrap >= 1.5.1
# refs https://github.com/nim-lang/Nim/issues/18334#issuecomment-867114536
@@ -120,8 +116,7 @@ proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
if cmdPrefix.len > 0: cmdPrefix.add " "
# without the `cmdPrefix.len > 0` check, on windows you'd get a cryptic:
# `The parameter is incorrect`
let cmd = cmdPrefix & output.quoteShell & ' ' & conf.arguments
execExternalProgram(conf, cmd.strip(leading=false,trailing=true))
execExternalProgram(conf, cmdPrefix & output.quoteShell & ' ' & conf.arguments)
of cmdDocLike, cmdRst2html, cmdRst2tex: # bugfix(cmdRst2tex was missing)
if conf.arguments.len > 0:
# reserved for future use

View File

@@ -12,9 +12,6 @@
import parseutils, strutils, os, options, msgs, sequtils, lineinfos, pathutils,
std/sha1, tables
when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
proc addPath*(conf: ConfigRef; path: AbsoluteDir, info: TLineInfo) =
if not conf.searchPaths.contains(path):
conf.searchPaths.insert(path, 0)

View File

@@ -13,9 +13,6 @@ import
llstream, commands, os, strutils, msgs, lexer, ast,
options, idents, wordrecg, strtabs, lineinfos, pathutils, scriptconfig
when defined(nimPreviewSlimSystem):
import std/syncio
# ---------------- configuration file parser -----------------------------
# we use Nim's lexer here to save space and work
@@ -301,7 +298,7 @@ proc loadConfigs*(cfg: RelativeFile; cache: IdentCache; conf: ConfigRef; idgen:
if conf.cmd == cmdNimscript:
showHintConf()
conf.configFiles.setLen 0
if conf.cmd notin {cmdIdeTools, cmdCheck, cmdDump}:
if conf.cmd != cmdIdeTools:
if conf.cmd == cmdNimscript:
runNimScriptIfExists(conf.projectFull, isMain = true)
else:
@@ -311,6 +308,5 @@ proc loadConfigs*(cfg: RelativeFile; cache: IdentCache; conf: ConfigRef; idgen:
runNimScriptIfExists(scriptFile, isMain = true)
else:
# 'nimsuggest foo.nims' means to just auto-complete the NimScript file
# `nim check foo.nims' means to check the syntax of the NimScript file
discard
showHintConf()

View File

@@ -15,9 +15,6 @@
import
llstream, strutils
when defined(nimPreviewSlimSystem):
import std/assertions
const
Lrz* = ' '
Apo* = '\''

View File

@@ -19,19 +19,13 @@ Unstable API
import os, strutils
when defined(nimPreviewSlimSystem):
import std/assertions
const
docCss* = "$nimr/doc/nimdoc.css"
docCls* = "$nimr/doc/nimdoc.cls"
docHackNim* = "$nimr/tools/dochack/dochack.nim"
docHackJs* = docHackNim.changeFileExt("js")
docHackJsFname* = docHackJs.lastPathPart
theindexFname* = "theindex.html"
nimdocOutCss* = "nimdoc.out.css"
nimdocOutCls* = "nimdoc.cls"
# `out` to make it easier to use with gitignore in user's repos
htmldocsDirname* = "htmldocs"
dotdotMangle* = "_._" ## refs #13223

View File

@@ -12,9 +12,6 @@
import
ast, astalgo, lineinfos, bitsets, types, options
when defined(nimPreviewSlimSystem):
import std/assertions
proc inSet*(s: PNode, elem: PNode): bool =
assert s.kind == nkCurly
if s.kind != nkCurly:

View File

@@ -127,11 +127,11 @@ proc analyse(c: var Con; b: var BasicBlock; n: PNode) =
for i in 0 ..< n.len:
analyse(c, b, n[i])
else:
#[ Test destructor/tmatrix.test3:
#[ Test tmatrix.test3:
Prevent this from being elided. We should probably
find a better solution...
`=sink`(b, -
`=sink`(b, - (
let blitTmp = b;
wasMoved(b);
blitTmp + a)

View File

@@ -14,17 +14,12 @@ import
from terminal import isatty
from times import utc, fromUnix, local, getTime, format, DateTime
from std/private/globs import nativeToUnixPath
when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
const
hasTinyCBackend* = defined(tinyc)
useEffectSystem* = true
useWriteTracking* = false
hasFFI* = defined(nimHasLibFFI)
copyrightYear* = "2022"
copyrightYear* = "2021"
nimEnableCovariance* = defined(nimEnableCovariance)
@@ -101,7 +96,6 @@ type # please make sure we have under 32 options
optPanics # turn panics (sysFatal) into a process termination
optNimV1Emulation # emulate Nim v1.0
optNimV12Emulation # emulate Nim v1.2
optNimV16Emulation # emulate Nim v1.6
optSourcemap
optProfileVM # enable VM profiler
optEnableDeepCopy # ORC specific: enable 'deepcopy' for all types.
@@ -183,14 +177,14 @@ type
gcMarkAndSweep = "markAndSweep"
gcHooks = "hooks"
gcRefc = "refc"
gcV2 = "v2"
gcGo = "go"
# gcRefc and the GCs that follow it use a write barrier,
# as far as usesWriteBarrier() is concerned
IdeCmd* = enum
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideChkFile, ideMod,
ideHighlight, ideOutline, ideKnown, ideMsg, ideProject, ideGlobalSymbols,
ideRecompile, ideChanged
ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideMod,
ideHighlight, ideOutline, ideKnown, ideMsg, ideProject
Feature* = enum ## experimental features; DO NOT RENAME THESE!
implicitDeref,
@@ -201,7 +195,7 @@ type
notnil,
dynamicBindSym,
forLoopMacros, # not experimental anymore; remains here for backwards compatibility
caseStmtMacros, # ditto
caseStmtMacros,
codeReordering,
compiletimeFFI,
## This requires building nim with `-d:nimHasLibFFI`
@@ -213,8 +207,7 @@ type
strictNotNil,
overloadableEnums,
strictEffects,
unicodeOperators,
flexibleOptionalParams
unicodeOperators
LegacyFeature* = enum
allowSemcheckedAstModification,
@@ -396,7 +389,6 @@ type
structuredErrorHook*: proc (config: ConfigRef; info: TLineInfo; msg: string;
severity: Severity) {.closure, gcsafe.}
cppCustomNamespace*: string
nimMainPrefix*: string
vmProfileData*: ProfileData
proc parseNimVersion*(a: string): NimVer =
@@ -603,7 +595,7 @@ proc isDefined*(conf: ConfigRef; symbol: string): bool =
osQnx, osAtari, osAix,
osHaiku, osVxWorks, osSolaris, osNetbsd,
osFreebsd, osOpenbsd, osDragonfly, osMacosx, osIos,
osAndroid, osNintendoSwitch, osFreeRTOS, osCrossos, osZephyr}
osAndroid, osNintendoSwitch, osFreeRTOS, osCrossos}
of "linux":
result = conf.target.targetOS in {osLinux, osAndroid}
of "bsd":
@@ -623,8 +615,6 @@ proc isDefined*(conf: ConfigRef; symbol: string): bool =
result = conf.target.targetOS == osNintendoSwitch
of "freertos", "lwip":
result = conf.target.targetOS == osFreeRTOS
of "zephyr":
result = conf.target.targetOS == osZephyr
of "littleendian": result = CPU[conf.target.targetCPU].endian == littleEndian
of "bigendian": result = CPU[conf.target.targetCPU].endian == bigEndian
of "cpu8": result = CPU[conf.target.targetCPU].bit == 8
@@ -807,8 +797,6 @@ proc toGeneratedFile*(conf: ConfigRef; path: AbsoluteFile,
proc completeGeneratedFilePath*(conf: ConfigRef; f: AbsoluteFile,
createSubDir: bool = true): AbsoluteFile =
## Return an absolute path of a generated intermediary file.
## Optionally creates the cache directory if `createSubDir` is `true`.
let subdir = getNimcacheDir(conf)
if createSubDir:
try:
@@ -816,6 +804,11 @@ proc completeGeneratedFilePath*(conf: ConfigRef; f: AbsoluteFile,
except OSError:
conf.quitOrRaise "cannot create directory: " & subdir.string
result = subdir / RelativeFile f.string.splitPath.tail
#echo "completeGeneratedFilePath(", f, ") = ", result
proc toRodFile*(conf: ConfigRef; f: AbsoluteFile; ext = RodExt): AbsoluteFile =
result = changeFileExt(completeGeneratedFilePath(conf,
withPackageName(conf, f)), ext)
proc rawFindFile(conf: ConfigRef; f: RelativeFile; suppressStdlib: bool): AbsoluteFile =
for it in conf.searchPaths:
@@ -994,16 +987,12 @@ proc parseIdeCmd*(s: string): IdeCmd =
of "use": ideUse
of "dus": ideDus
of "chk": ideChk
of "chkFile": ideChkFile
of "mod": ideMod
of "highlight": ideHighlight
of "outline": ideOutline
of "known": ideKnown
of "msg": ideMsg
of "project": ideProject
of "globalSymbols": ideGlobalSymbols
of "recompile": ideRecompile
of "changed": ideChanged
else: ideNone
proc `$`*(c: IdeCmd): string =
@@ -1014,7 +1003,6 @@ proc `$`*(c: IdeCmd): string =
of ideUse: "use"
of ideDus: "dus"
of ideChk: "chk"
of ideChkFile: "chkFile"
of ideMod: "mod"
of ideNone: "none"
of ideHighlight: "highlight"
@@ -1022,9 +1010,6 @@ proc `$`*(c: IdeCmd): string =
of ideKnown: "known"
of ideMsg: "msg"
of ideProject: "project"
of ideGlobalSymbols: "globalSymbols"
of ideRecompile: "recompile"
of ideChanged: "changed"
proc floatInt64Align*(conf: ConfigRef): int16 =
## Returns either 4 or 8 depending on reasons.

View File

@@ -37,7 +37,24 @@ proc getNimbleFile*(conf: ConfigRef; path: string): string =
proc getPackageName*(conf: ConfigRef; path: string): string =
## returns nimble package name, e.g.: `cligen`
let path = getNimbleFile(conf, path)
if path.len > 0:
return path.splitFile.name
result = path.splitFile.name
proc fakePackageName*(conf: ConfigRef; path: AbsoluteFile): string =
# Convert `path` so that 2 modules with same name
# in different directory get different name and they can be
# placed in a directory.
# foo-#head/../bar becomes @foo-@hhead@s..@sbar
result = "@m" & relativeTo(path, conf.projectPath).string.multiReplace(
{$os.DirSep: "@s", $os.AltSep: "@s", "#": "@h", "@": "@@", ":": "@c"})
proc demanglePackageName*(path: string): string =
result = path.multiReplace({"@@": "@", "@h": "#", "@s": "/", "@m": "", "@c": ":"})
proc withPackageName*(conf: ConfigRef; path: AbsoluteFile): AbsoluteFile =
let x = getPackageName(conf, path.string)
let (p, file, ext) = path.splitFile
if x == "stdlib":
# Hot code reloading now relies on 'stdlib_system' names etc.
result = p / RelativeFile((x & '_' & file) & ext)
else:
return "unknown"
result = p / RelativeFile(fakePackageName(conf, path))

View File

@@ -1,49 +0,0 @@
#
#
# The Nim Compiler
# (c) Copyright 2022 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Package related procs.
##
## See Also:
## * `packagehandling` for package path handling
## * `modulegraphs.getPackage`
## * `modulegraphs.belongsToStdlib`
import "." / [options, ast, lineinfos, idents, pathutils, msgs]
proc getPackage*(conf: ConfigRef; cache: IdentCache; fileIdx: FileIndex): PSym =
## Return a new package symbol.
##
## See Also:
## * `modulegraphs.getPackage`
let
filename = AbsoluteFile toFullPath(conf, fileIdx)
name = getIdent(cache, splitFile(filename).name)
info = newLineInfo(fileIdx, 1, 1)
pkgName = getPackageName(conf, filename.string)
pkgIdent = getIdent(cache, pkgName)
newSym(skPackage, pkgIdent, ItemId(module: PackageModuleId, item: int32(fileIdx)), nil, info)
func getPackageSymbol*(sym: PSym): PSym =
## Return the owning package symbol.
assert sym != nil
result = sym
while result.kind != skPackage:
result = result.owner
assert result != nil, repr(sym.info)
func getPackageId*(sym: PSym): int =
## Return the owning package ID.
sym.getPackageSymbol.id
func belongsToProjectPackage*(conf: ConfigRef, sym: PSym): bool =
## Return whether the symbol belongs to the project's package.
##
## See Also:
## * `modulegraphs.belongsToStdlib`
conf.mainPackageId == sym.getPackageId

View File

@@ -143,11 +143,8 @@ proc checkForSideEffects*(n: PNode): TSideEffectAnalysis =
let s = op.sym
if sfSideEffect in s.flags:
return seSideEffect
elif tfNoSideEffect in op.typ.flags:
result = seNoSideEffect
else:
# assume side effect:
result = seSideEffect
# assume no side effect:
result = seNoSideEffect
elif tfNoSideEffect in op.typ.flags:
# indirect call without side effects:
result = seNoSideEffect
@@ -179,7 +176,6 @@ type
arLocalLValue, # is an l-value, but local var; must not escape
# its stack frame!
arDiscriminant, # is a discriminant
arAddressableConst, # an addressable const
arLentValue, # lent value
arStrange # it is a strange beast like 'typedesc[var T]'
@@ -213,7 +209,7 @@ proc exprRoot*(n: PNode): PSym =
else:
break
proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult =
## 'owner' can be nil!
result = arNone
case n.kind
@@ -221,20 +217,20 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
if n.typ != nil and n.typ.kind in {tyVar}:
result = arLValue
of nkSym:
const kinds = {skVar, skResult, skTemp, skParam, skLet, skForVar}
if n.sym.kind == skParam:
result = if n.sym.typ.kind in {tyVar, tySink}: arLValue else: arAddressableConst
elif n.sym.kind == skConst and dontInlineConstant(n, n.sym.ast):
result = arAddressableConst
let kinds = if isUnsafeAddr: {skVar, skResult, skTemp, skParam, skLet, skForVar}
else: {skVar, skResult, skTemp}
if n.sym.kind == skParam and n.sym.typ.kind in {tyVar, tySink}:
result = arLValue
elif isUnsafeAddr and n.sym.kind == skParam:
result = arLValue
elif isUnsafeAddr and n.sym.kind == skConst and dontInlineConstant(n, n.sym.ast):
result = arLValue
elif n.sym.kind in kinds:
if n.sym.kind in {skParam, skLet, skForVar}:
result = arAddressableConst
if owner != nil and owner == n.sym.owner and
sfGlobal notin n.sym.flags:
result = arLocalLValue
else:
if owner != nil and owner == n.sym.owner and
sfGlobal notin n.sym.flags:
result = arLocalLValue
else:
result = arLValue
result = arLValue
elif n.sym.kind == skType:
let t = n.sym.typ.skipTypes({tyTypeDesc})
if t.kind in {tyVar}: result = arStrange
@@ -242,10 +238,10 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
let t = skipTypes(n[0].typ, abstractInst-{tyTypeDesc})
if t.kind in {tyVar, tySink, tyPtr, tyRef}:
result = arLValue
elif t.kind == tyLent:
result = arAddressableConst
elif isUnsafeAddr and t.kind == tyLent:
result = arLValue
else:
result = isAssignable(owner, n[0])
result = isAssignable(owner, n[0], isUnsafeAddr)
if result != arNone and n[1].kind == nkSym and
sfDiscriminant in n[1].sym.flags:
result = arDiscriminant
@@ -253,23 +249,23 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
let t = skipTypes(n[0].typ, abstractInst-{tyTypeDesc})
if t.kind in {tyVar, tySink, tyPtr, tyRef}:
result = arLValue
elif t.kind == tyLent:
result = arAddressableConst
elif isUnsafeAddr and t.kind == tyLent:
result = arLValue
else:
result = isAssignable(owner, n[0])
result = isAssignable(owner, n[0], isUnsafeAddr)
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
# Object and tuple conversions are still addressable, so we skip them
# XXX why is 'tyOpenArray' allowed here?
if skipTypes(n.typ, abstractPtrs-{tyTypeDesc}).kind in
{tyOpenArray, tyTuple, tyObject}:
result = isAssignable(owner, n[1])
result = isAssignable(owner, n[1], isUnsafeAddr)
elif compareTypes(n.typ, n[1].typ, dcEqIgnoreDistinct):
# types that are equal modulo distinction preserve l-value:
result = isAssignable(owner, n[1])
result = isAssignable(owner, n[1], isUnsafeAddr)
of nkHiddenDeref:
let n0 = n[0]
if n0.typ.kind == tyLent:
if n0.kind == nkSym and n0.sym.kind == skResult:
if isUnsafeAddr or (n0.kind == nkSym and n0.sym.kind == skResult):
result = arLValue
else:
result = arLentValue
@@ -278,19 +274,18 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
of nkDerefExpr, nkHiddenAddr:
result = arLValue
of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
result = isAssignable(owner, n[0])
result = isAssignable(owner, n[0], isUnsafeAddr)
of nkCallKinds:
# builtin slice keeps lvalue-ness:
if getMagic(n) in {mArrGet, mSlice}:
result = isAssignable(owner, n[1])
elif n.typ != nil:
case n.typ.kind
of tyVar: result = arLValue
of tyLent: result = arLentValue
else: discard
result = isAssignable(owner, n[1], isUnsafeAddr)
elif n.typ != nil and n.typ.kind in {tyVar}:
result = arLValue
elif isUnsafeAddr and n.typ != nil and n.typ.kind == tyLent:
result = arLValue
of nkStmtList, nkStmtListExpr:
if n.typ != nil:
result = isAssignable(owner, n.lastSon)
result = isAssignable(owner, n.lastSon, isUnsafeAddr)
of nkVarTy:
# XXX: The fact that this is here is a bit of a hack.
# The goal is to allow the use of checks such as "foo(var T)"

View File

@@ -36,9 +36,6 @@ import
when defined(nimpretty):
import layouter
when defined(nimPreviewSlimSystem):
import std/assertions
type
Parser* = object # A Parser object represents a file that
# is being parsed
@@ -585,10 +582,10 @@ proc parsePar(p: var Parser): PNode =
#| | 'finally' | 'except' | 'for' | 'block' | 'const' | 'let'
#| | 'when' | 'var' | 'mixin'
#| par = '(' optInd
#| ( &parKeyw (ifExpr / complexOrSimpleStmt) ^+ ';'
#| | ';' (ifExpr / complexOrSimpleStmt) ^+ ';'
#| ( &parKeyw (ifExpr \ complexOrSimpleStmt) ^+ ';'
#| | ';' (ifExpr \ complexOrSimpleStmt) ^+ ';'
#| | pragmaStmt
#| | simpleExpr ( ('=' expr (';' (ifExpr / complexOrSimpleStmt) ^+ ';' )? )
#| | simpleExpr ( ('=' expr (';' (ifExpr \ complexOrSimpleStmt) ^+ ';' )? )
#| | (':' expr (',' exprColonEqExpr ^+ ',' )? ) ) )
#| optPar ')'
#
@@ -814,7 +811,7 @@ proc primarySuffix(p: var Parser, r: PNode,
#| | DOTLIKEOP optInd symbol generalizedLit?
#| | '[' optInd exprColonEqExprList optPar ']'
#| | '{' optInd exprColonEqExprList optPar '}'
#| | &( '`'|IDENT|literal|'cast'|'addr'|'type') expr (comma expr)* # command syntax
#| | &( '`'|IDENT|literal|'cast'|'addr'|'type') expr # command syntax
result = r
# progress guaranteed
@@ -824,14 +821,14 @@ proc primarySuffix(p: var Parser, r: PNode,
of tkParLe:
# progress guaranteed
if p.tok.strongSpaceA > 0:
result = commandExpr(p, result, mode)
# type sections allow full command syntax
# inside type sections, expressions such as `ref (int, bar)`
# are parsed as a nkCommand with a single tuple argument (nkPar)
if mode == pmTypeDef:
var isFirstParam = false
while p.tok.tokType == tkComma:
getTok(p)
optInd(p, result)
result.add(commandParam(p, isFirstParam, mode))
result = newNodeP(nkCommand, p)
result.add r
result.add primary(p, pmNormal)
else:
result = commandExpr(p, result, mode)
break
result = namedParams(p, result, nkCall, tkParRi)
if result.len > 1 and result[1].kind == nkExprColonExpr:
@@ -872,18 +869,9 @@ proc primarySuffix(p: var Parser, r: PNode,
# actually parsing {.push hints:off.} as {.push(hints:off).} is a sweet
# solution, but pragmas.nim can't handle that
result = commandExpr(p, result, mode)
if mode == pmTypeDef:
var isFirstParam = false
while p.tok.tokType == tkComma:
getTok(p)
optInd(p, result)
result.add(commandParam(p, isFirstParam, mode))
break
else:
break
# type sections allow post-expr blocks
if mode == pmTypeDef:
result = postExprBlocks(p, result)
proc parseOperators(p: var Parser, headNode: PNode,
limit: int, mode: PrimaryMode): PNode =
@@ -1122,14 +1110,11 @@ proc optPragmas(p: var Parser): PNode =
proc parseDoBlock(p: var Parser; info: TLineInfo): PNode =
#| doBlock = 'do' paramListArrow pragma? colcom stmt
var params = parseParamList(p, retColon=false)
let params = parseParamList(p, retColon=false)
let pragmas = optPragmas(p)
colcom(p, result)
result = parseStmt(p)
if params.kind != nkEmpty or pragmas.kind != nkEmpty:
if params.kind == nkEmpty:
params = newNodeP(nkFormalParams, p)
params.add(p.emptyNode) # return type
if params.kind != nkEmpty:
result = newProcNode(nkDo, info,
body = result, params = params, name = p.emptyNode, pattern = p.emptyNode,
genericParams = p.emptyNode, pragmas = pragmas, exceptions = p.emptyNode)
@@ -1161,7 +1146,7 @@ proc isExprStart(p: Parser): bool =
of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf, tkFor,
tkProc, tkFunc, tkIterator, tkBind, tkBuiltInMagics,
tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCustomLit, tkVar, tkRef, tkPtr,
tkTuple, tkObject, tkWhen, tkCase, tkOut, tkTry, tkBlock:
tkTuple, tkObject, tkWhen, tkCase, tkOut:
result = true
else: result = false
@@ -1354,8 +1339,7 @@ proc parseTypeDesc(p: var Parser): PNode =
result = binaryNot(p, result)
proc parseTypeDefAux(p: var Parser): PNode =
#| typeDefAux = simpleExpr ('not' expr
#| | postExprBlocks)?
#| typeDefAux = simpleExpr ('not' expr)?
result = simpleExpr(p, pmTypeDef)
result = binaryNot(p, result)
@@ -1397,10 +1381,7 @@ proc postExprBlocks(p: var Parser, x: PNode): PNode =
if stmtList[0].kind == nkStmtList: stmtList = stmtList[0]
stmtList.flags.incl nfBlockArg
if openingParams.kind != nkEmpty or openingPragmas.kind != nkEmpty:
if openingParams.kind == nkEmpty:
openingParams = newNodeP(nkFormalParams, p)
openingParams.add(p.emptyNode) # return type
if openingParams.kind != nkEmpty:
result.add newProcNode(nkDo, stmtList.info, body = stmtList,
params = openingParams,
name = p.emptyNode, pattern = p.emptyNode,
@@ -1896,7 +1877,7 @@ proc parseEnum(p: var Parser): PNode =
var symPragma = a
var pragma: PNode
if (p.tok.indent < 0 or p.tok.indent >= p.currInd) and p.tok.tokType == tkCurlyDotLe:
if p.tok.tokType == tkCurlyDotLe:
pragma = optPragmas(p)
symPragma = newNodeP(nkPragmaExpr, p)
symPragma.add(a)
@@ -2393,10 +2374,6 @@ proc parseAll(p: var Parser): PNode =
if p.tok.indent != 0:
parMessage(p, errInvalidIndentation)
proc checkFirstLineIndentation*(p: var Parser) =
if p.tok.indent != 0 and p.tok.strongSpaceA > 0:
parMessage(p, errInvalidIndentation)
proc parseTopLevelStmt(p: var Parser): PNode =
## Implements an iterator which, when called repeatedly, returns the next
## top-level statement or emptyNode if end of stream.

View File

@@ -14,10 +14,7 @@ import
options, ast, llstream, msgs,
idents,
syntaxes, modulegraphs, reorder,
lineinfos, pathutils, std/sha1, packages
when defined(nimPreviewSlimSystem):
import std/syncio
lineinfos, pathutils
type
TPassData* = tuple[input: PNode, closeOutput: PNode]
@@ -104,7 +101,7 @@ const
proc prepareConfigNotes(graph: ModuleGraph; module: PSym) =
# don't be verbose unless the module belongs to the main package:
if graph.config.belongsToProjectPackage(module):
if module.getnimblePkgId == graph.config.mainPackageId:
graph.config.notes = graph.config.mainPackageNotes
else:
if graph.config.mainPackageNotes == {}: graph.config.mainPackageNotes = graph.config.notes
@@ -114,6 +111,12 @@ proc moduleHasChanged*(graph: ModuleGraph; module: PSym): bool {.inline.} =
result = true
#module.id >= 0 or isDefined(graph.config, "nimBackendAssumesChange")
proc partOfStdlib(x: PSym): bool =
var it = x.owner
while it != nil and it.kind == skPackage and it.owner != nil:
it = it.owner
result = it != nil and it.name.s == "stdlib"
proc processModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator;
stream: PLLStream): bool {.discardable.} =
if graph.stopCompile(): return true
@@ -132,15 +135,10 @@ proc processModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator;
return false
else:
s = stream
when defined(nimsuggest):
let filename = toFullPathConsiderDirty(graph.config, fileIdx).string
msgs.setHash(graph.config, fileIdx, $sha1.secureHashFile(filename))
while true:
openParser(p, fileIdx, s, graph.cache, graph.config)
if not belongsToStdlib(graph, module) or (belongsToStdlib(graph, module) and module.name.s == "distros"):
if not partOfStdlib(module) or module.name.s == "distros":
# XXX what about caching? no processing then? what if I change the
# modules to include between compilation runs? we'd need to track that
# in ROD files. I think we should enable this feature only
@@ -149,7 +147,6 @@ proc processModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator;
processImplicits graph, graph.config.implicitImports, nkImportStmt, a, module
processImplicits graph, graph.config.implicitIncludes, nkIncludeStmt, a, module
checkFirstLineIndentation(p)
while true:
if graph.stopCompile(): break
var n = parseTopLevelStmt(p)

View File

@@ -12,9 +12,6 @@
import os, pathnorm
when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
type
AbsoluteFile* = distinct string
AbsoluteDir* = distinct string

View File

@@ -13,9 +13,6 @@
import
ast, types, semdata, sigmatch, idents, aliases, parampatterns, trees
when defined(nimPreviewSlimSystem):
import std/assertions
type
TPatternContext = object
owner: PSym

View File

@@ -16,17 +16,13 @@
import
strutils
when defined(nimPreviewSlimSystem):
import std/assertions
type
TSystemOS* = enum # Also add OS in initialization section and alias
# conditionals to condsyms (end of module).
osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris,
osIrix, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osCrossos, osAix, osPalmos, osQnx,
osAmiga, osAtari, osNetware, osMacos, osMacosx, osIos, osHaiku, osAndroid, osVxWorks
osGenode, osJS, osNimVM, osStandalone, osNintendoSwitch, osFreeRTOS, osZephyr, osAny
osGenode, osJS, osNimVM, osStandalone, osNintendoSwitch, osFreeRTOS, osAny
type
TInfoOSProp* = enum
@@ -189,10 +185,6 @@ const
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {ospPosix}),
(name: "Zephyr", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {ospPosix}),
(name: "Any", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
@@ -205,8 +197,7 @@ type
cpuNone, cpuI386, cpuM68k, cpuAlpha, cpuPowerpc, cpuPowerpc64,
cpuPowerpc64el, cpuSparc, cpuVm, cpuHppa, cpuIa64, cpuAmd64, cpuMips,
cpuMipsel, cpuArm, cpuArm64, cpuJS, cpuNimVM, cpuAVR, cpuMSP430,
cpuSparc64, cpuMips64, cpuMips64el, cpuRiscV32, cpuRiscV64, cpuEsp, cpuWasm32,
cpuE2k, cpuLoongArch64
cpuSparc64, cpuMips64, cpuMips64el, cpuRiscV32, cpuRiscV64, cpuEsp, cpuWasm32
type
TInfoCPU* = tuple[name: string, intSize: int, endian: Endianness,
@@ -241,9 +232,7 @@ const
(name: "riscv32", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
(name: "riscv64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
(name: "esp", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
(name: "wasm32", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
(name: "e2k", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
(name: "loongarch64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64)]
(name: "wasm32", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32)]
type
Target* = object

View File

@@ -14,9 +14,6 @@ import
wordrecg, ropes, options, strutils, extccomp, math, magicsys, trees,
types, lookups, lineinfos, pathutils, linter
when defined(nimPreviewSlimSystem):
import std/assertions
from ic / ic import addCompilerProc
const
@@ -34,7 +31,7 @@ const
wAsmNoStackFrame, wDiscardable, wNoInit, wCodegenDecl,
wGensym, wInject, wRaises, wEffectsOf, wTags, wLocks, wDelegator, wGcSafe,
wConstructor, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy,
wRequires, wEnsures, wEnforceNoRaises}
wRequires, wEnsures}
converterPragmas* = procPragmas
methodPragmas* = procPragmas+{wBase}-{wImportCpp}
templatePragmas* = {wDeprecated, wError, wGensym, wInject, wDirty,
@@ -47,21 +44,18 @@ const
wDiscardable, wGensym, wInject, wRaises, wEffectsOf,
wTags, wLocks, wGcSafe, wRequires, wEnsures}
exprPragmas* = {wLine, wLocks, wNoRewrite, wGcSafe, wNoSideEffect}
stmtPragmas* = {
wHint, wWarning, wError,
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangeChecks,
wBoundChecks, wOverflowChecks, wNilChecks, wStaticBoundchecks,
wStyleChecks, wAssertions,
wWarnings, wHints,
wLineDir, wStackTrace, wLineTrace, wOptimization, wHint, wWarning, wError,
wFatal, wDefine, wUndef, wCompile, wLink, wLinksys, wPure, wPush, wPop,
wPassl, wPassc, wLocalPassc,
wDeadCodeElimUnused, # deprecated, always on
wDeprecated,
wPragma, wEmit, wUnroll,
wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
wLinearScanEnd, wPatterns, wTrMacros, wEffects, wNoForward, wReorder, wComputedGoto,
wExperimental, wThis, wUsed, wInvariant, wAssume, wAssert}
stmtPragmasTopLevel* = {wChecks, wObjChecks, wFieldChecks, wRangeChecks,
wBoundChecks, wOverflowChecks, wNilChecks, wStaticBoundchecks,
wStyleChecks, wAssertions,
wWarnings, wHints,
wLineDir, wStackTrace, wLineTrace, wOptimization,
wFloatChecks, wInfChecks, wNanChecks}
lambdaPragmas* = {FirstCallConv..LastCallConv,
wNoSideEffect, wSideEffect, wNoreturn, wNosinks, wDynlib, wHeader,
wThread, wAsmNoStackFrame,
@@ -641,13 +635,12 @@ proc pragmaLine(c: PContext, n: PNode) =
n.info = getInfoContext(c.config, -1)
proc processPragma(c: PContext, n: PNode, i: int) =
## Create and add a new custom pragma `{.pragma: name.}` node to the module's context.
let it = n[i]
if it.kind notin nkPragmaCallKinds and it.safeLen == 2: invalidPragma(c, n)
elif it.safeLen != 2 or it[0].kind != nkIdent or it[1].kind != nkIdent:
invalidPragma(c, n)
var userPragma = newSym(skTemplate, it[1].ident, nextSymId(c.idgen), c.module, it.info, c.config.options)
var userPragma = newSym(skTemplate, it[1].ident, nextSymId(c.idgen), nil, it.info, c.config.options)
userPragma.ast = newTreeI(nkPragma, n.info, n.sons[i+1..^1])
strTableAdd(c.userPragmas, userPragma)
@@ -657,7 +650,7 @@ proc pragmaRaisesOrTags(c: PContext, n: PNode) =
x.typ = makeTypeFromExpr(c, x)
else:
var t = skipTypes(c.semTypeNode(c, x, nil), skipPtrs)
if t.kind notin {tyObject, tyOr}:
if t.kind != tyObject and not t.isMetaType:
localError(c.config, x.info, errGenerated, "invalid type for raises/tags list")
x.typ = t
@@ -1244,8 +1237,6 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
pragmaProposition(c, it)
of wEnsures:
pragmaEnsures(c, it)
of wEnforceNoRaises:
sym.flags.incl sfNeverRaises
else: invalidPragma(c, it)
elif comesFromPush and whichKeyword(ident) != wInvalid:
discard "ignore the .push pragma; it doesn't apply"

View File

@@ -17,9 +17,6 @@ when defined(nimHasUsed):
import
lexer, options, idents, strutils, ast, msgs, lineinfos
when defined(nimPreviewSlimSystem):
import std/[syncio, assertions]
type
TRenderFlag* = enum
renderNone, renderNoBody, renderNoComments, renderDocComments,
@@ -165,7 +162,6 @@ proc putNL(g: var TSrcGen) =
proc optNL(g: var TSrcGen, indent: int) =
g.pendingNL = indent
g.lineLen = indent
g.col = g.indent
when defined(nimpretty): g.pendingNewlineCount = 0
proc optNL(g: var TSrcGen) =
@@ -174,7 +170,6 @@ proc optNL(g: var TSrcGen) =
proc optNL(g: var TSrcGen; a, b: PNode) =
g.pendingNL = g.indent
g.lineLen = g.indent
g.col = g.indent
when defined(nimpretty): g.pendingNewlineCount = lineDiff(a, b)
proc indentNL(g: var TSrcGen) =

View File

@@ -4,9 +4,6 @@ import
msgs, modulegraphs, syntaxes, options, modulepaths,
lineinfos
when defined(nimPreviewSlimSystem):
import std/assertions
type
DepN = ref object
pnode: PNode

View File

@@ -10,9 +10,6 @@
## Serialization utilities for the compiler.
import strutils, math
when defined(nimPreviewSlimSystem):
import std/assertions
# bcc on windows doesn't have C99 functions
when defined(windows) and defined(bcc):
{.emit: """#if defined(_MSC_VER) && _MSC_VER < 1900

View File

@@ -60,10 +60,6 @@ import
from pathutils import AbsoluteFile
when defined(nimPreviewSlimSystem):
import std/[assertions, syncio]
type
FormatStr* = string # later we may change it to CString for better
# performance of the code generator (assignments
@@ -333,3 +329,10 @@ proc equalsFile*(r: Rope, filename: AbsoluteFile): bool =
if result:
result = equalsFile(r, f)
close(f)
proc writeRopeIfNotEqual*(r: Rope, filename: AbsoluteFile): bool =
# returns true if overwritten
if not equalsFile(r, filename):
result = writeRope(r, filename)
else:
result = false

View File

@@ -16,9 +16,6 @@ import
os, times, osproc, wordrecg, strtabs, modulegraphs,
pathutils
when defined(nimPreviewSlimSystem):
import std/syncio
# we support 'cmpIgnoreStyle' natively for efficiency:
from strutils import cmpIgnoreStyle, contains

View File

@@ -703,16 +703,7 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym =
call.add(newIdentNode(fn.name, fn.info))
for i in 1..<fn.typ.n.len:
let param = fn.typ.n[i]
const desiredTypes = abstractVar + {tyCompositeTypeClass} - {tyTypeDesc, tyDistinct}
#[.
# We only want the type not any modifiers such as `ptr`, `var`, `ref` ...
# tyCompositeTypeClass is here for
# when using something like:
type Foo[T] = distinct int
proc `$`(f: Foo): string {.borrow.}
# We want to skip the `Foo` to get `int`
]#
let t = skipTypes(param.typ, desiredTypes)
let t = skipTypes(param.typ, abstractVar-{tyTypeDesc, tyDistinct})
if t.kind == tyDistinct or param.typ.kind == tyDistinct: hasDistinct = true
var x: PType
if param.typ.kind == tyVar:
@@ -730,4 +721,4 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym =
result = nil
elif result.magic in {mArrPut, mArrGet}:
# cannot borrow these magics for now
result = nil
result = nil

View File

@@ -11,9 +11,6 @@
import tables
when defined(nimPreviewSlimSystem):
import std/assertions
import
intsets, options, ast, astalgo, msgs, idents, renderer,
magicsys, vmdef, modulegraphs, lineinfos, sets, pathutils

View File

@@ -645,13 +645,13 @@ proc fixAbstractType(c: PContext, n: PNode) =
skipTypes(it.typ, abstractVar).kind notin {tyOpenArray, tyVarargs}:
if skipTypes(it[1].typ, abstractVar).kind in
{tyNil, tyTuple, tySet} or it[1].isArrayConstr:
var s = skipTypes(it.typ, abstractVar + tyUserTypeClasses)
var s = skipTypes(it.typ, abstractVar)
if s.kind != tyUntyped:
changeType(c, it[1], s, check=true)
n[i] = it[1]
proc isAssignable(c: PContext, n: PNode): TAssignableResult =
result = parampatterns.isAssignable(c.p.owner, n)
proc isAssignable(c: PContext, n: PNode; isUnsafeAddr=false): TAssignableResult =
result = parampatterns.isAssignable(c.p.owner, n, isUnsafeAddr)
proc isUnresolvedSym(s: PSym): bool =
result = s.kind == skGenericParam
@@ -1188,8 +1188,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
let s = getGenSym(c, sym)
case s.kind
of skConst:
if n.kind != nkDotExpr: # dotExpr is already checked by builtinFieldAccess
markUsed(c, n.info, s)
markUsed(c, n.info, s)
onUse(n.info, s)
let typ = skipTypes(s.typ, abstractInst-{tyTypeDesc})
case typ.kind
@@ -1250,8 +1249,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
if s.magic == mNimvm:
localError(c.config, n.info, "illegal context for 'nimvm' magic")
if n.kind != nkDotExpr: # dotExpr is already checked by builtinFieldAccess
markUsed(c, n.info, s)
markUsed(c, n.info, s)
onUse(n.info, s)
result = newSymNode(s, n.info)
# We cannot check for access to outer vars for example because it's still
@@ -1272,8 +1270,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
n.typ = s.typ
return n
of skType:
if n.kind != nkDotExpr: # dotExpr is already checked by builtinFieldAccess
markUsed(c, n.info, s)
markUsed(c, n.info, s)
onUse(n.info, s)
if s.typ.kind == tyStatic and s.typ.base.kind != tyNone and s.typ.n != nil:
return s.typ.n
@@ -1417,7 +1414,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
if ty.kind in tyUserTypeClasses and ty.isResolvedUserTypeClass:
ty = ty.lastSon
ty = skipTypes(ty, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef, tyOwned, tyAlias, tySink, tyStatic})
ty = skipTypes(ty, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef, tyOwned, tyAlias, tySink})
while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct, tyGenericInst, tyAlias})
var check: PNode = nil
if ty.kind == tyObject:
@@ -1436,10 +1433,8 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
# is the access to a public field or in the same module or in a friend?
markUsed(c, n[1].info, f)
onUse(n[1].info, f)
let info = n[1].info
n[0] = makeDeref(n[0])
n[1] = newSymNode(f) # we now have the correct field
n[1].info = info # preserve the original info
n.typ = f.typ
if check == nil:
result = n
@@ -1663,11 +1658,9 @@ proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode =
# `proc fun(a: var int): var int = a`
discard
else: discard
let valid = isAssignable(c, n)
let valid = isAssignable(c, n, isLent)
if valid != arLValue:
if valid in {arAddressableConst, arLentValue} and isLent:
discard "ok"
elif valid == arLocalLValue:
if valid == arLocalLValue:
localError(c.config, n.info, errXStackEscape % renderTree(n, {renderNoComments}))
else:
localError(c.config, n.info, errExprHasNoAddress)
@@ -1791,7 +1784,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
if le == nil:
localError(c.config, a.info, "expression has no type")
elif (skipTypes(le, {tyGenericInst, tyAlias, tySink}).kind notin {tyVar} and
isAssignable(c, a) in {arNone, arLentValue, arAddressableConst}) or (
isAssignable(c, a) in {arNone, arLentValue}) or (
skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs} and views notin c.features):
# Direct assignment to a discriminant is allowed!
localError(c.config, a.info, errXCannotBeAssignedTo %
@@ -2274,7 +2267,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
markUsed(c, n.info, s)
checkSonsLen(n, 2, c.config)
result[0] = newSymNode(s, n[0].info)
result[1] = semAddrArg(c, n[1])
result[1] = semAddrArg(c, n[1], s.name.s == "unsafeAddr")
result.typ = makePtrType(c, result[1].typ)
of mTypeOf:
markUsed(c, n.info, s)
@@ -2774,12 +2767,6 @@ proc enumFieldSymChoice(c: PContext, n: PNode, s: PSym): PNode =
onUse(info, a)
a = nextOverloadIter(o, c, n)
proc semPragmaStmt(c: PContext; n: PNode) =
if c.p.owner.kind == skModule:
pragma(c, c.p.owner, n, stmtPragmas+stmtPragmasTopLevel, true)
else:
pragma(c, c.p.owner, n, stmtPragmas, true)
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
when defined(nimCompilerStacktraceHints):
setFrameMsg c.config$n.info & " " & $n.kind
@@ -2869,7 +2856,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
of nkBind:
message(c.config, n.info, warnDeprecated, "bind is deprecated")
result = semExpr(c, n[0], flags)
of nkTypeOfExpr..nkTupleClassTy, nkStaticTy, nkRefTy..nkEnumTy:
of nkTypeOfExpr, nkTupleTy, nkTupleClassTy, nkRefTy..nkEnumTy, nkStaticTy:
if c.matchedConcept != nil and n.len == 1:
let modifier = n.modifierTypeKindOfNode
if modifier != tyNone:
@@ -3028,7 +3015,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
of nkUsingStmt: result = semUsing(c, n)
of nkAsmStmt: result = semAsm(c, n)
of nkYieldStmt: result = semYield(c, n)
of nkPragma: semPragmaStmt(c, n)
of nkPragma: pragma(c, c.p.owner, n, stmtPragmas, true)
of nkIteratorDef: result = semIterator(c, n)
of nkProcDef: result = semProc(c, n)
of nkFuncDef: result = semFunc(c, n)

View File

@@ -17,9 +17,6 @@ import
from system/memory import nimCStrLen
when defined(nimPreviewSlimSystem):
import std/assertions
proc errorType*(g: ModuleGraph): PType =
## creates a type representing an error state
result = newType(tyError, nextTypeId(g.idgen), g.owners[^1])
@@ -136,7 +133,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; idgen: IdGenerator; g: ModuleGraph): P
of mCard: result = newIntNodeT(toInt128(nimsets.cardSet(g.config, a)), n, idgen, g)
of mBitnotI:
if n.typ.isUnsigned:
result = newIntNodeT(bitnot(getInt(a)).maskBytes(int(getSize(g.config, n.typ))), n, idgen, g)
result = newIntNodeT(bitnot(getInt(a)).maskBytes(int(n.typ.size)), n, idgen, g)
else:
result = newIntNodeT(bitnot(getInt(a)), n, idgen, g)
of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, idgen, g)
@@ -251,23 +248,23 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; idgen: IdGenerator; g: ModuleGraph): P
of mBitorI, mOr: result = newIntNodeT(bitor(getInt(a), getInt(b)), n, idgen, g)
of mBitxorI, mXor: result = newIntNodeT(bitxor(getInt(a), getInt(b)), n, idgen, g)
of mAddU:
let val = maskBytes(getInt(a) + getInt(b), int(getSize(g.config, n.typ)))
let val = maskBytes(getInt(a) + getInt(b), int(n.typ.size))
result = newIntNodeT(val, n, idgen, g)
of mSubU:
let val = maskBytes(getInt(a) - getInt(b), int(getSize(g.config, n.typ)))
let val = maskBytes(getInt(a) - getInt(b), int(n.typ.size))
result = newIntNodeT(val, n, idgen, g)
# echo "subU: ", val, " n: ", n, " result: ", val
of mMulU:
let val = maskBytes(getInt(a) * getInt(b), int(getSize(g.config, n.typ)))
let val = maskBytes(getInt(a) * getInt(b), int(n.typ.size))
result = newIntNodeT(val, n, idgen, g)
of mModU:
let argA = maskBytes(getInt(a), int(getSize(g.config, a.typ)))
let argB = maskBytes(getInt(b), int(getSize(g.config, a.typ)))
let argA = maskBytes(getInt(a), int(a.typ.size))
let argB = maskBytes(getInt(b), int(a.typ.size))
if argB != Zero:
result = newIntNodeT(argA mod argB, n, idgen, g)
of mDivU:
let argA = maskBytes(getInt(a), int(getSize(g.config, a.typ)))
let argB = maskBytes(getInt(b), int(getSize(g.config, a.typ)))
let argA = maskBytes(getInt(a), int(a.typ.size))
let argB = maskBytes(getInt(b), int(a.typ.size))
if argB != Zero:
result = newIntNodeT(argA div argB, n, idgen, g)
of mLeSet: result = newIntNodeT(toInt128(ord(containsSets(g.config, a, b))), n, idgen, g)
@@ -295,7 +292,13 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; idgen: IdGenerator; g: ModuleGraph): P
else: result = newStrNodeT("true", n, g)
of mFloatToStr: result = newStrNodeT($getFloat(a), n, g)
of mCStrToStr, mCharToStr:
result = newStrNodeT(getStrOrChar(a), n, g)
if a.kind == nkBracket:
var s = ""
for b in a.sons:
s.add b.getStrOrChar
result = newStrNodeT(s, n, g)
else:
result = newStrNodeT(getStrOrChar(a), n, g)
of mStrToStr: result = newStrNodeT(getStrOrChar(a), n, g)
of mEnumToStr: result = newStrNodeT(ordinalValToString(a, g), n, g)
of mArrToSeq:
@@ -409,7 +412,7 @@ proc foldConv(n, a: PNode; idgen: IdGenerator; g: ModuleGraph; check = false): P
rangeCheck(n, getInt(result), g)
of tyFloat..tyFloat64:
case srcTyp.kind
of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyBool, tyChar:
of tyInt..tyInt64, tyEnum, tyBool, tyChar:
result = newFloatNodeT(toFloat64(getOrdValue(a)), n, g)
else:
result = a

View File

@@ -145,11 +145,7 @@ proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) =
if sfGenSym in param.flags:
idTablePut(symMap, params[i].sym, result.typ.n[param.position+1].sym)
freshGenSyms(c, b, result, orig, symMap)
if sfBorrow notin orig.flags:
# We do not want to generate a body for generic borrowed procs.
# As body is a sym to the borrowed proc.
b = semProcBody(c, b)
b = semProcBody(c, b)
result.ast[bodyPos] = hloBody(c, b)
excl(result.flags, sfForward)
trackProc(c, result, result.ast[bodyPos])

View File

@@ -10,12 +10,17 @@
# This include file implements the semantic checking for magics.
# included from sem.nim
proc semAddrArg(c: PContext; n: PNode): PNode =
proc semAddrArg(c: PContext; n: PNode; isUnsafeAddr = false): PNode =
let x = semExprWithType(c, n)
if x.kind == nkSym:
x.sym.flags.incl(sfAddrTaken)
if isAssignable(c, x) notin {arLValue, arLocalLValue, arAddressableConst, arLentValue}:
localError(c.config, n.info, errExprHasNoAddress)
if isAssignable(c, x, isUnsafeAddr) notin {arLValue, arLocalLValue}:
# Do not suggest the use of unsafeAddr if this expression already is a
# unsafeAddr
if isUnsafeAddr:
localError(c.config, n.info, errExprHasNoAddress)
else:
localError(c.config, n.info, errExprHasNoAddress & "; maybe use 'unsafeAddr'")
result = x
proc semTypeOf(c: PContext; n: PNode): PNode =
@@ -466,7 +471,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
of mAddr:
checkSonsLen(n, 2, c.config)
result = n
result[1] = semAddrArg(c, n[1])
result[1] = semAddrArg(c, n[1], n[0].sym.name.s == "unsafeAddr")
result.typ = makePtrType(c, result[1].typ)
of mTypeOf:
result = semTypeOf(c, n)

View File

@@ -366,9 +366,10 @@ proc defaultConstructionError(c: PContext, t: PType, info: TLineInfo) =
if objType.kind == tyObject:
var constrCtx = initConstrContext(objType, newNodeI(nkObjConstr, info))
let initResult = semConstructTypeAux(c, constrCtx, {})
if constrCtx.missingFields.len > 0:
localError(c.config, info,
"The $1 type doesn't have a default value. The following fields must be initialized: $2." % [typeToString(t), listSymbolNames(constrCtx.missingFields)])
assert constrCtx.missingFields.len > 0
localError(c.config, info,
"The $1 type doesn't have a default value. The following fields must " &
"be initialized: $2." % [typeToString(t), listSymbolNames(constrCtx.missingFields)])
elif objType.kind == tyDistinct:
localError(c.config, info,
"The $1 distinct type doesn't have a default value." % typeToString(t))

View File

@@ -12,9 +12,6 @@ import
wordrecg, strutils, options, guards, lineinfos, semfold, semdata,
modulegraphs, varpartitions, typeallowed, nilcheck, errorhandling, tables
when defined(nimPreviewSlimSystem):
import std/assertions
when defined(useDfa):
import dfa
@@ -854,15 +851,11 @@ proc trackCall(tracked: PEffects; n: PNode) =
elif isIndirectCall(tracked, a):
assumeTheWorst(tracked, n, op)
gcsafeAndSideeffectCheck()
else:
if strictEffects in tracked.c.features and a.kind == nkSym and
a.sym.kind in routineKinds:
propagateEffects(tracked, n, a.sym)
else:
mergeRaises(tracked, effectList[exceptionEffects], n)
mergeTags(tracked, effectList[tagEffects], n)
gcsafeAndSideeffectCheck()
if a.kind != nkSym or a.sym.magic notin {mNBindSym, mFinished, mExpandToAst, mQuoteAst}:
if a.kind != nkSym or a.sym.magic notin {mNBindSym, mFinished}:
for i in 1..<n.len:
trackOperandForIndirectCall(tracked, n[i], op, i, a)
if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize, mNewSeq}:
@@ -887,7 +880,7 @@ proc trackCall(tracked: PEffects; n: PNode) =
optStaticBoundsCheck in tracked.currOptions:
checkBounds(tracked, n[1], n[2])
if a.kind != nkSym or a.sym.magic notin {mRunnableExamples, mNBindSym, mExpandToAst, mQuoteAst}:
if a.kind != nkSym or a.sym.magic != mRunnableExamples:
for i in 0..<n.safeLen:
track(tracked, n[i])
@@ -1054,7 +1047,7 @@ proc track(tracked: PEffects, n: PNode) =
addAsgnFact(tracked.guards, n[0], n[1])
notNilCheck(tracked, n[1], n[0].typ)
when false: cstringCheck(tracked, n)
if tracked.owner.kind != skMacro and n[0].typ.kind notin {tyOpenArray, tyVarargs}:
if tracked.owner.kind != skMacro:
createTypeBoundOps(tracked, n[0].typ, n.info)
if n[0].kind != nkSym or not isLocalVar(tracked, n[0].sym):
checkForSink(tracked.config, tracked.c.idgen, tracked.owner, n[1])

View File

@@ -140,9 +140,7 @@ proc discardCheck(c: PContext, result: PNode, flags: TExprFlags) =
n[0] = result
elif result.typ.kind != tyError and c.config.cmd != cmdInteractive:
var n = result
while n.kind in skipForDiscardable:
if n.kind == nkTryStmt: n = n[0]
else: n = n.lastSon
while n.kind in skipForDiscardable: n = n.lastSon
var s = "expression '" & $n & "' is of type '" &
result.typ.typeToString & "' and has to be used (or discarded)"
if result.info.line != n.info.line or
@@ -308,7 +306,7 @@ proc identWithin(n: PNode, s: PIdent): bool =
if identWithin(n[i], s): return true
result = n.kind == nkSym and n.sym.name.id == s.id
proc semIdentDef(c: PContext, n: PNode, kind: TSymKind, reportToNimsuggest = true): PSym =
proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym =
if isTopLevel(c):
result = semIdentWithPragma(c, kind, n, {sfExported})
incl(result.flags, sfGlobal)
@@ -332,8 +330,7 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind, reportToNimsuggest = tru
discard
result = n.info
let info = getLineInfo(n)
if reportToNimsuggest:
suggestSym(c.graph, info, result, c.graph.usageSym)
suggestSym(c.graph, info, result, c.graph.usageSym)
proc checkNilable(c: PContext; v: PSym) =
if {sfGlobal, sfImportc} * v.flags == {sfGlobal} and v.typ.requiresInit:
@@ -344,12 +341,8 @@ proc checkNilable(c: PContext; v: PSym) =
#include liftdestructors
proc addToVarSection(c: PContext; result: var PNode; n: PNode) =
if result.kind != nkStmtList:
result = makeStmtList(result)
result.add n
proc addToVarSection(c: PContext; result: var PNode; orig, identDefs: PNode) =
proc addToVarSection(c: PContext; result: PNode; orig, identDefs: PNode) =
let value = identDefs[^1]
if result.kind == nkStmtList:
let o = copyNode(orig)
o.add identDefs
@@ -452,115 +445,55 @@ proc setVarType(c: PContext; v: PSym, typ: PType) =
"; new type is: " & typeToString(typ, preferDesc))
v.typ = typ
proc isPossibleMacroPragma(c: PContext, it: PNode, key: PNode): bool =
# make sure it's not a normal pragma, and calls an identifier
# considerQuotedIdent below will fail on non-identifiers
result = whichPragma(it) == wInvalid and key.kind in nkIdentKinds
if result:
# make sure it's not a user pragma
let ident = considerQuotedIdent(c, key)
result = strTableGet(c.userPragmas, ident) == nil
if result:
# make sure it's not a custom pragma
var amb = false
let sym = searchInScopes(c, ident, amb)
result = sym == nil or sfCustomPragma notin sym.flags
proc semLowerLetVarCustomPragma(c: PContext, a: PNode, n: PNode): PNode =
var b = a[0]
if b.kind == nkPragmaExpr:
if b[1].len != 1:
# we could in future support pragmas w args e.g.: `var foo {.bar:"goo".} = expr`
return nil
let nodePragma = b[1][0]
# see: `singlePragma`
proc copyExcept(n: PNode, i: int): PNode =
result = copyNode(n)
for j in 0..<n.len:
if j != i: result.add(n[j])
var amb = false
var sym: PSym = nil
case nodePragma.kind
of nkIdent, nkAccQuoted:
let ident = considerQuotedIdent(c, nodePragma)
var userPragma = strTableGet(c.userPragmas, ident)
if userPragma != nil: return nil
let w = nodePragma.whichPragma
if n.kind == nkVarSection and w in varPragmas or
n.kind == nkLetSection and w in letPragmas or
n.kind == nkConstSection and w in constPragmas:
return nil
sym = searchInScopes(c, ident, amb)
# XXX what if amb is true?
# CHECKME: should that test also apply to `nkSym` case?
if sym == nil or sfCustomPragma in sym.flags: return nil
of nkSym:
sym = nodePragma.sym
else:
return nil
# skip if not in scope; skip `template myAttr() {.pragma.}`
proc semVarMacroPragma(c: PContext, a: PNode, n: PNode): PNode =
# Mirrored with semProcAnnotation
result = nil
# a, b {.prag.}: int = 3 not allowed
const lhsPos = 0
if a.len == 3 and a[lhsPos].kind == nkPragmaExpr:
var b = a[lhsPos]
const
namePos = 0
pragmaPos = 1
let pragmas = b[pragmaPos]
for i in 0 ..< pragmas.len:
let it = pragmas[i]
let key = if it.kind in nkPragmaCallKinds and it.len >= 1: it[0] else: it
let lhs = b[0]
let clash = strTableGet(c.currentScope.symbols, lhs.ident)
if clash != nil:
# refs https://github.com/nim-lang/Nim/issues/8275
wrongRedefinition(c, lhs.info, lhs.ident.s, clash.info)
when false:
let lhs = b[0]
let clash = strTableGet(c.currentScope.symbols, lhs.ident)
if clash != nil:
# refs https://github.com/nim-lang/Nim/issues/8275
wrongRedefinition(c, lhs.info, lhs.ident.s, clash.info)
if isPossibleMacroPragma(c, it, key):
# we transform ``var p {.m, rest.}`` into ``m(do: var p {.rest.})`` and
# let the semantic checker deal with it:
var x = newNodeI(nkCall, key.info)
x.add(key)
if it.kind in nkPragmaCallKinds and it.len > 1:
# pass pragma arguments to the macro too:
for i in 1..<it.len:
x.add(it[i])
# Drop the pragma from the list, this prevents getting caught in endless
# recursion when the nkCall is semanticized
let oldExpr = a[lhsPos]
let newPragmas = copyExcept(pragmas, i)
if newPragmas.kind != nkEmpty and newPragmas.len == 0:
a[lhsPos] = oldExpr[namePos]
else:
a[lhsPos] = copyNode(oldExpr)
a[lhsPos].add(oldExpr[namePos])
a[lhsPos].add(newPragmas)
var unarySection = newNodeI(n.kind, a.info)
unarySection.add(a)
x.add(unarySection)
# recursion assures that this works for multiple macro annotations too:
var r = semOverloadedCall(c, x, x, {skMacro, skTemplate}, {efNoUndeclared})
if r == nil:
# Restore the old list of pragmas since we couldn't process this
a[lhsPos] = oldExpr
# No matching macro was found but there's always the possibility this may
# be a .pragma. template instead
continue
doAssert r[0].kind == nkSym
let m = r[0].sym
case m.kind
of skMacro: result = semMacroExpr(c, r, r, m, {})
of skTemplate: result = semTemplateExpr(c, r, m, {})
else:
a[lhsPos] = oldExpr
continue
doAssert result != nil
# since a macro pragma can set pragmas, we process these here again.
# This is required for SqueakNim-like export pragmas.
if false and result.kind in {nkVarSection, nkLetSection, nkConstSection}:
var validPragmas: TSpecialWords
case result.kind
of nkVarSection:
validPragmas = varPragmas
of nkLetSection:
validPragmas = letPragmas
of nkConstSection:
validPragmas = constPragmas
else:
# unreachable
discard
for defs in result:
for i in 0 ..< defs.len - 2:
let ex = defs[i]
if ex.kind == nkPragmaExpr and
ex[namePos].kind == nkSym and
ex[pragmaPos].kind != nkEmpty:
pragma(c, defs[lhsPos][namePos].sym, defs[lhsPos][pragmaPos], validPragmas)
return result
result = newTree(nkCall)
result.add nodePragma
result.add lhs
if a[1].kind != nkEmpty:
result.add a[1]
else:
result.add newNodeIT(nkNilLit, a.info, c.graph.sysTypes[tyNil])
result.add a[2]
result.info = a.info
let ret = newNodeI(nkStmtList, a.info)
ret.add result
result = semExprNoType(c, ret)
proc errorSymChoiceUseQualifier(c: PContext; n: PNode) =
assert n.kind in nkSymChoices
@@ -575,6 +508,10 @@ proc errorSymChoiceUseQualifier(c: PContext; n: PNode) =
localError(c.config, n.info, errGenerated, err)
proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
if n.len == 1:
result = semLowerLetVarCustomPragma(c, n[0], n)
if result != nil: return result
var b: PNode
result = copyNode(n)
for i in 0..<n.len:
@@ -584,11 +521,6 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
if a.kind notin {nkIdentDefs, nkVarTuple}: illFormedAst(a, c.config)
checkMinSonsLen(a, 3, c.config)
b = semVarMacroPragma(c, a, n)
if b != nil:
addToVarSection(c, result, b)
continue
var typ: PType = nil
if a[^2].kind != nkEmpty:
typ = semTypeNode(c, a[^2], nil)
@@ -663,7 +595,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
if a.kind != nkVarTuple: typ else: tup[j])
addToVarSection(c, result, n, a)
continue
var v = semIdentDef(c, a[j], symkind, false)
var v = semIdentDef(c, a[j], symkind)
styleCheckDef(c.config, v)
onDef(a[j].info, v)
if sfGenSym notin v.flags:
@@ -728,12 +660,9 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
if v.flags * {sfGlobal, sfThread} == {sfGlobal}:
message(c.config, v.info, hintGlobalVar)
suggestSym(c.graph, v.info, v, c.graph.usageSym)
proc semConst(c: PContext, n: PNode): PNode =
result = copyNode(n)
inc c.inStaticContext
var b: PNode
for i in 0..<n.len:
var a = n[i]
if c.config.cmd == cmdIdeTools: suggestStmt(c, a)
@@ -741,11 +670,6 @@ proc semConst(c: PContext, n: PNode): PNode =
if a.kind notin {nkConstDef, nkVarTuple}: illFormedAst(a, c.config)
checkMinSonsLen(a, 3, c.config)
b = semVarMacroPragma(c, a, n)
if b != nil:
addToVarSection(c, result, b)
continue
var typ: PType = nil
if a[^2].kind != nkEmpty:
typ = semTypeNode(c, a[^2], nil)
@@ -780,6 +704,7 @@ proc semConst(c: PContext, n: PNode): PNode =
typFlags.incl taConcept
typeAllowedCheck(c, a.info, typ, skConst, typFlags)
var b: PNode
if a.kind == nkVarTuple:
if typ.kind != tyTuple:
localError(c.config, a.info, errXExpected, "tuple")
@@ -810,7 +735,7 @@ proc semConst(c: PContext, n: PNode): PNode =
v.ast = if def[j].kind != nkExprColonExpr: def[j]
else: def[j][1]
b[j] = newSymNode(v)
addToVarSection(c, result, n, b)
result.add b
dec c.inStaticContext
include semfields
@@ -1062,10 +987,10 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode =
else:
popCaseContext(c)
closeScope(c)
#if caseStmtMacros in c.features:
result = handleCaseStmtMacro(c, n, flags)
if result != nil:
return result
if caseStmtMacros in c.features:
result = handleCaseStmtMacro(c, n, flags)
if result != nil:
return result
localError(c.config, n[0].info, errSelectorMustBeOfCertainTypes)
return
for i in 1..<n.len:
@@ -1187,12 +1112,7 @@ proc typeDefLeftSidePass(c: PContext, typeSection: PNode, i: int) =
if name.kind == nkPragmaExpr:
let rewritten = applyTypeSectionPragmas(c, name[1], typeDef)
if rewritten != nil:
case rewritten.kind
of nkTypeDef:
typeSection[i] = rewritten
of nkTypeSection:
typeSection.sons[i .. i] = rewritten.sons
else: illFormedAst(rewritten, c.config)
typeSection[i] = rewritten
typeDefLeftSidePass(c, typeSection, i)
return
pragma(c, s, name[1], typePragmas)
@@ -1223,19 +1143,16 @@ proc typeDefLeftSidePass(c: PContext, typeSection: PNode, i: int) =
proc typeSectionLeftSidePass(c: PContext, n: PNode) =
# process the symbols on the left side for the whole type section, before
# we even look at the type definitions on the right
var i = 0
while i < n.len: # n may grow due to type pragma macros
for i in 0..<n.len:
var a = n[i]
when defined(nimsuggest):
if c.config.cmd == cmdIdeTools:
inc c.inTypeContext
suggestStmt(c, a)
dec c.inTypeContext
case a.kind
of nkCommentStmt: discard
of nkTypeDef: typeDefLeftSidePass(c, n, i)
else: illFormedAst(a, c.config)
inc i
if a.kind == nkCommentStmt: continue
if a.kind != nkTypeDef: illFormedAst(a, c.config)
typeDefLeftSidePass(c, n, i)
proc checkCovariantParamsUsages(c: PContext; genericType: PType) =
var body = genericType[^1]
@@ -1594,61 +1511,77 @@ proc addResult(c: PContext, n: PNode, t: PType, owner: TSymKind) =
n.add newSymNode(c.p.resultSym)
addParamOrResult(c, c.p.resultSym, owner)
proc copyExcept(n: PNode, i: int): PNode =
result = copyNode(n)
for j in 0..<n.len:
if j != i: result.add(n[j])
proc semProcAnnotation(c: PContext, prc: PNode;
validPragmas: TSpecialWords): PNode =
# Mirrored with semVarMacroPragma
var n = prc[pragmasPos]
if n == nil or n.kind == nkEmpty: return
for i in 0..<n.len:
let it = n[i]
let key = if it.kind in nkPragmaCallKinds and it.len >= 1: it[0] else: it
if isPossibleMacroPragma(c, it, key):
# we transform ``proc p {.m, rest.}`` into ``m(do: proc p {.rest.})`` and
# let the semantic checker deal with it:
var x = newNodeI(nkCall, key.info)
x.add(key)
if it.kind in nkPragmaCallKinds and it.len > 1:
# pass pragma arguments to the macro too:
for i in 1..<it.len:
x.add(it[i])
# Drop the pragma from the list, this prevents getting caught in endless
# recursion when the nkCall is semanticized
prc[pragmasPos] = copyExcept(n, i)
if prc[pragmasPos].kind != nkEmpty and prc[pragmasPos].len == 0:
prc[pragmasPos] = c.graph.emptyNode
x.add(prc)
# recursion assures that this works for multiple macro annotations too:
var r = semOverloadedCall(c, x, x, {skMacro, skTemplate}, {efNoUndeclared})
if r == nil:
# Restore the old list of pragmas since we couldn't process this
prc[pragmasPos] = n
# No matching macro was found but there's always the possibility this may
# be a .pragma. template instead
continue
doAssert r[0].kind == nkSym
let m = r[0].sym
case m.kind
of skMacro: result = semMacroExpr(c, r, r, m, {})
of skTemplate: result = semTemplateExpr(c, r, m, {})
if whichPragma(it) != wInvalid:
# Not a custom pragma
continue
else:
let ident = considerQuotedIdent(c, key)
if strTableGet(c.userPragmas, ident) != nil:
continue # User defined pragma
else:
prc[pragmasPos] = n
continue
var amb = false
let sym = searchInScopes(c, ident, amb)
if sym != nil and sfCustomPragma in sym.flags:
continue # User custom pragma
doAssert result != nil
# we transform ``proc p {.m, rest.}`` into ``m(do: proc p {.rest.})`` and
# let the semantic checker deal with it:
var x = newNodeI(nkCall, key.info)
x.add(key)
# since a proc annotation can set pragmas, we process these here again.
# This is required for SqueakNim-like export pragmas.
if false and result.kind in procDefs and result[namePos].kind == nkSym and
result[pragmasPos].kind != nkEmpty:
pragma(c, result[namePos].sym, result[pragmasPos], validPragmas)
if it.kind in nkPragmaCallKinds and it.len > 1:
# pass pragma arguments to the macro too:
for i in 1..<it.len:
x.add(it[i])
return result
# Drop the pragma from the list, this prevents getting caught in endless
# recursion when the nkCall is semanticized
prc[pragmasPos] = copyExcept(n, i)
if prc[pragmasPos].kind != nkEmpty and prc[pragmasPos].len == 0:
prc[pragmasPos] = c.graph.emptyNode
x.add(prc)
# recursion assures that this works for multiple macro annotations too:
var r = semOverloadedCall(c, x, x, {skMacro, skTemplate}, {efNoUndeclared})
if r == nil:
# Restore the old list of pragmas since we couldn't process this
prc[pragmasPos] = n
# No matching macro was found but there's always the possibility this may
# be a .pragma. template instead
continue
doAssert r[0].kind == nkSym
let m = r[0].sym
case m.kind
of skMacro: result = semMacroExpr(c, r, r, m, {})
of skTemplate: result = semTemplateExpr(c, r, m, {})
else:
prc[pragmasPos] = n
continue
doAssert result != nil
# since a proc annotation can set pragmas, we process these here again.
# This is required for SqueakNim-like export pragmas.
if result.kind in procDefs and result[namePos].kind == nkSym and
result[pragmasPos].kind != nkEmpty:
pragma(c, result[namePos].sym, result[pragmasPos], validPragmas)
return
proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode {.nosinks.} =
## used for resolving 'auto' in lambdas based on their callsite
@@ -2142,7 +2075,6 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
incl(s.flags, sfWasForwarded)
elif sfBorrow in s.flags: semBorrow(c, n, s)
sideEffectsCheck(c, s)
closeScope(c) # close scope for parameters
# c.currentScope = oldScope
popOwner(c)

View File

@@ -270,8 +270,7 @@ proc semTemplSymbol(c: PContext, n: PNode, s: PSym; isField: bool): PNode =
# Issue #12832
when defined(nimsuggest):
suggestSym(c.graph, n.info, s, c.graph.usageSym, false)
# field access (dot expr) will be handled by builtinFieldAccess
if not isField and {optStyleHint, optStyleError} * c.config.globalOptions != {}:
if {optStyleHint, optStyleError} * c.config.globalOptions != {}:
styleCheckUse(c.config, n.info, s)
proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode =
@@ -603,12 +602,7 @@ proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode =
for i in 0..<n.len:
result[i] = semTemplBodyDirty(c, n[i])
# in semstmts.nim:
proc semProcAnnotation(c: PContext, prc: PNode; validPragmas: TSpecialWords): PNode
proc semTemplateDef(c: PContext, n: PNode): PNode =
result = semProcAnnotation(c, n, templatePragmas)
if result != nil: return result
result = n
var s: PSym
if isTopLevel(c):

View File

@@ -1993,10 +1993,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
of nkStmtListType: result = semStmtListType(c, n, prev)
of nkBlockType: result = semBlockType(c, n, prev)
else:
result = semTypeExpr(c, n, prev)
when false:
localError(c.config, n.info, "type expected, but got: " & renderTree(n))
result = newOrPrevType(tyError, prev, c)
localError(c.config, n.info, "type expected, but got: " & renderTree(n))
result = newOrPrevType(tyError, prev, c)
n.typ = result
dec c.inTypeContext

View File

@@ -14,9 +14,6 @@ import ast, astalgo, msgs, types, magicsys, semdata, renderer, options,
from concepts import makeTypeDesc
when defined(nimPreviewSlimSystem):
import std/assertions
const tfInstClearedFlags = {tfHasMeta, tfUnresolved}
proc checkPartialConstructedType(conf: ConfigRef; info: TLineInfo, t: PType) =

View File

@@ -9,14 +9,10 @@
## Computes hash values for routine (proc, method etc) signatures.
import ast, tables, ropes, md5_old, modulegraphs
import ast, tables, ropes, md5, modulegraphs
from hashes import Hash
import types
when defined(nimPreviewSlimSystem):
import std/assertions
proc `&=`(c: var MD5Context, s: string) = md5Update(c, s, s.len)
proc `&=`(c: var MD5Context, ch: char) =
# XXX suspicious code here; relies on ch being zero terminated?

View File

@@ -15,9 +15,6 @@ import
magicsys, idents, lexer, options, parampatterns, strutils, trees,
linter, lineinfos, lowerings, modulegraphs, concepts
when defined(nimPreviewSlimSystem):
import std/assertions
type
MismatchKind* = enum
kUnknown, kAlreadyGiven, kUnknownNamedParam, kTypeMismatch, kVarNeeded,
@@ -1637,15 +1634,6 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
bindConcreteTypeToUserTypeClass(matched, a)
if doBind: put(c, f, matched)
result = isGeneric
elif a.len > 0 and a.lastSon == f:
# Needed for checking `Y` == `Addable` in the following
#[
type
Addable = concept a, type A
a + a is A
MyType[T: Addable; Y: static T] = object
]#
result = isGeneric
else:
result = isNone
@@ -1691,8 +1679,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
var aa = a
while aa.kind in {tyTypeDesc, tyGenericParam} and aa.len > 0:
aa = lastSon(aa)
if aa.kind in {tyGenericParam} + tyTypeClasses:
# If the constraint is a genericParam or typeClass this isGeneric
if aa.kind == tyGenericParam:
return isGeneric
result = typeRel(c, f.base, aa, flags)
if result > isGeneric: result = isGeneric
@@ -1752,22 +1739,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
let prev = PType(idTableGet(c.bindings, f))
if prev == nil:
if aOrig.kind == tyStatic:
if f.base.kind notin {tyNone, tyGenericParam}:
if f.base.kind != tyNone:
result = typeRel(c, f.base, a, flags)
if result != isNone and f.n != nil:
if not exprStructuralEquivalent(f.n, aOrig.n):
result = isNone
elif f.base.kind == tyGenericParam:
# Handling things like `type A[T; Y: static T] = object`
if f.base.len > 0: # There is a constraint, handle it
result = typeRel(c, f.base.lastSon, a, flags)
else:
# No constraint
if tfGenericTypeParam in f.flags:
result = isGeneric
else:
# for things like `proc fun[T](a: static[T])`
result = typeRel(c, f.base, a, flags)
else:
result = isGeneric
if result != isNone: put(c, f, aOrig)
@@ -2017,6 +1993,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
arg = argSemantized
a = a
c = m.c
if tfHasStatic in fMaybeStatic.flags:
# XXX: When implicit statics are the default
# this will be done earlier - we just have to
@@ -2484,8 +2461,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var Int
if m.callee.n[f].kind != nkSym:
internalError(c.config, n[a].info, "matches")
noMatch()
if flexibleOptionalParams in c.features and a >= firstArgBlock:
f = max(f, m.callee.n.len - (n.len - a))
if a >= firstArgBlock: f = max(f, m.callee.n.len - (n.len - a))
formal = m.callee.n[f].sym
m.firstMismatch.kind = kTypeMismatch
if containsOrIncl(marker, formal.position) and container.isNil:

View File

@@ -40,15 +40,15 @@ proc inc(arg: var OffsetAccum; value: int) =
else:
arg.offset += value
proc alignmentMax(a, b: int): int =
proc alignmentMax(a,b: int): int =
if unlikely(a == szIllegalRecursion or b == szIllegalRecursion): raiseIllegalTypeRecursion()
if a == szUnknownSize or b == szUnknownSize:
szUnknownSize
else:
max(a, b)
max(a,b)
proc align(arg: var OffsetAccum; value: int) =
if unlikely(value == szIllegalRecursion): raiseIllegalTypeRecursion()
if unlikely(value == szIllegalRecursion): raiseIllegalTypeRecursion()
if value == szUnknownSize or arg.maxAlign == szUnknownSize or arg.offset == szUnknownSize:
arg.maxAlign = szUnknownSize
arg.offset = szUnknownSize
@@ -112,7 +112,7 @@ proc setOffsetsToUnknown(n: PNode) =
for i in 0..<n.safeLen:
setOffsetsToUnknown(n[i])
proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode; packed: bool; accum: var OffsetAccum) =
proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, packed: bool, accum: var OffsetAccum) =
## ``offset`` is the offset within the object, after the node has been written, no padding bytes added
## ``align`` maximum alignment from all sub nodes
assert n != nil
@@ -196,11 +196,6 @@ proc computeUnionObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode; packed: bo
accum.offset = szUnknownSize
proc computeSizeAlign(conf: ConfigRef; typ: PType) =
template setSize(typ, s) =
typ.size = s
typ.align = s
typ.paddingAtEnd = 0
## computes and sets ``size`` and ``align`` members of ``typ``
assert typ != nil
let hasSize = typ.size != szUncomputedSize
@@ -263,14 +258,14 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
of tyArray:
computeSizeAlign(conf, typ[1])
let elemSize = typ[1].size
let elemSize = typ[1].size
let len = lengthOrd(conf, typ[0])
if elemSize < 0:
typ.size = elemSize
typ.align = int16(elemSize)
elif len < 0:
typ.size = szUnknownSize
typ.align = szUnknownSize
typ.align = szUnknownSize
else:
typ.size = toInt64Checked(len * int32(elemSize), szTooBigSize)
typ.align = typ[1].align
@@ -380,8 +375,10 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
let info = if typ.sym != nil: typ.sym.info else: unknownLineInfo
localError(conf, info, "union type may not have an object header")
accum = OffsetAccum(offset: szUnknownSize, maxAlign: szUnknownSize)
elif tfPacked in typ.flags:
computeUnionObjectOffsetsFoldFunction(conf, typ.n, true, accum)
else:
computeUnionObjectOffsetsFoldFunction(conf, typ.n, tfPacked in typ.flags, accum)
computeUnionObjectOffsetsFoldFunction(conf, typ.n, false, accum)
elif tfPacked in typ.flags:
accum.maxAlign = 1
computeObjectOffsetsFoldFunction(conf, typ.n, true, accum)
@@ -448,16 +445,6 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
typ.size = szUnknownSize
typ.align = szUnknownSize
typ.paddingAtEnd = szUnknownSize
of tyInt, tyUInt:
setSize typ, conf.target.intSize.int16
of tyBool, tyChar, tyUInt8, tyInt8:
setSize typ, 1
of tyInt16, tyUInt16:
setSize typ, 2
of tyInt32, tyUInt32:
setSize typ, 4
of tyInt64, tyUInt64:
setSize typ, 8
else:
typ.size = szUnknownSize
typ.align = szUnknownSize
@@ -495,7 +482,7 @@ template foldOffsetOf*(conf: ConfigRef; n: PNode; fallback: PNode): PNode =
## Returns an int literal node of the given offsetof expression in `n`.
## Falls back to `fallback`, if the `offsetof` expression can't be processed.
let config = conf
let node = n
let node : PNode = n
var dotExpr: PNode
block findDotExpr:
if node[1].kind == nkDotExpr:

Some files were not shown because too many files have changed in this diff Show More