result_not_primitive: "Result of %0 must be a primitive, was %1",
invalid_json: "String '%0' is not valid JSON",
circular_structure: "Converting circular structure to JSON",
- object_keys_non_object: "Object.keys called on non-object",
- object_get_prototype_non_object: "Object.getPrototypeOf called on non-object",
+ obj_ctor_property_non_object: "Object.%0 called on non-object",
array_indexof_not_defined: "Array.getIndexOf: Argument undefined"
};
}
ObjectMirror.prototype.hasNamedInterceptor = function() {
// Get information on interceptors for this object.
- var x = %DebugInterceptorInfo(this.value_);
+ var x = %GetInterceptorInfo(this.value_);
return (x & 2) != 0;
};
ObjectMirror.prototype.hasIndexedInterceptor = function() {
// Get information on interceptors for this object.
- var x = %DebugInterceptorInfo(this.value_);
+ var x = %GetInterceptorInfo(this.value_);
return (x & 1) != 0;
};
// Find all the named properties.
if (kind & PropertyKind.Named) {
// Get the local property names.
- propertyNames = %DebugLocalPropertyNames(this.value_);
+ propertyNames = %GetLocalPropertyNames(this.value_);
total += propertyNames.length;
// Get names for named interceptor properties if any.
if (this.hasNamedInterceptor() && (kind & PropertyKind.Named)) {
var namedInterceptorNames =
- %DebugNamedInterceptorPropertyNames(this.value_);
+ %GetNamedInterceptorPropertyNames(this.value_);
if (namedInterceptorNames) {
propertyNames = propertyNames.concat(namedInterceptorNames);
total += namedInterceptorNames.length;
// Find all the indexed properties.
if (kind & PropertyKind.Indexed) {
// Get the local element names.
- elementNames = %DebugLocalElementNames(this.value_);
+ elementNames = %GetLocalElementNames(this.value_);
total += elementNames.length;
// Get names for indexed interceptor properties.
if (this.hasIndexedInterceptor() && (kind & PropertyKind.Indexed)) {
var indexedInterceptorNames =
- %DebugIndexedInterceptorElementNames(this.value_);
+ %GetIndexedInterceptorElementNames(this.value_);
if (indexedInterceptorNames) {
elementNames = elementNames.concat(indexedInterceptorNames);
total += indexedInterceptorNames.length;
}
+// Find the length of the prototype chain that is to to handled as one. If a
+// prototype object is hidden it is to be viewed as part of the the object it
+// is prototype for.
+static int LocalPrototypeChainLength(JSObject* obj) {
+ int count = 1;
+ Object* proto = obj->GetPrototype();
+ while (proto->IsJSObject() &&
+ JSObject::cast(proto)->map()->is_hidden_prototype()) {
+ count++;
+ proto = JSObject::cast(proto)->GetPrototype();
+ }
+ return count;
+}
+
+
+// Return the names of the local named properties.
+// args[0]: object
+static Object* Runtime_GetLocalPropertyNames(Arguments args) {
+ HandleScope scope;
+ ASSERT(args.length() == 1);
+ if (!args[0]->IsJSObject()) {
+ return Heap::undefined_value();
+ }
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
+
+ // Skip the global proxy as it has no properties and always delegates to the
+ // real global object.
+ if (obj->IsJSGlobalProxy()) {
+ obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
+ }
+
+ // Find the number of objects making up this.
+ int length = LocalPrototypeChainLength(*obj);
+
+ // Find the number of local properties for each of the objects.
+ int* local_property_count = NewArray<int>(length);
+ int total_property_count = 0;
+ Handle<JSObject> jsproto = obj;
+ for (int i = 0; i < length; i++) {
+ int n;
+ n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
+ local_property_count[i] = n;
+ total_property_count += n;
+ if (i < length - 1) {
+ jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
+ }
+ }
+
+ // Allocate an array with storage for all the property names.
+ Handle<FixedArray> names = Factory::NewFixedArray(total_property_count);
+
+ // Get the property names.
+ jsproto = obj;
+ int proto_with_hidden_properties = 0;
+ for (int i = 0; i < length; i++) {
+ jsproto->GetLocalPropertyNames(*names,
+ i == 0 ? 0 : local_property_count[i - 1]);
+ if (!GetHiddenProperties(jsproto, false)->IsUndefined()) {
+ proto_with_hidden_properties++;
+ }
+ if (i < length - 1) {
+ jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
+ }
+ }
+
+ // Filter out name of hidden propeties object.
+ if (proto_with_hidden_properties > 0) {
+ Handle<FixedArray> old_names = names;
+ names = Factory::NewFixedArray(
+ names->length() - proto_with_hidden_properties);
+ int dest_pos = 0;
+ for (int i = 0; i < total_property_count; i++) {
+ Object* name = old_names->get(i);
+ if (name == Heap::hidden_symbol()) {
+ continue;
+ }
+ names->set(dest_pos++, name);
+ }
+ }
+
+ DeleteArray(local_property_count);
+ return *Factory::NewJSArrayWithElements(names);
+}
+
+
+// Return the names of the local indexed properties.
+// args[0]: object
+static Object* Runtime_GetLocalElementNames(Arguments args) {
+ HandleScope scope;
+ ASSERT(args.length() == 1);
+ if (!args[0]->IsJSObject()) {
+ return Heap::undefined_value();
+ }
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
+
+ int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
+ Handle<FixedArray> names = Factory::NewFixedArray(n);
+ obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
+ return *Factory::NewJSArrayWithElements(names);
+}
+
+
+// Return information on whether an object has a named or indexed interceptor.
+// args[0]: object
+static Object* Runtime_GetInterceptorInfo(Arguments args) {
+ HandleScope scope;
+ ASSERT(args.length() == 1);
+ if (!args[0]->IsJSObject()) {
+ return Smi::FromInt(0);
+ }
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
+
+ int result = 0;
+ if (obj->HasNamedInterceptor()) result |= 2;
+ if (obj->HasIndexedInterceptor()) result |= 1;
+
+ return Smi::FromInt(result);
+}
+
+
+// Return property names from named interceptor.
+// args[0]: object
+static Object* Runtime_GetNamedInterceptorPropertyNames(Arguments args) {
+ HandleScope scope;
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
+
+ if (obj->HasNamedInterceptor()) {
+ v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
+ if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
+ }
+ return Heap::undefined_value();
+}
+
+
+// Return element names from indexed interceptor.
+// args[0]: object
+static Object* Runtime_GetIndexedInterceptorElementNames(Arguments args) {
+ HandleScope scope;
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
+
+ if (obj->HasIndexedInterceptor()) {
+ v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
+ if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
+ }
+ return Heap::undefined_value();
+}
+
+
static Object* Runtime_LocalKeys(Arguments args) {
ASSERT_EQ(args.length(), 1);
CONVERT_CHECKED(JSObject, raw_object, args[0]);
}
-// Find the length of the prototype chain that is to to handled as one. If a
-// prototype object is hidden it is to be viewed as part of the the object it
-// is prototype for.
-static int LocalPrototypeChainLength(JSObject* obj) {
- int count = 1;
- Object* proto = obj->GetPrototype();
- while (proto->IsJSObject() &&
- JSObject::cast(proto)->map()->is_hidden_prototype()) {
- count++;
- proto = JSObject::cast(proto)->GetPrototype();
- }
- return count;
-}
-
-
static Object* DebugLookupResultValue(Object* receiver, String* name,
LookupResult* result,
bool* caught_exception) {
}
-// Return the names of the local named properties.
-// args[0]: object
-static Object* Runtime_DebugLocalPropertyNames(Arguments args) {
- HandleScope scope;
- ASSERT(args.length() == 1);
- if (!args[0]->IsJSObject()) {
- return Heap::undefined_value();
- }
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
-
- // Skip the global proxy as it has no properties and always delegates to the
- // real global object.
- if (obj->IsJSGlobalProxy()) {
- obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
- }
-
- // Find the number of objects making up this.
- int length = LocalPrototypeChainLength(*obj);
-
- // Find the number of local properties for each of the objects.
- int* local_property_count = NewArray<int>(length);
- int total_property_count = 0;
- Handle<JSObject> jsproto = obj;
- for (int i = 0; i < length; i++) {
- int n;
- n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
- local_property_count[i] = n;
- total_property_count += n;
- if (i < length - 1) {
- jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
- }
- }
-
- // Allocate an array with storage for all the property names.
- Handle<FixedArray> names = Factory::NewFixedArray(total_property_count);
-
- // Get the property names.
- jsproto = obj;
- int proto_with_hidden_properties = 0;
- for (int i = 0; i < length; i++) {
- jsproto->GetLocalPropertyNames(*names,
- i == 0 ? 0 : local_property_count[i - 1]);
- if (!GetHiddenProperties(jsproto, false)->IsUndefined()) {
- proto_with_hidden_properties++;
- }
- if (i < length - 1) {
- jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
- }
- }
-
- // Filter out name of hidden propeties object.
- if (proto_with_hidden_properties > 0) {
- Handle<FixedArray> old_names = names;
- names = Factory::NewFixedArray(
- names->length() - proto_with_hidden_properties);
- int dest_pos = 0;
- for (int i = 0; i < total_property_count; i++) {
- Object* name = old_names->get(i);
- if (name == Heap::hidden_symbol()) {
- continue;
- }
- names->set(dest_pos++, name);
- }
- }
-
- DeleteArray(local_property_count);
- return *Factory::NewJSArrayWithElements(names);
-}
-
-
-// Return the names of the local indexed properties.
-// args[0]: object
-static Object* Runtime_DebugLocalElementNames(Arguments args) {
- HandleScope scope;
- ASSERT(args.length() == 1);
- if (!args[0]->IsJSObject()) {
- return Heap::undefined_value();
- }
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
-
- int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
- Handle<FixedArray> names = Factory::NewFixedArray(n);
- obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
- return *Factory::NewJSArrayWithElements(names);
-}
-
-
// Return the property type calculated from the property details.
// args[0]: smi with property details.
static Object* Runtime_DebugPropertyTypeFromDetails(Arguments args) {
}
-// Return information on whether an object has a named or indexed interceptor.
-// args[0]: object
-static Object* Runtime_DebugInterceptorInfo(Arguments args) {
- HandleScope scope;
- ASSERT(args.length() == 1);
- if (!args[0]->IsJSObject()) {
- return Smi::FromInt(0);
- }
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
-
- int result = 0;
- if (obj->HasNamedInterceptor()) result |= 2;
- if (obj->HasIndexedInterceptor()) result |= 1;
-
- return Smi::FromInt(result);
-}
-
-
-// Return property names from named interceptor.
-// args[0]: object
-static Object* Runtime_DebugNamedInterceptorPropertyNames(Arguments args) {
- HandleScope scope;
- ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
-
- if (obj->HasNamedInterceptor()) {
- v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
- if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
- }
- return Heap::undefined_value();
-}
-
-
-// Return element names from indexed interceptor.
-// args[0]: object
-static Object* Runtime_DebugIndexedInterceptorElementNames(Arguments args) {
- HandleScope scope;
- ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
-
- if (obj->HasIndexedInterceptor()) {
- v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
- if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
- }
- return Heap::undefined_value();
-}
-
-
// Return property value from named interceptor.
// args[0]: object
// args[1]: property name
F(IsPropertyEnumerable, 2, 1) \
F(GetPropertyNames, 1, 1) \
F(GetPropertyNamesFast, 1, 1) \
+ F(GetLocalPropertyNames, 1, 1) \
+ F(GetLocalElementNames, 1, 1) \
+ F(GetInterceptorInfo, 1, 1) \
+ F(GetNamedInterceptorPropertyNames, 1, 1) \
+ F(GetIndexedInterceptorElementNames, 1, 1) \
F(GetArgumentsProperty, 1, 1) \
F(ToFastProperties, 1, 1) \
F(ToSlowProperties, 1, 1) \
F(Break, 0, 1) \
F(DebugGetPropertyDetails, 2, 1) \
F(DebugGetProperty, 2, 1) \
- F(DebugLocalPropertyNames, 1, 1) \
- F(DebugLocalElementNames, 1, 1) \
F(DebugPropertyTypeFromDetails, 1, 1) \
F(DebugPropertyAttributesFromDetails, 1, 1) \
F(DebugPropertyIndexFromDetails, 1, 1) \
- F(DebugInterceptorInfo, 1, 1) \
- F(DebugNamedInterceptorPropertyNames, 1, 1) \
- F(DebugIndexedInterceptorElementNames, 1, 1) \
F(DebugNamedInterceptorPropertyValue, 2, 1) \
F(DebugIndexedInterceptorElementValue, 2, 1) \
F(CheckExecutionState, 1, 1) \
function ObjectKeys(obj) {
if ((!IS_OBJECT(obj) || IS_NULL_OR_UNDEFINED(obj)) && !IS_FUNCTION(obj))
- throw MakeTypeError('object_keys_non_object', [obj]);
+ throw MakeTypeError("obj_ctor_property_non_object", ["keys"]);
return %LocalKeys(obj);
}
// ES5 section 15.2.3.2.
function ObjectGetPrototypeOf(obj) {
- if (!IS_OBJECT(obj) && !IS_FUNCTION(obj)) {
- throw MakeTypeError("object_get_prototype_non_object", [obj]);
- }
- return obj.__proto__;
+ if ((!IS_OBJECT(obj) || IS_NULL_OR_UNDEFINED(obj)) && !IS_FUNCTION(obj))
+ throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]);
+ return obj.__proto__;
}
// ES5 section 15.2.3.3
function ObjectGetOwnPropertyDescriptor(obj, p) {
- if (!IS_OBJECT(obj) && !IS_FUNCTION(obj)) {
- throw MakeTypeError("object_get_prototype_non_object", [obj]);
- }
+ if ((!IS_OBJECT(obj) || IS_NULL_OR_UNDEFINED(obj)) && !IS_FUNCTION(obj))
+ throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyDescriptor"]);
var desc = GetOwnProperty(obj, p);
return FromPropertyDescriptor(desc);
}
+// ES5 section 15.2.3.4.
+function ObjectGetOwnPropertyNames(obj) {
+ if ((!IS_OBJECT(obj) || IS_NULL_OR_UNDEFINED(obj)) && !IS_FUNCTION(obj))
+ throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"]);
+
+ // Find all the indexed properties.
+
+ // Get the local element names.
+ var propertyNames = %GetLocalElementNames(obj);
+
+ // Get names for indexed interceptor properties.
+ if (%GetInterceptorInfo(obj) & 1) {
+ var indexedInterceptorNames =
+ %GetIndexedInterceptorElementNames(obj);
+ if (indexedInterceptorNames) {
+ propertyNames = propertyNames.concat(indexedInterceptorNames);
+ }
+ }
+
+ // Find all the named properties.
+
+ // Get the local property names.
+ propertyNames = propertyNames.concat(%GetLocalPropertyNames(obj));
+
+ // Get names for named interceptor properties if any.
+
+ if (%GetInterceptorInfo(obj) & 2) {
+ var namedInterceptorNames =
+ %GetNamedInterceptorPropertyNames(obj);
+ if (namedInterceptorNames) {
+ propertyNames = propertyNames.concat(namedInterceptorNames);
+ }
+ }
+
+ return propertyNames;
+}
+
+
// ES5 section 15.2.3.5.
function ObjectCreate(proto, properties) {
if (!IS_OBJECT(proto) && !IS_NULL(proto)) {
"keys", ObjectKeys,
"create", ObjectCreate,
"getPrototypeOf", ObjectGetPrototypeOf,
- "getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor
+ "getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor,
+ "getOwnPropertyNames", ObjectGetOwnPropertyNames
));
}
--- /dev/null
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test ES5 section 15.2.3.4 Object.getOwnPropertyNames.
+
+// Check simple cases.
+var obj = { a: 1, b: 2};
+var propertyNames = Object.getOwnPropertyNames(obj);
+propertyNames.sort();
+assertEquals(2, propertyNames.length);
+assertEquals("a", propertyNames[0]);
+assertEquals("b", propertyNames[1]);
+
+var obj = { a: function(){}, b: function(){} };
+var propertyNames = Object.getOwnPropertyNames(obj);
+propertyNames.sort();
+assertEquals(2, propertyNames.length);
+assertEquals("a", propertyNames[0]);
+assertEquals("b", propertyNames[1]);
+
+// Check slow case
+var obj = { a: 1, b: 2, c: 3 };
+delete obj.b;
+var propertyNames = Object.getOwnPropertyNames(obj)
+propertyNames.sort();
+assertEquals(2, propertyNames.length);
+assertEquals("a", propertyNames[0]);
+assertEquals("c", propertyNames[1]);
+
+// Check that non-enumerable properties are being returned.
+var propertyNames = Object.getOwnPropertyNames([1, 2]);
+propertyNames.sort();
+assertEquals(3, propertyNames.length);
+assertEquals("0", propertyNames[0]);
+assertEquals("1", propertyNames[1]);
+assertEquals("length", propertyNames[2]);
+
+// Check that no proto properties are returned.
+var obj = { foo: "foo" };
+obj.__proto__ = { bar: "bar" };
+propertyNames = Object.getOwnPropertyNames(obj);
+propertyNames.sort();
+assertEquals(1, propertyNames.length);
+assertEquals("foo", propertyNames[0]);
+
+// Check that getter properties are returned.
+var obj = {};
+obj.__defineGetter__("getter", function() {});
+propertyNames = Object.getOwnPropertyNames(obj);
+propertyNames.sort();
+assertEquals(1, propertyNames.length);
+assertEquals("getter", propertyNames[0]);
+
+try {
+ Object.getOwnPropertyNames(4);
+ assertTrue(false);
+} catch (e) {
+ assertTrue(/on non-object/.test(e));
+}
+
+try {
+ Object.getOwnPropertyNames("foo");
+ assertTrue(false);
+} catch (e) {
+ assertTrue(/on non-object/.test(e));
+}
+
+try {
+ Object.getOwnPropertyNames(undefined);
+ assertTrue(false);
+} catch (e) {
+ assertTrue(/on non-object/.test(e));
+}
+
+try {
+ Object.getOwnPropertyNames(null);
+ assertTrue(false);
+} catch (e) {
+ assertTrue(/on non-object/.test(e));
+}
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
Object.extend = function (dest, source) {
for (property in source) dest[property] = source[property];
return dest;