mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-09-19 19:17:25 +03:00
Check if intrinsic abstract values have unique names
Summary: Fix for #1155 Closes https://github.com/facebook/prepack/pull/1197 Differential Revision: D6546346 Pulled By: hermanventer fbshipit-source-id: 7c24e1ce4ebf121a6d50176e7dc124d83f7cdad4
This commit is contained in:
parent
a0ece2f8b4
commit
8ece9d1b3e
@ -24,6 +24,7 @@ import { ValuesDomain } from "../../domains/index.js";
|
||||
import { describeLocation } from "../ecma262/Error.js";
|
||||
import { To } from "../../singletons.js";
|
||||
import AbstractObjectValue from "../../values/AbstractObjectValue";
|
||||
import { CompilerDiagnostic, FatalError } from "../../errors.js";
|
||||
|
||||
const throwTemplateSrc = "(function(){throw new global.Error('abstract value defined at ' + A);})()";
|
||||
const throwTemplate = buildExpressionTemplate(throwTemplateSrc);
|
||||
@ -69,24 +70,33 @@ export function createAbstract(
|
||||
let { type, template } = parseTypeNameOrTemplate(realm, typeNameOrTemplate);
|
||||
|
||||
let result;
|
||||
let locString,
|
||||
loc = null;
|
||||
for (let executionContext of realm.contextStack.slice().reverse()) {
|
||||
let caller = executionContext.caller;
|
||||
loc = executionContext.loc;
|
||||
locString = describeLocation(
|
||||
realm,
|
||||
caller ? caller.function : undefined,
|
||||
caller ? caller.lexicalEnvironment : undefined,
|
||||
loc
|
||||
);
|
||||
if (locString !== undefined) break;
|
||||
}
|
||||
let nameString = name ? To.ToStringPartial(realm, name) : "";
|
||||
if (nameString === "") {
|
||||
let locString;
|
||||
for (let executionContext of realm.contextStack.slice().reverse()) {
|
||||
let caller = executionContext.caller;
|
||||
locString = describeLocation(
|
||||
realm,
|
||||
caller ? caller.function : undefined,
|
||||
caller ? caller.lexicalEnvironment : undefined,
|
||||
executionContext.loc
|
||||
);
|
||||
if (locString !== undefined) break;
|
||||
}
|
||||
let locVal = new StringValue(realm, locString || "(unknown location)");
|
||||
let kind = "__abstract_" + realm.objectCount++; // need not be an object, but must be unique
|
||||
result = AbstractValue.createFromTemplate(realm, throwTemplate, type, [locVal], kind);
|
||||
} else {
|
||||
let kind = "__abstract_" + nameString; // assume name is unique TODO #1155: check this
|
||||
let kind = "__abstract_" + nameString;
|
||||
if (!realm.isNameStringUnique(nameString)) {
|
||||
let error = new CompilerDiagnostic("An abstract value with the same name exists", loc, "PP0019", "FatalError");
|
||||
realm.handleError(error);
|
||||
throw new FatalError();
|
||||
} else {
|
||||
realm.saveNameString(nameString);
|
||||
}
|
||||
result = AbstractValue.createFromTemplate(realm, buildExpressionTemplate(nameString), type, [], kind);
|
||||
result.intrinsicName = nameString;
|
||||
}
|
||||
|
10
src/realm.js
10
src/realm.js
@ -181,6 +181,7 @@ export class Realm {
|
||||
this.errorHandler = opts.errorHandler;
|
||||
|
||||
this.globalSymbolRegistry = [];
|
||||
this._abstractValuesDefined = new Set(); // A set of nameStrings to ensure abstract values have unique names
|
||||
}
|
||||
|
||||
start: number;
|
||||
@ -264,6 +265,7 @@ export class Realm {
|
||||
debuggerInstance: DebugServerType | void;
|
||||
|
||||
nextGeneratorId: number = 0;
|
||||
_abstractValuesDefined: Set<string>;
|
||||
|
||||
// to force flow to type the annotations
|
||||
isCompatibleWith(compatibility: Compatibility): boolean {
|
||||
@ -952,4 +954,12 @@ export class Realm {
|
||||
}
|
||||
return errorHandler(diagnostic);
|
||||
}
|
||||
|
||||
saveNameString(nameString: string): void {
|
||||
this._abstractValuesDefined.add(nameString);
|
||||
}
|
||||
|
||||
isNameStringUnique(nameString: string): boolean {
|
||||
return !this._abstractValuesDefined.has(nameString);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,4 @@
|
||||
// expected errors: [{"location": {"start":{"line":4,"column":0},"end":{"line":4,"column":27},"source":"test/error-handler/abstract-value-check-dup-name-string.js"},"severity":"FatalError","errorCode":"PP0019","message":"An abstract value with the same name exists"}]
|
||||
|
||||
__abstract('number', 'foo');
|
||||
__abstract('number', 'foo');
|
@ -1,6 +1,6 @@
|
||||
(function() {
|
||||
let x = global.__abstract ? __abstract("boolean", "(true)") : true;
|
||||
let y = global.__abstract ? __abstract("boolean", "(true)") : true;
|
||||
let x = global.__abstract ? __abstract("boolean", "/* x = */(true)") : true;
|
||||
let y = global.__abstract ? __abstract("boolean", "/* y = */(true)") : true;
|
||||
let obj = { p: 42 };
|
||||
if (y) {
|
||||
if (x) {
|
||||
|
@ -2,16 +2,16 @@ let dims = global.__abstract ? __abstract({
|
||||
window: undefined,
|
||||
screen: undefined,
|
||||
windowPhysicalPixels: __abstract({
|
||||
width: __abstract("number", "1"),
|
||||
height: __abstract("number", "1"),
|
||||
scale: __abstract("number", "2"),
|
||||
fontScale: __abstract("number", "4"),
|
||||
width: __abstract("number", "/* windowPhysicalPixels.width = */ 1"),
|
||||
height: __abstract("number", "/* windowPhysicalPixels.height = */ 1"),
|
||||
scale: __abstract("number", "/* windowPhysicalPixels.scale = */ 2"),
|
||||
fontScale: __abstract("number", "/* windowPhysicalPixels.fontScale = */4"),
|
||||
}),
|
||||
screenPhysicalPixels: __abstract({
|
||||
width: __abstract("number", "1"),
|
||||
height: __abstract("number", "1"),
|
||||
scale: __abstract("number", "2"),
|
||||
fontScale: __abstract("number", "4"),
|
||||
width: __abstract("number", "/* screenPhysicalPixels.width = */ 1"),
|
||||
height: __abstract("number", "/* screenPhysicalPixels.height = */1"),
|
||||
scale: __abstract("number", "/* screenPhysicalPixels.scale = */ 2"),
|
||||
fontScale: __abstract("number", "/*screenPhysicalPixels.fontScale = */4"),
|
||||
}),
|
||||
}, `({
|
||||
window: undefined,
|
||||
|
@ -1,6 +1,6 @@
|
||||
var n = global.__abstract ? __abstract("string", '("x")') : "x";
|
||||
var m = global.__abstract ? __abstract("string", '("x")') : "x";
|
||||
var c = global.__abstract ? __abstract("boolean", "true") : true;
|
||||
var n = global.__abstract ? __abstract("string", '/* n = */ ("x")') : "x";
|
||||
var m = global.__abstract ? __abstract("string", '/* m = */ ("x")') : "x";
|
||||
var c = global.__abstract ? __abstract("boolean", "/* c = */ true") : true;
|
||||
|
||||
a = {x: 123, y: 444};
|
||||
if (global.__makeSimple) global.__makeSimple(a);
|
||||
|
@ -1,10 +1,13 @@
|
||||
let c = 0;
|
||||
let overflow = false;
|
||||
function check() {
|
||||
return global.__abstract ? __abstract('boolean', 'true') : true;
|
||||
function check1() {
|
||||
return global.__abstract ? __abstract('boolean', '/* check1 */ true') : true;
|
||||
}
|
||||
function call() {
|
||||
if (check()) {
|
||||
function check2() {
|
||||
return global.__abstract ? __abstract('boolean', '/* check2 */ true') : true;
|
||||
}
|
||||
function call1() {
|
||||
if (check1()) {
|
||||
c = c + 1;
|
||||
if (c > 2) {
|
||||
overflow = true;
|
||||
@ -13,8 +16,18 @@ function call() {
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
a = call();
|
||||
b = call();
|
||||
function call2() {
|
||||
if (check2()) {
|
||||
c = c + 1;
|
||||
if (c > 2) {
|
||||
overflow = true;
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
a = call1();
|
||||
b = call2();
|
||||
inspect = function() {
|
||||
return overflow;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user