Ignore modifications of Prepack-specific intrinsic properties (#2269)

Summary:
Release notes: None

Fixes #2266 and adds regression test.
Fixes #2262 and adds regression test.
Pull Request resolved: https://github.com/facebook/prepack/pull/2269

Differential Revision: D8896059

Pulled By: NTillmann

fbshipit-source-id: aee93083c6da6d703d7788a6458e2506638debc3
This commit is contained in:
Nikolai Tillmann 2018-07-18 10:46:01 -07:00 committed by Facebook Github Bot
parent 237d825dae
commit 7d355ef4c5
8 changed files with 50 additions and 8 deletions

View File

@ -507,9 +507,11 @@ function runTest(name, code, options: PrepackOptions, args) {
if (code.includes(diagnosticExpectedComment)) {
let idx = code.indexOf(diagnosticExpectedComment);
let errorCodeString = code.substring(idx + diagnosticExpectedComment.length, code.indexOf("\n", idx));
let errorCodeSet = new Set();
expectedDiagnostics.set(severity, errorCodeSet);
errorCodeString.split(",").forEach(errorCode => errorCodeSet.add(errorCode.trim()));
if (errorCodeString.trim() !== "") {
let errorCodeSet = new Set();
expectedDiagnostics.set(severity, errorCodeSet);
errorCodeString.split(",").forEach(errorCode => errorCodeSet.add(errorCode.trim()));
}
options.residual = false;
options.errorHandler = getErrorHandlerWithWarningCapture(diagnosticOutput, args.verbose);
}

View File

@ -21,6 +21,7 @@ import {
AbstractObjectValue,
ConcreteValue,
FunctionValue,
NativeFunctionValue,
ObjectValue,
Value,
} from "../values/index.js";
@ -266,7 +267,7 @@ function tryToEvaluateCallOrLeaveAsAbstract(
let effects;
let savedSuppressDiagnostics = realm.suppressDiagnostics;
try {
realm.suppressDiagnostics = true;
realm.suppressDiagnostics = !(func instanceof NativeFunctionValue) || func.name !== "__optimize";
effects = realm.evaluateForEffects(
() => EvaluateDirectCall(realm, strictCode, env, ref, func, thisValue, ast.arguments, tailCall),
undefined,

View File

@ -370,7 +370,7 @@ export class Functions {
};
let oldReportPropertyAccess = this.realm.reportPropertyAccess;
this.realm.reportPropertyAccess = (pb: PropertyBinding) => {
if (pb.object.refuseSerialization) return;
if (ObjectValue.refuseSerializationOnPropertyBinding(pb)) return;
let location = this.realm.currentLocation;
if (!location) return; // happens only when accessing an additional function property
if (pbs.has(pb) && !conflicts.has(location)) reportConflict(location);

View File

@ -217,12 +217,14 @@ export function handleReportedSideEffect(
exceptionHandler(`side-effects from mutating the binding ${name}${location}`);
} else if (sideEffectType === "MODIFIED_PROPERTY" || sideEffectType === "MODIFIED_GLOBAL") {
let name = "";
let key = ((binding: any): PropertyBinding).key;
let pb = ((binding: any): PropertyBinding);
let key = pb.key;
if (typeof key === "string") {
name = `"${key}"`;
}
if (sideEffectType === "MODIFIED_PROPERTY") {
exceptionHandler(`side-effects from mutating a property ${name}${location}`);
if (!ObjectValue.refuseSerializationOnPropertyBinding(pb))
exceptionHandler(`side-effects from mutating a property ${name}${location}`);
} else {
exceptionHandler(`side-effects from mutating the global object property ${name}${location}`);
}

View File

@ -559,7 +559,7 @@ export class Generator {
for (let propertyBinding of modifiedProperties.keys()) {
let object = propertyBinding.object;
if (createdObjects.has(object)) continue; // Created Object's binding
if (object.refuseSerialization) continue; // modification to internal state
if (ObjectValue.refuseSerializationOnPropertyBinding(propertyBinding)) continue; // modification to internal state
// modifications to intrinsic objects are tracked in the generator
if (object.isIntrinsic()) continue;
output.emitPropertyModification(propertyBinding);

View File

@ -1074,4 +1074,10 @@ export default class ObjectValue extends ConcreteValue {
$OwnPropertyKeys(): Array<PropertyKeyValue> {
return OrdinaryOwnPropertyKeys(this.$Realm, this);
}
static refuseSerializationOnPropertyBinding(pb: PropertyBinding): boolean {
if (pb.object.refuseSerialization) return true;
if (pb.internalSlot && typeof pb.key === "string" && pb.key[0] === "_") return true;
return false;
}
}

View File

@ -0,0 +1,19 @@
(function() {
let p = {};
function f(c) {
let o = {};
if (c) {
if (global.__makePartial) __makePartial(o);
throw o;
}
}
if (global.__optimize) __optimize(f);
inspect = function() {
try {
f(true);
return false;
} catch (e) {
return true;
}
};
})();

View File

@ -0,0 +1,12 @@
// expected Warning:
function outer() {
function inner() {
return 42;
}
if (global.__optimize) __optimize(inner);
return inner;
}
if (global.__optimize) __optimize(outer);
global.inspect = function() {
return outer()();
};