| Index: src/v8natives.js
|
| diff --git a/src/v8natives.js b/src/v8natives.js
|
| index 96b88c5285c9962d479fa75d0e71031cd0c35b6c..e987baf6d6b36ff3708c770a76ab8f463b657a46 100644
|
| --- a/src/v8natives.js
|
| +++ b/src/v8natives.js
|
| @@ -79,6 +79,21 @@ function InstallGetterSetter(object, name, getter, setter) {
|
| }
|
|
|
|
|
| +// Helper function for installing constant properties on objects.
|
| +function InstallConstants(object, constants) {
|
| + if (constants.length >= 4) {
|
| + %OptimizeObjectForAddingMultipleProperties(object, constants.length >> 1);
|
| + }
|
| + var attributes = DONT_ENUM | DONT_DELETE | READ_ONLY;
|
| + for (var i = 0; i < constants.length; i += 2) {
|
| + var name = constants[i];
|
| + var k = constants[i + 1];
|
| + %SetProperty(object, name, k, attributes);
|
| + }
|
| + %ToFastProperties(object);
|
| +}
|
| +
|
| +
|
| // Prevents changes to the prototype of a built-in function.
|
| // The "prototype" property of the function object is made non-configurable,
|
| // and the prototype object is made non-extensible. The latter prevents
|
| @@ -1037,46 +1052,41 @@ function ToNameArray(obj, trap, includeSymbols) {
|
| }
|
|
|
|
|
| -// ES5 section 15.2.3.4.
|
| -function ObjectGetOwnPropertyNames(obj) {
|
| - if (!IS_SPEC_OBJECT(obj)) {
|
| - throw MakeTypeError("called_on_non_object", ["Object.getOwnPropertyNames"]);
|
| - }
|
| - // Special handling for proxies.
|
| - if (%IsJSProxy(obj)) {
|
| - var handler = %GetHandler(obj);
|
| - var names = CallTrap0(handler, "getOwnPropertyNames", UNDEFINED);
|
| - return ToNameArray(names, "getOwnPropertyNames", false);
|
| - }
|
| -
|
| +function ObjectGetOwnPropertyKeys(obj, symbolsOnly) {
|
| var nameArrays = new InternalArray();
|
| + var filter = symbolsOnly ?
|
| + PROPERTY_ATTRIBUTES_STRING | PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL :
|
| + PROPERTY_ATTRIBUTES_SYMBOLIC;
|
|
|
| // Find all the indexed properties.
|
|
|
| - // Get the local element names.
|
| - var localElementNames = %GetLocalElementNames(obj);
|
| - for (var i = 0; i < localElementNames.length; ++i) {
|
| - localElementNames[i] = %_NumberToString(localElementNames[i]);
|
| - }
|
| - nameArrays.push(localElementNames);
|
| -
|
| - // Get names for indexed interceptor properties.
|
| - var interceptorInfo = %GetInterceptorInfo(obj);
|
| - if ((interceptorInfo & 1) != 0) {
|
| - var indexedInterceptorNames = %GetIndexedInterceptorElementNames(obj);
|
| - if (!IS_UNDEFINED(indexedInterceptorNames)) {
|
| - nameArrays.push(indexedInterceptorNames);
|
| + // Only get the local element names if we want to include string keys.
|
| + if (!symbolsOnly) {
|
| + var localElementNames = %GetLocalElementNames(obj);
|
| + for (var i = 0; i < localElementNames.length; ++i) {
|
| + localElementNames[i] = %_NumberToString(localElementNames[i]);
|
| + }
|
| + nameArrays.push(localElementNames);
|
| +
|
| + // Get names for indexed interceptor properties.
|
| + var interceptorInfo = %GetInterceptorInfo(obj);
|
| + if ((interceptorInfo & 1) != 0) {
|
| + var indexedInterceptorNames = %GetIndexedInterceptorElementNames(obj);
|
| + if (!IS_UNDEFINED(indexedInterceptorNames)) {
|
| + nameArrays.push(indexedInterceptorNames);
|
| + }
|
| }
|
| }
|
|
|
| // Find all the named properties.
|
|
|
| // Get the local property names.
|
| - nameArrays.push(%GetLocalPropertyNames(obj, false));
|
| + nameArrays.push(%GetLocalPropertyNames(obj, filter));
|
|
|
| // Get names for named interceptor properties if any.
|
| if ((interceptorInfo & 2) != 0) {
|
| - var namedInterceptorNames = %GetNamedInterceptorPropertyNames(obj);
|
| + var namedInterceptorNames =
|
| + %GetNamedInterceptorPropertyNames(obj);
|
| if (!IS_UNDEFINED(namedInterceptorNames)) {
|
| nameArrays.push(namedInterceptorNames);
|
| }
|
| @@ -1089,18 +1099,18 @@ function ObjectGetOwnPropertyNames(obj) {
|
| // Property names are expected to be unique strings,
|
| // but interceptors can interfere with that assumption.
|
| if (interceptorInfo != 0) {
|
| - var propertySet = { __proto__: null };
|
| + var seenKeys = { __proto__: null };
|
| var j = 0;
|
| for (var i = 0; i < propertyNames.length; ++i) {
|
| - if (IS_SYMBOL(propertyNames[i])) continue;
|
| - var name = ToString(propertyNames[i]);
|
| - // We need to check for the exact property value since for intrinsic
|
| - // properties like toString if(propertySet["toString"]) will always
|
| - // succeed.
|
| - if (propertySet[name] === true) {
|
| - continue;
|
| + var name = propertyNames[i];
|
| + if (symbolsOnly) {
|
| + if (!IS_SYMBOL(name) || IS_PRIVATE(name)) continue;
|
| + } else {
|
| + if (IS_SYMBOL(name)) continue;
|
| + name = ToString(name);
|
| }
|
| - propertySet[name] = true;
|
| + if (seenKeys[name]) continue;
|
| + seenKeys[name] = true;
|
| propertyNames[j++] = name;
|
| }
|
| propertyNames.length = j;
|
| @@ -1110,6 +1120,22 @@ function ObjectGetOwnPropertyNames(obj) {
|
| }
|
|
|
|
|
| +// ES5 section 15.2.3.4.
|
| +function ObjectGetOwnPropertyNames(obj) {
|
| + if (!IS_SPEC_OBJECT(obj)) {
|
| + throw MakeTypeError("called_on_non_object", ["Object.getOwnPropertyNames"]);
|
| + }
|
| + // Special handling for proxies.
|
| + if (%IsJSProxy(obj)) {
|
| + var handler = %GetHandler(obj);
|
| + var names = CallTrap0(handler, "getOwnPropertyNames", UNDEFINED);
|
| + return ToNameArray(names, "getOwnPropertyNames", false);
|
| + }
|
| +
|
| + return ObjectGetOwnPropertyKeys(obj, false);
|
| +}
|
| +
|
| +
|
| // ES5 section 15.2.3.5.
|
| function ObjectCreate(proto, properties) {
|
| if (!IS_SPEC_OBJECT(proto) && proto !== null) {
|
| @@ -1419,12 +1445,15 @@ function SetUpObject() {
|
| "getPrototypeOf", ObjectGetPrototypeOf,
|
| "getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor,
|
| "getOwnPropertyNames", ObjectGetOwnPropertyNames,
|
| + // getOwnPropertySymbols is added in symbol.js.
|
| "is", ObjectIs,
|
| "isExtensible", ObjectIsExtensible,
|
| "isFrozen", ObjectIsFrozen,
|
| "isSealed", ObjectIsSealed,
|
| "preventExtensions", ObjectPreventExtension,
|
| "seal", ObjectSeal
|
| + // deliverChangeRecords, getNotifier, observe and unobserve are added
|
| + // in object-observe.js.
|
| ));
|
| }
|
|
|
| @@ -1624,12 +1653,29 @@ function NumberIsFinite(number) {
|
| }
|
|
|
|
|
| +// Harmony isInteger
|
| +function NumberIsInteger(number) {
|
| + return NumberIsFinite(number) && TO_INTEGER(number) == number;
|
| +}
|
| +
|
| +
|
| // Harmony isNaN.
|
| function NumberIsNaN(number) {
|
| return IS_NUMBER(number) && NUMBER_IS_NAN(number);
|
| }
|
|
|
|
|
| +// Harmony isSafeInteger
|
| +function NumberIsSafeInteger(number) {
|
| + if (NumberIsFinite(number)) {
|
| + var integral = TO_INTEGER(number);
|
| + if (integral == number)
|
| + return MathAbs(integral) <= $Number.MAX_SAFE_INTEGER;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| // ----------------------------------------------------------------------------
|
|
|
| function SetUpNumber() {
|
| @@ -1642,32 +1688,24 @@ function SetUpNumber() {
|
| // Set up the constructor property on the Number prototype object.
|
| %SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
|
|
|
| - %OptimizeObjectForAddingMultipleProperties($Number, 5);
|
| - // ECMA-262 section 15.7.3.1.
|
| - %SetProperty($Number,
|
| - "MAX_VALUE",
|
| - 1.7976931348623157e+308,
|
| - DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| -
|
| - // ECMA-262 section 15.7.3.2.
|
| - %SetProperty($Number, "MIN_VALUE", 5e-324,
|
| - DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| -
|
| - // ECMA-262 section 15.7.3.3.
|
| - %SetProperty($Number, "NaN", NAN, DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| -
|
| - // ECMA-262 section 15.7.3.4.
|
| - %SetProperty($Number,
|
| - "NEGATIVE_INFINITY",
|
| - -INFINITY,
|
| - DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| -
|
| - // ECMA-262 section 15.7.3.5.
|
| - %SetProperty($Number,
|
| - "POSITIVE_INFINITY",
|
| - INFINITY,
|
| - DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| - %ToFastProperties($Number);
|
| + InstallConstants($Number, $Array(
|
| + // ECMA-262 section 15.7.3.1.
|
| + "MAX_VALUE", 1.7976931348623157e+308,
|
| + // ECMA-262 section 15.7.3.2.
|
| + "MIN_VALUE", 5e-324,
|
| + // ECMA-262 section 15.7.3.3.
|
| + "NaN", NAN,
|
| + // ECMA-262 section 15.7.3.4.
|
| + "NEGATIVE_INFINITY", -INFINITY,
|
| + // ECMA-262 section 15.7.3.5.
|
| + "POSITIVE_INFINITY", INFINITY,
|
| +
|
| + // --- Harmony constants (no spec refs until settled.)
|
| +
|
| + "MAX_SAFE_INTEGER", %_MathPow(2, 53) - 1,
|
| + "MIN_SAFE_INTEGER", -%_MathPow(2, 53) + 1,
|
| + "EPSILON", %_MathPow(2, -52)
|
| + ));
|
|
|
| // Set up non-enumerable functions on the Number prototype object.
|
| InstallFunctions($Number.prototype, DONT_ENUM, $Array(
|
| @@ -1678,9 +1716,15 @@ function SetUpNumber() {
|
| "toExponential", NumberToExponential,
|
| "toPrecision", NumberToPrecision
|
| ));
|
| +
|
| + // Harmony Number constructor additions
|
| InstallFunctions($Number, DONT_ENUM, $Array(
|
| "isFinite", NumberIsFinite,
|
| - "isNaN", NumberIsNaN
|
| + "isInteger", NumberIsInteger,
|
| + "isNaN", NumberIsNaN,
|
| + "isSafeInteger", NumberIsSafeInteger,
|
| + "parseInt", GlobalParseInt,
|
| + "parseFloat", GlobalParseFloat
|
| ));
|
| }
|
|
|
|
|