Fixed call argument value snapshotting.#1060
Conversation
Both are minor. |
Since fd5e523 (0.9.7), njs has evaluated all call argument expressions before emitting the frame and PUT_ARG instructions. This fixed await expressions in call arguments and preserved argument side effects before callee validation, but left PUT_ARG reading argument values only after later argument expressions had already run. As a result, an earlier argument backed by a mutable variable slot could observe a later mutation of the same slot. For example, f(a, a = 2) passed 2 as both arguments instead of preserving the first value as 1. The same issue applied to later argument effects such as getters. The fix is to preserve affected argument values in temporary registers where appropriate. This fixes nginx#1059 issue on Github.
The recursive walk is not dead. This is easily discoverable with simple assert statement + current tests. It is reached by compound argument expressions whose result aliases a mutable slot, for example assignment expressions |
Since fd5e523 (0.9.7), njs has evaluated all call argument expressions before emitting the frame and PUT_ARG instructions, this fixed await expressions in call arguments. This preserved argument side effects before callee validation, but left PUT_ARG reading argument values only after later argument expressions had already run.
As a result, an earlier argument backed by a mutable variable slot could observe a later mutation of the same slot. For example, f(a, a = 2) passed 2 as both arguments instead of preserving the first value as 1. The same issue applied to later argument effects such as getters.
The fix is to preserve arguments using temporary registers where appropriate.
This fixes #1059 issue on Github.