Fix rest optimization errors.
This commit is contained in:
parent
8419be1afc
commit
49e30f49bc
@ -58,40 +58,59 @@ let memberExpressionOptimisationVisitor = {
|
|||||||
state.deopted = true;
|
state.deopted = true;
|
||||||
} else {
|
} else {
|
||||||
let {parentPath} = path;
|
let {parentPath} = path;
|
||||||
let grandparentPath = parentPath.parentPath;
|
|
||||||
|
|
||||||
// ex: [rest[0]] = [rest[1]]
|
// ex: `args[0]`
|
||||||
if (grandparentPath.isLVal()) {
|
// ex: `args.whatever`
|
||||||
state.deopted = true;
|
if (parentPath.isMemberExpression({ object: node })) {
|
||||||
return;
|
let grandparentPath = parentPath.parentPath;
|
||||||
}
|
|
||||||
|
|
||||||
// ex: args[0]
|
let argsOptEligible = !state.deopted && !(
|
||||||
if (
|
// ex: `args[0] = "whatever"`
|
||||||
parentPath.isMemberExpression({ computed: true, object: node }) &&
|
(
|
||||||
|
grandparentPath.isAssignmentExpression() &&
|
||||||
|
parentPath.node === grandparentPath.node.left
|
||||||
|
) ||
|
||||||
|
|
||||||
// ex: `args[0] = "whatever"`
|
// ex: `[args[0]] = ["whatever"]`
|
||||||
!(
|
grandparentPath.isLVal() ||
|
||||||
grandparentPath.isAssignmentExpression() &&
|
|
||||||
parentPath.node === grandparentPath.node.left
|
|
||||||
) &&
|
|
||||||
!grandparentPath.isForInStatement()
|
|
||||||
) {
|
|
||||||
// if we know that this member expression is referencing a number then
|
|
||||||
// we can safely optimise it
|
|
||||||
let prop = parentPath.get("property");
|
|
||||||
if (prop.isBaseType("number")) {
|
|
||||||
state.candidates.push({cause: "indexGetter", path});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ex: args.length
|
// ex: `for (rest[0] in this)`
|
||||||
if (parentPath.isMemberExpression({ computed: false, object: node })) {
|
// ex: `for (rest[0] of this)`
|
||||||
let prop = parentPath.get("property");
|
grandparentPath.isForXStatement() ||
|
||||||
if (prop.node.name === "length") {
|
|
||||||
state.candidates.push({cause: "lengthGetter", path});
|
// ex: `++args[0]`
|
||||||
return;
|
// ex: `args[0]--`
|
||||||
|
grandparentPath.isUpdateExpression() ||
|
||||||
|
|
||||||
|
// ex: `delete args[0]`
|
||||||
|
grandparentPath.isUnaryExpression({ operator: "delete" }) ||
|
||||||
|
|
||||||
|
// ex: `args[0]()`
|
||||||
|
// ex: `new args[0]()`
|
||||||
|
// ex: `new args[0]`
|
||||||
|
(
|
||||||
|
(
|
||||||
|
grandparentPath.isCallExpression() ||
|
||||||
|
grandparentPath.isNewExpression()
|
||||||
|
) &&
|
||||||
|
parentPath.node === grandparentPath.node.callee
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (argsOptEligible) {
|
||||||
|
if (parentPath.node.computed) {
|
||||||
|
// if we know that this member expression is referencing a number then
|
||||||
|
// we can safely optimise it
|
||||||
|
if (parentPath.get("property").isBaseType("number")) {
|
||||||
|
state.candidates.push({cause: "indexGetter", path});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// args.length
|
||||||
|
else if (parentPath.node.property.name === "length") {
|
||||||
|
state.candidates.push({cause: "lengthGetter", path});
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user