Prevent accidental leakage of arguments between separate calls #2193
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
While trying to fix a different problem within Jint, I found this problem.
The problem is that the arguments array passed to execute a function internally is added back to the cache after completion. However, some functions invocations live longer than their their first call (generators, async functions [when the implementation for these gets changed]).
Its a niche problem but should be solved anyway I guess.
So imaging the following script (copied from the included new tests)
The expected output for this is:
But without this fix, it is
Underlying reason:
The basic execution flow is:
Line
var generator1 = method(42, undefined);method(42, undefined), anJsValue[]is fetched from the internalJsValueArrayPool.[42, undefined]methodreturns with a generator object.JsValue[]is returned to the poolLine
var generator2 = other(10, undefined);other(10, undefined)gets evaluated. For that - again - anJsValue[]is fetched from the internalJsValueArrayPool. That array however is the same instance which was used to when callingmethodin this particular case[10, undefined], but this also replaces the arguments used formethod()because they share the same arguments array instance.Line
.next().next()to run the log statements.Small detail. First I've had a different implementation within
JintCallExpressionitself but after some investigation, I saw that this was probably the wrong spot for this change. A function wherebindwas used has a different execution path in there (that's where the second generator test comes from) and after some digging I've realized that I would have to change a lot of places.I've kept the test inside just in case code is moved around later to catch potential regressions.