Skip to content

Commit

Permalink
Deoptimize ObjectExpression when a __proto__ property is present (#4019)
Browse files Browse the repository at this point in the history
* Deoptimize ObjectExpression when a __proto__ property is present

Closes #4014

* Integrate __proto__ detection with getPropertyMap

* Fix formatting

Co-authored-by: Lukas Taegert-Atkinson <lukastaegert@users.noreply.github.com>
Co-authored-by: Lukas Taegert-Atkinson <lukas.taegert-atkinson@tngtech.com>
  • Loading branch information
3 people committed Mar 29, 2021
1 parent 56b3eb8 commit 85a3724
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 9 deletions.
20 changes: 11 additions & 9 deletions src/ast/nodes/ObjectExpression.ts
Expand Up @@ -307,27 +307,29 @@ export default class ObjectExpression extends NodeBase implements DeoptimizableE
}
const isWrite = property.kind !== 'get';
const isRead = property.kind !== 'set';
let key;
let key: string;
let unmatchable = false;
if (property.computed) {
const keyValue = property.key.getLiteralValueAtPath(
EMPTY_PATH,
SHARED_RECURSION_TRACKER,
this
);
if (keyValue === UnknownValue) {
if (isRead) {
this.unmatchablePropertiesRead.push(property);
} else {
this.unmatchablePropertiesWrite.push(property);
}
continue;
}
if (keyValue === UnknownValue) unmatchable = true;
key = String(keyValue);
} else if (property.key instanceof Identifier) {
key = property.key.name;
} else {
key = String((property.key as Literal).value);
}
if (unmatchable || (key === '__proto__' && !property.computed)) {
if (isRead) {
this.unmatchablePropertiesRead.push(property);
} else {
this.unmatchablePropertiesWrite.push(property);
}
continue;
}
const propertyMapProperty = propertyMap[key];
if (!propertyMapProperty) {
propertyMap[key] = {
Expand Down
3 changes: 3 additions & 0 deletions test/form/samples/object-expression/proto-property/_config.js
@@ -0,0 +1,3 @@
module.exports = {
description: 'Deoptimize when __proto__ is used'
};
13 changes: 13 additions & 0 deletions test/form/samples/object-expression/proto-property/_expected.js
@@ -0,0 +1,13 @@
let proto = {
get a() { log(); }
};

let plainProto = {
__proto__: proto
};
if (plainProto.a) log("plainProto");

let quotedProto = {
"__proto__": proto
};
if (quotedProto.a) log("quotedProto");
18 changes: 18 additions & 0 deletions test/form/samples/object-expression/proto-property/main.js
@@ -0,0 +1,18 @@
let basic = {
a: false
};
if (basic.a) log("basic");

let proto = {
get a() { log(); }
};

let plainProto = {
__proto__: proto
};
if (plainProto.a) log("plainProto");

let quotedProto = {
"__proto__": proto
};
if (quotedProto.a) log("quotedProto");

0 comments on commit 85a3724

Please sign in to comment.