move {.injectStmt.} to experimental; add a test (#18300)
* move {.injectStmt.} to experimental; add a test
* undocument and deprecat `.injectStmt` but keep its implementation until we have a replacement
This commit is contained in:
parent
590d457631
commit
6030e139b5
6 changed files with 53 additions and 15 deletions
|
|
@ -1183,6 +1183,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
if sym == nil: invalidPragma(c, it)
|
if sym == nil: invalidPragma(c, it)
|
||||||
else: magicsys.registerNimScriptSymbol(c.graph, sym)
|
else: magicsys.registerNimScriptSymbol(c.graph, sym)
|
||||||
of wInjectStmt:
|
of wInjectStmt:
|
||||||
|
warningDeprecated(c.config, it.info, "'.injectStmt' pragma is deprecated")
|
||||||
if it.kind notin nkPragmaCallKinds or it.len != 2:
|
if it.kind notin nkPragmaCallKinds or it.len != 2:
|
||||||
localError(c.config, it.info, "expression expected")
|
localError(c.config, it.info, "expression expected")
|
||||||
else:
|
else:
|
||||||
|
|
@ -1194,10 +1195,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
of wThis:
|
of wThis:
|
||||||
if it.kind in nkPragmaCallKinds and it.len == 2:
|
if it.kind in nkPragmaCallKinds and it.len == 2:
|
||||||
c.selfName = considerQuotedIdent(c, it[1])
|
c.selfName = considerQuotedIdent(c, it[1])
|
||||||
message(c.config, n.info, warnDeprecated, "the '.this' pragma is deprecated")
|
message(c.config, n.info, warnDeprecated, "'.this' pragma is deprecated")
|
||||||
elif it.kind == nkIdent or it.len == 1:
|
elif it.kind == nkIdent or it.len == 1:
|
||||||
c.selfName = getIdent(c.cache, "self")
|
c.selfName = getIdent(c.cache, "self")
|
||||||
message(c.config, n.info, warnDeprecated, "the '.this' pragma is deprecated")
|
message(c.config, n.info, warnDeprecated, "'.this' pragma is deprecated")
|
||||||
else:
|
else:
|
||||||
localError(c.config, it.info, "'this' pragma is allowed to have zero or one arguments")
|
localError(c.config, it.info, "'this' pragma is allowed to have zero or one arguments")
|
||||||
of wNoRewrite:
|
of wNoRewrite:
|
||||||
|
|
|
||||||
|
|
@ -7432,17 +7432,6 @@ work properly (in particular regarding constructor and destructor) for
|
||||||
proc main()=
|
proc main()=
|
||||||
var a {.threadvar.}: Foo
|
var a {.threadvar.}: Foo
|
||||||
|
|
||||||
InjectStmt pragma
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
The `injectStmt` pragma can be used to inject a statement before every
|
|
||||||
other statement in the current module. It is only supposed to be used for
|
|
||||||
debugging:
|
|
||||||
|
|
||||||
.. code-block:: nim
|
|
||||||
{.injectStmt: gcInvariants().}
|
|
||||||
|
|
||||||
# ... complex code here that produces crashes ...
|
|
||||||
|
|
||||||
compile-time define pragmas
|
compile-time define pragmas
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
|
||||||
|
|
@ -380,6 +380,7 @@ pass multiple blocks to a macro:
|
||||||
# code to undo it
|
# code to undo it
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Special Operators
|
Special Operators
|
||||||
=================
|
=================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -176,8 +176,6 @@ export Port, SocketFlag
|
||||||
export asyncfutures except callSoon
|
export asyncfutures except callSoon
|
||||||
export asyncstreams
|
export asyncstreams
|
||||||
|
|
||||||
#{.injectStmt: newGcInvariant().}
|
|
||||||
|
|
||||||
# TODO: Check if yielded future is nil and throw a more meaningful exception
|
# TODO: Check if yielded future is nil and throw a more meaningful exception
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -429,6 +429,7 @@ proc sweep(gch: var GcHeap) =
|
||||||
else: freeCyclicCell(gch, c)
|
else: freeCyclicCell(gch, c)
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
|
# meant to be used with the now-deprected `.injectStmt`: {.injectStmt: newGcInvariant().}
|
||||||
proc newGcInvariant*() =
|
proc newGcInvariant*() =
|
||||||
for x in allObjects(gch.region):
|
for x in allObjects(gch.region):
|
||||||
if isCell(x):
|
if isCell(x):
|
||||||
|
|
|
||||||
48
tests/pragmas/tinjectstmt.nim
Normal file
48
tests/pragmas/tinjectstmt.nim
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
discard """
|
||||||
|
joinable: false
|
||||||
|
output:'''
|
||||||
|
onInject: 1
|
||||||
|
onInject: 2
|
||||||
|
ok0
|
||||||
|
ok1
|
||||||
|
onInject: 3
|
||||||
|
onInject: 4
|
||||||
|
0
|
||||||
|
onInject: 5
|
||||||
|
onInject: 6
|
||||||
|
1
|
||||||
|
onInject: 7
|
||||||
|
onInject: 8
|
||||||
|
2
|
||||||
|
ok2
|
||||||
|
onInject: 9
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
# test {.injectStmt.}
|
||||||
|
|
||||||
|
#[
|
||||||
|
{.injectStmt.} pragma can be used to inject a statement before every
|
||||||
|
other statement in the current module. It's now undocumented and may be removed
|
||||||
|
in the future and replaced with something more general and without its limitations.
|
||||||
|
e.g. (e.g. doesn't work in VM or js backends).
|
||||||
|
]#
|
||||||
|
|
||||||
|
from system/ansi_c import c_printf
|
||||||
|
|
||||||
|
var count = 0
|
||||||
|
proc onInject*() =
|
||||||
|
count.inc
|
||||||
|
# echo count # xxx would fail, probably infinite recursion
|
||||||
|
c_printf("onInject: %d\n", cast[int](count))
|
||||||
|
|
||||||
|
{.injectStmt: onInject().}
|
||||||
|
echo "ok0"
|
||||||
|
proc main()=
|
||||||
|
echo "ok1"
|
||||||
|
for a in 0..<3:
|
||||||
|
echo a
|
||||||
|
echo "ok2"
|
||||||
|
|
||||||
|
static: main() # xxx injectStmt not honred in VM
|
||||||
|
main()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue