Judging by only the C diff you provided, I'm very certain that the compiler PR 
causing you trouble is [this](https://github.com/nim-lang/Nim/pull/23769) one. 
It fixed an evaluation-order issue that your code seems to have relied on.

In Nim, evaluation order is strictly left-to-right, inside-to-outside (at least 
in theory, there were still some issues last time I checked, but they might 
have been fixed already). This also applies to assignments - again, in theory. 
A `push(stack.pop())` template invocation expands to:
    
    
    Stack[SP] = ((SP -= 1; move stack[SP]))
    
    
    Run

which, in your case, gets transformed into:
    
    
    `=sink`(Stack[SP], (SP -= 1; move Stack[SP]))
    
    
    Run

Prior to the aforementioned PR, the call was effectively evaluated like this 
(when using the C backend):
    
    
    SP -= 1
    let tmp = move Stack[SP]
    `=sink`(Stack[sp], tmp)
    
    
    Run

which is incorrect (according to the language rules), whereas now it is 
(correctly) evaluated like this:
    
    
    let tmp1 = addr Stack[SP]
    SP -= 1
    let tmp2 = move Stack[SP]
    `=sink`(tmp1[], tmp2)
    
    
    Run

Fortunately, the fix is simple. In your `push` template, simply assign the `v` 
template parameter to a temporary first, like so:
    
    
    template push(v: Value) =
      let tmp = v
      Stack[PC] = ensureMove tmp
      PC += 1
    
    
    Run

Alternatively, you could also assign `PC` to a temporary, which might result in 
slightly more efficient code.

Reply via email to