mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-09-20 11:37:22 +03:00
Add option to not emit invariants for model functions
Summary: FunctionValues should not be compared with `===` from the model. Add an option to disable this invariant. Closes https://github.com/facebook/prepack/pull/881 Differential Revision: D5626447 Pulled By: cblappert fbshipit-source-id: 3f0bb71cd6dd0b556e46df85658c715798fa0204
This commit is contained in:
parent
69761bf597
commit
be70144220
@ -189,14 +189,20 @@ function runTest(name, code, options, args) {
|
||||
markersToFind.push({ positive, value, start: i + marker.length });
|
||||
}
|
||||
}
|
||||
let addedCode = "";
|
||||
let injectAtRuntime = "// add at runtime:";
|
||||
if (code.includes(injectAtRuntime)) {
|
||||
let i = code.indexOf(injectAtRuntime);
|
||||
addedCode = code.substring(i + injectAtRuntime.length, code.indexOf("\n", i));
|
||||
}
|
||||
let unique = 27277;
|
||||
let oldUniqueSuffix = "";
|
||||
try {
|
||||
expected = exec(`(function () {${code} // keep newline here as code may end with comment
|
||||
expected = exec(`${addedCode}\n(function () {${code} // keep newline here as code may end with comment
|
||||
}).call(this);`);
|
||||
|
||||
let i = 0;
|
||||
let max = 4;
|
||||
let max = addedCode ? 1 : 4;
|
||||
let oldCode = code;
|
||||
let anyDelayedValues = false;
|
||||
for (; i < max; i++) {
|
||||
@ -220,7 +226,7 @@ function runTest(name, code, options, args) {
|
||||
}
|
||||
}
|
||||
if (markersIssue) break;
|
||||
actual = exec(newCode);
|
||||
actual = exec(addedCode + newCode);
|
||||
if (expected !== actual) {
|
||||
console.log(chalk.red("Output mismatch!"));
|
||||
break;
|
||||
@ -249,6 +255,7 @@ function runTest(name, code, options, args) {
|
||||
oldCode = newCode;
|
||||
oldUniqueSuffix = newUniqueSuffix;
|
||||
}
|
||||
if (i === 1) return true;
|
||||
if (i === max) {
|
||||
if (anyDelayedValues) {
|
||||
// TODO #835: Make delayed initializations logic more sophisticated in order to still reach a fixed point.
|
||||
|
@ -256,7 +256,7 @@ export default function(realm: Realm): void {
|
||||
"global.__assumeDataProperty",
|
||||
"__assumeDataProperty",
|
||||
3,
|
||||
(context, [object, propertyName, value]) => {
|
||||
(context, [object, propertyName, value, invariantOptions]) => {
|
||||
if (!realm.useAbstractInterpretation) {
|
||||
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "realm is not partial");
|
||||
}
|
||||
@ -267,12 +267,32 @@ export default function(realm: Realm): void {
|
||||
if ((object: any) instanceof AbstractObjectValue || (object: any) instanceof ObjectValue) {
|
||||
let generator = realm.generator;
|
||||
invariant(generator);
|
||||
generator.emitInvariant(
|
||||
[object, value, object],
|
||||
([objectNode, valueNode]) =>
|
||||
t.binaryExpression("!==", t.memberExpression(objectNode, t.identifier(key)), valueNode),
|
||||
objnode => t.memberExpression(objnode, t.identifier(key))
|
||||
);
|
||||
let condition = ([objectNode, valueNode]) =>
|
||||
t.binaryExpression("!==", t.memberExpression(objectNode, t.identifier(key)), valueNode);
|
||||
if (invariantOptions) {
|
||||
let invariantOptionString = ToStringPartial(realm, invariantOptions);
|
||||
switch (invariantOptionString) {
|
||||
case "VALUE_DEFINED_INVARIANT":
|
||||
condition = ([objectNode, valueNode]) =>
|
||||
t.binaryExpression(
|
||||
"===",
|
||||
t.memberExpression(objectNode, t.identifier(key)),
|
||||
t.valueToNode(undefined)
|
||||
);
|
||||
break;
|
||||
case "SKIP_INVARIANT":
|
||||
condition = null;
|
||||
break;
|
||||
case "FULL_INVARIANT":
|
||||
break;
|
||||
default:
|
||||
invariant(false, "Invalid invariantOption " + invariantOptionString);
|
||||
}
|
||||
}
|
||||
if (condition)
|
||||
generator.emitInvariant([object, value, object], condition, objnode =>
|
||||
t.memberExpression(objnode, t.identifier(key))
|
||||
);
|
||||
realm.generator = undefined; // don't emit code during the following $Set call
|
||||
// casting to due to Flow workaround above
|
||||
(object: any).$Set(key, value, object);
|
||||
|
15
test/serializer/abstract/ModelFunction.js
Normal file
15
test/serializer/abstract/ModelFunction.js
Normal file
@ -0,0 +1,15 @@
|
||||
// add at runtime: global.fun = console.log;
|
||||
var result = [];
|
||||
global.log = function (arg) { result.push(arg); };
|
||||
if (global.__assumeDataProperty) {
|
||||
__assumeDataProperty(global, "fun",
|
||||
function (arg1) {
|
||||
__residual("void", function(arg1, console) {
|
||||
console.log(arg1);
|
||||
}, arg1, console);
|
||||
}, "VALUE_DEFINED_INVARIANT");
|
||||
}
|
||||
|
||||
global.fun("literal");
|
||||
|
||||
inspect = function() { return undefined; };
|
Loading…
Reference in New Issue
Block a user