2010-01-12 Kent Hansen <kent.hansen@nokia.com>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Jan 2010 00:58:21 +0000 (00:58 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Jan 2010 00:58:21 +0000 (00:58 +0000)
        Reviewed by Geoffrey Garen.

        [ES5] Implement Object.getOwnPropertyNames
        https://bugs.webkit.org/show_bug.cgi?id=32242

        Add an extra argument to getPropertyNames() and getOwnPropertyNames()
        (and all reimplementations thereof) that indicates whether non-enumerable
        properties should be added.

        * API/JSCallbackObject.h:
        * API/JSCallbackObjectFunctions.h:
        (JSC::::getOwnPropertyNames):
        * JavaScriptCore.exp:
        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
        * debugger/DebuggerActivation.cpp:
        (JSC::DebuggerActivation::getOwnPropertyNames):
        * debugger/DebuggerActivation.h:
        * runtime/Arguments.cpp:
        (JSC::Arguments::getOwnPropertyNames):
        * runtime/Arguments.h:
        * runtime/CommonIdentifiers.h:
        * runtime/JSArray.cpp:
        (JSC::JSArray::getOwnPropertyNames):
        * runtime/JSArray.h:
        * runtime/JSByteArray.cpp:
        (JSC::JSByteArray::getOwnPropertyNames):
        * runtime/JSByteArray.h:
        * runtime/JSFunction.cpp:
        (JSC::JSFunction::getOwnPropertyNames):
        * runtime/JSFunction.h:
        * runtime/JSNotAnObject.cpp:
        (JSC::JSNotAnObject::getOwnPropertyNames):
        * runtime/JSNotAnObject.h:
        * runtime/JSObject.cpp:
        (JSC::getClassPropertyNames):
        (JSC::JSObject::getPropertyNames):
        (JSC::JSObject::getOwnPropertyNames):
        * runtime/JSObject.h:
        * runtime/JSVariableObject.cpp:
        (JSC::JSVariableObject::getOwnPropertyNames):
        * runtime/JSVariableObject.h:
        * runtime/ObjectConstructor.cpp:
        (JSC::ObjectConstructor::ObjectConstructor):
        (JSC::objectConstructorGetOwnPropertyNames):
        * runtime/RegExpMatchesArray.h:
        (JSC::RegExpMatchesArray::getOwnPropertyNames):
        * runtime/StringObject.cpp:
        (JSC::StringObject::getOwnPropertyNames):
        * runtime/StringObject.h:
        * runtime/Structure.cpp: Rename getEnumerablePropertyNames() to getPropertyNames(), which takes an extra argument.
        (JSC::Structure::getPropertyNames):
        * runtime/Structure.h:
        (JSC::):
2010-01-12  Kent Hansen  <kent.hansen@nokia.com>

        Reviewed by Geoffrey Garen.

        [ES5] Implement Object.getOwnPropertyNames
        https://bugs.webkit.org/show_bug.cgi?id=32242

        Add new argument to the reimplementation of getOwnPropertyNames().

        * UserObjectImp.cpp:
        (UserObjectImp::getOwnPropertyNames):
        * UserObjectImp.h:
2010-01-12  Kent Hansen  <kent.hansen@nokia.com>

        Reviewed by Geoffrey Garen.

        [ES5] Implement Object.getOwnPropertyNames
        https://bugs.webkit.org/show_bug.cgi?id=32242

        Add tests for Object.getOwnPropertyNames(o), both standard usage and cross origin.

        * fast/js/Object-getOwnPropertyNames-expected.txt: Added.
        * fast/js/Object-getOwnPropertyNames.html: Added.
        * fast/js/script-tests/Object-getOwnPropertyNames.js: Added.
        * http/tests/security/cross-frame-access-enumeration-expected.txt:
        * http/tests/security/cross-frame-access-enumeration.html:
2010-01-12  Kent Hansen  <kent.hansen@nokia.com>

        Reviewed by Geoffrey Garen.

        [ES5] Implement Object.getOwnPropertyNames
        https://bugs.webkit.org/show_bug.cgi?id=32242

        Add new argument to reimplementations of getPropertyNames()
        and getOwnPropertyNames(), and update the JS bindings generator.

        Test: fast/js/Object-getOwnPropertyNames.html

        * bindings/js/JSDOMWindowCustom.cpp:
        (WebCore::JSDOMWindow::getPropertyNames):
        (WebCore::JSDOMWindow::getOwnPropertyNames):
        * bindings/js/JSDOMWindowShell.cpp:
        (WebCore::JSDOMWindowShell::getPropertyNames):
        (WebCore::JSDOMWindowShell::getOwnPropertyNames):
        * bindings/js/JSDOMWindowShell.h:
        * bindings/js/JSHistoryCustom.cpp:
        (WebCore::JSHistory::getOwnPropertyNames):
        * bindings/js/JSLocationCustom.cpp:
        (WebCore::JSLocation::getOwnPropertyNames):
        * bindings/js/JSQuarantinedObjectWrapper.cpp:
        (WebCore::JSQuarantinedObjectWrapper::getPropertyNames):
        (WebCore::JSQuarantinedObjectWrapper::getOwnPropertyNames):
        * bindings/js/JSQuarantinedObjectWrapper.h:
        * bindings/js/JSStorageCustom.cpp:
        (WebCore::JSStorage::getOwnPropertyNames):
        * bindings/scripts/CodeGeneratorJS.pm:
        * bridge/runtime_array.cpp:
        (JSC::RuntimeArray::getOwnPropertyNames):
        * bridge/runtime_array.h:
        * bridge/runtime_object.cpp:
        (JSC::RuntimeObjectImp::getPropertyNames):
        (JSC::RuntimeObjectImp::getOwnPropertyNames):
        * bridge/runtime_object.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@53170 268f45cc-cd09-0410-ab3c-d52691b4dbfc

51 files changed:
JavaScriptCore/API/JSCallbackObject.h
JavaScriptCore/API/JSCallbackObjectFunctions.h
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
JavaScriptCore/debugger/DebuggerActivation.cpp
JavaScriptCore/debugger/DebuggerActivation.h
JavaScriptCore/runtime/Arguments.cpp
JavaScriptCore/runtime/Arguments.h
JavaScriptCore/runtime/CommonIdentifiers.h
JavaScriptCore/runtime/JSArray.cpp
JavaScriptCore/runtime/JSArray.h
JavaScriptCore/runtime/JSByteArray.cpp
JavaScriptCore/runtime/JSByteArray.h
JavaScriptCore/runtime/JSFunction.cpp
JavaScriptCore/runtime/JSFunction.h
JavaScriptCore/runtime/JSNotAnObject.cpp
JavaScriptCore/runtime/JSNotAnObject.h
JavaScriptCore/runtime/JSObject.cpp
JavaScriptCore/runtime/JSObject.h
JavaScriptCore/runtime/JSVariableObject.cpp
JavaScriptCore/runtime/JSVariableObject.h
JavaScriptCore/runtime/ObjectConstructor.cpp
JavaScriptCore/runtime/RegExpMatchesArray.h
JavaScriptCore/runtime/StringObject.cpp
JavaScriptCore/runtime/StringObject.h
JavaScriptCore/runtime/Structure.cpp
JavaScriptCore/runtime/Structure.h
JavaScriptGlue/ChangeLog
JavaScriptGlue/UserObjectImp.cpp
JavaScriptGlue/UserObjectImp.h
LayoutTests/ChangeLog
LayoutTests/fast/js/Object-getOwnPropertyNames-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/Object-getOwnPropertyNames.html [new file with mode: 0644]
LayoutTests/fast/js/script-tests/Object-getOwnPropertyNames.js [new file with mode: 0644]
LayoutTests/http/tests/security/cross-frame-access-enumeration-expected.txt
LayoutTests/http/tests/security/cross-frame-access-enumeration.html
WebCore/ChangeLog
WebCore/bindings/js/JSDOMWindowCustom.cpp
WebCore/bindings/js/JSDOMWindowShell.cpp
WebCore/bindings/js/JSDOMWindowShell.h
WebCore/bindings/js/JSHistoryCustom.cpp
WebCore/bindings/js/JSLocationCustom.cpp
WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp
WebCore/bindings/js/JSQuarantinedObjectWrapper.h
WebCore/bindings/js/JSStorageCustom.cpp
WebCore/bindings/scripts/CodeGeneratorJS.pm
WebCore/bridge/runtime_array.cpp
WebCore/bridge/runtime_array.h
WebCore/bridge/runtime_object.cpp
WebCore/bridge/runtime_object.h

index d19890a..e13dbd2 100644 (file)
@@ -69,7 +69,7 @@ private:
 
     virtual bool hasInstance(ExecState* exec, JSValue value, JSValue proto);
 
-    virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
+    virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
 
     virtual double toNumber(ExecState*) const;
     virtual UString toString(ExecState*) const;
index f1494e2..4000f63 100644 (file)
@@ -380,7 +380,7 @@ JSValue JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject,
 }
 
 template <class Base>
