diff --git a/src/methods/function.js b/src/methods/function.js index fbddaae6b..5fd8e3ca4 100644 --- a/src/methods/function.js +++ b/src/methods/function.js @@ -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") { diff --git a/test/serializer/abstract/ConstructFunctionReturnsAbstract.js b/test/serializer/abstract/ConstructFunctionReturnsAbstract.js new file mode 100644 index 000000000..9a3e5e7b9 --- /dev/null +++ b/test/serializer/abstract/ConstructFunctionReturnsAbstract.js @@ -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);