Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Unified Diff: src/v8natives.js

Issue 1398733002: Move builtin JavaScript sources into own directory. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Also move macros.py file. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/uri.js ('k') | src/weak-collection.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/v8natives.js
diff --git a/src/v8natives.js b/src/v8natives.js
deleted file mode 100644
index 34c35031b2601dd4c1ef614c877668d307502569..0000000000000000000000000000000000000000
--- a/src/v8natives.js
+++ /dev/null
@@ -1,1850 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-(function(global, utils) {
-
-%CheckIsBootstrapping();
-
-// ----------------------------------------------------------------------------
-// Imports
-
-var FLAG_harmony_tostring;
-var GlobalArray = global.Array;
-var GlobalBoolean = global.Boolean;
-var GlobalFunction = global.Function;
-var GlobalNumber = global.Number;
-var GlobalObject = global.Object;
-var InternalArray = utils.InternalArray;
-var iteratorSymbol = utils.ImportNow("iterator_symbol");
-var MathAbs;
-var ProxyDelegateCallAndConstruct;
-var ProxyDerivedHasOwnTrap;
-var ProxyDerivedKeysTrap;
-var StringIndexOf;
-var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
-
-utils.Import(function(from) {
- MathAbs = from.MathAbs;
- StringIndexOf = from.StringIndexOf;
-});
-
-utils.ImportFromExperimental(function(from) {
- FLAG_harmony_tostring = from.FLAG_harmony_tostring;
- ProxyDelegateCallAndConstruct = from.ProxyDelegateCallAndConstruct;
- ProxyDerivedHasOwnTrap = from.ProxyDerivedHasOwnTrap;
- ProxyDerivedKeysTrap = from.ProxyDerivedKeysTrap;
-});
-
-// ----------------------------------------------------------------------------
-
-
-// ECMA 262 - 15.1.4
-function GlobalIsNaN(number) {
- number = TO_NUMBER(number);
- return NUMBER_IS_NAN(number);
-}
-
-
-// ECMA 262 - 15.1.5
-function GlobalIsFinite(number) {
- number = TO_NUMBER(number);
- return NUMBER_IS_FINITE(number);
-}
-
-
-// ECMA-262 - 15.1.2.2
-function GlobalParseInt(string, radix) {
- if (IS_UNDEFINED(radix) || radix === 10 || radix === 0) {
- // Some people use parseInt instead of Math.floor. This
- // optimization makes parseInt on a Smi 12 times faster (60ns
- // vs 800ns). The following optimization makes parseInt on a
- // non-Smi number 9 times faster (230ns vs 2070ns). Together
- // they make parseInt on a string 1.4% slower (274ns vs 270ns).
- if (%_IsSmi(string)) return string;
- if (IS_NUMBER(string) &&
- ((0.01 < string && string < 1e9) ||
- (-1e9 < string && string < -0.01))) {
- // Truncate number.
- return string | 0;
- }
- string = TO_STRING(string);
- radix = radix | 0;
- } else {
- // The spec says ToString should be evaluated before ToInt32.
- string = TO_STRING(string);
- radix = TO_INT32(radix);
- if (!(radix == 0 || (2 <= radix && radix <= 36))) {
- return NAN;
- }
- }
-
- if (%_HasCachedArrayIndex(string) &&
- (radix == 0 || radix == 10)) {
- return %_GetCachedArrayIndex(string);
- }
- return %StringParseInt(string, radix);
-}
-
-
-// ECMA-262 - 15.1.2.3
-function GlobalParseFloat(string) {
- string = TO_STRING(string);
- if (%_HasCachedArrayIndex(string)) return %_GetCachedArrayIndex(string);
- return %StringParseFloat(string);
-}
-
-
-function GlobalEval(x) {
- if (!IS_STRING(x)) return x;
-
- var global_proxy = %GlobalProxy(GlobalEval);
-
- var f = %CompileString(x, false);
- if (!IS_FUNCTION(f)) return f;
-
- return %_CallFunction(global_proxy, f);
-}
-
-
-// ----------------------------------------------------------------------------
-
-// Set up global object.
-var attributes = DONT_ENUM | DONT_DELETE | READ_ONLY;
-
-utils.InstallConstants(global, [
- // ECMA 262 - 15.1.1.1.
- "NaN", NAN,
- // ECMA-262 - 15.1.1.2.
- "Infinity", INFINITY,
- // ECMA-262 - 15.1.1.2.
- "undefined", UNDEFINED,
-]);
-
-// Set up non-enumerable function on the global object.
-utils.InstallFunctions(global, DONT_ENUM, [
- "isNaN", GlobalIsNaN,
- "isFinite", GlobalIsFinite,
- "parseInt", GlobalParseInt,
- "parseFloat", GlobalParseFloat,
- "eval", GlobalEval
-]);
-
-
-// ----------------------------------------------------------------------------
-// Object
-
-// ECMA-262 - 15.2.4.2
-function ObjectToString() {
- if (IS_UNDEFINED(this)) return "[object Undefined]";
- if (IS_NULL(this)) return "[object Null]";
- var O = TO_OBJECT(this);
- var builtinTag = %_ClassOf(O);
- var tag;
-
- // TODO(caitp): cannot wait to get rid of this flag :>
- if (FLAG_harmony_tostring) {
- tag = O[toStringTagSymbol];
- if (!IS_STRING(tag)) {
- tag = builtinTag;
- }
- } else {
- tag = builtinTag;
- }
-
- return `[object ${tag}]`;
-}
-
-
-// ECMA-262 - 15.2.4.3
-function ObjectToLocaleString() {
- CHECK_OBJECT_COERCIBLE(this, "Object.prototype.toLocaleString");
- return this.toString();
-}
-
-
-// ECMA-262 - 15.2.4.4
-function ObjectValueOf() {
- return TO_OBJECT(this);
-}
-
-
-// ECMA-262 - 15.2.4.5
-function ObjectHasOwnProperty(value) {
- var name = TO_NAME(value);
- var object = TO_OBJECT(this);
-
- if (%_IsJSProxy(object)) {
- // TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (IS_SYMBOL(value)) return false;
-
- var handler = %GetHandler(object);
- return CallTrap1(handler, "hasOwn", ProxyDerivedHasOwnTrap, name);
- }
- return %HasOwnProperty(object, name);
-}
-
-
-// ECMA-262 - 15.2.4.6
-function ObjectIsPrototypeOf(V) {
- if (!IS_SPEC_OBJECT(V)) return false;
- var O = TO_OBJECT(this);
- return %_HasInPrototypeChain(V, O);
-}
-
-
-// ECMA-262 - 15.2.4.6
-function ObjectPropertyIsEnumerable(V) {
- var P = TO_NAME(V);
- if (%_IsJSProxy(this)) {
- // TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (IS_SYMBOL(V)) return false;
-
- var desc = GetOwnPropertyJS(this, P);
- return IS_UNDEFINED(desc) ? false : desc.isEnumerable();
- }
- return %IsPropertyEnumerable(TO_OBJECT(this), P);
-}
-
-
-// Extensions for providing property getters and setters.
-function ObjectDefineGetter(name, fun) {
- var receiver = this;
- if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
- receiver = %GlobalProxy(ObjectDefineGetter);
- }
- if (!IS_CALLABLE(fun)) {
- throw MakeTypeError(kObjectGetterExpectingFunction);
- }
- var desc = new PropertyDescriptor();
- desc.setGet(fun);
- desc.setEnumerable(true);
- desc.setConfigurable(true);
- DefineOwnProperty(TO_OBJECT(receiver), TO_NAME(name), desc, false);
-}
-
-
-function ObjectLookupGetter(name) {
- var receiver = this;
- if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
- receiver = %GlobalProxy(ObjectLookupGetter);
- }
- return %LookupAccessor(TO_OBJECT(receiver), TO_NAME(name), GETTER);
-}
-
-
-function ObjectDefineSetter(name, fun) {
- var receiver = this;
- if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
- receiver = %GlobalProxy(ObjectDefineSetter);
- }
- if (!IS_CALLABLE(fun)) {
- throw MakeTypeError(kObjectSetterExpectingFunction);
- }
- var desc = new PropertyDescriptor();
- desc.setSet(fun);
- desc.setEnumerable(true);
- desc.setConfigurable(true);
- DefineOwnProperty(TO_OBJECT(receiver), TO_NAME(name), desc, false);
-}
-
-
-function ObjectLookupSetter(name) {
- var receiver = this;
- if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
- receiver = %GlobalProxy(ObjectLookupSetter);
- }
- return %LookupAccessor(TO_OBJECT(receiver), TO_NAME(name), SETTER);
-}
-
-
-function ObjectKeys(obj) {
- obj = TO_OBJECT(obj);
- if (%_IsJSProxy(obj)) {
- var handler = %GetHandler(obj);
- var names = CallTrap0(handler, "keys", ProxyDerivedKeysTrap);
- return ToNameArray(names, "keys", false);
- }
- return %OwnKeys(obj);
-}
-
-
-// ES5 8.10.1.
-function IsAccessorDescriptor(desc) {
- if (IS_UNDEFINED(desc)) return false;
- return desc.hasGetter() || desc.hasSetter();
-}
-
-
-// ES5 8.10.2.
-function IsDataDescriptor(desc) {
- if (IS_UNDEFINED(desc)) return false;
- return desc.hasValue() || desc.hasWritable();
-}
-
-
-// ES5 8.10.3.
-function IsGenericDescriptor(desc) {
- if (IS_UNDEFINED(desc)) return false;
- return !(IsAccessorDescriptor(desc) || IsDataDescriptor(desc));
-}
-
-
-function IsInconsistentDescriptor(desc) {
- return IsAccessorDescriptor(desc) && IsDataDescriptor(desc);
-}
-
-
-// ES5 8.10.4
-function FromPropertyDescriptor(desc) {
- if (IS_UNDEFINED(desc)) return desc;
-
- if (IsDataDescriptor(desc)) {
- return { value: desc.getValue(),
- writable: desc.isWritable(),
- enumerable: desc.isEnumerable(),
- configurable: desc.isConfigurable() };
- }
- // Must be an AccessorDescriptor then. We never return a generic descriptor.
- return { get: desc.getGet(),
- set: desc.getSet(),
- enumerable: desc.isEnumerable(),
- configurable: desc.isConfigurable() };
-}
-
-
-// Harmony Proxies
-function FromGenericPropertyDescriptor(desc) {
- if (IS_UNDEFINED(desc)) return desc;
- var obj = new GlobalObject();
-
- if (desc.hasValue()) {
- %AddNamedProperty(obj, "value", desc.getValue(), NONE);
- }
- if (desc.hasWritable()) {
- %AddNamedProperty(obj, "writable", desc.isWritable(), NONE);
- }
- if (desc.hasGetter()) {
- %AddNamedProperty(obj, "get", desc.getGet(), NONE);
- }
- if (desc.hasSetter()) {
- %AddNamedProperty(obj, "set", desc.getSet(), NONE);
- }
- if (desc.hasEnumerable()) {
- %AddNamedProperty(obj, "enumerable", desc.isEnumerable(), NONE);
- }
- if (desc.hasConfigurable()) {
- %AddNamedProperty(obj, "configurable", desc.isConfigurable(), NONE);
- }
- return obj;
-}
-
-
-// ES5 8.10.5.
-function ToPropertyDescriptor(obj) {
- if (!IS_SPEC_OBJECT(obj)) throw MakeTypeError(kPropertyDescObject, obj);
-
- var desc = new PropertyDescriptor();
-
- if ("enumerable" in obj) {
- desc.setEnumerable(TO_BOOLEAN(obj.enumerable));
- }
-
- if ("configurable" in obj) {
- desc.setConfigurable(TO_BOOLEAN(obj.configurable));
- }
-
- if ("value" in obj) {
- desc.setValue(obj.value);
- }
-
- if ("writable" in obj) {
- desc.setWritable(TO_BOOLEAN(obj.writable));
- }
-
- if ("get" in obj) {
- var get = obj.get;
- if (!IS_UNDEFINED(get) && !IS_CALLABLE(get)) {
- throw MakeTypeError(kObjectGetterCallable, get);
- }
- desc.setGet(get);
- }
-
- if ("set" in obj) {
- var set = obj.set;
- if (!IS_UNDEFINED(set) && !IS_CALLABLE(set)) {
- throw MakeTypeError(kObjectSetterCallable, set);
- }
- desc.setSet(set);
- }
-
- if (IsInconsistentDescriptor(desc)) {
- throw MakeTypeError(kValueAndAccessor, obj);
- }
- return desc;
-}
-
-
-// For Harmony proxies.
-function ToCompletePropertyDescriptor(obj) {
- var desc = ToPropertyDescriptor(obj);
- if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) {
- if (!desc.hasValue()) desc.setValue(UNDEFINED);
- if (!desc.hasWritable()) desc.setWritable(false);
- } else {
- // Is accessor descriptor.
- if (!desc.hasGetter()) desc.setGet(UNDEFINED);
- if (!desc.hasSetter()) desc.setSet(UNDEFINED);
- }
- if (!desc.hasEnumerable()) desc.setEnumerable(false);
- if (!desc.hasConfigurable()) desc.setConfigurable(false);
- return desc;
-}
-
-
-function PropertyDescriptor() {
- // Initialize here so they are all in-object and have the same map.
- // Default values from ES5 8.6.1.
- this.value_ = UNDEFINED;
- this.hasValue_ = false;
- this.writable_ = false;
- this.hasWritable_ = false;
- this.enumerable_ = false;
- this.hasEnumerable_ = false;
- this.configurable_ = false;
- this.hasConfigurable_ = false;
- this.get_ = UNDEFINED;
- this.hasGetter_ = false;
- this.set_ = UNDEFINED;
- this.hasSetter_ = false;
-}
-
-utils.SetUpLockedPrototype(PropertyDescriptor, [
- "value_",
- "hasValue_",
- "writable_",
- "hasWritable_",
- "enumerable_",
- "hasEnumerable_",
- "configurable_",
- "hasConfigurable_",
- "get_",
- "hasGetter_",
- "set_",
- "hasSetter_"
-], [
- "toString", function PropertyDescriptor_ToString() {
- return "[object PropertyDescriptor]";
- },
- "setValue", function PropertyDescriptor_SetValue(value) {
- this.value_ = value;
- this.hasValue_ = true;
- },
- "getValue", function PropertyDescriptor_GetValue() {
- return this.value_;
- },
- "hasValue", function PropertyDescriptor_HasValue() {
- return this.hasValue_;
- },
- "setEnumerable", function PropertyDescriptor_SetEnumerable(enumerable) {
- this.enumerable_ = enumerable;
- this.hasEnumerable_ = true;
- },
- "isEnumerable", function PropertyDescriptor_IsEnumerable() {
- return this.enumerable_;
- },
- "hasEnumerable", function PropertyDescriptor_HasEnumerable() {
- return this.hasEnumerable_;
- },
- "setWritable", function PropertyDescriptor_SetWritable(writable) {
- this.writable_ = writable;
- this.hasWritable_ = true;
- },
- "isWritable", function PropertyDescriptor_IsWritable() {
- return this.writable_;
- },
- "hasWritable", function PropertyDescriptor_HasWritable() {
- return this.hasWritable_;
- },
- "setConfigurable",
- function PropertyDescriptor_SetConfigurable(configurable) {
- this.configurable_ = configurable;
- this.hasConfigurable_ = true;
- },
- "hasConfigurable", function PropertyDescriptor_HasConfigurable() {
- return this.hasConfigurable_;
- },
- "isConfigurable", function PropertyDescriptor_IsConfigurable() {
- return this.configurable_;
- },
- "setGet", function PropertyDescriptor_SetGetter(get) {
- this.get_ = get;
- this.hasGetter_ = true;
- },
- "getGet", function PropertyDescriptor_GetGetter() {
- return this.get_;
- },
- "hasGetter", function PropertyDescriptor_HasGetter() {
- return this.hasGetter_;
- },
- "setSet", function PropertyDescriptor_SetSetter(set) {
- this.set_ = set;
- this.hasSetter_ = true;
- },
- "getSet", function PropertyDescriptor_GetSetter() {
- return this.set_;
- },
- "hasSetter", function PropertyDescriptor_HasSetter() {
- return this.hasSetter_;
- }
-]);
-
-
-// Converts an array returned from Runtime_GetOwnProperty to an actual
-// property descriptor. For a description of the array layout please
-// see the runtime.cc file.
-function ConvertDescriptorArrayToDescriptor(desc_array) {
- if (IS_UNDEFINED(desc_array)) {
- return UNDEFINED;
- }
-
- var desc = new PropertyDescriptor();
- // This is an accessor.
- if (desc_array[IS_ACCESSOR_INDEX]) {
- desc.setGet(desc_array[GETTER_INDEX]);
- desc.setSet(desc_array[SETTER_INDEX]);
- } else {
- desc.setValue(desc_array[VALUE_INDEX]);
- desc.setWritable(desc_array[WRITABLE_INDEX]);
- }
- desc.setEnumerable(desc_array[ENUMERABLE_INDEX]);
- desc.setConfigurable(desc_array[CONFIGURABLE_INDEX]);
-
- return desc;
-}
-
-
-// For Harmony proxies.
-function GetTrap(handler, name, defaultTrap) {
- var trap = handler[name];
- if (IS_UNDEFINED(trap)) {
- if (IS_UNDEFINED(defaultTrap)) {
- throw MakeTypeError(kProxyHandlerTrapMissing, handler, name);
- }
- trap = defaultTrap;
- } else if (!IS_CALLABLE(trap)) {
- throw MakeTypeError(kProxyHandlerTrapMustBeCallable, handler, name);
- }
- return trap;
-}
-
-
-function CallTrap0(handler, name, defaultTrap) {
- return %_CallFunction(handler, GetTrap(handler, name, defaultTrap));
-}
-
-
-function CallTrap1(handler, name, defaultTrap, x) {
- return %_CallFunction(handler, x, GetTrap(handler, name, defaultTrap));
-}
-
-
-function CallTrap2(handler, name, defaultTrap, x, y) {
- return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap));
-}
-
-
-// ES5 section 8.12.1.
-function GetOwnPropertyJS(obj, v) {
- var p = TO_NAME(v);
- if (%_IsJSProxy(obj)) {
- // TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (IS_SYMBOL(v)) return UNDEFINED;
-
- var handler = %GetHandler(obj);
- var descriptor = CallTrap1(
- handler, "getOwnPropertyDescriptor", UNDEFINED, p);
- if (IS_UNDEFINED(descriptor)) return descriptor;
- var desc = ToCompletePropertyDescriptor(descriptor);
- if (!desc.isConfigurable()) {
- throw MakeTypeError(kProxyPropNotConfigurable,
- handler, p, "getOwnPropertyDescriptor");
- }
- return desc;
- }
-
- // GetOwnProperty returns an array indexed by the constants
- // defined in macros.py.
- // If p is not a property on obj undefined is returned.
- var props = %GetOwnProperty(TO_OBJECT(obj), p);
-
- return ConvertDescriptorArrayToDescriptor(props);
-}
-
-
-// ES5 section 8.12.7.
-function Delete(obj, p, should_throw) {
- var desc = GetOwnPropertyJS(obj, p);
- if (IS_UNDEFINED(desc)) return true;
- if (desc.isConfigurable()) {
- %DeleteProperty_Sloppy(obj, p);
- return true;
- } else if (should_throw) {
- throw MakeTypeError(kDefineDisallowed, p);
- } else {
- return;
- }
-}
-
-
-// ES6, draft 12-24-14, section 7.3.8
-function GetMethod(obj, p) {
- var func = obj[p];
- if (IS_NULL_OR_UNDEFINED(func)) return UNDEFINED;
- if (IS_CALLABLE(func)) return func;
- throw MakeTypeError(kCalledNonCallable, typeof func);
-}
-
-
-// Harmony proxies.
-function DefineProxyProperty(obj, p, attributes, should_throw) {
- // TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (IS_SYMBOL(p)) return false;
-
- var handler = %GetHandler(obj);
- var result = CallTrap2(handler, "defineProperty", UNDEFINED, p, attributes);
- if (!result) {
- if (should_throw) {
- throw MakeTypeError(kProxyHandlerReturned,
- handler, "false", "defineProperty");
- } else {
- return false;
- }
- }
- return true;
-}
-
-
-// ES5 8.12.9.
-function DefineObjectProperty(obj, p, desc, should_throw) {
- var current_array = %GetOwnProperty(obj, TO_NAME(p));
- var current = ConvertDescriptorArrayToDescriptor(current_array);
- var extensible = %IsExtensible(obj);
-
- // Error handling according to spec.
- // Step 3
- if (IS_UNDEFINED(current) && !extensible) {
- if (should_throw) {
- throw MakeTypeError(kDefineDisallowed, p);
- } else {
- return false;
- }
- }
-
- if (!IS_UNDEFINED(current)) {
- // Step 5 and 6
- if ((IsGenericDescriptor(desc) ||
- IsDataDescriptor(desc) == IsDataDescriptor(current)) &&
- (!desc.hasEnumerable() ||
- $sameValue(desc.isEnumerable(), current.isEnumerable())) &&
- (!desc.hasConfigurable() ||
- $sameValue(desc.isConfigurable(), current.isConfigurable())) &&
- (!desc.hasWritable() ||
- $sameValue(desc.isWritable(), current.isWritable())) &&
- (!desc.hasValue() ||
- $sameValue(desc.getValue(), current.getValue())) &&
- (!desc.hasGetter() ||
- $sameValue(desc.getGet(), current.getGet())) &&
- (!desc.hasSetter() ||
- $sameValue(desc.getSet(), current.getSet()))) {
- return true;
- }
- if (!current.isConfigurable()) {
- // Step 7
- if (desc.isConfigurable() ||
- (desc.hasEnumerable() &&
- desc.isEnumerable() != current.isEnumerable())) {
- if (should_throw) {
- throw MakeTypeError(kRedefineDisallowed, p);
- } else {
- return false;
- }
- }
- // Step 8
- if (!IsGenericDescriptor(desc)) {
- // Step 9a
- if (IsDataDescriptor(current) != IsDataDescriptor(desc)) {
- if (should_throw) {
- throw MakeTypeError(kRedefineDisallowed, p);
- } else {
- return false;
- }
- }
- // Step 10a
- if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
- var currentIsWritable = current.isWritable();
- if (currentIsWritable != desc.isWritable()) {
- if (!currentIsWritable || IS_STRONG(obj)) {
- if (should_throw) {
- throw currentIsWritable
- ? MakeTypeError(kStrongRedefineDisallowed, obj, p)
- : MakeTypeError(kRedefineDisallowed, p);
- } else {
- return false;
- }
- }
- }
- if (!currentIsWritable && desc.hasValue() &&
- !$sameValue(desc.getValue(), current.getValue())) {
- if (should_throw) {
- throw MakeTypeError(kRedefineDisallowed, p);
- } else {
- return false;
- }
- }
- }
- // Step 11
- if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
- if (desc.hasSetter() &&
- !$sameValue(desc.getSet(), current.getSet())) {
- if (should_throw) {
- throw MakeTypeError(kRedefineDisallowed, p);
- } else {
- return false;
- }
- }
- if (desc.hasGetter() && !$sameValue(desc.getGet(),current.getGet())) {
- if (should_throw) {
- throw MakeTypeError(kRedefineDisallowed, p);
- } else {
- return false;
- }
- }
- }
- }
- }
- }
-
- // Send flags - enumerable and configurable are common - writable is
- // only send to the data descriptor.
- // Take special care if enumerable and configurable is not defined on
- // desc (we need to preserve the existing values from current).
- var flag = NONE;
- if (desc.hasEnumerable()) {
- flag |= desc.isEnumerable() ? 0 : DONT_ENUM;
- } else if (!IS_UNDEFINED(current)) {
- flag |= current.isEnumerable() ? 0 : DONT_ENUM;
- } else {
- flag |= DONT_ENUM;
- }
-
- if (desc.hasConfigurable()) {
- flag |= desc.isConfigurable() ? 0 : DONT_DELETE;
- } else if (!IS_UNDEFINED(current)) {
- flag |= current.isConfigurable() ? 0 : DONT_DELETE;
- } else
- flag |= DONT_DELETE;
-
- if (IsDataDescriptor(desc) ||
- (IsGenericDescriptor(desc) &&
- (IS_UNDEFINED(current) || IsDataDescriptor(current)))) {
- // There are 3 cases that lead here:
- // Step 4a - defining a new data property.
- // Steps 9b & 12 - replacing an existing accessor property with a data
- // property.
- // Step 12 - updating an existing data property with a data or generic
- // descriptor.
-
- if (desc.hasWritable()) {
- flag |= desc.isWritable() ? 0 : READ_ONLY;
- } else if (!IS_UNDEFINED(current)) {
- flag |= current.isWritable() ? 0 : READ_ONLY;
- } else {
- flag |= READ_ONLY;
- }
-
- var value = UNDEFINED; // Default value is undefined.
- if (desc.hasValue()) {
- value = desc.getValue();
- } else if (!IS_UNDEFINED(current) && IsDataDescriptor(current)) {
- value = current.getValue();
- }
-
- %DefineDataPropertyUnchecked(obj, p, value, flag);
- } else {
- // There are 3 cases that lead here:
- // Step 4b - defining a new accessor property.
- // Steps 9c & 12 - replacing an existing data property with an accessor
- // property.
- // Step 12 - updating an existing accessor property with an accessor
- // descriptor.
- var getter = null;
- if (desc.hasGetter()) {
- getter = desc.getGet();
- } else if (IsAccessorDescriptor(current) && current.hasGetter()) {
- getter = current.getGet();
- }
- var setter = null;
- if (desc.hasSetter()) {
- setter = desc.getSet();
- } else if (IsAccessorDescriptor(current) && current.hasSetter()) {
- setter = current.getSet();
- }
- %DefineAccessorPropertyUnchecked(obj, p, getter, setter, flag);
- }
- return true;
-}
-
-
-// ES5 section 15.4.5.1.
-function DefineArrayProperty(obj, p, desc, should_throw) {
- // Step 3 - Special handling for array index.
- if (!IS_SYMBOL(p)) {
- var index = TO_UINT32(p);
- var emit_splice = false;
- if (TO_STRING(index) == p && index != 4294967295) {
- var length = obj.length;
- if (index >= length && %IsObserved(obj)) {
- emit_splice = true;
- $observeBeginPerformSplice(obj);
- }
-
- var length_desc = GetOwnPropertyJS(obj, "length");
- if ((index >= length && !length_desc.isWritable()) ||
- !DefineObjectProperty(obj, p, desc, true)) {
- if (emit_splice)
- $observeEndPerformSplice(obj);
- if (should_throw) {
- throw MakeTypeError(kDefineDisallowed, p);
- } else {
- return false;
- }
- }
- if (index >= length) {
- obj.length = index + 1;
- }
- if (emit_splice) {
- $observeEndPerformSplice(obj);
- $observeEnqueueSpliceRecord(obj, length, [], index + 1 - length);
- }
- return true;
- }
- }
-
- // Step 5 - Fallback to default implementation.
- return DefineObjectProperty(obj, p, desc, should_throw);
-}
-
-
-// ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies.
-function DefineOwnProperty(obj, p, desc, should_throw) {
- if (%_IsJSProxy(obj)) {
- // TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (IS_SYMBOL(p)) return false;
-
- var attributes = FromGenericPropertyDescriptor(desc);
- return DefineProxyProperty(obj, p, attributes, should_throw);
- } else if (IS_ARRAY(obj)) {
- return DefineArrayProperty(obj, p, desc, should_throw);
- } else {
- return DefineObjectProperty(obj, p, desc, should_throw);
- }
-}
-
-
-function DefineOwnPropertyFromAPI(obj, p, value, desc) {
- return DefineOwnProperty(obj, p, ToPropertyDescriptor({
- value: value,
- writable: desc[0],
- enumerable: desc[1],
- configurable: desc[2]
- }),
- false);
-}
-
-
-// ES6 section 19.1.2.9
-function ObjectGetPrototypeOf(obj) {
- return %_GetPrototype(TO_OBJECT(obj));
-}
-
-// ES6 section 19.1.2.19.
-function ObjectSetPrototypeOf(obj, proto) {
- CHECK_OBJECT_COERCIBLE(obj, "Object.setPrototypeOf");
-
- if (proto !== null && !IS_SPEC_OBJECT(proto)) {
- throw MakeTypeError(kProtoObjectOrNull, proto);
- }
-
- if (IS_SPEC_OBJECT(obj)) {
- %SetPrototype(obj, proto);
- }
-
- return obj;
-}
-
-
-// ES6 section 19.1.2.6
-function ObjectGetOwnPropertyDescriptor(obj, p) {
- var desc = GetOwnPropertyJS(TO_OBJECT(obj), p);
- return FromPropertyDescriptor(desc);
-}
-
-
-// For Harmony proxies
-function ToNameArray(obj, trap, includeSymbols) {
- if (!IS_SPEC_OBJECT(obj)) {
- throw MakeTypeError(kProxyNonObjectPropNames, trap, obj);
- }
- var n = TO_UINT32(obj.length);
- var array = new GlobalArray(n);
- var realLength = 0;
- var names = { __proto__: null }; // TODO(rossberg): use sets once ready.
- for (var index = 0; index < n; index++) {
- var s = TO_NAME(obj[index]);
- // TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (IS_SYMBOL(s) && !includeSymbols) continue;
- if (%HasOwnProperty(names, s)) {
- throw MakeTypeError(kProxyRepeatedPropName, trap, s);
- }
- array[realLength] = s;
- ++realLength;
- names[s] = 0;
- }
- array.length = realLength;
- return array;
-}
-
-
-function ObjectGetOwnPropertyKeys(obj, filter) {
- var nameArrays = new InternalArray();
- filter |= PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL;
- var interceptorInfo = %GetInterceptorInfo(obj);
-
- // Find all the indexed properties.
-
- // Only get own element names if we want to include string keys.
- if ((filter & PROPERTY_ATTRIBUTES_STRING) === 0) {
- var ownElementNames = %GetOwnElementNames(obj);
- for (var i = 0; i < ownElementNames.length; ++i) {
- ownElementNames[i] = %_NumberToString(ownElementNames[i]);
- }
- nameArrays.push(ownElementNames);
- // Get names for indexed interceptor properties.
- if ((interceptorInfo & 1) != 0) {
- var indexedInterceptorNames = %GetIndexedInterceptorElementNames(obj);
- if (!IS_UNDEFINED(indexedInterceptorNames)) {
- nameArrays.push(indexedInterceptorNames);
- }
- }
- }
-
- // Find all the named properties.
-
- // Get own property names.
- nameArrays.push(%GetOwnPropertyNames(obj, filter));
-
- // Get names for named interceptor properties if any.
- if ((interceptorInfo & 2) != 0) {
- var namedInterceptorNames =
- %GetNamedInterceptorPropertyNames(obj);
- if (!IS_UNDEFINED(namedInterceptorNames)) {
- nameArrays.push(namedInterceptorNames);
- }
- }
-
- var propertyNames =
- %Apply(InternalArray.prototype.concat,
- nameArrays[0], nameArrays, 1, nameArrays.length - 1);
-
- // Property names are expected to be unique strings,
- // but interceptors can interfere with that assumption.
- if (interceptorInfo != 0) {
- var seenKeys = { __proto__: null };
- var j = 0;
- for (var i = 0; i < propertyNames.length; ++i) {
- var name = propertyNames[i];
- if (IS_SYMBOL(name)) {
- if ((filter & PROPERTY_ATTRIBUTES_SYMBOLIC) || IS_PRIVATE(name)) {
- continue;
- }
- } else {
- if (filter & PROPERTY_ATTRIBUTES_STRING) continue;
- name = TO_STRING(name);
- }
- if (seenKeys[name]) continue;
- seenKeys[name] = true;
- propertyNames[j++] = name;
- }
- propertyNames.length = j;
- }
-
- return propertyNames;
-}
-
-
-// ES6 section 9.1.12 / 9.5.12
-function OwnPropertyKeys(obj) {
- if (%_IsJSProxy(obj)) {
- var handler = %GetHandler(obj);
- // TODO(caitp): Proxy.[[OwnPropertyKeys]] can not be implemented to spec
- // without an implementation of Direct Proxies.
- var names = CallTrap0(handler, "ownKeys", UNDEFINED);
- return ToNameArray(names, "getOwnPropertyNames", false);
- }
- return ObjectGetOwnPropertyKeys(obj, PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL);
-}
-
-
-// ES5 section 15.2.3.4.
-function ObjectGetOwnPropertyNames(obj) {
- obj = TO_OBJECT(obj);
- // 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, PROPERTY_ATTRIBUTES_SYMBOLIC);
-}
-
-
-// ES5 section 15.2.3.5.
-function ObjectCreate(proto, properties) {
- if (!IS_SPEC_OBJECT(proto) && proto !== null) {
- throw MakeTypeError(kProtoObjectOrNull, proto);
- }
- var obj = {};
- %InternalSetPrototype(obj, proto);
- if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties);
- return obj;
-}
-
-
-// ES5 section 15.2.3.6.
-function ObjectDefineProperty(obj, p, attributes) {
- if (!IS_SPEC_OBJECT(obj)) {
- throw MakeTypeError(kCalledOnNonObject, "Object.defineProperty");
- }
- var name = TO_NAME(p);
- if (%_IsJSProxy(obj)) {
- // Clone the attributes object for protection.
- // TODO(rossberg): not spec'ed yet, so not sure if this should involve
- // non-own properties as it does (or non-enumerable ones, as it doesn't?).
- var attributesClone = { __proto__: null };
- for (var a in attributes) {
- attributesClone[a] = attributes[a];
- }
- DefineProxyProperty(obj, name, attributesClone, true);
- // The following would implement the spec as in the current proposal,
- // but after recent comments on es-discuss, is most likely obsolete.
- /*
- var defineObj = FromGenericPropertyDescriptor(desc);
- var names = ObjectGetOwnPropertyNames(attributes);
- var standardNames =
- {value: 0, writable: 0, get: 0, set: 0, enumerable: 0, configurable: 0};
- for (var i = 0; i < names.length; i++) {
- var N = names[i];
- if (!(%HasOwnProperty(standardNames, N))) {
- var attr = GetOwnPropertyJS(attributes, N);
- DefineOwnProperty(descObj, N, attr, true);
- }
- }
- // This is really confusing the types, but it is what the proxies spec
- // currently requires:
- desc = descObj;
- */
- } else {
- var desc = ToPropertyDescriptor(attributes);
- DefineOwnProperty(obj, name, desc, true);
- }
- return obj;
-}
-
-
-function GetOwnEnumerablePropertyNames(object) {
- var names = new InternalArray();
- for (var key in object) {
- if (%HasOwnProperty(object, key)) {
- names.push(key);
- }
- }
-
- var filter = PROPERTY_ATTRIBUTES_STRING | PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL;
- var symbols = %GetOwnPropertyNames(object, filter);
- for (var i = 0; i < symbols.length; ++i) {
- var symbol = symbols[i];
- if (IS_SYMBOL(symbol)) {
- var desc = ObjectGetOwnPropertyDescriptor(object, symbol);
- if (desc.enumerable) names.push(symbol);
- }
- }
-
- return names;
-}
-
-
-// ES5 section 15.2.3.7.
-function ObjectDefineProperties(obj, properties) {
- if (!IS_SPEC_OBJECT(obj)) {
- throw MakeTypeError(kCalledOnNonObject, "Object.defineProperties");
- }
- var props = TO_OBJECT(properties);
- var names = GetOwnEnumerablePropertyNames(props);
- var descriptors = new InternalArray();
- for (var i = 0; i < names.length; i++) {
- descriptors.push(ToPropertyDescriptor(props[names[i]]));
- }
- for (var i = 0; i < names.length; i++) {
- DefineOwnProperty(obj, names[i], descriptors[i], true);
- }
- return obj;
-}
-
-
-// Harmony proxies.
-function ProxyFix(obj) {
- var handler = %GetHandler(obj);
- var props = CallTrap0(handler, "fix", UNDEFINED);
- if (IS_UNDEFINED(props)) {
- throw MakeTypeError(kProxyHandlerReturned, handler, "undefined", "fix");
- }
-
- if (%IsJSFunctionProxy(obj)) {
- var callTrap = %GetCallTrap(obj);
- var constructTrap = %GetConstructTrap(obj);
- var code = ProxyDelegateCallAndConstruct(callTrap, constructTrap);
- %Fix(obj); // becomes a regular function
- %SetCode(obj, code);
- // TODO(rossberg): What about length and other properties? Not specified.
- // We just put in some half-reasonable defaults for now.
- var prototype = new GlobalObject();
- ObjectDefineProperty(prototype, "constructor",
- {value: obj, writable: true, enumerable: false, configurable: true});
- // TODO(v8:1530): defineProperty does not handle prototype and length.
- %FunctionSetPrototype(obj, prototype);
- obj.length = 0;
- } else {
- %Fix(obj);
- }
- ObjectDefineProperties(obj, props);
-}
-
-
-// ES5 section 15.2.3.8.
-function ObjectSealJS(obj) {
- if (!IS_SPEC_OBJECT(obj)) return obj;
- var isProxy = %_IsJSProxy(obj);
- if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) {
- if (isProxy) {
- ProxyFix(obj);
- }
- var names = ObjectGetOwnPropertyNames(obj);
- for (var i = 0; i < names.length; i++) {
- var name = names[i];
- var desc = GetOwnPropertyJS(obj, name);
- if (desc.isConfigurable()) {
- desc.setConfigurable(false);
- DefineOwnProperty(obj, name, desc, true);
- }
- }
- %PreventExtensions(obj);
- } else {
- // TODO(adamk): Is it worth going to this fast path if the
- // object's properties are already in dictionary mode?
- %ObjectSeal(obj);
- }
- return obj;
-}
-
-
-// ES5 section 15.2.3.9.
-function ObjectFreezeJS(obj) {
- if (!IS_SPEC_OBJECT(obj)) return obj;
- var isProxy = %_IsJSProxy(obj);
- // TODO(conradw): Investigate modifying the fast path to accommodate strong
- // objects.
- if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj) ||
- IS_STRONG(obj)) {
- if (isProxy) {
- ProxyFix(obj);
- }
- var names = ObjectGetOwnPropertyNames(obj);
- for (var i = 0; i < names.length; i++) {
- var name = names[i];
- var desc = GetOwnPropertyJS(obj, name);
- if (desc.isWritable() || desc.isConfigurable()) {
- if (IsDataDescriptor(desc)) desc.setWritable(false);
- desc.setConfigurable(false);
- DefineOwnProperty(obj, name, desc, true);
- }
- }
- %PreventExtensions(obj);
- } else {
- // TODO(adamk): Is it worth going to this fast path if the
- // object's properties are already in dictionary mode?
- %ObjectFreeze(obj);
- }
- return obj;
-}
-
-
-// ES5 section 15.2.3.10
-function ObjectPreventExtension(obj) {
- if (!IS_SPEC_OBJECT(obj)) return obj;
- if (%_IsJSProxy(obj)) {
- ProxyFix(obj);
- }
- %PreventExtensions(obj);
- return obj;
-}
-
-
-// ES5 section 15.2.3.11
-function ObjectIsSealed(obj) {
- if (!IS_SPEC_OBJECT(obj)) return true;
- if (%_IsJSProxy(obj)) {
- return false;
- }
- if (%IsExtensible(obj)) {
- return false;
- }
- var names = ObjectGetOwnPropertyNames(obj);
- for (var i = 0; i < names.length; i++) {
- var name = names[i];
- var desc = GetOwnPropertyJS(obj, name);
- if (desc.isConfigurable()) {
- return false;
- }
- }
- return true;
-}
-
-
-// ES5 section 15.2.3.12
-function ObjectIsFrozen(obj) {
- if (!IS_SPEC_OBJECT(obj)) return true;
- if (%_IsJSProxy(obj)) {
- return false;
- }
- if (%IsExtensible(obj)) {
- return false;
- }
- var names = ObjectGetOwnPropertyNames(obj);
- for (var i = 0; i < names.length; i++) {
- var name = names[i];
- var desc = GetOwnPropertyJS(obj, name);
- if (IsDataDescriptor(desc) && desc.isWritable()) return false;
- if (desc.isConfigurable()) return false;
- }
- return true;
-}
-
-
-// ES5 section 15.2.3.13
-function ObjectIsExtensible(obj) {
- if (!IS_SPEC_OBJECT(obj)) return false;
- if (%_IsJSProxy(obj)) {
- return true;
- }
- return %IsExtensible(obj);
-}
-
-
-// ECMA-262, Edition 6, section 19.1.2.10
-function ObjectIs(obj1, obj2) {
- return $sameValue(obj1, obj2);
-}
-
-
-// ECMA-262, Edition 6, section 19.1.2.1
-function ObjectAssign(target, sources) {
- // TODO(bmeurer): Move this to toplevel.
- "use strict";
- var to = TO_OBJECT(target);
- var argsLen = %_ArgumentsLength();
- if (argsLen < 2) return to;
-
- for (var i = 1; i < argsLen; ++i) {
- var nextSource = %_Arguments(i);
- if (IS_NULL_OR_UNDEFINED(nextSource)) {
- continue;
- }
-
- var from = TO_OBJECT(nextSource);
- var keys = OwnPropertyKeys(from);
- var len = keys.length;
-
- for (var j = 0; j < len; ++j) {
- var key = keys[j];
- if (%IsPropertyEnumerable(from, key)) {
- var propValue = from[key];
- to[key] = propValue;
- }
- }
- }
- return to;
-}
-
-
-// ECMA-262, Edition 6, section B.2.2.1.1
-function ObjectGetProto() {
- return %_GetPrototype(TO_OBJECT(this));
-}
-
-
-// ECMA-262, Edition 6, section B.2.2.1.2
-function ObjectSetProto(proto) {
- CHECK_OBJECT_COERCIBLE(this, "Object.prototype.__proto__");
-
- if ((IS_SPEC_OBJECT(proto) || IS_NULL(proto)) && IS_SPEC_OBJECT(this)) {
- %SetPrototype(this, proto);
- }
-}
-
-
-function ObjectConstructor(x) {
- if (%_IsConstructCall()) {
- if (x == null) return this;
- return TO_OBJECT(x);
- } else {
- if (x == null) return { };
- return TO_OBJECT(x);
- }
-}
-
-
-// ----------------------------------------------------------------------------
-// Object
-
-%SetNativeFlag(GlobalObject);
-%SetCode(GlobalObject, ObjectConstructor);
-
-%AddNamedProperty(GlobalObject.prototype, "constructor", GlobalObject,
- DONT_ENUM);
-
-// Set up non-enumerable functions on the Object.prototype object.
-utils.InstallFunctions(GlobalObject.prototype, DONT_ENUM, [
- "toString", ObjectToString,
- "toLocaleString", ObjectToLocaleString,
- "valueOf", ObjectValueOf,
- "hasOwnProperty", ObjectHasOwnProperty,
- "isPrototypeOf", ObjectIsPrototypeOf,
- "propertyIsEnumerable", ObjectPropertyIsEnumerable,
- "__defineGetter__", ObjectDefineGetter,
- "__lookupGetter__", ObjectLookupGetter,
- "__defineSetter__", ObjectDefineSetter,
- "__lookupSetter__", ObjectLookupSetter
-]);
-utils.InstallGetterSetter(GlobalObject.prototype, "__proto__", ObjectGetProto,
- ObjectSetProto);
-
-// Set up non-enumerable functions in the Object object.
-utils.InstallFunctions(GlobalObject, DONT_ENUM, [
- "assign", ObjectAssign,
- "keys", ObjectKeys,
- "create", ObjectCreate,
- "defineProperty", ObjectDefineProperty,
- "defineProperties", ObjectDefineProperties,
- "freeze", ObjectFreezeJS,
- "getPrototypeOf", ObjectGetPrototypeOf,
- "setPrototypeOf", ObjectSetPrototypeOf,
- "getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor,
- "getOwnPropertyNames", ObjectGetOwnPropertyNames,
- // getOwnPropertySymbols is added in symbol.js.
- "is", ObjectIs,
- "isExtensible", ObjectIsExtensible,
- "isFrozen", ObjectIsFrozen,
- "isSealed", ObjectIsSealed,
- "preventExtensions", ObjectPreventExtension,
- "seal", ObjectSealJS
- // deliverChangeRecords, getNotifier, observe and unobserve are added
- // in object-observe.js.
-]);
-
-
-// ----------------------------------------------------------------------------
-// Boolean
-
-function BooleanConstructor(x) {
- // TODO(bmeurer): Move this to toplevel.
- "use strict";
- if (%_IsConstructCall()) {
- %_SetValueOf(this, TO_BOOLEAN(x));
- } else {
- return TO_BOOLEAN(x);
- }
-}
-
-
-function BooleanToString() {
- // NOTE: Both Boolean objects and values can enter here as
- // 'this'. This is not as dictated by ECMA-262.
- var b = this;
- if (!IS_BOOLEAN(b)) {
- if (!IS_BOOLEAN_WRAPPER(b)) {
- throw MakeTypeError(kNotGeneric, 'Boolean.prototype.toString');
- }
- b = %_ValueOf(b);
- }
- return b ? 'true' : 'false';
-}
-
-
-function BooleanValueOf() {
- // NOTE: Both Boolean objects and values can enter here as
- // 'this'. This is not as dictated by ECMA-262.
- if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this)) {
- throw MakeTypeError(kNotGeneric, 'Boolean.prototype.valueOf');
- }
- return %_ValueOf(this);
-}
-
-
-// ----------------------------------------------------------------------------
-
-%SetCode(GlobalBoolean, BooleanConstructor);
-%FunctionSetPrototype(GlobalBoolean, new GlobalBoolean(false));
-%AddNamedProperty(GlobalBoolean.prototype, "constructor", GlobalBoolean,
- DONT_ENUM);
-
-utils.InstallFunctions(GlobalBoolean.prototype, DONT_ENUM, [
- "toString", BooleanToString,
- "valueOf", BooleanValueOf
-]);
-
-
-// ----------------------------------------------------------------------------
-// Number
-
-function NumberConstructor(x) {
- // TODO(bmeurer): Move this to toplevel.
- "use strict";
- var value = %_ArgumentsLength() == 0 ? 0 : TO_NUMBER(x);
- if (%_IsConstructCall()) {
- %_SetValueOf(this, value);
- } else {
- return value;
- }
-}
-
-
-// ECMA-262 section 15.7.4.2.
-function NumberToStringJS(radix) {
- // NOTE: Both Number objects and values can enter here as
- // 'this'. This is not as dictated by ECMA-262.
- var number = this;
- if (!IS_NUMBER(this)) {
- if (!IS_NUMBER_WRAPPER(this)) {
- throw MakeTypeError(kNotGeneric, 'Number.prototype.toString');
- }
- // Get the value of this number in case it's an object.
- number = %_ValueOf(this);
- }
- // Fast case: Convert number in radix 10.
- if (IS_UNDEFINED(radix) || radix === 10) {
- return %_NumberToString(number);
- }
-
- // Convert the radix to an integer and check the range.
- radix = TO_INTEGER(radix);
- if (radix < 2 || radix > 36) throw MakeRangeError(kToRadixFormatRange);
- // Convert the number to a string in the given radix.
- return %NumberToRadixString(number, radix);
-}
-
-
-// ECMA-262 section 15.7.4.3
-function NumberToLocaleString() {
- return %_CallFunction(this, NumberToStringJS);
-}
-
-
-// ECMA-262 section 15.7.4.4
-function NumberValueOf() {
- // NOTE: Both Number objects and values can enter here as
- // 'this'. This is not as dictated by ECMA-262.
- if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this)) {
- throw MakeTypeError(kNotGeneric, 'Number.prototype.valueOf');
- }
- return %_ValueOf(this);
-}
-
-
-// ECMA-262 section 15.7.4.5
-function NumberToFixedJS(fractionDigits) {
- var x = this;
- if (!IS_NUMBER(this)) {
- if (!IS_NUMBER_WRAPPER(this)) {
- throw MakeTypeError(kIncompatibleMethodReceiver,
- "Number.prototype.toFixed", this);
- }
- // Get the value of this number in case it's an object.
- x = %_ValueOf(this);
- }
- var f = TO_INTEGER(fractionDigits);
-
- if (f < 0 || f > 20) {
- throw MakeRangeError(kNumberFormatRange, "toFixed() digits");
- }
-
- if (NUMBER_IS_NAN(x)) return "NaN";
- if (x == INFINITY) return "Infinity";
- if (x == -INFINITY) return "-Infinity";
-
- return %NumberToFixed(x, f);
-}
-
-
-// ECMA-262 section 15.7.4.6
-function NumberToExponentialJS(fractionDigits) {
- var x = this;
- if (!IS_NUMBER(this)) {
- if (!IS_NUMBER_WRAPPER(this)) {
- throw MakeTypeError(kIncompatibleMethodReceiver,
- "Number.prototype.toExponential", this);
- }
- // Get the value of this number in case it's an object.
- x = %_ValueOf(this);
- }
- var f = IS_UNDEFINED(fractionDigits) ? UNDEFINED : TO_INTEGER(fractionDigits);
-
- if (NUMBER_IS_NAN(x)) return "NaN";
- if (x == INFINITY) return "Infinity";
- if (x == -INFINITY) return "-Infinity";
-
- if (IS_UNDEFINED(f)) {
- f = -1; // Signal for runtime function that f is not defined.
- } else if (f < 0 || f > 20) {
- throw MakeRangeError(kNumberFormatRange, "toExponential()");
- }
- return %NumberToExponential(x, f);
-}
-
-
-// ECMA-262 section 15.7.4.7
-function NumberToPrecisionJS(precision) {
- var x = this;
- if (!IS_NUMBER(this)) {
- if (!IS_NUMBER_WRAPPER(this)) {
- throw MakeTypeError(kIncompatibleMethodReceiver,
- "Number.prototype.toPrecision", this);
- }
- // Get the value of this number in case it's an object.
- x = %_ValueOf(this);
- }
- if (IS_UNDEFINED(precision)) return TO_STRING(x);
- var p = TO_INTEGER(precision);
-
- if (NUMBER_IS_NAN(x)) return "NaN";
- if (x == INFINITY) return "Infinity";
- if (x == -INFINITY) return "-Infinity";
-
- if (p < 1 || p > 21) {
- throw MakeRangeError(kToPrecisionFormatRange);
- }
- return %NumberToPrecision(x, p);
-}
-
-
-// Harmony isFinite.
-function NumberIsFinite(number) {
- return IS_NUMBER(number) && NUMBER_IS_FINITE(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) <= kMaxSafeInteger;
- }
- }
- return false;
-}
-
-
-// ----------------------------------------------------------------------------
-
-%SetCode(GlobalNumber, NumberConstructor);
-%FunctionSetPrototype(GlobalNumber, new GlobalNumber(0));
-
-%OptimizeObjectForAddingMultipleProperties(GlobalNumber.prototype, 8);
-// Set up the constructor property on the Number prototype object.
-%AddNamedProperty(GlobalNumber.prototype, "constructor", GlobalNumber,
- DONT_ENUM);
-
-utils.InstallConstants(GlobalNumber, [
- // 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.
-utils.InstallFunctions(GlobalNumber.prototype, DONT_ENUM, [
- "toString", NumberToStringJS,
- "toLocaleString", NumberToLocaleString,
- "valueOf", NumberValueOf,
- "toFixed", NumberToFixedJS,
- "toExponential", NumberToExponentialJS,
- "toPrecision", NumberToPrecisionJS
-]);
-
-// Harmony Number constructor additions
-utils.InstallFunctions(GlobalNumber, DONT_ENUM, [
- "isFinite", NumberIsFinite,
- "isInteger", NumberIsInteger,
- "isNaN", NumberIsNaN,
- "isSafeInteger", NumberIsSafeInteger,
- "parseInt", GlobalParseInt,
- "parseFloat", GlobalParseFloat
-]);
-
-%SetForceInlineFlag(NumberIsNaN);
-
-
-// ----------------------------------------------------------------------------
-// Function
-
-function NativeCodeFunctionSourceString(func) {
- var name = %FunctionGetName(func);
- if (name) {
- // Mimic what KJS does.
- return 'function ' + name + '() { [native code] }';
- }
-
- return 'function () { [native code] }';
-}
-
-function FunctionSourceString(func) {
- while (%IsJSFunctionProxy(func)) {
- func = %GetCallTrap(func);
- }
-
- if (!IS_FUNCTION(func)) {
- throw MakeTypeError(kNotGeneric, 'Function.prototype.toString');
- }
-
- if (%FunctionHidesSource(func)) {
- return NativeCodeFunctionSourceString(func);
- }
-
- var classSource = %ClassGetSourceCode(func);
- if (IS_STRING(classSource)) {
- return classSource;
- }
-
- var source = %FunctionGetSourceCode(func);
- if (!IS_STRING(source)) {
- return NativeCodeFunctionSourceString(func);
- }
-
- if (%FunctionIsArrow(func)) {
- return source;
- }
-
- var name = %FunctionNameShouldPrintAsAnonymous(func)
- ? 'anonymous'
- : %FunctionGetName(func);
-
- var isGenerator = %FunctionIsGenerator(func);
- var head = %FunctionIsConciseMethod(func)
- ? (isGenerator ? '*' : '')
- : (isGenerator ? 'function* ' : 'function ');
- return head + name + source;
-}
-
-
-function FunctionToString() {
- return FunctionSourceString(this);
-}
-
-
-// ES5 15.3.4.5
-function FunctionBind(this_arg) { // Length is 1.
- if (!IS_CALLABLE(this)) throw MakeTypeError(kFunctionBind);
-
- var boundFunction = function () {
- // Poison .arguments and .caller, but is otherwise not detectable.
- "use strict";
- // This function must not use any object literals (Object, Array, RegExp),
- // since the literals-array is being used to store the bound data.
- if (%_IsConstructCall()) {
- return %NewObjectFromBound(boundFunction);
- }
- var bindings = %BoundFunctionGetBindings(boundFunction);
-
- var argc = %_ArgumentsLength();
- if (argc == 0) {
- return %Apply(bindings[0], bindings[1], bindings, 2, bindings.length - 2);
- }
- if (bindings.length === 2) {
- return %Apply(bindings[0], bindings[1], arguments, 0, argc);
- }
- var bound_argc = bindings.length - 2;
- var argv = new InternalArray(bound_argc + argc);
- for (var i = 0; i < bound_argc; i++) {
- argv[i] = bindings[i + 2];
- }
- for (var j = 0; j < argc; j++) {
- argv[i++] = %_Arguments(j);
- }
- return %Apply(bindings[0], bindings[1], argv, 0, bound_argc + argc);
- };
-
- var new_length = 0;
- var old_length = this.length;
- // FunctionProxies might provide a non-UInt32 value. If so, ignore it.
- if ((typeof old_length === "number") &&
- ((old_length >>> 0) === old_length)) {
- var argc = %_ArgumentsLength();
- if (argc > 0) argc--; // Don't count the thisArg as parameter.
- new_length = old_length - argc;
- if (new_length < 0) new_length = 0;
- }
- // This runtime function finds any remaining arguments on the stack,
- // so we don't pass the arguments object.
- var result = %FunctionBindArguments(boundFunction, this,
- this_arg, new_length);
-
- var name = this.name;
- var bound_name = IS_STRING(name) ? name : "";
- %DefineDataPropertyUnchecked(result, "name", "bound " + bound_name,
- DONT_ENUM | READ_ONLY);
-
- // We already have caller and arguments properties on functions,
- // which are non-configurable. It therefore makes no sence to
- // try to redefine these as defined by the spec. The spec says
- // that bind should make these throw a TypeError if get or set
- // is called and make them non-enumerable and non-configurable.
- // To be consistent with our normal functions we leave this as it is.
- // TODO(lrn): Do set these to be thrower.
- return result;
-}
-
-
-function NewFunctionString(args, function_token) {
- var n = args.length;
- var p = '';
- if (n > 1) {
- p = TO_STRING(args[0]);
- for (var i = 1; i < n - 1; i++) {
- p += ',' + TO_STRING(args[i]);
- }
- // If the formal parameters string include ) - an illegal
- // character - it may make the combined function expression
- // compile. We avoid this problem by checking for this early on.
- if (%_CallFunction(p, ')', StringIndexOf) != -1) {
- throw MakeSyntaxError(kParenthesisInArgString);
- }
- // If the formal parameters include an unbalanced block comment, the
- // function must be rejected. Since JavaScript does not allow nested
- // comments we can include a trailing block comment to catch this.
- p += '\n/' + '**/';
- }
- var body = (n > 0) ? TO_STRING(args[n - 1]) : '';
- return '(' + function_token + '(' + p + ') {\n' + body + '\n})';
-}
-
-
-function FunctionConstructor(arg1) { // length == 1
- var source = NewFunctionString(arguments, 'function');
- var global_proxy = %GlobalProxy(FunctionConstructor);
- // Compile the string in the constructor and not a helper so that errors
- // appear to come from here.
- var f = %_CallFunction(global_proxy, %CompileString(source, true));
- %FunctionMarkNameShouldPrintAsAnonymous(f);
- return f;
-}
-
-
-// ----------------------------------------------------------------------------
-
-%SetCode(GlobalFunction, FunctionConstructor);
-%AddNamedProperty(GlobalFunction.prototype, "constructor", GlobalFunction,
- DONT_ENUM);
-
-utils.InstallFunctions(GlobalFunction.prototype, DONT_ENUM, [
- "bind", FunctionBind,
- "toString", FunctionToString
-]);
-
-// ----------------------------------------------------------------------------
-// Iterator related spec functions.
-
-// ES6 rev 33, 2015-02-12
-// 7.4.1 GetIterator ( obj, method )
-function GetIterator(obj, method) {
- if (IS_UNDEFINED(method)) {
- method = obj[iteratorSymbol];
- }
- if (!IS_CALLABLE(method)) {
- throw MakeTypeError(kNotIterable, obj);
- }
- var iterator = %_CallFunction(obj, method);
- if (!IS_SPEC_OBJECT(iterator)) {
- throw MakeTypeError(kNotAnIterator, iterator);
- }
- return iterator;
-}
-
-// ----------------------------------------------------------------------------
-// Exports
-
-utils.Export(function(to) {
- to.Delete = Delete;
- to.FunctionSourceString = FunctionSourceString;
- to.GetIterator = GetIterator;
- to.GetMethod = GetMethod;
- to.IsFinite = GlobalIsFinite;
- to.IsNaN = GlobalIsNaN;
- to.NewFunctionString = NewFunctionString;
- to.NumberIsNaN = NumberIsNaN;
- to.ObjectDefineProperties = ObjectDefineProperties;
- to.ObjectDefineProperty = ObjectDefineProperty;
- to.ObjectFreeze = ObjectFreezeJS;
- to.ObjectGetOwnPropertyKeys = ObjectGetOwnPropertyKeys;
- to.ObjectHasOwnProperty = ObjectHasOwnProperty;
- to.ObjectIsFrozen = ObjectIsFrozen;
- to.ObjectIsSealed = ObjectIsSealed;
- to.ObjectToString = ObjectToString;
- to.ToNameArray = ToNameArray;
-});
-
-%InstallToContext([
- "global_eval_fun", GlobalEval,
- "object_value_of", ObjectValueOf,
- "object_to_string", ObjectToString,
- "object_define_own_property", DefineOwnPropertyFromAPI,
- "object_get_own_property_descriptor", ObjectGetOwnPropertyDescriptor,
- "to_complete_property_descriptor", ToCompletePropertyDescriptor,
-]);
-
-})
« no previous file with comments | « src/uri.js ('k') | src/weak-collection.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698