diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2011-06-29 17:26:51 +0200 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2011-06-29 17:26:51 +0200 |
commit | 33af2720f26c2b25bc7f75ce7eb454ff99db6d35 (patch) | |
tree | 9a38f0c96420edf503eebd6325dd8d2d8249f653 /deps/v8/src/v8natives.js | |
parent | 6afdca885adeeeed9eef8cbb01c3d97af0bc084d (diff) | |
download | node-new-33af2720f26c2b25bc7f75ce7eb454ff99db6d35.tar.gz |
Upgrade V8 to 3.4.8
Diffstat (limited to 'deps/v8/src/v8natives.js')
-rw-r--r-- | deps/v8/src/v8natives.js | 238 |
1 files changed, 199 insertions, 39 deletions
diff --git a/deps/v8/src/v8natives.js b/deps/v8/src/v8natives.js index 823f8ee579..0afe231c8c 100644 --- a/deps/v8/src/v8natives.js +++ b/deps/v8/src/v8natives.js @@ -56,6 +56,7 @@ function InstallFunctions(object, attributes, functions) { %FunctionSetName(f, key); %FunctionRemovePrototype(f); %SetProperty(object, key, f, attributes); + %SetNativeFlag(f); } %ToFastProperties(object); } @@ -105,7 +106,7 @@ function GlobalParseInt(string, radix) { // Truncate number. return string | 0; } - if (IS_UNDEFINED(radix)) radix = 0; + radix = radix | 0; } else { radix = TO_INT32(radix); if (!(radix == 0 || (2 <= radix && radix <= 36))) @@ -131,10 +132,19 @@ function GlobalParseFloat(string) { function GlobalEval(x) { if (!IS_STRING(x)) return x; + var receiver = this; var global_receiver = %GlobalReceiver(global); - var this_is_global_receiver = (this === global_receiver); + + if (receiver == null && !IS_UNDETECTABLE(receiver)) { + receiver = global_receiver; + } + + var this_is_global_receiver = (receiver === global_receiver); var global_is_detached = (global === global_receiver); + // For consistency with JSC we require the global object passed to + // eval to be the global object from which 'eval' originated. This + // is not mandated by the spec. if (!this_is_global_receiver || global_is_detached) { throw new $EvalError('The "this" object passed to eval must ' + 'be the global object from which eval originated'); @@ -143,7 +153,7 @@ function GlobalEval(x) { var f = %CompileString(x); if (!IS_FUNCTION(f)) return f; - return f.call(this); + return %_CallFunction(receiver, f); } @@ -196,12 +206,20 @@ $Object.prototype.constructor = $Object; // ECMA-262 - 15.2.4.2 function ObjectToString() { + if (IS_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { + return '[object Undefined]'; + } + if (IS_NULL(this)) return '[object Null]'; return "[object " + %_ClassOf(ToObject(this)) + "]"; } // ECMA-262 - 15.2.4.3 function ObjectToLocaleString() { + if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { + throw MakeTypeError("called_on_null_or_undefined", + ["Object.prototype.toLocaleString"]); + } return this.toString(); } @@ -214,12 +232,16 @@ function ObjectValueOf() { // ECMA-262 - 15.2.4.5 function ObjectHasOwnProperty(V) { - return %HasLocalProperty(ToObject(this), ToString(V)); + return %HasLocalProperty(TO_OBJECT_INLINE(this), TO_STRING_INLINE(V)); } // ECMA-262 - 15.2.4.6 function ObjectIsPrototypeOf(V) { + if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { + throw MakeTypeError("called_on_null_or_undefined", + ["Object.prototype.isPrototypeOf"]); + } if (!IS_SPEC_OBJECT(V)) return false; return %IsInPrototypeChain(this, V); } @@ -233,41 +255,53 @@ function ObjectPropertyIsEnumerable(V) { // Extensions for providing property getters and setters. function ObjectDefineGetter(name, fun) { - if (this == null && !IS_UNDETECTABLE(this)) { - throw new $TypeError('Object.prototype.__defineGetter__: this is Null'); + var receiver = this; + if (receiver == null && !IS_UNDETECTABLE(receiver)) { + receiver = %GlobalReceiver(global); } if (!IS_FUNCTION(fun)) { throw new $TypeError('Object.prototype.__defineGetter__: Expecting function'); } - return %DefineAccessor(ToObject(this), ToString(name), GETTER, fun); + var desc = new PropertyDescriptor(); + desc.setGet(fun); + desc.setEnumerable(true); + desc.setConfigurable(true); + DefineOwnProperty(ToObject(receiver), ToString(name), desc, false); } function ObjectLookupGetter(name) { - if (this == null && !IS_UNDETECTABLE(this)) { - throw new $TypeError('Object.prototype.__lookupGetter__: this is Null'); + var receiver = this; + if (receiver == null && !IS_UNDETECTABLE(receiver)) { + receiver = %GlobalReceiver(global); } - return %LookupAccessor(ToObject(this), ToString(name), GETTER); + return %LookupAccessor(ToObject(receiver), ToString(name), GETTER); } function ObjectDefineSetter(name, fun) { - if (this == null && !IS_UNDETECTABLE(this)) { - throw new $TypeError('Object.prototype.__defineSetter__: this is Null'); + var receiver = this; + if (receiver == null && !IS_UNDETECTABLE(receiver)) { + receiver = %GlobalReceiver(global); } if (!IS_FUNCTION(fun)) { throw new $TypeError( 'Object.prototype.__defineSetter__: Expecting function'); } - return %DefineAccessor(ToObject(this), ToString(name), SETTER, fun); + var desc = new PropertyDescriptor(); + desc.setSet(fun); + desc.setEnumerable(true); + desc.setConfigurable(true); + DefineOwnProperty(ToObject(receiver), ToString(name), desc, false); } function ObjectLookupSetter(name) { - if (this == null && !IS_UNDETECTABLE(this)) { - throw new $TypeError('Object.prototype.__lookupSetter__: this is Null'); + var receiver = this; + if (receiver == null && !IS_UNDETECTABLE(receiver)) { + receiver = %GlobalReceiver(global); } - return %LookupAccessor(ToObject(this), ToString(name), SETTER); + return %LookupAccessor(ToObject(receiver), ToString(name), SETTER); } @@ -302,6 +336,7 @@ function IsInconsistentDescriptor(desc) { return IsAccessorDescriptor(desc) && IsDataDescriptor(desc); } + // ES5 8.10.4 function FromPropertyDescriptor(desc) { if (IS_UNDEFINED(desc)) return desc; @@ -365,6 +400,23 @@ function ToPropertyDescriptor(obj) { } +// For Harmony proxies. +function ToCompletePropertyDescriptor(obj) { + var desc = ToPropertyDescriptor(obj) + if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) { + if (!("value" in desc)) desc.value = void 0; + if (!("writable" in desc)) desc.writable = false; + } else { + // Is accessor descriptor. + if (!("get" in desc)) desc.get = void 0; + if (!("set" in desc)) desc.set = void 0; + } + if (!("enumerable" in desc)) desc.enumerable = false; + if (!("configurable" in desc)) desc.configurable = 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. @@ -382,6 +434,10 @@ function PropertyDescriptor() { this.hasSetter_ = false; } +PropertyDescriptor.prototype.__proto__ = null; +PropertyDescriptor.prototype.toString = function() { + return "[object PropertyDescriptor]"; +}; PropertyDescriptor.prototype.setValue = function(value) { this.value_ = value; @@ -483,7 +539,7 @@ PropertyDescriptor.prototype.hasSetter = function() { // property descriptor. For a description of the array layout please // see the runtime.cc file. function ConvertDescriptorArrayToDescriptor(desc_array) { - if (desc_array == false) { + if (desc_array === false) { throw 'Internal error: invalid desc_array'; } @@ -509,9 +565,25 @@ function ConvertDescriptorArrayToDescriptor(desc_array) { // ES5 section 8.12.2. function GetProperty(obj, p) { + if (%IsJSProxy(obj)) { + var handler = %GetHandler(obj); + var getProperty = handler.getPropertyDescriptor; + if (IS_UNDEFINED(getProperty)) { + throw MakeTypeError("handler_trap_missing", + [handler, "getPropertyDescriptor"]); + } + var descriptor = getProperty.call(handler, p); + if (IS_UNDEFINED(descriptor)) return descriptor; + var desc = ToCompletePropertyDescriptor(descriptor); + if (!desc.configurable) { + throw MakeTypeError("proxy_prop_not_configurable", + [handler, "getPropertyDescriptor", p, descriptor]); + } + return desc; + } var prop = GetOwnProperty(obj); if (!IS_UNDEFINED(prop)) return prop; - var proto = obj.__proto__; + var proto = %GetPrototype(obj); if (IS_NULL(proto)) return void 0; return GetProperty(proto, p); } @@ -519,6 +591,12 @@ function GetProperty(obj, p) { // ES5 section 8.12.6 function HasProperty(obj, p) { + if (%IsJSProxy(obj)) { + var handler = %GetHandler(obj); + var has = handler.has; + if (IS_UNDEFINED(has)) has = DerivedHasTrap; + return ToBoolean(has.call(handler, obj, p)); + } var desc = GetProperty(obj, p); return IS_UNDEFINED(desc) ? false : true; } @@ -532,7 +610,7 @@ function GetOwnProperty(obj, p) { var props = %GetOwnProperty(ToObject(obj), ToString(p)); // A false value here means that access checks failed. - if (props == false) return void 0; + if (props === false) return void 0; return ConvertDescriptorArrayToDescriptor(props); } @@ -542,15 +620,20 @@ function GetOwnProperty(obj, p) { function DefineOwnProperty(obj, p, desc, should_throw) { var current_or_access = %GetOwnProperty(ToObject(obj), ToString(p)); // A false value here means that access checks failed. - if (current_or_access == false) return void 0; + if (current_or_access === false) return void 0; var current = ConvertDescriptorArrayToDescriptor(current_or_access); var extensible = %IsExtensible(ToObject(obj)); // Error handling according to spec. // Step 3 - if (IS_UNDEFINED(current) && !extensible) - throw MakeTypeError("define_disallowed", ["defineProperty"]); + if (IS_UNDEFINED(current) && !extensible) { + if (should_throw) { + throw MakeTypeError("define_disallowed", [p]); + } else { + return; + } + } if (!IS_UNDEFINED(current)) { // Step 5 and 6 @@ -575,31 +658,55 @@ function DefineOwnProperty(obj, p, desc, should_throw) { if (desc.isConfigurable() || (desc.hasEnumerable() && desc.isEnumerable() != current.isEnumerable())) { - throw MakeTypeError("redefine_disallowed", ["defineProperty"]); + if (should_throw) { + throw MakeTypeError("redefine_disallowed", [p]); + } else { + return; + } } // Step 8 if (!IsGenericDescriptor(desc)) { // Step 9a if (IsDataDescriptor(current) != IsDataDescriptor(desc)) { - throw MakeTypeError("redefine_disallowed", ["defineProperty"]); + if (should_throw) { + throw MakeTypeError("redefine_disallowed", [p]); + } else { + return; + } } // Step 10a if (IsDataDescriptor(current) && IsDataDescriptor(desc)) { if (!current.isWritable() && desc.isWritable()) { - throw MakeTypeError("redefine_disallowed", ["defineProperty"]); + if (should_throw) { + throw MakeTypeError("redefine_disallowed", [p]); + } else { + return; + } } if (!current.isWritable() && desc.hasValue() && !SameValue(desc.getValue(), current.getValue())) { - throw MakeTypeError("redefine_disallowed", ["defineProperty"]); + if (should_throw) { + throw MakeTypeError("redefine_disallowed", [p]); + } else { + return; + } } } // Step 11 if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) { if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())) { - throw MakeTypeError("redefine_disallowed", ["defineProperty"]); + if (should_throw) { + throw MakeTypeError("redefine_disallowed", [p]); + } else { + return; + } } if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) { - throw MakeTypeError("redefine_disallowed", ["defineProperty"]); + if (should_throw) { + throw MakeTypeError("redefine_disallowed", [p]); + } else { + return; + } } } } @@ -678,7 +785,7 @@ function DefineOwnProperty(obj, p, desc, should_throw) { function ObjectGetPrototypeOf(obj) { if (!IS_SPEC_OBJECT(obj)) throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]); - return obj.__proto__; + return %GetPrototype(obj); } @@ -691,11 +798,43 @@ function ObjectGetOwnPropertyDescriptor(obj, p) { } +// For Harmony proxies +function ToStringArray(obj, trap) { + if (!IS_SPEC_OBJECT(obj)) { + throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]); + } + var n = ToUint32(obj.length); + var array = new $Array(n); + var names = {} + for (var index = 0; index < n; index++) { + var s = ToString(obj[index]); + if (s in names) { + throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]) + } + array[index] = s; + names.s = 0; + } + return array; +} + + // ES5 section 15.2.3.4. function ObjectGetOwnPropertyNames(obj) { if (!IS_SPEC_OBJECT(obj)) throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"]); + // Special handling for proxies. + if (%IsJSProxy(obj)) { + var handler = %GetHandler(obj); + var getOwnPropertyNames = handler.getOwnPropertyNames; + if (IS_UNDEFINED(getOwnPropertyNames)) { + throw MakeTypeError("handler_trap_missing", + [handler, "getOwnPropertyNames"]); + } + var names = getOwnPropertyNames.call(handler); + return ToStringArray(names, "getOwnPropertyNames"); + } + // Find all the indexed properties. // Get the local element names. @@ -799,8 +938,10 @@ function ObjectSeal(obj) { for (var i = 0; i < names.length; i++) { var name = names[i]; var desc = GetOwnProperty(obj, name); - if (desc.isConfigurable()) desc.setConfigurable(false); - DefineOwnProperty(obj, name, desc, true); + if (desc.isConfigurable()) { + desc.setConfigurable(false); + DefineOwnProperty(obj, name, desc, true); + } } return ObjectPreventExtension(obj); } @@ -815,9 +956,11 @@ function ObjectFreeze(obj) { for (var i = 0; i < names.length; i++) { var name = names[i]; var desc = GetOwnProperty(obj, name); - if (IsDataDescriptor(desc)) desc.setWritable(false); - if (desc.isConfigurable()) desc.setConfigurable(false); - DefineOwnProperty(obj, name, desc, true); + if (desc.isWritable() || desc.isConfigurable()) { + if (IsDataDescriptor(desc)) desc.setWritable(false); + desc.setConfigurable(false); + DefineOwnProperty(obj, name, desc, true); + } } return ObjectPreventExtension(obj); } @@ -873,7 +1016,7 @@ function ObjectIsFrozen(obj) { // ES5 section 15.2.3.13 function ObjectIsExtensible(obj) { if (!IS_SPEC_OBJECT(obj)) { - throw MakeTypeError("obj_ctor_property_non_object", ["preventExtension"]); + throw MakeTypeError("obj_ctor_property_non_object", ["isExtensible"]); } return %IsExtensible(obj); } @@ -1009,6 +1152,10 @@ function NumberToString(radix) { // ECMA-262 section 15.7.4.3 function NumberToLocaleString() { + if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { + throw MakeTypeError("called_on_null_or_undefined", + ["Number.prototype.toLocaleString"]); + } return this.toString(); } @@ -1029,6 +1176,10 @@ function NumberToFixed(fractionDigits) { if (f < 0 || f > 20) { throw new $RangeError("toFixed() digits argument must be between 0 and 20"); } + if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { + throw MakeTypeError("called_on_null_or_undefined", + ["Number.prototype.toFixed"]); + } var x = ToNumber(this); return %NumberToFixed(x, f); } @@ -1043,6 +1194,10 @@ function NumberToExponential(fractionDigits) { throw new $RangeError("toExponential() argument must be between 0 and 20"); } } + if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { + throw MakeTypeError("called_on_null_or_undefined", + ["Number.prototype.toExponential"]); + } var x = ToNumber(this); return %NumberToExponential(x, f); } @@ -1050,6 +1205,10 @@ function NumberToExponential(fractionDigits) { // ECMA-262 section 15.7.4.7 function NumberToPrecision(precision) { + if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { + throw MakeTypeError("called_on_null_or_undefined", + ["Number.prototype.toPrecision"]); + } if (IS_UNDEFINED(precision)) return ToString(%_ValueOf(this)); var p = TO_INTEGER(precision); if (p < 1 || p > 21) { @@ -1158,7 +1317,7 @@ function FunctionBind(this_arg) { // Length is 1. return fn.apply(this_arg, arguments); }; } else { - var bound_args = new $Array(argc_bound); + var bound_args = new InternalArray(argc_bound); for(var i = 0; i < argc_bound; i++) { bound_args[i] = %_Arguments(i+1); } @@ -1176,7 +1335,7 @@ function FunctionBind(this_arg) { // Length is 1. // Combine the args we got from the bind call with the args // given as argument to the invocation. var argc = %_ArgumentsLength(); - var args = new $Array(argc + argc_bound); + var args = new InternalArray(argc + argc_bound); // Add bound arguments. for (var i = 0; i < argc_bound; i++) { args[i] = bound_args[i]; @@ -1199,7 +1358,8 @@ function FunctionBind(this_arg) { // Length is 1. // Set the correct length. var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0; %FunctionSetLength(result, length); - + %FunctionRemovePrototype(result); + %FunctionSetBound(result); return result; } @@ -1208,7 +1368,7 @@ function NewFunction(arg1) { // length == 1 var n = %_ArgumentsLength(); var p = ''; if (n > 1) { - p = new $Array(n - 1); + p = new InternalArray(n - 1); for (var i = 0; i < n - 1; i++) p[i] = %_Arguments(i); p = Join(p, n - 1, ',', NonStringToString); // If the formal parameters string include ) - an illegal |