Changeset 48336 in webkit


Ignore:
Timestamp:
Sep 12, 2009 7:44:32 PM (15 years ago)
Author:
oliver@apple.com
Message:

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

Reviewed by Maciej Stachowiak.

This patch basically requires two separate steps, the first is to split getPropertyNames
into two functions -- getOwnPropertyNames and getPropertyNames, basically making them behave
in the same way as getOwnPropertySlot and getPropertySlot. In essence getOwnPropertyNames
produces the list of properties on an object excluding its prototype chain and getPropertyNames
just iterates the the object and its prototype chain calling getOwnPropertyNames at each level.

Location:
trunk
Files:
3 added
41 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/API/JSCallbackObject.h

    r43372 r48336  
    6767    virtual bool hasInstance(ExecState* exec, JSValue value, JSValue proto);
    6868
    69     virtual void getPropertyNames(ExecState*, PropertyNameArray&);
     69    virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
    7070
    7171    virtual double toNumber(ExecState*) const;
  • trunk/JavaScriptCore/API/JSCallbackObjectFunctions.h

    r46598 r48336  
    374374
    375375template <class Base>
    376 void JSCallbackObject<Base>::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     376void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    377377{
    378378    JSContextRef execRef = toRef(exec);
     
    408408    }
    409409   
    410     Base::getPropertyNames(exec, propertyNames);
     410    Base::getOwnPropertyNames(exec, propertyNames);
    411411}
    412412
  • trunk/JavaScriptCore/ChangeLog

    r48331 r48336  
     12009-09-12  Oliver Hunt  <oliver@apple.com>
     2
     3        Reviewed by Maciej Stachowiak.
     4
     5        [ES5] Implement Object.keys
     6        https://bugs.webkit.org/show_bug.cgi?id=29170
     7
     8        This patch basically requires two separate steps, the first is to split getPropertyNames
     9        into two functions -- getOwnPropertyNames and getPropertyNames, basically making them behave
     10        in the same way as getOwnPropertySlot and getPropertySlot.  In essence getOwnPropertyNames
     11        produces the list of properties on an object excluding its prototype chain and getPropertyNames
     12        just iterates the the object and its prototype chain calling getOwnPropertyNames at each level.
     13
     14        * API/JSCallbackObject.h:
     15        * API/JSCallbackObjectFunctions.h:
     16        (JSC::::getOwnPropertyNames):
     17        * JavaScriptCore.exp:
     18        * debugger/DebuggerActivation.cpp:
     19        (JSC::DebuggerActivation::getOwnPropertyNames):
     20        * debugger/DebuggerActivation.h:
     21        * runtime/CommonIdentifiers.h:
     22        * runtime/JSArray.cpp:
     23        (JSC::JSArray::getOwnPropertyNames):
     24        * runtime/JSArray.h:
     25        * runtime/JSByteArray.cpp:
     26        (JSC::JSByteArray::getOwnPropertyNames):
     27        * runtime/JSByteArray.h:
     28        * runtime/JSNotAnObject.cpp:
     29        (JSC::JSNotAnObject::getOwnPropertyNames):
     30        * runtime/JSNotAnObject.h:
     31        * runtime/JSObject.cpp:
     32        (JSC::JSObject::getOwnPropertyNames):
     33        * runtime/JSObject.h:
     34        * runtime/JSVariableObject.cpp:
     35        (JSC::JSVariableObject::getOwnPropertyNames):
     36        * runtime/JSVariableObject.h:
     37        * runtime/ObjectConstructor.cpp:
     38        (JSC::ObjectConstructor::ObjectConstructor):
     39        (JSC::objectConstructorKeys):
     40        * runtime/RegExpMatchesArray.h:
     41        (JSC::RegExpMatchesArray::getOwnPropertyNames):
     42        * runtime/StringObject.cpp:
     43        (JSC::StringObject::getOwnPropertyNames):
     44        * runtime/StringObject.h:
     45        * runtime/Structure.cpp:
     46        (JSC::Structure::getOwnEnumerablePropertyNames):
     47        (JSC::Structure::getEnumerablePropertyNames):
     48        * runtime/Structure.h:
     49
    1502009-09-11  Oliver Hunt  <oliver@apple.com>
    251
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r48270 r48336  
    114114__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
    115115__ZN3JSC12StringObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
    116 __ZN3JSC12StringObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
    117116__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
    118117__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
     118__ZN3JSC12StringObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
    119119__ZN3JSC12StringObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
    120120__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
     
    148148__ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
    149149__ZN3JSC16JSVariableObject14symbolTableGetERKNS_10IdentifierERNS_18PropertyDescriptorE
    150 __ZN3JSC16JSVariableObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
     150__ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
    151151__ZN3JSC16toUInt32SlowCaseEdRb
    152152__ZN3JSC17BytecodeGenerator21setDumpsGeneratedCodeEb
     
    251251__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
    252252__ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE
     253__ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
    253254__ZN3JSC8JSObject21getPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
    254255__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_7JSValueE 
  • trunk/JavaScriptCore/debugger/DebuggerActivation.cpp

    r47022 r48336  
    7272}
    7373
    74 void DebuggerActivation::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     74void DebuggerActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    7575{
    7676    m_activation->getPropertyNames(exec, propertyNames);
  • trunk/JavaScriptCore/debugger/DebuggerActivation.h

    r48331 r48336  
    4343        virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
    4444        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    45         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
     45        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
    4646        virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
    4747        virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction);
  • trunk/JavaScriptCore/runtime/CommonIdentifiers.h

    r47780 r48336  
    5454    macro(isArray) \
    5555    macro(isPrototypeOf) \
     56    macro(keys) \
    5657    macro(length) \
    5758    macro(message) \
  • trunk/JavaScriptCore/runtime/JSArray.cpp

    r47780 r48336  
    465465}
    466466
    467 void JSArray::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     467void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    468468{
    469469    // FIXME: Filling PropertyNameArray with an identifier for every integer
     
    485485    }
    486486
    487     JSObject::getPropertyNames(exec, propertyNames);
     487    JSObject::getOwnPropertyNames(exec, propertyNames);
    488488}
    489489
  • trunk/JavaScriptCore/runtime/JSArray.h

    r48068 r48336  
    9292        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    9393        virtual bool deleteProperty(ExecState*, unsigned propertyName);
    94         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
     94        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
    9595        virtual void markChildren(MarkStack&);
    9696
  • trunk/JavaScriptCore/runtime/JSByteArray.cpp

    r47780 r48336  
    9797}
    9898
    99 void JSByteArray::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     99void JSByteArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    100100{
    101101    unsigned length = m_storage->length();
    102102    for (unsigned i = 0; i < length; ++i)
    103103        propertyNames.add(Identifier::from(exec, i));
    104     JSObject::getPropertyNames(exec, propertyNames);
     104    JSObject::getOwnPropertyNames(exec, propertyNames);
    105105}
    106106
  • trunk/JavaScriptCore/runtime/JSByteArray.h

    r47780 r48336  
    8383        virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue);
    8484
    85         virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
     85        virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
    8686
    8787        virtual const ClassInfo* classInfo() const { return m_classInfo; }
  • trunk/JavaScriptCore/runtime/JSNotAnObject.cpp

    r47780 r48336  
    122122}
    123123
    124 void JSNotAnObject::getPropertyNames(ExecState* exec, PropertyNameArray&)
     124void JSNotAnObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray&)
    125125{
    126126    ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
  • trunk/JavaScriptCore/runtime/JSNotAnObject.h

    r47780 r48336  
    8989        virtual bool deleteProperty(ExecState*, unsigned propertyName);
    9090
    91         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
     91        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
    9292
    9393        JSNotAnObjectErrorStub* m_exception;
  • trunk/JavaScriptCore/runtime/JSObject.cpp

    r48068 r48336  
    428428}
    429429
     430void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     431{
     432    m_structure->getOwnEnumerablePropertyNames(exec, propertyNames, this);
     433}
     434
    430435bool JSObject::toBoolean(ExecState*) const
    431436{
  • trunk/JavaScriptCore/runtime/JSObject.h

    r48331 r48336  
    124124
    125125        virtual void getPropertyNames(ExecState*, PropertyNameArray&);
     126        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
    126127
    127128        virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
  • trunk/JavaScriptCore/runtime/JSVariableObject.cpp

    r47780 r48336  
    4343}
    4444
    45 void JSVariableObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     45void JSVariableObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    4646{
    4747    SymbolTable::const_iterator end = symbolTable().end();
     
    5151    }
    5252   
    53     JSObject::getPropertyNames(exec, propertyNames);
     53    JSObject::getOwnPropertyNames(exec, propertyNames);
    5454}
    5555
  • trunk/JavaScriptCore/runtime/JSVariableObject.h

    r48331 r48336  
    5050
    5151        virtual bool deleteProperty(ExecState*, const Identifier&);
    52         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
     52        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
    5353       
    5454        virtual bool isVariableObject() const;
  • trunk/JavaScriptCore/runtime/ObjectConstructor.cpp

    r47780 r48336  
    3535static JSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*, JSObject*, JSValue, const ArgList&);
    3636static JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*, JSObject*, JSValue, const ArgList&);
     37static JSValue JSC_HOST_CALL objectConstructorKeys(ExecState*, JSObject*, JSValue, const ArgList&);
    3738
    3839ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> structure, ObjectPrototype* objectPrototype, Structure* prototypeFunctionStructure)
     
    4748    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().getPrototypeOf, objectConstructorGetPrototypeOf), DontEnum);
    4849    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().getOwnPropertyDescriptor, objectConstructorGetOwnPropertyDescriptor), DontEnum);
     50    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().keys, objectConstructorKeys), DontEnum);
    4951}
    5052
     
    117119}
    118120
     121JSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec, JSObject*, JSValue, const ArgList& args)
     122{
     123    if (!args.at(0).isObject())
     124        return throwError(exec, TypeError, "Requested keys of a value that is not an object.");
     125    PropertyNameArray properties(exec);
     126    asObject(args.at(0))->getOwnPropertyNames(exec, properties);
     127    JSArray* keys = constructEmptyArray(exec);
     128    size_t numProperties = properties.size();
     129    for (size_t i = 0; i < numProperties; i++)
     130        keys->push(exec, jsOwnedString(exec, properties[i].ustring()));
     131    return keys;
     132}
     133
    119134} // namespace JSC
  • trunk/JavaScriptCore/runtime/RegExpMatchesArray.h

    r47780 r48336  
    8080        }
    8181
    82         virtual void getPropertyNames(ExecState* exec, PropertyNameArray& arr)
     82        virtual void getOwnPropertyNames(ExecState* exec, PropertyNameArray& arr)
    8383        {
    8484            if (lazyCreationData())
    8585                fillArrayInstance(exec);
    86             JSArray::getPropertyNames(exec, arr);
     86            JSArray::getOwnPropertyNames(exec, arr);
    8787        }
    8888
  • trunk/JavaScriptCore/runtime/StringObject.cpp

    r48083 r48336  
    8383}
    8484
    85 void StringObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     85void StringObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    8686{
    8787    int size = internalValue()->value().size();
    8888    for (int i = 0; i < size; ++i)
    8989        propertyNames.add(Identifier(exec, UString::from(i)));
    90     return JSObject::getPropertyNames(exec, propertyNames);
     90    return JSObject::getOwnPropertyNames(exec, propertyNames);
    9191}
    9292
  • trunk/JavaScriptCore/runtime/StringObject.h

    r48083 r48336  
    4040        virtual void put(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&);
    4141        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    42         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
     42        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
    4343
    4444        virtual const ClassInfo* classInfo() const { return &info; }
  • trunk/JavaScriptCore/runtime/Structure.cpp

    r48264 r48336  
    274274}
    275275
     276void Structure::getOwnEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
     277{
     278    getEnumerableNamesFromPropertyTable(propertyNames);
     279    getEnumerableNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames);
     280}
     281
    276282void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
    277283{
     
    286292    }
    287293
    288     getEnumerableNamesFromPropertyTable(propertyNames);
    289     getEnumerableNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames);
     294    baseObject->getOwnPropertyNames(exec, propertyNames);
    290295
    291296    if (m_prototype.isObject()) {
    292297        propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly.
    293         asObject(m_prototype)->getPropertyNames(exec, propertyNames);
     298        JSObject* prototype = asObject(m_prototype);
     299        while(1) {
     300            if (!prototype->structure()->typeInfo().hasDefaultGetPropertyNames()) {
     301                prototype->getPropertyNames(exec, propertyNames);
     302                break;
     303            }
     304            prototype->getOwnPropertyNames(exec, propertyNames);
     305            JSValue nextProto = prototype->prototype();
     306            if (!nextProto.isObject())
     307                break;
     308            prototype = asObject(nextProto);
     309        }
    294310    }
    295311
  • trunk/JavaScriptCore/runtime/Structure.h

    r48264 r48336  
    115115
    116116        void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
     117        void getOwnEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
    117118
    118119        bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
  • trunk/JavaScriptGlue/ChangeLog

    r48067 r48336  
     12009-09-12  Oliver Hunt  <oliver@apple.com>
     2
     3        Reviewed by Maciej Stachowiak.
     4
     5        [ES5] Implement Object.keys
     6        https://bugs.webkit.org/show_bug.cgi?id=29170
     7
     8        Switch over to getOwnPropertyNames instead of getPropertyNames.
     9
     10        * UserObjectImp.cpp:
     11        (UserObjectImp::getOwnPropertyNames):
     12        * UserObjectImp.h:
     13
    1142009-09-02  Darin Adler  <darin@apple.com>
    215
  • trunk/JavaScriptGlue/UserObjectImp.cpp

    r47022 r48336  
    9595
    9696
    97 void UserObjectImp::getPropertyNames(ExecState *exec, PropertyNameArray& propertyNames)
     97void UserObjectImp::getOwnPropertyNames(ExecState *exec, PropertyNameArray& propertyNames)
    9898{
    9999    JSUserObject* ptr = GetJSUserObject();
     
    110110        }
    111111    }
    112     JSObject::getPropertyNames(exec, propertyNames);
     112    JSObject::getOwnPropertyNames(exec, propertyNames);
    113113}
    114114
  • trunk/JavaScriptGlue/UserObjectImp.h

    r47022 r48336  
    4545    virtual CallType getCallData(CallData&);
    4646
    47     virtual void getPropertyNames(ExecState*, PropertyNameArray&);
     47    virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
    4848
    4949    virtual JSValue callAsFunction(ExecState *exec, JSObject *thisObj, const ArgList &args);
  • trunk/LayoutTests/ChangeLog

    r48334 r48336  
     12009-09-12  Oliver Hunt  <oliver@apple.com>
     2
     3        Reviewed by Maciej Stachowiak.
     4
     5        [ES5] Implement Object.keys
     6        https://bugs.webkit.org/show_bug.cgi?id=29170
     7
     8        Add tests for Object.keys(o), both standard usage and cross origin.
     9
     10        * fast/js/Object-keys-expected.txt: Added.
     11        * fast/js/Object-keys.html: Added.
     12        * fast/js/resources/Object-keys.js: Added.
     13        * http/tests/security/cross-frame-access-enumeration-expected.txt:
     14        * http/tests/security/cross-frame-access-enumeration.html:
     15
    1162009-09-12  Sam Weinig  <sam@webkit.org>
    217
  • trunk/LayoutTests/http/tests/security/cross-frame-access-enumeration-expected.txt

    r34142 r48336  
     1CONSOLE 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.
     2
     3CONSOLE 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.
     4
     5CONSOLE 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.
     6
    17CONSOLE 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.
    28
     
    915
    1016PASS: Cross frame access by enumerating the window object was denied.
     17PASS: Cross frame access by getting the keys of the window object was denied.
    1118PASS: Cross frame access by enumerating the History object was denied.
     19PASS: Cross frame access by getting the keys of the History object was denied.
    1220PASS: Cross frame access by enumerating the Location object was denied.
     21PASS: Cross frame access by getting the keys of the Location object was denied.
    1322
  • trunk/LayoutTests/http/tests/security/cross-frame-access-enumeration.html

    r34142 r48336  
    4646            log("PASS: Cross frame access by enumerating the window object was denied.");
    4747
     48            var b_winKeys = Object.keys(b_win);
     49            if (b_winKeys.indexOf("customWindowProperty") != -1) {
     50                log("FAIL: Cross frame access by getting the keys of the window object was allowed.");
     51                return;
     52            }
     53            log("PASS: Cross frame access by getting the keys of the window object was denied.");
     54
    4855            // Test enumerating the History object
    4956            var b_win_history = b_win.history;
     
    5966            log("PASS: Cross frame access by enumerating the History object was denied.");
    6067
     68            var b_winHistoryKeys = Object.keys(b_win_history);
     69            if (b_winHistoryKeys.indexOf("customHistoryProperty") != -1) {
     70                log("FAIL: Cross frame access by getting the keys of the History object was allowed.");
     71                return;
     72            }
     73            log("PASS: Cross frame access by getting the keys of the History object was denied.");
     74
    6175            // Test enumerating the Location object
    6276            var b_win_location = b_win.location;
     
    7185            }
    7286            log("PASS: Cross frame access by enumerating the Location object was denied.");
     87
     88            var b_winLocationKeys = Object.keys(b_win_location);
     89            if (b_winLocationKeys.indexOf("customLocationProperty") != -1) {
     90                log("FAIL: Cross frame access by getting the keys of the Location object was allowed.");
     91                return;
     92            }
     93            log("PASS: Cross frame access by getting the keys of the Location object was denied.");
    7394        }
    7495    </script>
  • trunk/WebCore/ChangeLog

    r48334 r48336  
     12009-09-12  Oliver Hunt  <oliver@apple.com>
     2
     3        Reviewed by Maciej Stachowiak.
     4
     5        [ES5] Implement Object.keys
     6        https://bugs.webkit.org/show_bug.cgi?id=29170
     7
     8        Switch from getPropertyNames to getOwnPropertyNames, and provide custom
     9        getPropertyNames to DOMWindow, DOMWindowShell and QuarantinedObjectWrapper
     10        in order to ensure correct semantics are maintained.
     11
     12        Test: fast/js/Object-keys.html
     13
     14        * bindings/js/JSDOMWindowCustom.cpp:
     15        (WebCore::JSDOMWindow::getOwnPropertyNames):
     16        * bindings/js/JSDOMWindowShell.cpp:
     17        (WebCore::JSDOMWindowShell::getOwnPropertyNames):
     18        * bindings/js/JSDOMWindowShell.h:
     19        * bindings/js/JSHistoryCustom.cpp:
     20        (WebCore::JSHistory::getOwnPropertyNames):
     21        * bindings/js/JSLocationCustom.cpp:
     22        (WebCore::JSLocation::getOwnPropertyNames):
     23        * bindings/js/JSQuarantinedObjectWrapper.cpp:
     24        (WebCore::JSQuarantinedObjectWrapper::getPropertyNames):
     25        (WebCore::JSQuarantinedObjectWrapper::getOwnPropertyNames):
     26        * bindings/js/JSQuarantinedObjectWrapper.h:
     27        * bindings/js/JSStorageCustom.cpp:
     28        (WebCore::JSStorage::getOwnPropertyNames):
     29        * bindings/scripts/CodeGeneratorJS.pm:
     30        * bridge/runtime_object.cpp:
     31        (JSC::RuntimeObjectImp::getPropertyNames):
     32        (JSC::RuntimeObjectImp::getOwnPropertyNames):
     33        * bridge/runtime_object.h:
     34
    1352009-09-12  Sam Weinig  <sam@webkit.org>
    236
  • trunk/WebCore/bindings/js/JSDOMWindowCustom.cpp

    r48270 r48336  
    473473}
    474474
     475void JSDOMWindow::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     476{
     477    // Only allow the window to enumerated by frames in the same origin.
     478    if (!allowsAccessFrom(exec))
     479        return;
     480    Base::getOwnPropertyNames(exec, propertyNames);
     481}
     482
    475483bool JSDOMWindow::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
    476484{
  • trunk/WebCore/bindings/js/JSDOMWindowShell.cpp

    r47780 r48336  
    114114}
    115115
     116void JSDOMWindowShell::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     117{
     118    m_window->getOwnPropertyNames(exec, propertyNames);
     119}
     120
    116121bool JSDOMWindowShell::getPropertyAttributes(JSC::ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
    117122{
  • trunk/WebCore/bindings/js/JSDOMWindowShell.h

    r47780 r48336  
    7373        virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier& propertyName);
    7474        virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
     75        virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
    7576        virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier& propertyName, unsigned& attributes) const;
    7677        virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction);
  • trunk/WebCore/bindings/js/JSHistoryCustom.cpp

    r47780 r48336  
    156156}
    157157
    158 void JSHistory::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     158void JSHistory::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    159159{
    160160    // Only allow the history object to enumerated by frames in the same origin.
    161161    if (!allowsAccessFromFrame(exec, impl()->frame()))
    162162        return;
    163     Base::getPropertyNames(exec, propertyNames);
     163    Base::getOwnPropertyNames(exec, propertyNames);
    164164}
    165165
  • trunk/WebCore/bindings/js/JSLocationCustom.cpp

    r47780 r48336  
    175175}
    176176
    177 void JSLocation::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     177void JSLocation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    178178{
    179179    // Only allow the location object to enumerated by frames in the same origin.
    180180    if (!allowsAccessFromFrame(exec, impl()->frame()))
    181181        return;
    182     Base::getPropertyNames(exec, propertyNames);
     182    Base::getOwnPropertyNames(exec, propertyNames);
    183183}
    184184
  • trunk/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp

    r47780 r48336  
    291291    if (!allowsGetPropertyNames())
    292292        return;
    293 
     293   
    294294    m_unwrappedObject->getPropertyNames(unwrappedExecState(), array);
    295295}
    296296
     297void JSQuarantinedObjectWrapper::getOwnPropertyNames(ExecState*, PropertyNameArray& array)
     298{
     299    if (!allowsGetPropertyNames())
     300        return;
     301
     302    m_unwrappedObject->getOwnPropertyNames(unwrappedExecState(), array);
     303}
     304
    297305} // namespace WebCore
  • trunk/WebCore/bindings/js/JSQuarantinedObjectWrapper.h

    r47780 r48336  
    7171
    7272        virtual bool hasInstance(JSC::ExecState*, JSC::JSValue, JSC::JSValue proto);
    73 
     73       
    7474        virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
     75        virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
    7576
    7677        virtual JSC::UString className() const { return m_unwrappedObject->className(); }
  • trunk/WebCore/bindings/js/JSStorageCustom.cpp

    r47020 r48336  
    6565}
    6666
    67 void JSStorage::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     67void JSStorage::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    6868{
    6969    unsigned length = m_impl->length();
     
    7171        propertyNames.add(Identifier(exec, m_impl->key(i)));
    7272       
    73     Base::getPropertyNames(exec, propertyNames);
     73    Base::getOwnPropertyNames(exec, propertyNames);
    7474}
    7575
  • trunk/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r48266 r48336  
    626626    push(@headerContent, "    virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier&);\n") if $dataNode->extendedAttributes->{"CustomDeleteProperty"};
    627627
    628     # Custom getPropertyNames function
    629     push(@headerContent, "    virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n") if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"});
     628    # Custom getPropertyNames function exists on DOMWindow
     629    push(@headerContent, "    virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n") if $interfaceName eq "DOMWindow";
     630    # Custom getOwnPropertyNames function
     631    push(@headerContent, "    virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n") if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"});   
    630632
    631633    # Custom getPropertyAttributes function
     
    14871489
    14881490    if (($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) && !$dataNode->extendedAttributes->{"CustomGetPropertyNames"}) {
    1489         push(@implContent, "void ${className}::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)\n");
     1491        push(@implContent, "void ${className}::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)\n");
    14901492        push(@implContent, "{\n");
    14911493        if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}) {
     
    14931495            push(@implContent, "        propertyNames.add(Identifier::from(exec, i));\n");
    14941496        }
    1495         push(@implContent, "     Base::getPropertyNames(exec, propertyNames);\n");
     1497        push(@implContent, "     Base::getOwnPropertyNames(exec, propertyNames);\n");
    14961498        push(@implContent, "}\n\n");
    14971499    }
  • trunk/WebCore/bridge/runtime_object.cpp

    r47780 r48336  
    296296        return;
    297297    }
    298    
     298
    299299    instance->begin();
    300300    instance->getPropertyNames(exec, propertyNames);
     
    302302}
    303303
     304void RuntimeObjectImp::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     305{
     306    getOwnPropertyNames(exec, propertyNames);
     307}
     308
    304309JSObject* RuntimeObjectImp::throwInvalidAccessError(ExecState* exec)
    305310{
  • trunk/WebCore/bridge/runtime_object.h

    r47780 r48336  
    4545    virtual CallType getCallData(CallData&);
    4646    virtual ConstructType getConstructData(ConstructData&);
    47    
     47
    4848    virtual void getPropertyNames(ExecState*, PropertyNameArray&);
     49    virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
    4950
    5051    virtual void invalidate();
Note: See TracChangeset for help on using the changeset viewer.