For abstract objects, look into values domain for IsCall (#2268)

Summary:
Release notes: None

IsCall used to fail on abstract values even if they have a set of values in their domain.
This in turn would make `typeof` not work on abstract values.
This makes it work, and adds a regression test.
Pull Request resolved: https://github.com/facebook/prepack/pull/2268

Differential Revision: D8878641

Pulled By: NTillmann

fbshipit-source-id: f6dda513786eaf3f02bd13d5c6474c2f20fb0082
This commit is contained in:
Nikolai Tillmann 2018-07-18 01:50:02 -07:00 committed by Facebook Github Bot
parent cd67ae0e8c
commit 7ec32cf3aa
2 changed files with 16 additions and 0 deletions

View File

@ -108,6 +108,16 @@ export function IsCallable(realm: Realm, _func: Value): boolean {
if (HasCompatibleType(func, FunctionValue)) return true;
if (func.isSimpleObject()) return false;
if (func instanceof AbstractObjectValue && !func.values.isTop()) {
let result;
for (let element of func.values.getElements()) {
let isCallable = IsCallable(realm, element);
if (result === undefined) result = isCallable;
else if (result !== isCallable) func.throwIfNotConcreteObject();
}
if (result !== undefined) return result;
}
// 2. If argument has a [[Call]] internal method, return true.
func = func.throwIfNotConcreteObject();
if (func.$Call) return true;

View File

@ -0,0 +1,6 @@
let obj = global.__abstract ? __abstract({}, "obj") : {};
let func = global.__abstract ? __abstract(function() {}, "func") : function() {};
global.result = typeof obj + "/" + typeof func;
global.inspect = function() {
return global.result;
};