Special handling for temporal assignments to unknown properties

Summary:
Release note: Support temporal assignment to object properties using unknown property names

Resolves issue: #1818

There was no code for dealing with assignments using unknown property names that showed up in generator entries.
Closes https://github.com/facebook/prepack/pull/1822

Differential Revision: D7833068

Pulled By: hermanventer

fbshipit-source-id: 2c3e8d211bd4770ba736ff9be03a0f4d85adad34
This commit is contained in:
Herman Venter 2018-05-01 12:41:12 -07:00 committed by Facebook Github Bot
parent ee1b47625a
commit c3a1fd3c46
4 changed files with 53 additions and 23 deletions

View File

@ -25,9 +25,9 @@ test:
- yarn test-sourcemaps
- yarn test-std-in
- yarn test-residual
- yarn test-test262 -- --statusFile $CIRCLE_ARTIFACTS/test262-status.txt --timeout 120 --cpuScale 0.25 --verbose:
- yarn test-test262 --statusFile $CIRCLE_ARTIFACTS/test262-status.txt --timeout 120 --cpuScale 0.25 --verbose:
timeout: 1800
# - yarn test-test262-new -- --statusFile $CIRCLE_ARTIFACTS/test262-new-status.txt --timeout 120 --verbose:
# - yarn test-test262-new --statusFile $CIRCLE_ARTIFACTS/test262-new-status.txt --timeout 120 --verbose:
# timeout: 1800
post:
- mv coverage/lcov-report $CIRCLE_ARTIFACTS/coverage-report

View File

@ -333,28 +333,31 @@ export class ResidualHeapVisitor {
visitObjectPropertiesWithComputedNames(absVal: AbstractValue): void {
if (absVal.kind === "widened property") return;
if (absVal.kind === "template for prototype member expression") return;
invariant(absVal.args.length === 3);
let cond = absVal.args[0];
invariant(cond instanceof AbstractValue);
if (cond.kind === "template for property name condition") {
let P = cond.args[0];
invariant(P instanceof AbstractValue);
let V = absVal.args[1];
let earlier_props = absVal.args[2];
if (earlier_props instanceof AbstractValue) this.visitObjectPropertiesWithComputedNames(earlier_props);
this.visitValue(P);
this.visitValue(V);
if (absVal.kind === "conditional") {
let cond = absVal.args[0];
invariant(cond instanceof AbstractValue);
if (cond.kind === "template for property name condition") {
let P = cond.args[0];
invariant(P instanceof AbstractValue);
let V = absVal.args[1];
let earlier_props = absVal.args[2];
if (earlier_props instanceof AbstractValue) this.visitObjectPropertiesWithComputedNames(earlier_props);
this.visitValue(P);
this.visitValue(V);
} else {
// conditional assignment
absVal.args[0] = this.visitEquivalentValue(cond);
let consequent = absVal.args[1];
if (consequent instanceof AbstractValue) {
this.visitObjectPropertiesWithComputedNames(consequent);
}
let alternate = absVal.args[2];
if (alternate instanceof AbstractValue) {
this.visitObjectPropertiesWithComputedNames(alternate);
}
}
} else {
// conditional assignment
absVal.args[0] = this.visitEquivalentValue(cond);
let consequent = absVal.args[1];
if (consequent instanceof AbstractValue) {
this.visitObjectPropertiesWithComputedNames(consequent);
}
let alternate = absVal.args[2];
if (alternate instanceof AbstractValue) {
this.visitObjectPropertiesWithComputedNames(alternate);
}
this.visitValue(absVal);
}
}
@ -1068,6 +1071,7 @@ export class ResidualHeapVisitor {
visitModifiedObjectProperty: (binding: PropertyBinding) => {
let fixpoint_rerun = () => {
if (this.values.has(binding.object)) {
if (binding.key instanceof Value) this.visitValue(binding.key);
this.visitObjectProperty(binding);
return true;
} else {

View File

@ -176,6 +176,22 @@ type ModifiedPropertyEntryArgs = {|
class ModifiedPropertyEntry extends GeneratorEntry {
constructor(args: ModifiedPropertyEntryArgs) {
super();
let desc = args.newDescriptor;
if (desc !== undefined) {
let val = desc.value;
if (val instanceof AbstractValue && val.kind === "conditional") {
desc.value = removePrototypeMemberExpression(val);
function removePrototypeMemberExpression(absVal: AbstractValue): Value {
if (absVal.kind !== "conditional") return absVal;
let [c, x, y] = absVal.args;
if (!(y instanceof AbstractValue)) return absVal;
if (y.kind === "template for prototype member expression") return x;
y = removePrototypeMemberExpression(y);
invariant(c instanceof AbstractValue);
return AbstractValue.createFromConditionalOp(absVal.$Realm, c, x, y);
}
}
}
Object.assign(this, args);
}

View File

@ -0,0 +1,10 @@
var cache = {};
function f(x, y) {
cache[x] = y;
}
if (global.__optimize) __optimize(f);
inspect = function() {
f(42, 5);
return cache[42];
};