Commit c293f4c8 authored by eric@webkit.org's avatar eric@webkit.org

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  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: http://svn.webkit.org/repository/webkit/trunk@53170 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 80be9e72
......@@ -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;
......
......@@ -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>
......
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.
......
......@@ -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
......
......@@ -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
......
......@@ -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)
......
......@@ -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);
......
......@@ -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])) {
......
......@@ -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);
......
......@@ -50,6 +50,7 @@
macro(get) \
macro(getPrototypeOf) \
macro(getOwnPropertyDescriptor) \
macro(getOwnPropertyNames) \
macro(hasOwnProperty) \
macro(ignoreCase) \
macro(index) \
......
......@@ -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)
......
......@@ -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();
......
......@@ -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);
}
}
......
......@@ -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;
......
......@@ -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()) {
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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;
};
......
......@@ -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
......
......@@ -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);
......
......@@ -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
......
......@@ -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;
......
......@@ -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);
......@@ -125,6 +127,20 @@ JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec,
return description;
}
// 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)
{
......
......@@ -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*);
......
......@@ -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
......@@ -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;
......
......@@ -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];
}
......
......@@ -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&);
......
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.
......
......@@ -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)
......
......@@ -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&);
......
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.
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']