You're running into a C code generator double-evaluation bug recently
introduced for projects using `--gc:arc|orc|atomicArc`.
I haven't inspected all callsites of the `pop` template, but assuming that the
popped stack-entries always become re-usable, you can move the `move` call into
the template, like so:
template pop*(): Value =
...
move Stack[SP]
Run
Apart from working around the compiler bug, this also removes the need to use
`move` at `pop` callsites.
* * *
For anyone interested in fixing the bug, the problematic part are the following
[lines](https://github.com/nim-lang/Nim/blob/7d9fe106ecd70bf99b9f3224430debfe10060ce1/compiler/ccgexprs.nim#L2366-L2368)
in `ccgexprs.nim`, introduced by
[this](https://github.com/nim-lang/Nim/pull/22288) PR.
The AST for a new `=wasMoved` call statement is constructed, using the `move`
call's operand as the argument. Generating the code for said call statement
then results in the `move` call's operand being code-gen and emitted twice.
A quick-fix (which might not work with the C++ backend, I haven't tested it)
could be replacing the aforementioned lines with:
var b = default(TLoc)
initLocExpr(p, b, newSymNode(op))
linefmt(p, "$1($2);$n", [rdLoc(b), byRefLoc(a)]
Run
However, this doesn't fix the related issue of `move` behaving differently with
the JavaScript and VM backends (no `=wasMoved` call is inserted there) than
compared to with the C backend.
Ultimately, lowering the `mMove` magic during the `injectdestructors` pass
would be the more robust fix.