summaryrefslogtreecommitdiff
path: root/deps/v8/src/v8natives.js
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2011-06-29 17:26:51 +0200
committerRyan Dahl <ry@tinyclouds.org>2011-06-29 17:26:51 +0200
commit33af2720f26c2b25bc7f75ce7eb454ff99db6d35 (patch)
tree9a38f0c96420edf503eebd6325dd8d2d8249f653 /deps/v8/src/v8natives.js
parent6afdca885adeeeed9eef8cbb01c3d97af0bc084d (diff)
downloadnode-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.js238
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