-void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     JSContextRef execRef = toRef(exec);
     JSObjectRef thisRef = toRef(this);
@@ -397,7 +397,7 @@ void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameAr
             for (iterator it = staticValues->begin(); it != end; ++it) {
                 UString::Rep* name = it->first.get();
                 StaticValueEntry* entry = it->second;
-                if (entry->getProperty && !(entry->attributes & kJSPropertyAttributeDontEnum))
+                if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties)))
                     propertyNames.add(Identifier(exec, name));
             }
         }
@@ -408,13 +408,13 @@ void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameAr
             for (iterator it = staticFunctions->begin(); it != end; ++it) {
                 UString::Rep* name = it->first.get();
                 StaticFunctionEntry* entry = it->second;
-                if (!(entry->attributes & kJSPropertyAttributeDontEnum))
+                if (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties))
                     propertyNames.add(Identifier(exec, name));
             }
         }
     }
     
-    Base::getOwnPropertyNames(exec, propertyNames);
+    Base::getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 template <class Base>
index 53ef271..9902a97 100644 (file)
@@ -1,3 +1,59 @@
+2010-01-12  Kent Hansen  <kent.hansen@nokia.com>
+
+        Reviewed by Geoffrey Garen.
+
+        [ES5] Implement Object.getOwnPropertyNames
+        https://bugs.webkit.org/show_bug.cgi?id=32242
+
+        Add an extra argument to getPropertyNames() and getOwnPropertyNames()
+        (and all reimplementations thereof) that indicates whether non-enumerable
+        properties should be added.
+
+        * API/JSCallbackObject.h:
+        * API/JSCallbackObjectFunctions.h:
+        (JSC::::getOwnPropertyNames):
+        * JavaScriptCore.exp:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+        * debugger/DebuggerActivation.cpp:
+        (JSC::DebuggerActivation::getOwnPropertyNames):
+        * debugger/DebuggerActivation.h:
+        * runtime/Arguments.cpp:
+        (JSC::Arguments::getOwnPropertyNames):
+        * runtime/Arguments.h:
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::getOwnPropertyNames):
+        * runtime/JSArray.h:
+        * runtime/JSByteArray.cpp:
+        (JSC::JSByteArray::getOwnPropertyNames):
+        * runtime/JSByteArray.h:
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::getOwnPropertyNames):
+        * runtime/JSFunction.h:
+        * runtime/JSNotAnObject.cpp:
+        (JSC::JSNotAnObject::getOwnPropertyNames):
+        * runtime/JSNotAnObject.h:
+        * runtime/JSObject.cpp:
+        (JSC::getClassPropertyNames):
+        (JSC::JSObject::getPropertyNames):
+        (JSC::JSObject::getOwnPropertyNames):
+        * runtime/JSObject.h:
+        * runtime/JSVariableObject.cpp:
+        (JSC::JSVariableObject::getOwnPropertyNames):
+        * runtime/JSVariableObject.h:
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructor::ObjectConstructor):
+        (JSC::objectConstructorGetOwnPropertyNames):
+        * runtime/RegExpMatchesArray.h:
+        (JSC::RegExpMatchesArray::getOwnPropertyNames):
+        * runtime/StringObject.cpp:
+        (JSC::StringObject::getOwnPropertyNames):
+        * runtime/StringObject.h:
+        * runtime/Structure.cpp: Rename getEnumerablePropertyNames() to getPropertyNames(), which takes an extra argument.
+        (JSC::Structure::getPropertyNames):
+        * runtime/Structure.h:
+        (JSC::):
+
 2010-01-12  Alexey Proskuryakov  <ap@apple.com>
 
         Reviewed by Darin Adler.
index 48f6096..39285b9 100644 (file)
@@ -126,7 +126,7 @@ __ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
 __ZN3JSC12StringObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC12StringObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC12StringObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
 __ZN3JSC12StringObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
 __ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC12StringObject4infoE
@@ -159,7 +159,7 @@ __ZN3JSC16InternalFunction4nameEPNS_9ExecStateE
 __ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_10IdentifierE
 __ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC16JSVariableObject14symbolTableGetERKNS_10IdentifierERNS_18PropertyDescriptorE
-__ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
 __ZN3JSC16toUInt32SlowCaseEdRb
 __ZN3JSC17BytecodeGenerator21setDumpsGeneratedCodeEb
 __ZN3JSC17PropertyNameArray3addEPNS_11UStringImplE
@@ -253,7 +253,7 @@ __ZN3JSC8JSObject12markChildrenERNS_9MarkStackE
 __ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj
 __ZN3JSC8JSObject15unwrappedObjectEv
-__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
 __ZN3JSC8JSObject17createInheritorIDEv
 __ZN3JSC8JSObject17defineOwnPropertyEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorEb
 __ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj
@@ -262,7 +262,7 @@ __ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValu
 __ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateEjNS_7JSValueEj
 __ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
 __ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE
-__ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
 __ZN3JSC8JSObject21getPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
 __ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_7JSValueE  
 __ZN3JSC8JSObject23allocatePropertyStorageEmm
index b9a85cf..b31e248 100644 (file)
@@ -138,9 +138,9 @@ EXPORTS
     ?getOwnPropertyDescriptor@JSObject@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z
     ?getOwnPropertyDescriptor@JSString@JSC@@EAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z
     ?getOwnPropertyDescriptor@StringObject@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z
-    ?getOwnPropertyNames@JSObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@@Z
-    ?getOwnPropertyNames@JSVariableObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@@Z
-    ?getOwnPropertyNames@StringObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@@Z
+    ?getOwnPropertyNames@JSObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
+    ?getOwnPropertyNames@JSVariableObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
+    ?getOwnPropertyNames@StringObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
     ?getOwnPropertySlot@JSCell@JSC@@EAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertySlot@2@@Z
     ?getOwnPropertySlot@JSCell@JSC@@EAE_NPAVExecState@2@IAAVPropertySlot@2@@Z
     ?getOwnPropertySlot@JSObject@JSC@@UAE_NPAVExecState@2@IAAVPropertySlot@2@@Z
