mirror of
https://github.com/nim-lang/Nim.git
synced 2026-09-01 03:13:41 +00:00
Compare commits
13 Commits
v2.0.16
...
version-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10564f25b3 | ||
|
|
fbc7e54e95 | ||
|
|
7f3dbd5656 | ||
|
|
71f3e100b6 | ||
|
|
d2cb099e44 | ||
|
|
7e51e48cac | ||
|
|
19c89622ca | ||
|
|
b1d9af4d5f | ||
|
|
c467532484 | ||
|
|
114d0b8bdc | ||
|
|
f8ce7ddd6d | ||
|
|
cd6dbbd7f3 | ||
|
|
acac0bc1f2 |
@@ -19,6 +19,11 @@
|
||||
slots when enlarging a sequence.
|
||||
- Added `hasDefaultValue` to `std/typetraits` to check if a type has a valid default value.
|
||||
- Added Viewport API for the JavaScript targets in the `dom` module.
|
||||
- Added `toSinglyLinkedRing` and `toDoublyLinkedRing` to `std/lists` to convert from `openArray`s.
|
||||
- ORC: To be enabled via `nimOrcStats` there is a new API called `GC_orcStats` that can be used to query how many
|
||||
objects the cyclic collector did free. If the number is zero that is a strong indicator that you can use `--mm:arc`
|
||||
instead of `--mm:orc`.
|
||||
- A `$` template is provided for `Path` in `std/paths`.
|
||||
|
||||
[//]: # "Deprecations:"
|
||||
|
||||
|
||||
@@ -217,24 +217,38 @@ proc fillBodyObj(c: var TLiftCtx; n, body, x, y: PNode; enforceDefaultOp: bool,
|
||||
fillBodyObj(c, n[0], body, x, y, enforceDefaultOp = false)
|
||||
c.filterDiscriminator = oldfilterDiscriminator
|
||||
of nkRecList:
|
||||
for t in items(n): fillBodyObj(c, t, body, x, y, enforceDefaultOp, enforceWasMoved)
|
||||
# destroys in reverse order #24719
|
||||
if c.kind == attachedDestructor:
|
||||
for i in countdown(n.len-1, 0):
|
||||
fillBodyObj(c, n[i], body, x, y, enforceDefaultOp, enforceWasMoved)
|
||||
else:
|
||||
for t in items(n): fillBodyObj(c, t, body, x, y, enforceDefaultOp, enforceWasMoved)
|
||||
else:
|
||||
illFormedAstLocal(n, c.g.config)
|
||||
|
||||
proc fillBodyObjTImpl(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
||||
if t.len > 0 and t[0] != nil:
|
||||
let obj = newNodeIT(nkHiddenSubConv, c.info, t[0])
|
||||
obj.add newNodeI(nkEmpty, c.info)
|
||||
obj.add x
|
||||
var src = y
|
||||
template fillBase =
|
||||
if t.len > 0 and t[0] != nil:
|
||||
let dest = newNodeIT(nkHiddenSubConv, c.info, t[0])
|
||||
dest.add newNodeI(nkEmpty, c.info)
|
||||
dest.add x
|
||||
var src = y
|
||||
if c.kind in {attachedAsgn, attachedDeepCopy, attachedSink}:
|
||||
src = newNodeIT(nkHiddenSubConv, c.info, t[0])
|
||||
src.add newNodeI(nkEmpty, c.info)
|
||||
src.add y
|
||||
|
||||
if c.kind in {attachedAsgn, attachedDeepCopy, attachedSink}:
|
||||
src = newNodeIT(nkHiddenSubConv, c.info, t[0])
|
||||
src.add newNodeI(nkEmpty, c.info)
|
||||
src.add y
|
||||
fillBody(c, skipTypes(t[0], abstractPtrs), body, dest, src)
|
||||
template fillFields =
|
||||
fillBodyObj(c, t.n, body, x, y, enforceDefaultOp = false)
|
||||
|
||||
fillBody(c, skipTypes(t[0], abstractPtrs), body, obj, src)
|
||||
fillBodyObj(c, t.n, body, x, y, enforceDefaultOp = false)
|
||||
if c.kind == attachedDestructor:
|
||||
# destroys in reverse order #24719
|
||||
fillFields()
|
||||
fillBase()
|
||||
else:
|
||||
fillBase()
|
||||
fillFields()
|
||||
|
||||
proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
||||
var hasCase = isCaseObj(t.n)
|
||||
|
||||
@@ -1345,7 +1345,9 @@ proc readTypeParameter(c: PContext, typ: PType,
|
||||
# This seems semantically correct and then we'll be able
|
||||
# to return the section symbol directly here
|
||||
let foundType = makeTypeDesc(c, def[2].typ)
|
||||
return newSymNode(copySym(def[0].sym, c.idgen).linkTo(foundType), info)
|
||||
let s = copySym(def[0].sym, c.idgen)
|
||||
s.typ = foundType
|
||||
return newSymNode(s, info)
|
||||
|
||||
of nkConstSection:
|
||||
for def in statement:
|
||||
@@ -1370,7 +1372,9 @@ proc readTypeParameter(c: PContext, typ: PType,
|
||||
return c.graph.emptyNode
|
||||
else:
|
||||
let foundTyp = makeTypeDesc(c, rawTyp)
|
||||
return newSymNode(copySym(tParam.sym, c.idgen).linkTo(foundTyp), info)
|
||||
let s = copySym(tParam.sym, c.idgen)
|
||||
s.typ = foundTyp
|
||||
return newSymNode(s, info)
|
||||
|
||||
return nil
|
||||
|
||||
|
||||
@@ -1837,7 +1837,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc], c.idgen)
|
||||
else:
|
||||
stackTrace(c, tos, pc, "node has no type")
|
||||
else:
|
||||
of 3:
|
||||
# getTypeImpl opcode:
|
||||
ensureKind(rkNode)
|
||||
if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
|
||||
@@ -1846,6 +1846,15 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc], c.idgen)
|
||||
else:
|
||||
stackTrace(c, tos, pc, "node has no type")
|
||||
else:
|
||||
# getTypeInstSkipAlias opcode:
|
||||
ensureKind(rkNode)
|
||||
if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
|
||||
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.typ, c.debug[pc], c.idgen, skipAlias = true)
|
||||
elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
|
||||
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc], c.idgen, skipAlias = true)
|
||||
else:
|
||||
stackTrace(c, tos, pc, "node has no type")
|
||||
of opcNGetSize:
|
||||
decodeBImm(rkInt)
|
||||
let n = regs[rb].node
|
||||
|
||||
@@ -40,7 +40,7 @@ proc atomicTypeX(s: PSym; info: TLineInfo): PNode =
|
||||
result.info = info
|
||||
|
||||
proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator;
|
||||
inst=false; allowRecursionX=false): PNode
|
||||
inst=false; allowRecursionX=false; skipAlias = false): PNode
|
||||
|
||||
proc mapTypeToBracketX(cache: IdentCache; name: string; m: TMagic; t: PType; info: TLineInfo;
|
||||
idgen: IdGenerator;
|
||||
@@ -68,7 +68,7 @@ proc objectNode(cache: IdentCache; n: PNode; idgen: IdGenerator): PNode =
|
||||
|
||||
proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
idgen: IdGenerator;
|
||||
inst=false; allowRecursionX=false): PNode =
|
||||
inst=false; allowRecursionX=false; skipAlias = false): PNode =
|
||||
var allowRecursion = allowRecursionX
|
||||
template atomicType(name, m): untyped = atomicTypeX(cache, name, m, t, info, idgen)
|
||||
template atomicType(s): untyped = atomicTypeX(s, info)
|
||||
@@ -89,7 +89,8 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
id
|
||||
template newIdentDefs(s): untyped = newIdentDefs(s, s.typ)
|
||||
|
||||
if inst and not allowRecursion and t.sym != nil:
|
||||
if inst and not allowRecursion and t.sym != nil and
|
||||
not (skipAlias and t.kind == tyAlias):
|
||||
# getTypeInst behavior: return symbol
|
||||
return atomicType(t.sym)
|
||||
|
||||
@@ -122,7 +123,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
if t.base != nil:
|
||||
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
|
||||
result.add atomicType("typeDesc", mTypeDesc)
|
||||
result.add mapTypeToAst(t.base, info)
|
||||
result.add mapTypeToAstX(cache, t.base, info, idgen, inst, skipAlias = skipAlias)
|
||||
else:
|
||||
result = atomicType("typeDesc", mTypeDesc)
|
||||
of tyGenericInvocation:
|
||||
@@ -151,7 +152,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
else:
|
||||
result = mapTypeToAst(t.lastSon, info)
|
||||
of tyAlias:
|
||||
result = mapTypeToAstX(cache, t.lastSon, info, idgen, inst, allowRecursion)
|
||||
result = mapTypeToAstX(cache, t.lastSon, info, idgen, inst, allowRecursion, skipAlias = skipAlias)
|
||||
of tyOrdinal:
|
||||
result = mapTypeToAst(t.lastSon, info)
|
||||
of tyDistinct:
|
||||
@@ -316,8 +317,9 @@ proc opMapTypeToAst*(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGene
|
||||
|
||||
# the "Inst" version includes generic parameters in the resulting type tree
|
||||
# and also tries to look like the corresponding Nim type declaration
|
||||
proc opMapTypeInstToAst*(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator): PNode =
|
||||
result = mapTypeToAstX(cache, t, info, idgen, inst=true, allowRecursionX=false)
|
||||
proc opMapTypeInstToAst*(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator; skipAlias = false): PNode =
|
||||
# skipAlias: skips aliases and typedesc
|
||||
result = mapTypeToAstX(cache, t, info, idgen, inst=true, allowRecursionX=false, skipAlias = skipAlias)
|
||||
|
||||
# the "Impl" version includes generic parameters in the resulting type tree
|
||||
# and also tries to look like the corresponding Nim type implementation
|
||||
|
||||
@@ -1324,7 +1324,8 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}, m: TMag
|
||||
of "getType": 0
|
||||
of "typeKind": 1
|
||||
of "getTypeInst": 2
|
||||
else: 3 # "getTypeImpl"
|
||||
of "getTypeImpl": 3 # "getTypeImpl"
|
||||
else: 4 # getTypeInstSkipAlias
|
||||
c.gABC(n, opcNGetType, dest, tmp, rc)
|
||||
c.freeTemp(tmp)
|
||||
#genUnaryABC(c, n, dest, opcNGetType)
|
||||
|
||||
6
koch.nim
6
koch.nim
@@ -11,13 +11,13 @@
|
||||
|
||||
const
|
||||
# examples of possible values for repos: Head, ea82b54
|
||||
NimbleStableCommit = "123f97a5e4ee9ba35720c0869e19a047c43c797e" # 0.16.4
|
||||
NimbleStableCommit = "6a2486b597132340ea7422b078c769b58f21d16d" # 0.20.0
|
||||
AtlasStableCommit = "5faec3e9a33afe99a7d22377dd1b45a5391f5504"
|
||||
ChecksumsStableCommit = "bd9bf4eaea124bf8d01e08f92ac1b14c6879d8d3"
|
||||
ChecksumsStableCommit = "f8f6bd34bfa3fe12c64b919059ad856a96efcba0" # 2.0.1
|
||||
SatStableCommit = "faf1617f44d7632ee9601ebc13887644925dcc01"
|
||||
|
||||
# examples of possible values for fusion: #head, #ea82b54, 1.2.3
|
||||
FusionStableHash = "#372ee4313827ef9f2ea388840f7d6b46c2b1b014"
|
||||
FusionStableHash = "#562467452b32cb7a97410ea177f083e6d8405734"
|
||||
HeadHash = "#head"
|
||||
when not defined(windows):
|
||||
const
|
||||
|
||||
@@ -1574,10 +1574,13 @@ proc extractTypeImpl(n: NimNode): NimNode =
|
||||
result = n[2]
|
||||
else: error("Invalid node to retrieve type implementation of: " & $n.kind)
|
||||
|
||||
|
||||
proc getTypeInstSkipAlias(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
|
||||
|
||||
proc customPragmaNode(n: NimNode): NimNode =
|
||||
expectKind(n, {nnkSym, nnkDotExpr, nnkBracketExpr, nnkTypeOfExpr, nnkType, nnkCheckedFieldExpr})
|
||||
let
|
||||
typ = n.getTypeInst()
|
||||
|
||||
let typ = n.getTypeInstSkipAlias()
|
||||
|
||||
if typ.kind == nnkBracketExpr and typ.len > 1 and typ[1].kind == nnkProcTy:
|
||||
return typ[1][1]
|
||||
|
||||
@@ -215,6 +215,11 @@ when defined(osx): # 2001 POSIX evidently does not concern Apple
|
||||
# present size & has no good reason to call this unless it is growing.
|
||||
if fcntl(a1, F_PREALLOCATE, fst.addr) != cint(-1): ftruncate(a1, a2 + a3)
|
||||
else: cint(-1)
|
||||
elif defined(openbsd):
|
||||
proc posix_fallocate*(a1: cint, a2, a3: Off): cint =
|
||||
# above assumption: "has no good reason to call this unless it is growing."
|
||||
# man ftruncate "it will be extended as if by writing bytes with the value zero."
|
||||
return ftruncate(a1, a2 + a3)
|
||||
else:
|
||||
proc posix_fallocate*(a1: cint, a2, a3: Off): cint {.
|
||||
importc, header: "<fcntl.h>".}
|
||||
|
||||
@@ -25,6 +25,9 @@ export ReadDirEffect, WriteDirEffect
|
||||
type
|
||||
Path* = distinct string
|
||||
|
||||
template `$`*(x: Path): string =
|
||||
string(x)
|
||||
|
||||
func `==`*(x, y: Path): bool {.inline.} =
|
||||
## Compares two paths.
|
||||
##
|
||||
|
||||
@@ -14,6 +14,8 @@ at offset 0 then. The ``ref`` object header is independent from the
|
||||
runtime type and only contains a reference count.
|
||||
]#
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
when defined(gcOrc):
|
||||
const
|
||||
rcIncrement = 0b10000 # so that lowest 4 bits are not touched
|
||||
@@ -239,3 +241,5 @@ template tearDownForeignThreadGc* =
|
||||
|
||||
proc isObjDisplayCheck(source: PNimTypeV2, targetDepth: int16, token: uint32): bool {.compilerRtl, inl.} =
|
||||
result = targetDepth <= source.depth and source.display[targetDepth] == token
|
||||
|
||||
{.pop.} # raises: []
|
||||
|
||||
@@ -252,12 +252,12 @@ iterator elementsExcept(t, s: CellSet): PCell {.inline.} =
|
||||
var r = t.head
|
||||
while r != nil:
|
||||
let ss = cellSetGet(s, r.key)
|
||||
var i:uint = 0
|
||||
var i = 0'u
|
||||
while int(i) <= high(r.bits):
|
||||
var w = r.bits[i]
|
||||
if ss != nil:
|
||||
w = w and not ss.bits[i]
|
||||
var j:uint = 0
|
||||
var j = 0'u
|
||||
while w != 0:
|
||||
if (w and 1) != 0:
|
||||
yield cast[PCell]((r.key shl PageShift) or
|
||||
|
||||
@@ -10,7 +10,7 @@ const
|
||||
## is the minor number of Nim's version.
|
||||
## Odd for devel, even for releases.
|
||||
|
||||
NimPatch* {.intdefine.}: int = 16
|
||||
NimPatch* {.intdefine.}: int = 17
|
||||
## is the patch number of Nim's version.
|
||||
## Odd for devel, even for releases.
|
||||
|
||||
|
||||
@@ -62,8 +62,8 @@ const
|
||||
colorMask = 0b011
|
||||
|
||||
type
|
||||
TraceProc = proc (p, env: pointer) {.nimcall, benign.}
|
||||
DisposeProc = proc (p: pointer) {.nimcall, benign.}
|
||||
TraceProc = proc (p, env: pointer) {.nimcall, benign, raises: [].}
|
||||
DisposeProc = proc (p: pointer) {.nimcall, benign, raises: [].}
|
||||
|
||||
template color(c): untyped = c.rc and colorMask
|
||||
template setColor(c, col) =
|
||||
|
||||
@@ -60,6 +60,7 @@ comparisons).
|
||||
]#
|
||||
|
||||
{.push profiler:off.}
|
||||
{.push raises: [].}
|
||||
|
||||
const
|
||||
CycleIncrease = 2 # is a multiplicative increase
|
||||
@@ -595,7 +596,13 @@ proc sweep(gch: var GcHeap) =
|
||||
if isCell(x):
|
||||
# cast to PCell is correct here:
|
||||
var c = cast[PCell](x)
|
||||
if c notin gch.marked: freeCyclicCell(gch, c)
|
||||
if c notin gch.marked:
|
||||
# Don't free objects that have the ZctFlag set (created in finalizers)
|
||||
if (c.refcount and ZctFlag) == 0:
|
||||
freeCyclicCell(gch, c)
|
||||
else:
|
||||
# Clear the ZctFlag for the next collection cycle
|
||||
c.refcount = c.refcount and not ZctFlag
|
||||
|
||||
proc markS(gch: var GcHeap, c: PCell) =
|
||||
gcAssert isAllocatedPtr(gch.region, c), "markS: foreign heap root detected A!"
|
||||
@@ -906,4 +913,5 @@ when not defined(useNimRtl):
|
||||
result.add "[GC] stack bottom: " & gch.stack.bottom.repr
|
||||
result.add "[GC] max stack size: " & $gch.stat.maxStackSize & "\n"
|
||||
|
||||
{.pop.} # raises: []
|
||||
{.pop.} # profiler: off, stackTrace: off
|
||||
|
||||
@@ -25,33 +25,33 @@ when hasAlloc and not defined(js) and not usesDestructors:
|
||||
proc GC_enable*() {.rtl, inl, benign, raises: [].}
|
||||
## Enables the GC again.
|
||||
|
||||
proc GC_fullCollect*() {.rtl, benign.}
|
||||
proc GC_fullCollect*() {.rtl, benign, raises: [].}
|
||||
## Forces a full garbage collection pass.
|
||||
## Ordinary code does not need to call this (and should not).
|
||||
|
||||
proc GC_enableMarkAndSweep*() {.rtl, benign.}
|
||||
proc GC_disableMarkAndSweep*() {.rtl, benign.}
|
||||
proc GC_enableMarkAndSweep*() {.rtl, benign, raises: [].}
|
||||
proc GC_disableMarkAndSweep*() {.rtl, benign, raises: [].}
|
||||
## The current implementation uses a reference counting garbage collector
|
||||
## with a seldomly run mark and sweep phase to free cycles. The mark and
|
||||
## sweep phase may take a long time and is not needed if the application
|
||||
## does not create cycles. Thus the mark and sweep phase can be deactivated
|
||||
## and activated separately from the rest of the GC.
|
||||
|
||||
proc GC_getStatistics*(): string {.rtl, benign.}
|
||||
proc GC_getStatistics*(): string {.rtl, benign, raises: [].}
|
||||
## Returns an informative string about the GC's activity. This may be useful
|
||||
## for tweaking.
|
||||
|
||||
proc GC_ref*[T](x: ref T) {.magic: "GCref", benign.}
|
||||
proc GC_ref*[T](x: seq[T]) {.magic: "GCref", benign.}
|
||||
proc GC_ref*(x: string) {.magic: "GCref", benign.}
|
||||
proc GC_ref*[T](x: ref T) {.magic: "GCref", benign, raises: [].}
|
||||
proc GC_ref*[T](x: seq[T]) {.magic: "GCref", benign, raises: [].}
|
||||
proc GC_ref*(x: string) {.magic: "GCref", benign, raises: [].}
|
||||
## Marks the object `x` as referenced, so that it will not be freed until
|
||||
## it is unmarked via `GC_unref`.
|
||||
## If called n-times for the same object `x`,
|
||||
## n calls to `GC_unref` are needed to unmark `x`.
|
||||
|
||||
proc GC_unref*[T](x: ref T) {.magic: "GCunref", benign.}
|
||||
proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", benign.}
|
||||
proc GC_unref*(x: string) {.magic: "GCunref", benign.}
|
||||
proc GC_unref*[T](x: ref T) {.magic: "GCunref", benign, raises: [].}
|
||||
proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", benign, raises: [].}
|
||||
proc GC_unref*(x: string) {.magic: "GCunref", benign, raises: [].}
|
||||
## See the documentation of `GC_ref <#GC_ref,string>`_.
|
||||
|
||||
proc nimGC_setStackBottom*(theStackBottom: pointer) {.compilerRtl, noinline, benign, raises: [].}
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
# R.D. Lins / Information Processing Letters 109 (2008) 71–78
|
||||
#
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
include cellseqs_v2
|
||||
|
||||
const
|
||||
@@ -27,8 +29,8 @@ const
|
||||
logOrc = defined(nimArcIds)
|
||||
|
||||
type
|
||||
TraceProc = proc (p, env: pointer) {.nimcall, benign.}
|
||||
DisposeProc = proc (p: pointer) {.nimcall, benign.}
|
||||
TraceProc = proc (p, env: pointer) {.nimcall, benign, raises: [].}
|
||||
DisposeProc = proc (p: pointer) {.nimcall, benign, raises: [].}
|
||||
|
||||
template color(c): untyped = c.rc and colorMask
|
||||
template setColor(c, col) =
|
||||
@@ -520,3 +522,5 @@ proc nimDecRefIsLastCyclicStatic(p: pointer; desc: PNimTypeV2): bool {.compilerR
|
||||
dec cell.rc, rcIncrement
|
||||
#if cell.color == colPurple:
|
||||
rememberCycle(result, cell, desc)
|
||||
|
||||
{.pop.} # raises: []
|
||||
|
||||
@@ -61,15 +61,25 @@ elif defined(netbsd):
|
||||
result = threadId
|
||||
|
||||
elif defined(freebsd):
|
||||
proc syscall(arg: cint, arg0: ptr cint): cint {.varargs, importc: "syscall", header: "<unistd.h>".}
|
||||
var SYS_thr_self {.importc:"SYS_thr_self", header:"<sys/syscall.h>".}: cint
|
||||
when defined(amd64) or defined(i386):
|
||||
const SYS_thr_self = 432
|
||||
else:
|
||||
var SYS_thr_self {.importc:"SYS_thr_self", header:"<sys/syscall.h>".}: cint
|
||||
|
||||
when defined(cpu64):
|
||||
type
|
||||
Off {.importc: "off_t", header: "<sys/types.h>".} = int64
|
||||
Quad {.importc: "quad_t", header: "<sys/types.h>".} = int64
|
||||
proc syscall(arg: Quad): Off {.varargs, importc: "__syscall", header: "<unistd.h>".}
|
||||
else:
|
||||
proc syscall(arg: cint): cint {.varargs, importc: "syscall", header: "<unistd.h>".}
|
||||
|
||||
proc getThreadId*(): int =
|
||||
## Gets the ID of the currently running thread.
|
||||
var tid = 0.cint
|
||||
var tid = when defined(cpu64): Off(0) else: cint(0)
|
||||
if threadId == 0:
|
||||
discard syscall(SYS_thr_self, addr tid)
|
||||
threadId = tid
|
||||
threadId = int(tid)
|
||||
result = threadId
|
||||
|
||||
elif defined(macosx):
|
||||
|
||||
@@ -83,7 +83,7 @@ proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string, isOrc =
|
||||
|
||||
if "boehm" notin options and not isOrc:
|
||||
# hcr tests
|
||||
|
||||
|
||||
testSpec r, makeTest("tests/dll/nimhcr_basic.nim", options & " --threads:off --forceBuild --hotCodeReloading:on " & rpath, cat)
|
||||
|
||||
# force build required - see the comments in the .nim file for more details
|
||||
@@ -162,6 +162,7 @@ proc gcTests(r: var TResults, cat: Category, options: string) =
|
||||
test "stackrefleak"
|
||||
test "cyclecollector"
|
||||
testWithoutBoehm "trace_globals"
|
||||
test "tfinalizers"
|
||||
|
||||
# ------------------------- threading tests -----------------------------------
|
||||
|
||||
|
||||
39
tests/arc/tdestructor_order.nim
Normal file
39
tests/arc/tdestructor_order.nim
Normal file
@@ -0,0 +1,39 @@
|
||||
discard """
|
||||
output: '''
|
||||
destroying d
|
||||
destroying c
|
||||
destroying a 2
|
||||
destroying d
|
||||
destroying c
|
||||
destroying a 1
|
||||
'''
|
||||
joinable: false
|
||||
"""
|
||||
|
||||
type
|
||||
Aaaa {.inheritable.} = object
|
||||
vvvv: int
|
||||
Bbbb = object of Aaaa
|
||||
c: Cccc
|
||||
d: Dddd
|
||||
Cccc = object
|
||||
Dddd = object
|
||||
|
||||
Holder = object
|
||||
member: ref Aaaa
|
||||
|
||||
proc `=destroy`(v: Cccc) =
|
||||
echo "destroying c"
|
||||
|
||||
proc `=destroy`(v: Dddd) =
|
||||
echo "destroying d"
|
||||
|
||||
proc `=destroy`(v: Aaaa) =
|
||||
echo "destroying a ", v.vvvv
|
||||
|
||||
func makeHolder(vvvv: int): ref Holder =
|
||||
(ref Holder)(member: (ref Bbbb)(vvvv: vvvv))
|
||||
|
||||
block:
|
||||
var v = makeHolder(1)
|
||||
var v2 = makeHolder(2)
|
||||
@@ -1,5 +1,6 @@
|
||||
discard """
|
||||
output: '''----1
|
||||
output: '''
|
||||
----1
|
||||
myobj constructed
|
||||
myobj destroyed
|
||||
----2
|
||||
@@ -14,8 +15,8 @@ mygeneric3 constructed
|
||||
mygeneric1 destroyed
|
||||
----5
|
||||
mydistinctObj constructed
|
||||
myobj destroyed
|
||||
mygeneric2 destroyed
|
||||
myobj destroyed
|
||||
------------------8
|
||||
mygeneric1 destroyed
|
||||
----6
|
||||
|
||||
19
tests/gc/tfinalizers.nim
Normal file
19
tests/gc/tfinalizers.nim
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
type
|
||||
PNode = ref TNode
|
||||
TNode = object
|
||||
le: PNode
|
||||
|
||||
proc finalizeNode(n: PNode) =
|
||||
var s = @[0]
|
||||
|
||||
proc returnTree() =
|
||||
var cycle: PNode
|
||||
new(cycle, finalizeNode)
|
||||
cycle.le = cycle
|
||||
|
||||
for i in 1..100:
|
||||
returnTree()
|
||||
|
||||
GC_fullCollect()
|
||||
GC_fullCollect()
|
||||
@@ -531,3 +531,13 @@ block:
|
||||
|
||||
check(a)
|
||||
check(b)
|
||||
|
||||
block:
|
||||
template p {.pragma.}
|
||||
|
||||
func foo[T0](v: T0): bool =
|
||||
type T = T0
|
||||
T.hasCustomPragma(p)
|
||||
|
||||
type X {.p.} = object
|
||||
doAssert foo(X())
|
||||
|
||||
13
tests/pragmas/tgenericparamcustompragma.nim
Normal file
13
tests/pragmas/tgenericparamcustompragma.nim
Normal file
@@ -0,0 +1,13 @@
|
||||
# issue #23713
|
||||
|
||||
import std/macros
|
||||
|
||||
template p {.pragma.}
|
||||
|
||||
type
|
||||
X {.p.} = object
|
||||
|
||||
Y[T] = object
|
||||
t: T
|
||||
|
||||
doAssert Y[X].T.hasCustomPragma(p)
|
||||
Reference in New Issue
Block a user