Add abstract support to Object.getOwnPropertySymbols (#2575)

Summary:
Release notes: none

Fixes https://github.com/facebook/prepack/issues/2574. This PR adds abstract value support to `Object.getOwnPropertySymbols` like we have done other internal methods (like `Object.keys` and `Array.from`) where we know the internal method creates an array with unknown numeric properties.
Pull Request resolved: https://github.com/facebook/prepack/pull/2575

Differential Revision: D10114237

Pulled By: trueadm

fbshipit-source-id: 07301147e2dff1ab370243a8dc9648745bbbbb96
This commit is contained in:
Dominic Gannaway 2018-09-28 15:52:11 -07:00 committed by Facebook Github Bot
parent 0ef3c43563
commit ed784d6899
4 changed files with 63 additions and 5 deletions

View File

@ -495,11 +495,29 @@ export default function(realm: Realm): NativeFunctionValue {
});
// ECMA262 19.1.2.9
if (!realm.isCompatibleWith(realm.MOBILE_JSC_VERSION) && !realm.isCompatibleWith("mobile"))
func.defineNativeMethod("getOwnPropertySymbols", 1, (context, [O]) => {
if (!realm.isCompatibleWith(realm.MOBILE_JSC_VERSION) && !realm.isCompatibleWith("mobile")) {
let getOwnPropertySymbols = func.defineNativeMethod("getOwnPropertySymbols", 1, (context, [O]) => {
if (O instanceof AbstractValue && realm.isInPureScope()) {
let obj = O instanceof AbstractObjectValue ? O : To.ToObject(realm, O);
realm.callReportObjectGetOwnProperties(obj);
return ArrayValue.createTemporalWithWidenedNumericProperty(
realm,
[getOwnPropertySymbols, obj],
createOperationDescriptor("UNKNOWN_ARRAY_METHOD_CALL")
);
} else if (ArrayValue.isIntrinsicAndHasWidenedNumericProperty(O)) {
realm.callReportObjectGetOwnProperties(O);
return ArrayValue.createTemporalWithWidenedNumericProperty(
realm,
[getOwnPropertySymbols, O],
createOperationDescriptor("UNKNOWN_ARRAY_METHOD_CALL")
);
}
// Return ? GetOwnPropertyKeys(O, Symbol).
return GetOwnPropertyKeys(realm, O, SymbolValue);
});
}
// ECMA262 19.1.2.10
func.defineNativeMethod("getPrototypeOf", 1, (context, [O]) => {

View File

@ -365,7 +365,7 @@ export class Realm {
modifiedProperties: void | PropertyBindings;
createdObjects: void | CreatedObjects;
createdObjectsTrackedForLeaks: void | CreatedObjects;
reportObjectGetOwnProperties: void | (ObjectValue => void);
reportObjectGetOwnProperties: void | ((ObjectValue | AbstractObjectValue) => void);
reportSideEffectCallbacks: Set<
(sideEffectType: SideEffectType, binding: void | Binding | PropertyBinding, expressionLocation: any) => void
>;
@ -1491,7 +1491,7 @@ export class Realm {
return binding;
}
callReportObjectGetOwnProperties(ob: ObjectValue): void {
callReportObjectGetOwnProperties(ob: ObjectValue | AbstractObjectValue): void {
if (this.reportObjectGetOwnProperties !== undefined) {
this.reportObjectGetOwnProperties(ob);
}

View File

@ -390,7 +390,7 @@ export class Functions {
writtenObjects.add(key.object);
});
let oldReportObjectGetOwnProperties = this.realm.reportObjectGetOwnProperties;
this.realm.reportObjectGetOwnProperties = (ob: ObjectValue) => {
this.realm.reportObjectGetOwnProperties = (ob: ObjectValue | AbstractObjectValue) => {
let location = this.realm.currentLocation;
invariant(location);
if (writtenObjects.has(ob) && !conflicts.has(location))

View File

@ -0,0 +1,40 @@
function objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === "function") {
ownKeys = ownKeys.concat(
Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
})
);
}
ownKeys.forEach(function(key) {
babelHelpers.defineProperty(target, key, source[key]);
});
}
return target;
}
function fn(baseHeaders, contentEncoding, userAgent) {
var headers = objectSpread({}, baseHeaders);
if (contentEncoding) {
headers["Content-Encoding"] = contentEncoding;
}
if (userAgent) {
headers["User-Agent"] = userAgent;
}
return headers;
}
global.__optimize && __optimize(fn);
inspect = function() {
return JSON.stringify(fn({ a: 1, b: 2 }, "123", "456"));
};