@@ -152,7 +152,7 @@ EXPORTS
     ?getPrimitiveNumber@JSObject@JSC@@UAE_NPAVExecState@2@AANAAVJSValue@2@@Z
     ?getPrimitiveNumber@JSString@JSC@@EAE_NPAVExecState@2@AANAAVJSValue@2@@Z
     ?getPropertyDescriptor@JSObject@JSC@@QAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z
-    ?getPropertyNames@JSObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@@Z
+    ?getPropertyNames@JSObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
     ?getSlice@ArgList@JSC@@QBEXHAAV12@@Z
     ?getString@JSCell@JSC@@QBE?AVUString@2@PAVExecState@2@@Z
     ?getString@JSCell@JSC@@QBE_NPAVExecState@2@AAVUString@2@@Z
index d47db5b..0444d23 100644 (file)
@@ -71,9 +71,9 @@ bool DebuggerActivation::deleteProperty(ExecState* exec, const Identifier& prope
     return m_activation->deleteProperty(exec, propertyName);
 }
 
-void DebuggerActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void DebuggerActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
-    m_activation->getPropertyNames(exec, propertyNames);
+    m_activation->getPropertyNames(exec, propertyNames, mode);
 }
 
 bool DebuggerActivation::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
index 373e62d..354fcb8 100644 (file)
@@ -42,7 +42,7 @@ namespace JSC {
         virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
         virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
-        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
+        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
         virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
         virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes);
         virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes);
index 86a8f0a..bb30e3b 100644 (file)
@@ -204,6 +204,19 @@ bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& prop
     return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
 }
 
+void Arguments::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+    if (mode == IncludeDontEnumProperties) {
+        for (unsigned i = 0; i < d->numArguments; ++i) {
+            if (!d->deletedArguments || !d->deletedArguments[i])
+                propertyNames.add(Identifier(exec, UString::from(i)));
+        }
+        propertyNames.add(exec->propertyNames().callee);
+        propertyNames.add(exec->propertyNames().length);
+    }
+    JSObject::getOwnPropertyNames(exec, propertyNames, mode);
+}
+
 void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot& slot)
 {
     if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
index 9b674a2..783044d 100644 (file)
@@ -96,6 +96,7 @@ namespace JSC {
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
         virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
+        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
         virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
         virtual void put(ExecState*, unsigned propertyName, JSValue, PutPropertySlot&);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
index abe5038..de24f4a 100644 (file)
@@ -50,6 +50,7 @@
     macro(get) \
     macro(getPrototypeOf) \
     macro(getOwnPropertyDescriptor) \
+    macro(getOwnPropertyNames) \
     macro(hasOwnProperty) \
     macro(ignoreCase) \
     macro(index) \
index 7221f87..2be7371 100644 (file)
@@ -469,7 +469,7 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i)
     return false;
 }
 
-void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     // FIXME: Filling PropertyNameArray with an identifier for every integer
     // is incredibly inefficient for large arrays. We need a different approach,
@@ -489,7 +489,10 @@ void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNa
             propertyNames.add(Identifier::from(exec, it->first));
     }
 
-    JSObject::getOwnPropertyNames(exec, propertyNames);
+    if (mode == IncludeDontEnumProperties)
+        propertyNames.add(exec->propertyNames().length);
+
+    JSObject::getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 bool JSArray::increaseVectorLength(unsigned newLength)
index 635b142..64b2ff1 100644 (file)
@@ -98,7 +98,7 @@ namespace JSC {
         virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
         virtual bool deleteProperty(ExecState*, unsigned propertyName);
-        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
+        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
         virtual void markChildren(MarkStack&);
 
         void* lazyCreationData();
index 2509f85..f8ab1e8 100644 (file)
@@ -104,12 +104,12 @@ void JSByteArray::put(ExecState* exec, unsigned propertyName, JSValue value)
     setIndex(exec, propertyName, value);
 }
 
-void JSByteArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSByteArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     unsigned length = m_storage->length();
     for (unsigned i = 0; i < length; ++i)
         propertyNames.add(Identifier::from(exec, i));
-    JSObject::getOwnPropertyNames(exec, propertyNames);
+    JSObject::getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 }
index df481f8..5b7adcf 100644 (file)
@@ -82,7 +82,7 @@ namespace JSC {
         virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
         virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue);
 
-        virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
+        virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
 
         virtual const ClassInfo* classInfo() const { return m_classInfo; }
         static const ClassInfo s_defaultInfo;
index fdf20bd..d213b4a 100644 (file)
@@ -208,6 +208,17 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
         return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
     }
     
+void JSFunction::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+    if (!isHostFunction() && (mode == IncludeDontEnumProperties)) {
+        propertyNames.add(exec->propertyNames().arguments);
+        propertyNames.add(exec->propertyNames().callee);
+        propertyNames.add(exec->propertyNames().caller);
+        propertyNames.add(exec->propertyNames().length);
+    }
+    Base::getOwnPropertyNames(exec, propertyNames, mode);
+}
+
 void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     if (isHostFunction()) {
index 67f07fb..bdb79b8 100644 (file)
@@ -82,6 +82,7 @@ namespace JSC {
 
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
         virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
+        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
         virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
 
index c36dc10..f4764e2 100644 (file)
@@ -121,7 +121,7 @@ bool JSNotAnObject::deleteProperty(ExecState* exec, unsigned)
     return false;
 }
 
-void JSNotAnObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray&)
+void JSNotAnObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray&, EnumerationMode)
 {
     ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
 }
index a271c4e..d5f430c 100644 (file)
@@ -91,7 +91,7 @@ namespace JSC {
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
         virtual bool deleteProperty(ExecState*, unsigned propertyName);
 
-        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
+        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
 
         JSNotAnObjectErrorStub* m_exception;
     };
index ed9fdc2..d9500aa 100644 (file)
@@ -42,7 +42,7 @@ namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(JSObject);
 
-static inline void getEnumerablePropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames)
+static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     // Add properties from the static hashtables of properties
     for (; classInfo; classInfo = classInfo->parentClass) {
@@ -55,7 +55,7 @@ static inline void getEnumerablePropertyNames(ExecState* exec, const ClassInfo*
         int hashSizeMask = table->compactSize - 1;
         const HashEntry* entry = table->table;
         for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
-            if (entry->key() && !(entry->attributes() & DontEnum))
+            if (entry->key() && (!(entry->attributes() & DontEnum) || (mode == IncludeDontEnumProperties)))
                 propertyNames.add(entry->key());
         }
     }
@@ -425,9 +425,9 @@ bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyNa
     return false;
 }
 
-void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
-    getOwnPropertyNames(exec, propertyNames);
+    getOwnPropertyNames(exec, propertyNames, mode);
 
     if (prototype().isNull())
         return;
@@ -435,10 +435,10 @@ void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyName
     JSObject* prototype = asObject(this->prototype());
     while(1) {
         if (prototype->structure()->typeInfo().overridesGetPropertyNames()) {
-            prototype->getPropertyNames(exec, propertyNames);
+            prototype->getPropertyNames(exec, propertyNames, mode);
             break;
         }
-        prototype->getOwnPropertyNames(exec, propertyNames);
+        prototype->getOwnPropertyNames(exec, propertyNames, mode);
         JSValue nextProto = prototype->prototype();
         if (nextProto.isNull())
             break;
@@ -446,10 +446,10 @@ void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyName
     }
 }
 
-void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
-    m_structure->getEnumerablePropertyNames(propertyNames);
-    getEnumerablePropertyNames(exec, classInfo(), propertyNames);
+    m_structure->getPropertyNames(propertyNames, mode);
+    getClassPropertyNames(exec, classInfo(), propertyNames, mode);
 }
 
 bool JSObject::toBoolean(ExecState*) const
index a5da267..d931a4a 100644 (file)
@@ -122,8 +122,8 @@ namespace JSC {
 
         virtual bool hasInstance(ExecState*, JSValue, JSValue prototypeProperty);
 
-        virtual void getPropertyNames(ExecState*, PropertyNameArray&);
-        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
+        virtual void getPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
+        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
 
         virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
         virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
index 3aa9e62..7365001 100644 (file)
@@ -42,15 +42,15 @@ bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propert
     return JSObject::deleteProperty(exec, propertyName);
 }
 
-void JSVariableObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSVariableObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     SymbolTable::const_iterator end = symbolTable().end();
     for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) {
-        if (!(it->second.getAttributes() & DontEnum))
+        if (!(it->second.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties))
             propertyNames.add(Identifier(exec, it->first.get()));
     }
     
-    JSObject::getOwnPropertyNames(exec, propertyNames);
+    JSObject::getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 bool JSVariableObject::isVariableObject() const
index 15d6ff5..737816d 100644 (file)
@@ -49,7 +49,7 @@ namespace JSC {
         virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes) = 0;
 
         virtual bool deleteProperty(ExecState*, const Identifier&);
-        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
+        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
         
         virtual bool isVariableObject() const;
         virtual bool isDynamicScope() const = 0;
index 693efc3..0838eb4 100644 (file)
@@ -36,6 +36,7 @@ ASSERT_CLASS_FITS_IN_CELL(ObjectConstructor);
 
 static JSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*, JSObject*, JSValue, const ArgList&);
 static JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState*, JSObject*, JSValue, const ArgList&);
 static JSValue JSC_HOST_CALL objectConstructorKeys(ExecState*, JSObject*, JSValue, const ArgList&);
 static JSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState*, JSObject*, JSValue, const ArgList&);
 static JSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState*, JSObject*, JSValue, const ArgList&);
@@ -52,6 +53,7 @@ ObjectConstructor::ObjectConstructor(ExecState* exec, NonNullPassRefPtr<Structur
     
     putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().getPrototypeOf, objectConstructorGetPrototypeOf), DontEnum);
     putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().getOwnPropertyDescriptor, objectConstructorGetOwnPropertyDescriptor), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().getOwnPropertyNames, objectConstructorGetOwnPropertyNames), DontEnum);
     putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().keys, objectConstructorKeys), DontEnum);
     putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 3, exec->propertyNames().defineProperty, objectConstructorDefineProperty), DontEnum);
     putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().defineProperties, objectConstructorDefineProperties), DontEnum);
@@ -126,6 +128,20 @@ JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec,
 }
 
 // FIXME: Use the enumeration cache.
+JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+    if (!args.at(0).isObject())
+        return throwError(exec, TypeError, "Requested property names of a value that is not an object.");
+    PropertyNameArray properties(exec);
+    asObject(args.at(0))->getOwnPropertyNames(exec, properties, IncludeDontEnumProperties);
+    JSArray* names = constructEmptyArray(exec);
+    size_t numProperties = properties.size();
+    for (size_t i = 0; i < numProperties; i++)
+        names->push(exec, jsOwnedString(exec, properties[i].ustring()));
+    return names;
+}
+
+// FIXME: Use the enumeration cache.
 JSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     if (!args.at(0).isObject())
index 829f7cf..38d3cb4 100644 (file)
@@ -79,11 +79,11 @@ namespace JSC {
             return JSArray::deleteProperty(exec, propertyName);
         }
 
-        virtual void getOwnPropertyNames(ExecState* exec, PropertyNameArray& arr)
+        virtual void getOwnPropertyNames(ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties)
         {
             if (lazyCreationData())
                 fillArrayInstance(exec);
-            JSArray::getOwnPropertyNames(exec, arr);
+            JSArray::getOwnPropertyNames(exec, arr, mode);
         }
 
         void fillArrayInstance(ExecState*);
index f23a20d..f8e0e87 100644 (file)
@@ -86,12 +86,14 @@ bool StringObject::deleteProperty(ExecState* exec, const Identifier& propertyNam
     return JSObject::deleteProperty(exec, propertyName);
 }
 
-void StringObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void StringObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     int size = internalValue()->length();
     for (int i = 0; i < size; ++i)
         propertyNames.add(Identifier(exec, UString::from(i)));
-    return JSObject::getOwnPropertyNames(exec, propertyNames);
+    if (mode == IncludeDontEnumProperties)
+        propertyNames.add(exec->propertyNames().length);
+    return JSObject::getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 } // namespace JSC
index 84e1ad2..b720b90 100644 (file)
@@ -39,7 +39,7 @@ namespace JSC {
 
         virtual void put(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
-        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
+        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
 
         virtual const ClassInfo* classInfo() const { return &info; }
         static const JS_EXPORTDATA ClassInfo info;
index 5b9a553..c370383 100644 (file)
@@ -1074,7 +1074,7 @@ int comparePropertyMapEntryIndices(const void* a, const void* b)
     return 0;
 }
 
-void Structure::getEnumerablePropertyNames(PropertyNameArray& propertyNames)
+void Structure::getPropertyNames(PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     materializePropertyMapIfNecessary();
     if (!m_propertyTable)
@@ -1086,7 +1086,7 @@ void Structure::getEnumerablePropertyNames(PropertyNameArray& propertyNames)
         unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
         for (unsigned k = 1; k <= entryCount; k++) {
             ASSERT(m_hasNonEnumerableProperties || !(m_propertyTable->entries()[k].attributes & DontEnum));
-            if (m_propertyTable->entries()[k].key && !(m_propertyTable->entries()[k].attributes & DontEnum)) {
+            if (m_propertyTable->entries()[k].key && (!(m_propertyTable->entries()[k].attributes & DontEnum) || (mode == IncludeDontEnumProperties))) {
                 PropertyMapEntry* value = &m_propertyTable->entries()[k];
                 int j;
                 for (j = i - 1; j >= 0 && a[j]->index > value->index; --j)
@@ -1113,7 +1113,7 @@ void Structure::getEnumerablePropertyNames(PropertyNameArray& propertyNames)
     PropertyMapEntry** p = sortedEnumerables.data();
     unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
     for (unsigned i = 1; i <= entryCount; i++) {
-        if (m_propertyTable->entries()[i].key && !(m_propertyTable->entries()[i].attributes & DontEnum))
+        if (m_propertyTable->entries()[i].key && (!(m_propertyTable->entries()[i].attributes & DontEnum) || (mode == IncludeDontEnumProperties)))
             *p++ = &m_propertyTable->entries()[i];
     }
 
index 839cbd0..099da6e 100644 (file)
@@ -51,6 +51,11 @@ namespace JSC {
     class PropertyNameArray;
     class PropertyNameArrayData;
 
+    enum EnumerationMode {
+        ExcludeDontEnumProperties,
+        IncludeDontEnumProperties
+    };
+
     class Structure : public RefCounted<Structure> {
     public:
         friend class JIT;
@@ -131,7 +136,7 @@ namespace JSC {
 
         void setEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
         JSPropertyNameIterator* enumerationCache() { return m_enumerationCache.get(); }
-        void getEnumerablePropertyNames(PropertyNameArray&);
+        void getPropertyNames(PropertyNameArray&, EnumerationMode mode);
         
     private:
         Structure(JSValue prototype, const TypeInfo&);
index 5facc12..f187392 100644 (file)
@@ -1,3 +1,16 @@
+2010-01-12  Kent Hansen  <kent.hansen@nokia.com>
+
+        Reviewed by Geoffrey Garen.
+
+        [ES5] Implement Object.getOwnPropertyNames
+        https://bugs.webkit.org/show_bug.cgi?id=32242
+
+        Add new argument to the reimplementation of getOwnPropertyNames().
+
+        * UserObjectImp.cpp:
+        (UserObjectImp::getOwnPropertyNames):
+        * UserObjectImp.h:
+
 2010-01-07  Alexey Proskuryakov  <ap@apple.com>
 
         Mac build fix.
index 7129475..1fbb982 100644 (file)
@@ -94,7 +94,7 @@ JSValue UserObjectImp::callAsFunction(ExecState *exec, JSObject *thisObj, const
 }
 
 
-void UserObjectImp::getOwnPropertyNames(ExecState *exec, PropertyNameArray& propertyNames)
+void UserObjectImp::getOwnPropertyNames(ExecState *exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     JSUserObject* ptr = GetJSUserObject();
     if (ptr) {
@@ -109,7 +109,7 @@ void UserObjectImp::getOwnPropertyNames(ExecState *exec, PropertyNameArray& prop
             CFRelease(cfPropertyNames);
         }
     }
-    JSObject::getOwnPropertyNames(exec, propertyNames);
+    JSObject::getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 JSValue UserObjectImp::userObjectGetter(ExecState*, const Identifier& propertyName, const PropertySlot& slot)
index 6bb5792..6541a84 100644 (file)
@@ -44,7 +44,7 @@ public:
 
     virtual CallType getCallData(CallData&);
 
-    virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
+    virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
 
     virtual JSValue callAsFunction(ExecState *exec, JSObject *thisObj, const ArgList &args);
     virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
index fc6b712..3f3a4b2 100644 (file)
@@ -1,3 +1,18 @@
+2010-01-12  Kent Hansen  <kent.hansen@nokia.com>
+
+        Reviewed by Geoffrey Garen.
+
+        [ES5] Implement Object.getOwnPropertyNames
+        https://bugs.webkit.org/show_bug.cgi?id=32242
+
+        Add tests for Object.getOwnPropertyNames(o), both standard usage and cross origin.
+
+        * fast/js/Object-getOwnPropertyNames-expected.txt: Added.
+        * fast/js/Object-getOwnPropertyNames.html: Added.
+        * fast/js/script-tests/Object-getOwnPropertyNames.js: Added.
+        * http/tests/security/cross-frame-access-enumeration-expected.txt:
+        * http/tests/security/cross-frame-access-enumeration.html:
+
 2010-01-12  Brian Weinstein  <bweinstein@apple.com>
 
         Add correct expected results after r53168 for GTK and Qt.
diff --git a/LayoutTests/fast/js/Object-getOwnPropertyNames-expected.txt b/LayoutTests/fast/js/Object-getOwnPropertyNames-expected.txt
new file mode 100644 (file)
index 0000000..49878f2
--- /dev/null
@@ -0,0 +1,90 @@
+Test to ensure correct behaviour of Object.getOwnPropertyNames
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS getSortedOwnPropertyNames({}) is []
+PASS getSortedOwnPropertyNames({a:null}) is ['a']
+PASS getSortedOwnPropertyNames({a:null, b:null}) is ['a', 'b']
+PASS getSortedOwnPropertyNames({b:null, a:null}) is ['a', 'b']
+PASS getSortedOwnPropertyNames({__proto__:{a:null}}) is []
+PASS getSortedOwnPropertyNames({__proto__:[1,2,3]}) is []
+PASS getSortedOwnPropertyNames(Object.create({}, { 'a': { 'value': 1, 'enumerable': false } })) is ['a']
+PASS getSortedOwnPropertyNames(Object.create([1,2,3], { 'a': { 'value': 1, 'enumerable': false } })) is ['a']
+PASS getSortedOwnPropertyNames(new Function()) is ['arguments', 'callee', 'caller', 'length', 'name']
+PASS getSortedOwnPropertyNames((function(){var x=new Function();x.__proto__=[1,2,3];return x;})()) is ['arguments', 'callee', 'caller', 'length', 'name']
+PASS getSortedOwnPropertyNames(new String('')) is ['length']
+PASS getSortedOwnPropertyNames(new String('a')) is ['0', 'length']
+PASS getSortedOwnPropertyNames(new String('abc')) is ['0', '1', '2', 'length']
+PASS getSortedOwnPropertyNames((function(){var x=new String('');x.__proto__=[1,2,3];return x;})()) is ['length']
+PASS getSortedOwnPropertyNames([]) is ['length']
+PASS getSortedOwnPropertyNames([null]) is ['0', 'length']
+PASS getSortedOwnPropertyNames([null,null]) is ['0','1', 'length']
+PASS getSortedOwnPropertyNames([null,null,,,,null]) is ['0','1','5', 'length']
+PASS getSortedOwnPropertyNames((function(){var x=[];x.__proto__=[1,2,3];return x;})()) is ['length']
+PASS getSortedOwnPropertyNames(new Date()) is []
+PASS getSortedOwnPropertyNames((function(){var x=new Date();x.__proto__=[1,2,3];return x;})()) is []
+PASS getSortedOwnPropertyNames(new RegExp('foo')) is ['global', 'ignoreCase', 'lastIndex', 'multiline', 'source']
+PASS getSortedOwnPropertyNames((function(){var x=new RegExp();x.__proto__=[1,2,3];return x;})()) is ['global', 'ignoreCase', 'lastIndex', 'multiline', 'source']
+PASS getSortedOwnPropertyNames(argumentsObject()) is ['callee', 'length']
+PASS getSortedOwnPropertyNames(argumentsObject(1)) is ['0', 'callee', 'length']
+PASS getSortedOwnPropertyNames(argumentsObject(1,2,3)) is ['0', '1', '2', 'callee', 'length']
+PASS getSortedOwnPropertyNames((function(){arguments.__proto__=[1,2,3];return arguments;})()) is ['callee', 'length']
+PASS getSortedOwnPropertyNames(parseInt) is ['length', 'name']
+PASS getSortedOwnPropertyNames(parseFloat) is ['length', 'name']
+PASS getSortedOwnPropertyNames(isNaN) is ['length', 'name']
+PASS getSortedOwnPropertyNames(isFinite) is ['length', 'name']
+PASS getSortedOwnPropertyNames(escape) is ['length', 'name']
+PASS getSortedOwnPropertyNames(unescape) is ['length', 'name']
+PASS getSortedOwnPropertyNames(decodeURI) is ['length', 'name']
+PASS getSortedOwnPropertyNames(decodeURIComponent) is ['length', 'name']
+PASS getSortedOwnPropertyNames(encodeURI) is ['length', 'name']
+PASS getSortedOwnPropertyNames(encodeURIComponent) is ['length', 'name']
+PASS getSortedOwnPropertyNames(Object) is ['create', 'defineProperties', 'defineProperty', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getPrototypeOf', 'keys', 'length', 'name', 'prototype']
+PASS getSortedOwnPropertyNames(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']
+PASS getSortedOwnPropertyNames(Function) is ['length', 'name', 'prototype']
+PASS getSortedOwnPropertyNames(Function.prototype) is ['apply', 'call', 'constructor', 'length', 'name', 'toString']
+PASS getSortedOwnPropertyNames(Array) is ['isArray', 'length', 'name', 'prototype']
+PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'every', 'filter', 'forEach', 'indexOf', 'join', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']
+PASS getSortedOwnPropertyNames(String) is ['fromCharCode', 'length', 'name', 'prototype']
+PASS getSortedOwnPropertyNames(String.prototype) is ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'replace', 'search', 'slice', 'small', 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']
+PASS getSortedOwnPropertyNames(Boolean) is ['length', 'name', 'prototype']
+PASS getSortedOwnPropertyNames(Boolean.prototype) is ['constructor', 'toString', 'valueOf']
+PASS getSortedOwnPropertyNames(Number) is ['MAX_VALUE', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'length', 'name', 'prototype']
+PASS getSortedOwnPropertyNames(Number.prototype) is ['constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf']
+PASS getSortedOwnPropertyNames(Date) is ['UTC', 'length', 'name', 'now', 'parse', 'prototype']
+PASS getSortedOwnPropertyNames(Date.prototype) is ['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf']
+PASS getSortedOwnPropertyNames(RegExp) is ['$&', "$'", '$*', '$+', '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_', '$`', 'input', 'lastMatch', 'lastParen', 'leftContext', 'length', 'multiline', 'name', 'prototype', 'rightContext']
+PASS getSortedOwnPropertyNames(RegExp.prototype) is ['compile', 'constructor', 'exec', 'test', 'toString']
+PASS getSortedOwnPropertyNames(Error) is ['length', 'name', 'prototype']
+PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString']
+PASS getSortedOwnPropertyNames(Math) is ['E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2', 'abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan']
+PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
+PASS globalPropertyNames.indexOf('NaN') != -1 is true
+PASS globalPropertyNames.indexOf('Infinity') != -1 is true
+PASS globalPropertyNames.indexOf('undefined') != -1 is true
+PASS globalPropertyNames.indexOf('parseInt') != -1 is true
+PASS globalPropertyNames.indexOf('parseFloat') != -1 is true
+PASS globalPropertyNames.indexOf('isNaN') != -1 is true
+PASS globalPropertyNames.indexOf('isFinite') != -1 is true
+PASS globalPropertyNames.indexOf('escape') != -1 is true
+PASS globalPropertyNames.indexOf('unescape') != -1 is true
+PASS globalPropertyNames.indexOf('decodeURI') != -1 is true
+PASS globalPropertyNames.indexOf('decodeURIComponent') != -1 is true
+PASS globalPropertyNames.indexOf('encodeURI') != -1 is true
+PASS globalPropertyNames.indexOf('encodeURIComponent') != -1 is true
+PASS globalPropertyNames.indexOf('Object') != -1 is true
+PASS globalPropertyNames.indexOf('Function') != -1 is true
+PASS globalPropertyNames.indexOf('Array') != -1 is true
+PASS globalPropertyNames.indexOf('String') != -1 is true
+PASS globalPropertyNames.indexOf('Boolean') != -1 is true
+PASS globalPropertyNames.indexOf('Number') != -1 is true
+PASS globalPropertyNames.indexOf('Date') != -1 is true
+PASS globalPropertyNames.indexOf('RegExp') != -1 is true
+PASS globalPropertyNames.indexOf('Error') != -1 is true
+PASS globalPropertyNames.indexOf('Math') != -1 is true
+PASS globalPropertyNames.indexOf('JSON') != -1 is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/Object-getOwnPropertyNames.html b/LayoutTests/fast/js/Object-getOwnPropertyNames.html
new file mode 100644 (file)
index 0000000..bc1ac4f
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/js-test-style.css">
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/Object-getOwnPropertyNames.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/js/script-tests/Object-getOwnPropertyNames.js b/LayoutTests/fast/js/script-tests/Object-getOwnPropertyNames.js
new file mode 100644 (file)
index 0000000..477f024
--- /dev/null
@@ -0,0 +1,114 @@
+description("Test to ensure correct behaviour of Object.getOwnPropertyNames");
+
+function argumentsObject() { return arguments; };
+
+var expectedPropertyNamesSet = {
+    "{}": "[]",
+    "{a:null}": "['a']",
+    "{a:null, b:null}": "['a', 'b']",
+    "{b:null, a:null}": "['a', 'b']",
+    "{__proto__:{a:null}}": "[]",
+    "{__proto__:[1,2,3]}": "[]",
+    "Object.create({}, { 'a': { 'value': 1, 'enumerable': false } })": "['a']",
+    "Object.create([1,2,3], { 'a': { 'value': 1, 'enumerable': false } })": "['a']",
+// Function objects
+    "new Function()": "['arguments', 'callee', 'caller', 'length', 'name']",
+    "(function(){var x=new Function();x.__proto__=[1,2,3];return x;})()": "['arguments', 'callee', 'caller', 'length', 'name']",
+// String objects
+    "new String('')": "['length']",
+    "new String('a')": "['0', 'length']",
+    "new String('abc')": "['0', '1', '2', 'length']",
+    "(function(){var x=new String('');x.__proto__=[1,2,3];return x;})()": "['length']",
+// Array objects
+    "[]": "['length']",
+    "[null]": "['0', 'length']",
+    "[null,null]": "['0','1', 'length']",
+    "[null,null,,,,null]": "['0','1','5', 'length']",
+    "(function(){var x=[];x.__proto__=[1,2,3];return x;})()": "['length']",
+// Date objects
+    "new Date()": "[]",
+    "(function(){var x=new Date();x.__proto__=[1,2,3];return x;})()": "[]",
+// RegExp objects
+    "new RegExp('foo')": "['global', 'ignoreCase', 'lastIndex', 'multiline', 'source']",
+    "(function(){var x=new RegExp();x.__proto__=[1,2,3];return x;})()": "['global', 'ignoreCase', 'lastIndex', 'multiline', 'source']",
+// Arguments objects
+     "argumentsObject()": "['callee', 'length']",
+     "argumentsObject(1)": "['0', 'callee', 'length']",
+     "argumentsObject(1,2,3)": "['0', '1', '2', 'callee', 'length']",
+    "(function(){arguments.__proto__=[1,2,3];return arguments;})()": "['callee', 'length']",
+// Built-in ECMA functions
+    "parseInt": "['length', 'name']",
+    "parseFloat": "['length', 'name']",
+    "isNaN": "['length', 'name']",
+    "isFinite": "['length', 'name']",
+    "escape": "['length', 'name']",
+    "unescape": "['length', 'name']",
+    "decodeURI": "['length', 'name']",
+    "decodeURIComponent": "['length', 'name']",
+    "encodeURI": "['length', 'name']",
+    "encodeURIComponent": "['length', 'name']",
+// Built-in ECMA objects
+    "Object": "['create', 'defineProperties', 'defineProperty', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getPrototypeOf', 'keys', 'length', 'name', 'prototype']",
+    "Object.prototype": "['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']",
+    "Function": "['length', 'name', 'prototype']",
+    "Function.prototype": "['apply', 'call', 'constructor', 'length', 'name', 'toString']",
+    "Array": "['isArray', 'length', 'name', 'prototype']",
+    "Array.prototype": "['concat', 'constructor', 'every', 'filter', 'forEach', 'indexOf', 'join', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']",
+    "String": "['fromCharCode', 'length', 'name', 'prototype']",
+    "String.prototype": "['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'replace', 'search', 'slice', 'small', 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']",
+    "Boolean": "['length', 'name', 'prototype']",
+    "Boolean.prototype": "['constructor', 'toString', 'valueOf']",
+    "Number": "['MAX_VALUE', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'length', 'name', 'prototype']",
+    "Number.prototype": "['constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf']",
+    "Date": "['UTC', 'length', 'name', 'now', 'parse', 'prototype']",
+    "Date.prototype": "['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf']",
+    "RegExp": "['$&', \"$'\", '$*', '$+', '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_', '$`', 'input', 'lastMatch', 'lastParen', 'leftContext', 'length', 'multiline', 'name', 'prototype', 'rightContext']",
+    "RegExp.prototype": "['compile', 'constructor', 'exec', 'test', 'toString']",
+    "Error": "['length', 'name', 'prototype']",
+    "Error.prototype": "['constructor', 'message', 'name', 'toString']",
+    "Math": "['E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2', 'abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan']",
+    "JSON": "['parse', 'stringify']"
+};
+
+function getSortedOwnPropertyNames(obj)
+{
+    return Object.getOwnPropertyNames(obj).sort();
+}
+
+for (var expr in expectedPropertyNamesSet)
+    shouldBe("getSortedOwnPropertyNames(" + expr + ")", expectedPropertyNamesSet[expr]);
+
+// Global Object
+// Only check for ECMA properties here
+var globalPropertyNames = Object.getOwnPropertyNames(this);
+var expectedGlobalPropertyNames = [
+    "NaN",
+    "Infinity",
+    "undefined",
+    "parseInt",
+    "parseFloat",
+    "isNaN",
+    "isFinite",
+    "escape",
+    "unescape",
+    "decodeURI",
+    "decodeURIComponent",
+    "encodeURI",
+    "encodeURIComponent",
+    "Object",
+    "Function",
+    "Array",
+    "String",
+    "Boolean",
+    "Number",
+    "Date",
+    "RegExp",
+    "Error",
+    "Math",
+    "JSON"
+];
+
+for (var i = 0; i < expectedGlobalPropertyNames.length; ++i)
+    shouldBeTrue("globalPropertyNames.indexOf('" + expectedGlobalPropertyNames[i] + "') != -1");
+
+var successfullyParsed = true;
index 26b4365..e972f36 100644 (file)
@@ -14,13 +14,22 @@ CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http
 
 CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-enumeration-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-enumeration.html. Domains, protocols and ports must match.
 
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-enumeration-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-enumeration.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-enumeration-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-enumeration.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://localhost:8000/security/resources/cross-frame-iframe-for-enumeration-test.html from frame with URL http://127.0.0.1:8000/security/cross-frame-access-enumeration.html. Domains, protocols and ports must match.
+
 This tests that variable names can't be enumerated cross domain (see http://bugs.webkit.org/show_bug.cgi?id=16387)
 
 
 PASS: Cross frame access by enumerating the window object was denied.
 PASS: Cross frame access by getting the keys of the window object was denied.
+PASS: Cross frame access by getting the property names of the window object was denied.
 PASS: Cross frame access by enumerating the History object was denied.
 PASS: Cross frame access by getting the keys of the History object was denied.
+PASS: Cross frame access by getting the property names of the History object was denied.
 PASS: Cross frame access by enumerating the Location object was denied.
 PASS: Cross frame access by getting the keys of the Location object was denied.
+PASS: Cross frame access by getting the property names of the Location object was denied.
 
index 707fff5..49bfcf6 100644 (file)
             }
             log("PASS: Cross frame access by getting the keys of the window object was denied.");
 
+            var b_winPropertyNames = Object.getOwnPropertyNames(b_win);
+            if (b_winPropertyNames.indexOf("customWindowProperty") != -1) {
+                log("FAIL: Cross frame access by getting the property names of the window object was allowed.");
+                return;
+            }
+            log("PASS: Cross frame access by getting the property names of the window object was denied.");
+
             // Test enumerating the History object
             var b_win_history = b_win.history;
             try {
             }
             log("PASS: Cross frame access by getting the keys of the History object was denied.");
 
+            var b_winHistoryPropertyNames = Object.getOwnPropertyNames(b_win_history);
+            if (b_winHistoryPropertyNames.indexOf("customHistoryProperty") != -1) {
+                log("FAIL: Cross frame access by getting the property names of the History object was allowed.");
+                return;
+            }
+            log("PASS: Cross frame access by getting the property names of the History object was denied.");
+
             // Test enumerating the Location object
             var b_win_location = b_win.location;
             try {
                 return;
             }
             log("PASS: Cross frame access by getting the keys of the Location object was denied.");
+
+            var b_winLocationPropertyNames = Object.getOwnPropertyNames(b_win_location);
+            if (b_winLocationPropertyNames.indexOf("customLocationProperty") != -1) {
+                log("FAIL: Cross frame access by getting the property names of the Location object was allowed.");
+                return;
+            }
+            log("PASS: Cross frame access by getting the property names of the Location object was denied.");
         }
     </script>
 </head>
index c89ae0d..1e1faf0 100644 (file)
@@ -1,3 +1,41 @@
+2010-01-12  Kent Hansen  <kent.hansen@nokia.com>
+
+        Reviewed by Geoffrey Garen.
+
+        [ES5] Implement Object.getOwnPropertyNames
+        https://bugs.webkit.org/show_bug.cgi?id=32242
+
+        Add new argument to reimplementations of getPropertyNames()
+        and getOwnPropertyNames(), and update the JS bindings generator.
+
+        Test: fast/js/Object-getOwnPropertyNames.html
+
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::JSDOMWindow::getPropertyNames):
+        (WebCore::JSDOMWindow::getOwnPropertyNames):
+        * bindings/js/JSDOMWindowShell.cpp:
+        (WebCore::JSDOMWindowShell::getPropertyNames):
+        (WebCore::JSDOMWindowShell::getOwnPropertyNames):
+        * bindings/js/JSDOMWindowShell.h:
+        * bindings/js/JSHistoryCustom.cpp:
+        (WebCore::JSHistory::getOwnPropertyNames):
+        * bindings/js/JSLocationCustom.cpp:
+        (WebCore::JSLocation::getOwnPropertyNames):
+        * bindings/js/JSQuarantinedObjectWrapper.cpp:
+        (WebCore::JSQuarantinedObjectWrapper::getPropertyNames):
+        (WebCore::JSQuarantinedObjectWrapper::getOwnPropertyNames):
+        * bindings/js/JSQuarantinedObjectWrapper.h:
+        * bindings/js/JSStorageCustom.cpp:
+        (WebCore::JSStorage::getOwnPropertyNames):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        * bridge/runtime_array.cpp:
+        (JSC::RuntimeArray::getOwnPropertyNames):
+        * bridge/runtime_array.h:
+        * bridge/runtime_object.cpp:
+        (JSC::RuntimeObjectImp::getPropertyNames):
+        (JSC::RuntimeObjectImp::getOwnPropertyNames):
+        * bridge/runtime_object.h:
+
 2010-01-12  Brian Weinstein  <bweinstein@apple.com>
 
         Reviewed by Dave Hyatt.
index b9f6d32..e6c3e91 100644 (file)
@@ -419,20 +419,20 @@ bool JSDOMWindow::deleteProperty(ExecState* exec, const Identifier& propertyName
     return Base::deleteProperty(exec, propertyName);
 }
 
-void JSDOMWindow::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSDOMWindow::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     // Only allow the window to enumerated by frames in the same origin.
     if (!allowsAccessFrom(exec))
         return;
-    Base::getPropertyNames(exec, propertyNames);
+    Base::getPropertyNames(exec, propertyNames, mode);
 }
 
-void JSDOMWindow::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSDOMWindow::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     // Only allow the window to enumerated by frames in the same origin.
     if (!allowsAccessFrom(exec))
         return;
-    Base::getOwnPropertyNames(exec, propertyNames);
+    Base::getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 void JSDOMWindow::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes)
index 09141ee..1e82a49 100644 (file)
@@ -114,14 +114,14 @@ bool JSDOMWindowShell::deleteProperty(ExecState* exec, const Identifier& propert
     return m_window->deleteProperty(exec, propertyName);
 }
 
-void JSDOMWindowShell::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSDOMWindowShell::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
-    m_window->getPropertyNames(exec, propertyNames);
+    m_window->getPropertyNames(exec, propertyNames, mode);
 }
 
-void JSDOMWindowShell::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSDOMWindowShell::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
-    m_window->getOwnPropertyNames(exec, propertyNames);
+    m_window->getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 void JSDOMWindowShell::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes)
index 27036d4..a895177 100644 (file)
@@ -75,8 +75,8 @@ namespace WebCore {
         virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
         virtual void putWithAttributes(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, unsigned attributes);
         virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier& propertyName);
-        virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
-        virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
+        virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);
+        virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);
         virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes);
         virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes);
         virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&, bool shouldThrow);
index 3076503..fff747f 100644 (file)
@@ -154,12 +154,12 @@ bool JSHistory::deleteProperty(ExecState* exec, const Identifier& propertyName)
     return Base::deleteProperty(exec, propertyName);
 }
 
-void JSHistory::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSHistory::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     // Only allow the history object to enumerated by frames in the same origin.
     if (!allowsAccessFromFrame(exec, impl()->frame()))
         return;
-    Base::getOwnPropertyNames(exec, propertyNames);
+    Base::getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 JSValue JSHistory::pushState(ExecState* exec, const ArgList& args)
index 6c8e032..78d00de 100644 (file)
@@ -168,12 +168,12 @@ bool JSLocation::deleteProperty(ExecState* exec, const Identifier& propertyName)
     return Base::deleteProperty(exec, propertyName);
 }
 
-void JSLocation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSLocation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     // Only allow the location object to enumerated by frames in the same origin.
     if (!allowsAccessFromFrame(exec, impl()->frame()))
         return;
-    Base::getOwnPropertyNames(exec, propertyNames);
+    Base::getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes)
index ea2f72f..d7797f1 100644 (file)
@@ -313,20 +313,20 @@ CallType JSQuarantinedObjectWrapper::getCallData(CallData& callData)
     return CallTypeHost;
 }
 
-void JSQuarantinedObjectWrapper::getPropertyNames(ExecState*, PropertyNameArray& array)
+void JSQuarantinedObjectWrapper::getPropertyNames(ExecState*, PropertyNameArray& array, EnumerationMode mode)
 {
     if (!allowsGetPropertyNames())
         return;
     
-    m_unwrappedObject->getPropertyNames(unwrappedExecState(), array);
+    m_unwrappedObject->getPropertyNames(unwrappedExecState(), array, mode);
 }
 
-void JSQuarantinedObjectWrapper::getOwnPropertyNames(ExecState*, PropertyNameArray& array)
+void JSQuarantinedObjectWrapper::getOwnPropertyNames(ExecState*, PropertyNameArray& array, EnumerationMode mode)
 {
     if (!allowsGetPropertyNames())
         return;
 
-    m_unwrappedObject->getOwnPropertyNames(unwrappedExecState(), array);
+    m_unwrappedObject->getOwnPropertyNames(unwrappedExecState(), array, mode);
 }
 
 } // namespace WebCore
index 9f62495..e423a2b 100644 (file)
@@ -74,8 +74,8 @@ namespace WebCore {
 
         virtual bool hasInstance(JSC::ExecState*, JSC::JSValue, JSC::JSValue proto);
         
-        virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
-        virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
+        virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);
+        virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);
 
         virtual JSC::UString className() const { return m_unwrappedObject->className(); }
 
index e416d35..3cfe22e 100644 (file)
@@ -64,13 +64,13 @@ bool JSStorage::deleteProperty(ExecState* exec, const Identifier& propertyName)
     return true;
 }
 
-void JSStorage::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSStorage::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     unsigned length = m_impl->length();
     for (unsigned i = 0; i < length; ++i)
         propertyNames.add(Identifier(exec, m_impl->key(i)));
         
-    Base::getOwnPropertyNames(exec, propertyNames);
+    Base::getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 bool JSStorage::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&)
index f7d0f09..cab34ed 100644 (file)
@@ -647,7 +647,7 @@ sub GenerateHeader
 
     # Custom getPropertyNames function exists on DOMWindow
     if ($interfaceName eq "DOMWindow") {
-        push(@headerContent, "    virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n");
+        push(@headerContent, "    virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);\n");
         $structureFlags{"JSC::OverridesGetPropertyNames"} = 1;
     }
 
@@ -656,7 +656,7 @@ sub GenerateHeader
 
     # Custom getOwnPropertyNames function
     if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) {
-        push(@headerContent, "    virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n");
+        push(@headerContent, "    virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);\n");
         $structureFlags{"JSC::OverridesGetPropertyNames"} = 1;       
     }
 
@@ -1538,13 +1538,13 @@ sub GenerateImplementation
     }
 
     if (($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) && !$dataNode->extendedAttributes->{"CustomGetPropertyNames"}) {
-        push(@implContent, "void ${className}::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)\n");
+        push(@implContent, "void ${className}::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)\n");
         push(@implContent, "{\n");
         if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) {
             push(@implContent, "    for (unsigned i = 0; i < static_cast<${implClassName}*>(impl())->length(); ++i)\n");
             push(@implContent, "        propertyNames.add(Identifier::from(exec, i));\n");
         }
-        push(@implContent, "     Base::getOwnPropertyNames(exec, propertyNames);\n");
+        push(@implContent, "     Base::getOwnPropertyNames(exec, propertyNames, mode);\n");
         push(@implContent, "}\n\n");
     }
 
index cb027bf..9e8da85 100644 (file)
@@ -57,13 +57,16 @@ JSValue RuntimeArray::indexGetter(ExecState* exec, const Identifier&, const Prop
     return thisObj->getConcreteArray()->valueAt(exec, slot.index());
 }
 
-void RuntimeArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void RuntimeArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     unsigned length = getLength();
     for (unsigned i = 0; i < length; ++i)
         propertyNames.add(Identifier::from(exec, i));
 
-    JSObject::getOwnPropertyNames(exec, propertyNames);
+    if (mode == IncludeDontEnumProperties)
+        propertyNames.add(exec->propertyNames().length);
+
+    JSObject::getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 bool RuntimeArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
index 99425ee..f77ef6d 100644 (file)
@@ -35,7 +35,7 @@ class RuntimeArray : public JSObject {
 public:
     RuntimeArray(ExecState*, Bindings::Array*);
 
-    virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
+    virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
     virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
     virtual bool getOwnPropertySlot(ExecState *, unsigned, PropertySlot&);
     virtual bool getOwnPropertyDescriptor(ExecState *, const Identifier&, PropertyDescriptor&);
index 9583fb2..9fc9f0c 100644 (file)
@@ -302,7 +302,7 @@ ConstructType RuntimeObjectImp::getConstructData(ConstructData& constructData)
     return ConstructTypeHost;
 }
 
-void RuntimeObjectImp::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void RuntimeObjectImp::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode)
 {
     if (!m_instance) {
         throwInvalidAccessError(exec);
@@ -316,9 +316,9 @@ void RuntimeObjectImp::getPropertyNames(ExecState* exec, PropertyNameArray& prop
     instance->end();
 }
 
-void RuntimeObjectImp::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void RuntimeObjectImp::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
-    getOwnPropertyNames(exec, propertyNames);
+    getOwnPropertyNames(exec, propertyNames, mode);
 }
 
 JSObject* RuntimeObjectImp::throwInvalidAccessError(ExecState* exec)
index 391e078..87c47bf 100644 (file)
@@ -44,8 +44,8 @@ public:
     virtual CallType getCallData(CallData&);
     virtual ConstructType getConstructData(ConstructData&);
 
-    virtual void getPropertyNames(ExecState*, PropertyNameArray&);
-    virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
+    virtual void getPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
+    virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
 
     void invalidate();