Have es2015 rest transform safely use arguments - #2833
Conversation
|
Thanks for your comments. In this first commit I fixed the |
There was a problem hiding this comment.
Is the || arguments[0] === undefined necessary for the v8 optimisation? It seems odd that it would
There was a problem hiding this comment.
You're right, it's not. In most cases arguments.length <= 0 || (undefined || arguments[0]) (I suppose that's what you suggest?) behaves the same way, but they are not really equivalent. Consider the following:
var _arguments = {length: 0};
console.log(_arguments.length <= 0 || _arguments[0] === undefined ? undefined : _arguments[0]);
console.log(_arguments.length <= 0 || (undefined || _arguments[0]));First case will return undefined, second case will return true.
1fb31c9 to
1cd8cb7
Compare
1cd8cb7 to
b82138e
Compare
b82138e to
9a97d92
Compare
Current coverage is
|
|
I finally fixed my PR. Tests are green, coverage remains unchanged. |
|
Looks good to me, @sebmck ? |
|
Super disappointing that VMs require this :( I'll hopefully get around to reviewing this early next week. Please feel free to ping this issue if I forget. Really sorry for the delay! |
There was a problem hiding this comment.
Minor style issue: would INDEX be more appropriate than KEY?
There was a problem hiding this comment.
I would've picked INDEX, but it doesn't really matter either way.
Have es2015 rest transform safely use `arguments`
|
Thanks for doing this @vhf! Extremely sorry for the delay in merging this. |
|
my KEY gets transformed to NaN: function func(...sources) {
for (let i = 0; i < sources.length; i += 1) {
const source = sources[i];
// ...
}
}function func() {
for (var i = 0; i < arguments.length; i += 1) {
var source = arguments.length <= NaN || arguments[NaN] === undefined ? undefined : arguments[NaN];
// ...
}
} |
|
Should be function func() {
for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
sources[_key] = arguments[_key];
}
for (var i = 0; i < sources.length; i++) {
const source = sources[i];
}
}instead. Fixed by #3165 |
Hi, I audited some code generated by Babel and noticed that in some cases some improvements could be made to ensure that V8 optimiser (Crankshaft) will not bail out a little too soon. I focused on the use of
arguments: usingargumentsin an unsafe way prevents V8 (and therefore Node.js) to optimise a function. Here is a first patch in the direction of usingargumentssafely in Babel es2015-transformed code. Although far from perfect in terms of implementation (first time contributor here, still learning Babel internals, happy to receive your comments and/or to chat on slack or by email) this patch will probably give an idea of what could be done, and could be followed by other patches aiming towards the goal of avoiding generation of V8-unoptimisable code.With this PR I'm only focusing on the very first and easiest part of my findings. In the future, I'll try to fix some other unsafe uses of
argumentsin every transformation and then try to focus on other possible V8 optimisations.From what I understood, performances are more important to Babel than prettiness. This patch somewhat impacts readability of es2015-presets generated code. But it also has impact on performance.
Although tests are green and I did my best to adhere to what I think are Babel's codebase best practices, please review very carefully. For example, I was not sure whether to include
optimiseLoadStatementdefinition invisitor(as seen indefaults.js) or to define them outside ofvisitor's scope.