parent
8b107972c5
commit
bdf6f59c6d
3 changed files with 73 additions and 3 deletions
|
|
@ -28,7 +28,7 @@ template createCb(retFutureSym, iteratorNameSym,
|
||||||
name, futureVarCompletions: untyped) =
|
name, futureVarCompletions: untyped) =
|
||||||
var nameIterVar = iteratorNameSym
|
var nameIterVar = iteratorNameSym
|
||||||
#{.push stackTrace: off.}
|
#{.push stackTrace: off.}
|
||||||
proc cb {.closure,gcsafe.} =
|
proc cb {.closure.} =
|
||||||
try:
|
try:
|
||||||
if not nameIterVar.finished:
|
if not nameIterVar.finished:
|
||||||
var next = nameIterVar()
|
var next = nameIterVar()
|
||||||
|
|
@ -38,7 +38,8 @@ template createCb(retFutureSym, iteratorNameSym,
|
||||||
"`nil` Future?"
|
"`nil` Future?"
|
||||||
raise newException(AssertionError, msg % name)
|
raise newException(AssertionError, msg % name)
|
||||||
else:
|
else:
|
||||||
next.callback = cb
|
{.gcsafe.}:
|
||||||
|
next.callback = (proc() {.closure, gcsafe.})(cb)
|
||||||
except:
|
except:
|
||||||
futureVarCompletions
|
futureVarCompletions
|
||||||
|
|
||||||
|
|
@ -379,7 +380,10 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
procBody, nnkIteratorDef)
|
procBody, nnkIteratorDef)
|
||||||
closureIterator.pragma = newNimNode(nnkPragma, lineInfoFrom=prc.body)
|
closureIterator.pragma = newNimNode(nnkPragma, lineInfoFrom=prc.body)
|
||||||
closureIterator.addPragma(newIdentNode("closure"))
|
closureIterator.addPragma(newIdentNode("closure"))
|
||||||
closureIterator.addPragma(newIdentNode("gcsafe"))
|
|
||||||
|
# If proc has an explicit gcsafe pragma, we add it to iterator as well.
|
||||||
|
if prc.pragma.findChild(it.kind in {nnkSym, nnkIdent} and $it == "gcsafe") != nil:
|
||||||
|
closureIterator.addPragma(newIdentNode("gcsafe"))
|
||||||
outerProcBody.add(closureIterator)
|
outerProcBody.add(closureIterator)
|
||||||
|
|
||||||
# -> createCb(retFuture)
|
# -> createCb(retFuture)
|
||||||
|
|
|
||||||
36
tests/async/tasync_gcsafe.nim
Normal file
36
tests/async/tasync_gcsafe.nim
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
discard """
|
||||||
|
cmd: "nim c --threads:on $file"
|
||||||
|
output: '''
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
assert compileOption("threads"), "this test will not do anything useful without --threads:on"
|
||||||
|
|
||||||
|
import asyncdispatch
|
||||||
|
|
||||||
|
var globalDummy: ref int
|
||||||
|
proc gcUnsafeProc() =
|
||||||
|
if not globalDummy.isNil:
|
||||||
|
echo globalDummy[]
|
||||||
|
echo "1"
|
||||||
|
|
||||||
|
proc gcSafeAsyncProcWithNoAnnotation() {.async.} =
|
||||||
|
echo "2"
|
||||||
|
|
||||||
|
proc gcSafeAsyncProcWithAnnotation() {.gcsafe, async.} =
|
||||||
|
echo "3"
|
||||||
|
|
||||||
|
proc gcUnsafeAsyncProc() {.async.} =
|
||||||
|
# We should be able to call gcUnsafe
|
||||||
|
gcUnsafeProc()
|
||||||
|
|
||||||
|
# We should be able to call async implicitly gcsafe
|
||||||
|
await gcSafeAsyncProcWithNoAnnotation()
|
||||||
|
|
||||||
|
# We should be able to call async explicitly gcsafe
|
||||||
|
await gcSafeAsyncProcWithAnnotation()
|
||||||
|
|
||||||
|
waitFor gcUnsafeAsyncProc()
|
||||||
30
tests/async/tasync_gcunsafe.nim
Normal file
30
tests/async/tasync_gcunsafe.nim
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
discard """
|
||||||
|
cmd: "nim c --threads:on $file"
|
||||||
|
file: "asyncmacro.nim"
|
||||||
|
errormsg: "'anotherGCSafeAsyncProcIter' is not GC-safe as it calls 'asyncGCUnsafeProc'"
|
||||||
|
"""
|
||||||
|
|
||||||
|
assert compileOption("threads"), "this test will not do anything useful without --threads:on"
|
||||||
|
|
||||||
|
import asyncdispatch
|
||||||
|
|
||||||
|
var globalDummy: ref int
|
||||||
|
proc gcUnsafeProc() =
|
||||||
|
if not globalDummy.isNil:
|
||||||
|
echo globalDummy[]
|
||||||
|
|
||||||
|
proc asyncExplicitlyGCSafeProc() {.gcsafe, async.} =
|
||||||
|
echo "hi"
|
||||||
|
|
||||||
|
proc asyncImplicitlyGCSafeProc() {.async.} =
|
||||||
|
echo "hi"
|
||||||
|
|
||||||
|
proc asyncGCUnsafeProc() {.async.} =
|
||||||
|
gcUnsafeProc()
|
||||||
|
|
||||||
|
proc anotherGCSafeAsyncProc() {.async, gcsafe.} =
|
||||||
|
# We should be able to call other gcsafe procs
|
||||||
|
await asyncExplicitlyGCSafeProc()
|
||||||
|
await asyncImplicitlyGCSafeProc()
|
||||||
|
# But we can't call gcunsafe procs
|
||||||
|
await asyncGCUnsafeProc()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue