mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-09-11 22:57:35 +03:00
Unify logic for checking for intrinsic objects that have been derived (#2581)
Summary: Release notes: none This PR cleans up some of the `onArrayWithWidenedNumericProperty` logic, making it more generic for cases where we want to use concrete derived object values. Furthermore, it strengthens the validation process by checking for existence of `isScopedTemplate` on the internal object. Pull Request resolved: https://github.com/facebook/prepack/pull/2581 Differential Revision: D10141954 Pulled By: trueadm fbshipit-source-id: 8de828080b8a41357830cdbf7e49359512bc7244
This commit is contained in:
parent
ed784d6899
commit
5fc6feeeb2
@ -305,7 +305,7 @@ function InternalCloneObject(realm: Realm, val: ObjectValue): ObjectValue {
|
|||||||
}
|
}
|
||||||
if (val.isPartialObject()) clone.makePartial();
|
if (val.isPartialObject()) clone.makePartial();
|
||||||
if (val.isSimpleObject()) clone.makeSimple();
|
if (val.isSimpleObject()) clone.makeSimple();
|
||||||
clone._isScopedTemplate = true; // because this object doesn't exist ahead of time, and the visitor would otherwise declare it in the common scope
|
clone.isScopedTemplate = true; // because this object doesn't exist ahead of time, and the visitor would otherwise declare it in the common scope
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
AbstractValue,
|
AbstractValue,
|
||||||
ArrayValue,
|
|
||||||
BoundFunctionValue,
|
BoundFunctionValue,
|
||||||
FunctionValue,
|
FunctionValue,
|
||||||
ObjectValue,
|
ObjectValue,
|
||||||
@ -38,9 +37,9 @@ type EmitterDependenciesVisitorCallbacks<T> = {
|
|||||||
// Callback invoked whenever a dependency is visited that is an abstract value with an identifier.
|
// Callback invoked whenever a dependency is visited that is an abstract value with an identifier.
|
||||||
// A return value that is not undefined indicates that the visitor should stop, and return the value as the overall result.
|
// A return value that is not undefined indicates that the visitor should stop, and return the value as the overall result.
|
||||||
onAbstractValueWithIdentifier?: AbstractValue => void | T,
|
onAbstractValueWithIdentifier?: AbstractValue => void | T,
|
||||||
// Callback invoked whenever a dependency is visited that is an array value with a widened numeric property.
|
// Callback invoked whenever a dependency is visited that is an intrinsic object that was derived
|
||||||
// A return value that is not undefined indicates that the visitor should stop, and return the value as the overall result.
|
// A return value that is not undefined indicates that the visitor should stop, and return the value as the overall result.
|
||||||
onArrayWithWidenedNumericProperty?: ArrayValue => void | T,
|
onIntrinsicDerivedObject?: ObjectValue => void | T,
|
||||||
};
|
};
|
||||||
|
|
||||||
// The emitter keeps track of a stack of what's currently being emitted.
|
// The emitter keeps track of a stack of what's currently being emitted.
|
||||||
@ -78,7 +77,7 @@ export class Emitter {
|
|||||||
this._activeValues = new Set();
|
this._activeValues = new Set();
|
||||||
this._activeGeneratorStack = [this._mainBody];
|
this._activeGeneratorStack = [this._mainBody];
|
||||||
this._finalized = false;
|
this._finalized = false;
|
||||||
let mustWaitForValue = (val: AbstractValue | ArrayValue) => {
|
let mustWaitForValue = (val: AbstractValue | ObjectValue) => {
|
||||||
if (this.cannotDeclare()) return false;
|
if (this.cannotDeclare()) return false;
|
||||||
if (this.hasBeenDeclared(val)) return false;
|
if (this.hasBeenDeclared(val)) return false;
|
||||||
let activeOptimizedFunction = this.getActiveOptimizedFunction();
|
let activeOptimizedFunction = this.getActiveOptimizedFunction();
|
||||||
@ -95,7 +94,7 @@ export class Emitter {
|
|||||||
},
|
},
|
||||||
onAbstractValueWithIdentifier: val =>
|
onAbstractValueWithIdentifier: val =>
|
||||||
derivedIds.has(val.getIdentifier()) && mustWaitForValue(val) ? val : undefined,
|
derivedIds.has(val.getIdentifier()) && mustWaitForValue(val) ? val : undefined,
|
||||||
onArrayWithWidenedNumericProperty: val => (mustWaitForValue(val) ? val : undefined),
|
onIntrinsicDerivedObject: val => (mustWaitForValue(val) ? val : undefined),
|
||||||
};
|
};
|
||||||
this._conditionalFeasibility = conditionalFeasibility;
|
this._conditionalFeasibility = conditionalFeasibility;
|
||||||
}
|
}
|
||||||
@ -351,10 +350,8 @@ export class Emitter {
|
|||||||
result = recurse(val.$Description);
|
result = recurse(val.$Description);
|
||||||
if (result !== undefined) return result;
|
if (result !== undefined) return result;
|
||||||
}
|
}
|
||||||
} else if (val instanceof ArrayValue && ArrayValue.isIntrinsicAndHasWidenedNumericProperty(val)) {
|
} else if (val instanceof ObjectValue && ObjectValue.isIntrinsicDerivedObject(val)) {
|
||||||
result = callbacks.onArrayWithWidenedNumericProperty
|
result = callbacks.onIntrinsicDerivedObject ? callbacks.onIntrinsicDerivedObject(val) : undefined;
|
||||||
? callbacks.onArrayWithWidenedNumericProperty(val)
|
|
||||||
: undefined;
|
|
||||||
if (result !== undefined) return result;
|
if (result !== undefined) return result;
|
||||||
} else if (val instanceof ObjectValue) {
|
} else if (val instanceof ObjectValue) {
|
||||||
let kind = val.getKind();
|
let kind = val.getKind();
|
||||||
|
@ -940,11 +940,9 @@ export class ResidualHeapSerializer {
|
|||||||
// which is related to one of the scopes this value is used by.
|
// which is related to one of the scopes this value is used by.
|
||||||
let notYetDoneBodies = new Set();
|
let notYetDoneBodies = new Set();
|
||||||
this.emitter.dependenciesVisitor(val, {
|
this.emitter.dependenciesVisitor(val, {
|
||||||
onArrayWithWidenedNumericProperty: dependency => {
|
onIntrinsicDerivedObject: dependency => {
|
||||||
if (trace) {
|
if (trace) {
|
||||||
console.log(
|
console.log(` depending on intrinsic derived object and an identifier ${dependency.intrinsicName || "?"}`);
|
||||||
` depending on array with widened numeric properties and an identifier ${dependency.intrinsicName || "?"}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
invariant(
|
invariant(
|
||||||
optimizedFunctionRoot === undefined || !!this.emitter.getActiveOptimizedFunction(),
|
optimizedFunctionRoot === undefined || !!this.emitter.getActiveOptimizedFunction(),
|
||||||
|
@ -1087,7 +1087,7 @@ export class ResidualHeapVisitor {
|
|||||||
} else if (val.isIntrinsic()) {
|
} else if (val.isIntrinsic()) {
|
||||||
// All intrinsic values exist from the beginning of time...
|
// All intrinsic values exist from the beginning of time...
|
||||||
// ...except for a few that come into existence as templates for abstract objects via executable code.
|
// ...except for a few that come into existence as templates for abstract objects via executable code.
|
||||||
if (val instanceof ObjectValue && val._isScopedTemplate) {
|
if (val instanceof ObjectValue && val.isScopedTemplate) {
|
||||||
this.preProcessValue(val);
|
this.preProcessValue(val);
|
||||||
this.postProcessValue(val);
|
this.postProcessValue(val);
|
||||||
} else
|
} else
|
||||||
|
@ -1067,7 +1067,7 @@ export class Generator {
|
|||||||
let id = this.preludeGenerator.nameGenerator.generate("derived");
|
let id = this.preludeGenerator.nameGenerator.generate("derived");
|
||||||
let value = buildValue(id);
|
let value = buildValue(id);
|
||||||
value.intrinsicNameGenerated = true;
|
value.intrinsicNameGenerated = true;
|
||||||
value._isScopedTemplate = true; // because this object doesn't exist ahead of time, and the visitor would otherwise declare it in the common scope
|
value.isScopedTemplate = true; // because this object doesn't exist ahead of time, and the visitor would otherwise declare it in the common scope
|
||||||
invariant(value.intrinsicName === id);
|
invariant(value.intrinsicName === id);
|
||||||
this._addDerivedEntry({
|
this._addDerivedEntry({
|
||||||
isPure: optionalArgs ? optionalArgs.isPure : undefined,
|
isPure: optionalArgs ? optionalArgs.isPure : undefined,
|
||||||
|
@ -242,7 +242,8 @@ export default class ArrayValue extends ObjectValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isIntrinsicAndHasWidenedNumericProperty(obj: Value): boolean {
|
static isIntrinsicAndHasWidenedNumericProperty(obj: Value): boolean {
|
||||||
if (obj instanceof ArrayValue && obj.intrinsicName !== undefined) {
|
if (obj instanceof ArrayValue && obj.intrinsicName !== undefined && obj.isScopedTemplate !== undefined) {
|
||||||
|
invariant(ObjectValue.isIntrinsicDerivedObject(obj));
|
||||||
const prop = obj.unknownProperty;
|
const prop = obj.unknownProperty;
|
||||||
if (prop !== undefined && prop.descriptor !== undefined) {
|
if (prop !== undefined && prop.descriptor !== undefined) {
|
||||||
const desc = prop.descriptor.throwIfNotConcrete(obj.$Realm);
|
const desc = prop.descriptor.throwIfNotConcrete(obj.$Realm);
|
||||||
|
@ -279,7 +279,7 @@ export default class ObjectValue extends ConcreteValue {
|
|||||||
|
|
||||||
// Specifies whether the object is a template that needs to be created in a scope
|
// Specifies whether the object is a template that needs to be created in a scope
|
||||||
// If set, this happened during object initialization and the value is never changed again, so not tracked.
|
// If set, this happened during object initialization and the value is never changed again, so not tracked.
|
||||||
_isScopedTemplate: void | true;
|
isScopedTemplate: void | true;
|
||||||
|
|
||||||
// If true, then unknown properties should return transitively simple abstract object values
|
// If true, then unknown properties should return transitively simple abstract object values
|
||||||
_simplicityIsTransitive: AbstractValue | BooleanValue;
|
_simplicityIsTransitive: AbstractValue | BooleanValue;
|
||||||
@ -718,4 +718,8 @@ export default class ObjectValue extends ConcreteValue {
|
|||||||
if (pb.internalSlot && typeof pb.key === "string" && pb.key[0] === "_") return true;
|
if (pb.internalSlot && typeof pb.key === "string" && pb.key[0] === "_") return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isIntrinsicDerivedObject(obj: Value): boolean {
|
||||||
|
return obj instanceof ObjectValue && obj.intrinsicName !== undefined && obj.isScopedTemplate !== undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user