mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-09-11 14:46:37 +03:00
Support constructor returning an unknown abstract value (#2535)
Summary: The following test case currently fails: ```js function F() { this.a = 1; this.b = 2; if (global.__abstract) return global.__abstract(undefined, "undefined"); } const result = new F(); global.inspect = () => JSON.stringify(result); ``` We hit this bug in our internal React Native bundle. I only added support for `base` construction kinds since the template for `derived` construction kinds would get more complicated. Pull Request resolved: https://github.com/facebook/prepack/pull/2535 Differential Revision: D9906309 Pulled By: trueadm fbshipit-source-id: 49a71ceaf30a851075879295e63e98ce7e1bbe2d
This commit is contained in:
parent
781cae5b38
commit
a4620bd4bf
@ -276,17 +276,32 @@ function InternalConstruct(
|
||||
function map(value: Value) {
|
||||
if (value === realm.intrinsics.__bottomValue) return value;
|
||||
|
||||
if (value instanceof AbstractValue && value.kind === "conditional") {
|
||||
const [condition, consequent, alternate] = value.args;
|
||||
return realm.evaluateWithAbstractConditional(
|
||||
condition,
|
||||
() => realm.evaluateForEffects(() => map(consequent), undefined, "AbstractValue/conditional/true"),
|
||||
() => realm.evaluateForEffects(() => map(alternate), undefined, "AbstractValue/conditional/false")
|
||||
);
|
||||
if (value instanceof AbstractValue) {
|
||||
if (value.kind === "conditional") {
|
||||
const [condition, consequent, alternate] = value.args;
|
||||
return realm.evaluateWithAbstractConditional(
|
||||
condition,
|
||||
() => realm.evaluateForEffects(() => map(consequent), undefined, "AbstractValue/conditional/true"),
|
||||
() => realm.evaluateForEffects(() => map(alternate), undefined, "AbstractValue/conditional/false")
|
||||
);
|
||||
}
|
||||
if (!(value instanceof AbstractObjectValue)) {
|
||||
if (kind === "base") {
|
||||
invariant(thisArgument, "this wasn't initialized for some reason");
|
||||
return AbstractValue.createFromTemplate(
|
||||
realm,
|
||||
"typeof A === 'object' || typeof A === 'function' ? A : B",
|
||||
ObjectValue,
|
||||
[value, thisArgument]
|
||||
);
|
||||
} else {
|
||||
value.throwIfNotConcreteObject(); // Not yet supported.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// a. If Type(result.[[Value]]) is Object, return NormalCompletion(result.[[Value]]).
|
||||
if (value.mightBeObject()) return value.throwIfNotConcreteObject();
|
||||
if (value instanceof ObjectValue || value instanceof AbstractObjectValue) return value;
|
||||
|
||||
// b. If kind is "base", return NormalCompletion(thisArgument).
|
||||
if (kind === "base") {
|
||||
|
@ -0,0 +1,9 @@
|
||||
function F() {
|
||||
this.a = 1;
|
||||
this.b = 2;
|
||||
if (global.__abstract) return global.__abstract(undefined, "undefined");
|
||||
}
|
||||
|
||||
const result = new F();
|
||||
|
||||
global.inspect = () => JSON.stringify(result);
|
Loading…
Reference in New Issue
Block a user