Changeset 15468 in webkit for trunk/JavaScriptCore/API


Ignore:
Timestamp:
Jul 16, 2006, 2:06:28 PM (19 years ago)
Author:
mjs
Message:

JavaScriptCore:

Reviewed by Darin.


  • switch property lists to be vector+set of Identifiers instead of list of References


This has the following benefits:


  • no duplicates in property lists
  • simplifies API calls
  • probably more efficient, since linked list is gone
  • entirely removed Reference, ReferenceList and ProtectedReference types from the API
  • kjs/PropertyNameArray.cpp: Added. (KJS::PropertyNameArray::add): Check set, if not already there, add to vector.
  • kjs/PropertyNameArray.h: Added. (KJS::PropertyNameArray::PropertyNameArray): Newly added type, combines a set and a vector to make a unique but ordered list of identifiers. (KJS::PropertyNameArray::begin): ditto (KJS::PropertyNameArray::end): ditto (KJS::PropertyNameArray::size): ditto (KJS::PropertyNameArray::operator[]): ditto
  • kjs/array_instance.h:
  • kjs/array_object.cpp: (ArrayInstance::getPropertyNames): renamed from getPropertyList, updated for PropertyNameArray (ArrayInstance::setLength): updated for PropertyNameArray (ArrayInstance::pushUndefinedObjectsToEnd): ditto
  • kjs/nodes.cpp: (ForInNode::execute): updated for PropertyNameArray
  • kjs/nodes.h:
  • kjs/object.cpp: (KJS::JSObject::getPropertyNames): renamed from getPropertyList, updated for PropertyNameArray
  • kjs/object.h:
  • kjs/property_map.cpp: (KJS::PropertyMap::getEnumerablePropertyNames): updated for PropertyNameArray (KJS::PropertyMap::getSparseArrayPropertyNames): ditto
  • kjs/property_map.h:
  • kjs/protected_reference.h: Removed.
  • kjs/reference.cpp: Removed.
  • kjs/reference.h: Removed.
  • kjs/reference_list.cpp: Removed.
  • kjs/reference_list.h: Removed.
  • kjs/scope_chain.cpp: (KJS::ScopeChain::print): Use PropertyNamesArray instead of ReferenceList.
  • kjs/string_object.cpp: (StringInstance::getPropertyNames): Updated for new approach.
  • kjs/string_object.h:
  • kjs/ustring.h:
  • API/APICast.h: (toJS): Added overload for PropertyNameAccumulatorRef / PropertyNameArray* (toRef): ditto
  • API/JSBase.h:
  • API/JSCallbackObject.cpp: (KJS::JSCallbackObject::getPropertyNames): Fixed for new API.
  • API/JSCallbackObject.h:
  • API/JSObjectRef.cpp: (JSPropertyNameArray::JSPropertyNameArray): Type used for a publicly vended JSPropertyNameArrayRef. (JSObjectCopyPropertyNames): New API call - renamed / refactored from JSObjectCreatePropertyList (JSPropertyNameArrayRetain): new retain call for JSPropertyNameArray. (JSPropertyNameArrayRelease): new release call for - " -. (JSPropertyNameArrayGetCount): Instead of having to use a stateful enumerator you can now get the count and items in any order. (JSPropertyNameArrayGetNameAtIndex): See above. (JSPropertyNameAccumulatorAddName): What you add properties to is now an opaque accumulator object.
  • API/JSObjectRef.h: Prototyped new functions, removed old ones
  • JavaScriptCore.exp: Updated exported symbols.
  • JavaScriptCore.xcodeproj/project.pbxproj: Added new files, removed old.
  • API/testapi.c: (MyObject_getPropertyNames): Renamed / fixed callback to fit new paradigm. (main): Updated for new API.

JavaScriptGlue:

Reviewed by Darin.

  • switch property lists to be vector+set of Identifiers instead of list of References


  • JSUtils.cpp: (KJSValueToCFTypeInternal): updated for JSC SPI changes
  • JSValueWrapper.cpp: (JSValueWrapper::JSObjectCopyPropertyNames): ditto
  • UserObjectImp.cpp: (UserObjectImp::getPropertyNames): ditto
  • UserObjectImp.h:

LayoutTests:

Reviewed by Darin.


  • new test case and updated results for property list changes
  • fast/js/for-in-avoid-duplicates-expected.txt: Added.
  • fast/js/for-in-avoid-duplicates.html: Added.
  • fast/js/kde/Array-expected.txt:
  • fast/js/resources/for-in-avoid-duplicates.js: Added.
Location:
trunk/JavaScriptCore/API
Files:
9 edited

Legend:

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

    r15437 r15468  
    3535    class JSValue;
    3636    class JSObject;
    37     class ReferenceList;
     37    class PropertyNameArray;
    3838}
    3939
     
    6565}
    6666
    67 inline KJS::ReferenceList* toJS(JSPropertyListRef l)
     67inline KJS::PropertyNameArray* toJS(JSPropertyNameAccumulatorRef a)
    6868{
    69     return reinterpret_cast<KJS::ReferenceList*>(l);
     69    return reinterpret_cast<KJS::PropertyNameArray*>(a);
    7070}
    7171
     
    9595}
    9696
    97 inline JSPropertyListRef toRef(KJS::ReferenceList* l)
    98 {
    99     return reinterpret_cast<JSPropertyListRef>(l);
    100 }
    101 
    10297inline JSContextRef toRef(KJS::ExecState* e)
    10398{
     
    105100}
    106101
     102inline JSPropertyNameAccumulatorRef toRef(KJS::PropertyNameArray* l)
     103{
     104    return reinterpret_cast<JSPropertyNameAccumulatorRef>(l);
     105}
     106
    107107#endif // APICast_h
  • trunk/JavaScriptCore/API/JSBase.h

    r15437 r15468  
    4444typedef struct __JSClass* JSClassRef;
    4545
    46 /*! @typedef JSPropertyListRef A JavaScript property list. Used for listing the properties in an object so they can be enumerated. */
    47 typedef struct __JSPropertyList* JSPropertyListRef;
     46/*! @typedef JSPropertyNameArrayRef An array of JavaScript property names. */
     47typedef struct __JSPropertyNameArray* JSPropertyNameArrayRef;
    4848
    49 /*! @typedef JSPropertyEnumeratorRef A JavaScript property enumerator. Used for enumerating the properties in an object. */
    50 typedef struct __JSPropertyEnumerator* JSPropertyEnumeratorRef;
     49/*! @typedef JSPropertyNameAccumulatorRef A data type used to collect a JavaScript object's property names. */
     50typedef struct __JSPropertyNameAccumulator* JSPropertyNameAccumulatorRef;
    5151
    5252
  • trunk/JavaScriptCore/API/JSCallbackObject.cpp

    r15462 r15468  
    3131#include "JSObjectRef.h"
    3232#include "internal.h"
    33 #include "reference.h"
    34 #include "reference_list.h"
     33#include "PropertyNameArray.h"
    3534
    3635namespace KJS {
     
    291290}
    292291
    293 void JSCallbackObject::getPropertyList(ReferenceList& propertyList, bool recursive)
    294 {
    295     JSObjectRef thisRef = toRef(this);
    296 
    297     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
    298         if (JSObjectAddPropertiesToListCallback addPropertiesToList = jsClass->addPropertiesToList)
    299             addPropertiesToList(thisRef, toRef(&propertyList));
     292void JSCallbackObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
     293{
     294    JSContextRef execRef = toRef(exec);
     295    JSObjectRef thisRef = toRef(this);
     296
     297    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
     298        if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames)
     299            getPropertyNames(execRef, thisRef, toRef(&propertyNames));
    300300
    301301        if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
     
    306306                StaticValueEntry* entry = it->second;
    307307                if (entry->getProperty && !(entry->attributes & kJSPropertyAttributeDontEnum))
    308                     propertyList.append(Reference(this, Identifier(name)));
     308                    propertyNames.add(Identifier(name));
    309309            }
    310310        }
     
    317317                StaticFunctionEntry* entry = it->second;
    318318                if (!(entry->attributes & kJSPropertyAttributeDontEnum))
    319                     propertyList.append(Reference(this, Identifier(name)));
    320             }
    321         }
    322     }
    323 
    324     JSObject::getPropertyList(propertyList, recursive);
     319                    propertyNames.add(Identifier(name));
     320            }
     321        }
     322    }
     323
     324    JSObject::getPropertyNames(exec, propertyNames);
    325325}
    326326
  • trunk/JavaScriptCore/API/JSCallbackObject.h

    r15443 r15468  
    6161    virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List &args);
    6262
    63     virtual void getPropertyList(ReferenceList& propertyList, bool recursive);
     63    virtual void getPropertyNames(ExecState*, PropertyNameArray&);
    6464
    6565    virtual double toNumber(ExecState*) const;
  • trunk/JavaScriptCore/API/JSClassRef.cpp

    r15462 r15468  
    4545    , setProperty(definition->setProperty)
    4646    , deleteProperty(definition->deleteProperty)
    47     , addPropertiesToList(definition->addPropertiesToList)
     47    , getPropertyNames(definition->getPropertyNames)
    4848    , callAsFunction(definition->callAsFunction)
    4949    , callAsConstructor(definition->callAsConstructor)
  • trunk/JavaScriptCore/API/JSClassRef.h

    r15462 r15468  
    7474    JSObjectSetPropertyCallback setProperty;
    7575    JSObjectDeletePropertyCallback deleteProperty;
    76     JSObjectAddPropertiesToListCallback addPropertiesToList;
     76    JSObjectGetPropertyNamesCallback getPropertyNames;
    7777    JSObjectCallAsFunctionCallback callAsFunction;
    7878    JSObjectCallAsConstructorCallback callAsConstructor;
  • trunk/JavaScriptCore/API/JSObjectRef.cpp

    r15465 r15468  
    3838#include "internal.h"
    3939#include "object.h"
    40 #include "reference_list.h"
     40#include "PropertyNameArray.h"
    4141
    4242using namespace KJS;
     
    307307}
    308308
    309 struct __JSPropertyEnumerator
    310 {
    311     __JSPropertyEnumerator() : refCount(0), iterator(list.end())
     309struct __JSPropertyNameArray
     310{
     311    __JSPropertyNameArray() : refCount(0)
    312312    {
    313313    }
    314314   
    315315    unsigned refCount;
    316     ReferenceList list;
    317     ReferenceListIterator iterator;
     316    PropertyNameArray array;
    318317};
    319318
    320 JSPropertyEnumeratorRef JSObjectCreatePropertyEnumerator(JSObjectRef object)
    321 {
    322     JSLock lock;
    323     JSObject* jsObject = toJS(object);
    324    
    325     JSPropertyEnumeratorRef enumerator = new __JSPropertyEnumerator();
    326     jsObject->getPropertyList(enumerator->list);
    327     enumerator->iterator = enumerator->list.begin();
    328    
    329     return JSPropertyEnumeratorRetain(enumerator);
    330 }
    331 
    332 JSStringRef JSPropertyEnumeratorGetNextName(JSPropertyEnumeratorRef enumerator)
    333 {
    334     ReferenceListIterator& iterator = enumerator->iterator;
    335     if (iterator != enumerator->list.end()) {
    336         JSStringRef result = toRef(iterator->getPropertyName().ustring().rep());
    337         iterator++;
    338         return result;
    339     }
    340     return 0;
    341 }
    342 
    343 JSPropertyEnumeratorRef JSPropertyEnumeratorRetain(JSPropertyEnumeratorRef enumerator)
    344 {
    345     ++enumerator->refCount;
    346     return enumerator;
    347 }
    348 
    349 void JSPropertyEnumeratorRelease(JSPropertyEnumeratorRef enumerator)
    350 {
    351     if (--enumerator->refCount == 0)
    352         delete enumerator;
    353 }
    354 
    355 void JSPropertyListAdd(JSPropertyListRef propertyList, JSObjectRef thisObject, JSStringRef propertyName)
    356 {
    357     JSLock lock;
    358     ReferenceList* jsPropertyList = toJS(propertyList);
    359     JSObject* jsObject = toJS(thisObject);
     319JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef context, JSObjectRef object)
     320{
     321    JSLock lock;
     322    JSObject* jsObject = toJS(object);
     323    ExecState* exec = toJS(context);
     324   
     325    JSPropertyNameArrayRef propertyNames = new __JSPropertyNameArray();
     326    jsObject->getPropertyNames(exec, propertyNames->array);
     327   
     328    return JSPropertyNameArrayRetain(propertyNames);
     329}
     330
     331JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array)
     332{
     333    ++array->refCount;
     334    return array;
     335}
     336
     337void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array)
     338{
     339    if (--array->refCount == 0)
     340        delete array;
     341}
     342
     343size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array)
     344{
     345    return array->array.size();
     346}
     347
     348JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index)
     349{
     350    return toRef(array->array[index].ustring().rep());
     351}
     352
     353void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array, JSStringRef propertyName)
     354{
     355    JSLock lock;
     356    PropertyNameArray* propertyNames = toJS(array);
    360357    UString::Rep* rep = toJS(propertyName);
    361358   
    362     jsPropertyList->append(Reference(jsObject, Identifier(rep)));
    363 }
     359    propertyNames->add(Identifier(rep));
     360}
  • trunk/JavaScriptCore/API/JSObjectRef.h

    r15464 r15468  
    155155
    156156/*!
    157 @typedef JSObjectAddPropertiesToListCallback
    158 @abstract The callback invoked when adding an object's properties to a property list.
    159 @param object The JSObject whose properties need to be added to propertyList.
    160 @param propertyList A JavaScript property list that will be used to enumerate object's properties.
    161 @discussion If you named your function GetPropertyList, you would declare it like this:
    162 
    163 void AddPropertiesToList(JSObjectRef object, JSPropertyListRef propertyList);
    164 
    165 Use JSPropertyListAdd to add properties to propertyList.
    166 
    167 Property lists are used by JSPropertyEnumerators and JavaScript for...in loops.
     157@typedef JSObjectGetPropertyNamesCallback
     158@abstract The callback invoked to get the names of an object's properties.
     159@param context The current execution context.
     160@param object The JSObject whose property names need to be appended to propertyNames.
     161@param accumulator A JavaScript property name accumulator, to which the object should add the names of its properties.
     162@discussion If you named your function GetPropertyNames, you would declare it like this:
     163
     164void GetPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef accumulator);
     165
     166Use JSPropertyNameAccumulatorAddName to add property names to accumulator.
     167
     168Property lists are used by JSPropertyEnumerators and JavaScript for...in loops.
     169
     170It's only necessary to add names of properties that you handle
     171specially in your own get / set callbacks. Static property names,
     172names of standard JS properties, and properties from the prototype
     173will be added automatically.
    168174*/
    169175typedef void
    170 (*JSObjectAddPropertiesToListCallback) (JSObjectRef object, JSPropertyListRef propertyList);
     176(*JSObjectGetPropertyNamesCallback) (JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames);
    171177
    172178/*!
     
    327333    JSObjectSetPropertyCallback         setProperty;
    328334    JSObjectDeletePropertyCallback      deleteProperty;
    329     JSObjectAddPropertiesToListCallback addPropertiesToList;
     335    JSObjectGetPropertyNamesCallback    getPropertyNames;
    330336    JSObjectCallAsFunctionCallback      callAsFunction;
    331337    JSObjectCallAsConstructorCallback   callAsConstructor;
     
    486492@param propertyIndex The property's name as a number
    487493@param value A JSValue to use as the property's value.
    488 @param attributes A logically ORed set of JSPropertyAttributes to give to the property.
    489494@discussion This is equivalent to setting a property by a string name containing the number, but allows faster access to JS arrays.
    490495*/
    491 void JSObjectSetPropertyAtIndex(JSContextRef context, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSPropertyAttributes attributes);
     496void JSObjectSetPropertyAtIndex(JSContextRef context, JSObjectRef object, unsigned propertyIndex, JSValueRef value);
    492497
    493498/*!
     
    550555/*!
    551556@function
    552 @abstract Creates an enumerator for an object's properties.
    553 @param object The object whose properties you want to enumerate.
    554 @result A JSPropertyEnumerator with a list of object's properties. Ownership follows the Create Rule.
    555 */
    556 JSPropertyEnumeratorRef JSObjectCreatePropertyEnumerator(JSObjectRef object);
    557 /*!
    558 @function
    559 @abstract Retains a property enumerator.
    560 @param enumerator The JSPropertyEnumerator to retain.
    561 @result A JSPropertyEnumerator that is the same as enumerator.
    562 */
    563 JSPropertyEnumeratorRef JSPropertyEnumeratorRetain(JSPropertyEnumeratorRef enumerator);
    564 /*!
    565 @function
    566 @abstract Releases a property enumerator.
    567 @param enumerator The JSPropertyEnumerator to release.
    568 */
    569 void JSPropertyEnumeratorRelease(JSPropertyEnumeratorRef enumerator);
    570 /*!
    571 @function
    572 @abstract Gets a property enumerator's next property.
    573 @param enumerator The JSPropertyEnumerator whose next property you want to get.
    574 @result A JSString containing the property's name, or NULL if all properties have been enumerated.
    575 */
    576 JSStringRef JSPropertyEnumeratorGetNextName(JSPropertyEnumeratorRef enumerator);
    577 
    578 /*!
    579 @function
    580 @abstract Adds a property to a property list.
    581 @discussion Use this method inside a JSObjectAddPropertiesToListCallback to add a property to an object's property list.
    582 @param propertyList The JSPropertyList to which you want to add a property.
    583 @param thisObject The JSObject to which the property belongs.
    584 @param propertyName A JSString specifying the property's name.
    585 */
    586 void JSPropertyListAdd(JSPropertyListRef propertyList, JSObjectRef thisObject, JSStringRef propertyName);
     557@abstract Get the names of all enumerable properties of an object.
     558@param context The execution context to use.
     559@param object The object from which to get property names.
     560@result A JSPropertyNameArray containing the names of all the object's enumerable properties.
     561*/
     562JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef context, JSObjectRef object);
     563
     564/*!
     565@function
     566@abstract         Retains a JavaScript property name array.
     567@param array      The JSPropertyNameArray to retain.
     568@result           A JSPropertyNameArray that is the same as array.
     569*/
     570JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array);
     571
     572/*!
     573@function
     574@abstract         Releases a JavaScript property name array.
     575@param array      The JSPropetyNameArray to release.
     576*/
     577void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array);
     578
     579/*!
     580@function
     581@abstract      Get the number of items in a JavaScript property name array.
     582@param array   The array from which to retrieve the count.
     583@result        The count of items in the array.
     584*/
     585size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array);
     586
     587/*!
     588@function
     589@abstract      Get a single item from a JavaScript property name array.
     590@param array   The array from which to retrieve a property name.
     591@param index   The index of the property name to retrieve.
     592@result        A JSStringRef containing the name of the property.
     593*/
     594JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index);
     595
     596/*!
     597@function
     598@abstract           Add a property name - useful while getting the property names for an object.
     599@param accumulator  The accumulator object to which to add the property.
     600@param propertyName The new property to add.
     601*/
     602void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef accumulator, JSStringRef propertyName);
    587603
    588604#ifdef __cplusplus
  • trunk/JavaScriptCore/API/testapi.c

    r15465 r15468  
    170170}
    171171
    172 static void MyObject_addPropertiesToList(JSObjectRef object, JSPropertyListRef propertyList)
     172static void MyObject_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames)
    173173{
    174174    UNUSED_PARAM(context);
     
    177177   
    178178    propertyName = JSStringCreateWithUTF8CString("alwaysOne");
    179     JSPropertyListAdd(propertyList, object, propertyName);
     179    JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
    180180    JSStringRelease(propertyName);
    181181   
    182182    propertyName = JSStringCreateWithUTF8CString("myPropertyName");
    183     JSPropertyListAdd(propertyList, object, propertyName);
     183    JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
    184184    JSStringRelease(propertyName);
    185185}
     
    258258    MyObject_setProperty,
    259259    MyObject_deleteProperty,
    260     MyObject_addPropertiesToList,
     260    MyObject_getPropertyNames,
    261261    MyObject_callAsFunction,
    262262    MyObject_callAsConstructor,
     
    589589    JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(1), kJSPropertyAttributeNone, NULL);
    590590    JSObjectSetProperty(context, o, jsCFIString,  JSValueMakeNumber(1), kJSPropertyAttributeDontEnum, NULL);
    591     JSPropertyEnumeratorRef enumerator = JSObjectCreatePropertyEnumerator(o);
    592     int count = 0;
    593     while (JSPropertyEnumeratorGetNextName(enumerator))
    594         ++count;
    595     JSPropertyEnumeratorRelease(enumerator);
     591    JSPropertyNameArrayRef nameArray = JSObjectCopyPropertyNames(context, o);
     592    size_t expectedCount = JSPropertyNameArrayGetCount(nameArray);
     593    size_t count;
     594    for (count = 0; count < expectedCount; ++count)
     595        JSPropertyNameArrayGetNameAtIndex(nameArray, count);
     596    JSPropertyNameArrayRelease(nameArray);
    596597    assert(count == 1); // jsCFString should not be enumerated
    597598
Note: See TracChangeset for help on using the changeset viewer.