Changeset 48336 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Sep 12, 2009, 7:44:32 PM (16 years ago)
Author:
[email protected]
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/JavaScriptCore
Files:
23 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  <[email protected]>
     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  <[email protected]>
    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; }
Note: See TracChangeset for help on using the changeset viewer.