JavaScriptCore:
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 16 Jul 2006 21:06:28 +0000 (21:06 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 16 Jul 2006 21:06:28 +0000 (21:06 +0000)
        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.

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

41 files changed:
JavaScriptCore/API/APICast.h
JavaScriptCore/API/JSBase.h
JavaScriptCore/API/JSCallbackObject.cpp
JavaScriptCore/API/JSCallbackObject.h
JavaScriptCore/API/JSClassRef.cpp
JavaScriptCore/API/JSClassRef.h
JavaScriptCore/API/JSObjectRef.cpp
JavaScriptCore/API/JSObjectRef.h
JavaScriptCore/API/testapi.c
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/kjs/PropertyNameArray.cpp [new file with mode: 0644]
JavaScriptCore/kjs/PropertyNameArray.h [new file with mode: 0644]
JavaScriptCore/kjs/array_instance.h
JavaScriptCore/kjs/array_object.cpp
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/nodes.h
JavaScriptCore/kjs/object.cpp
JavaScriptCore/kjs/object.h
JavaScriptCore/kjs/property_map.cpp
JavaScriptCore/kjs/property_map.h
JavaScriptCore/kjs/protected_reference.h [deleted file]
JavaScriptCore/kjs/reference.cpp [deleted file]
JavaScriptCore/kjs/reference.h [deleted file]
JavaScriptCore/kjs/reference_list.cpp [deleted file]
JavaScriptCore/kjs/reference_list.h [deleted file]
JavaScriptCore/kjs/scope_chain.cpp
JavaScriptCore/kjs/string_object.cpp
JavaScriptCore/kjs/string_object.h
JavaScriptCore/kjs/ustring.h
JavaScriptGlue/ChangeLog
JavaScriptGlue/JSUtils.cpp
JavaScriptGlue/JSValueWrapper.cpp
JavaScriptGlue/UserObjectImp.cpp
JavaScriptGlue/UserObjectImp.h
LayoutTests/ChangeLog
LayoutTests/fast/js/for-in-avoid-duplicates-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/for-in-avoid-duplicates.html [new file with mode: 0644]
LayoutTests/fast/js/kde/Array-expected.txt
LayoutTests/fast/js/resources/for-in-avoid-duplicates.js [new file with mode: 0644]

index 0f961a0..07cea79 100644 (file)
@@ -34,7 +34,7 @@ namespace KJS {
     class ExecState;
     class JSValue;
     class JSObject;
-    class ReferenceList;
+    class PropertyNameArray;
 }
 
 /* Opaque typing convenience methods */
@@ -64,9 +64,9 @@ inline KJS::JSObject* toJS(JSObjectRef o)
     return reinterpret_cast<KJS::JSObject*>(o);
 }
 
-inline KJS::ReferenceList* toJS(JSPropertyListRef l)
+inline KJS::PropertyNameArray* toJS(JSPropertyNameAccumulatorRef a)
 {
-    return reinterpret_cast<KJS::ReferenceList*>(l);
+    return reinterpret_cast<KJS::PropertyNameArray*>(a);
 }
 
 inline JSValueRef toRef(KJS::JSValue* v)
@@ -94,14 +94,14 @@ inline JSObjectRef toRef(const KJS::JSObject* o)
     return reinterpret_cast<JSObjectRef>(const_cast<KJS::JSObject*>(o));
 }
 
-inline JSPropertyListRef toRef(KJS::ReferenceList* l)
+inline JSContextRef toRef(KJS::ExecState* e)
 {
-    return reinterpret_cast<JSPropertyListRef>(l);
+    return reinterpret_cast<JSContextRef>(e);
 }
 
-inline JSContextRef toRef(KJS::ExecState* e)
+inline JSPropertyNameAccumulatorRef toRef(KJS::PropertyNameArray* l)
 {
-    return reinterpret_cast<JSContextRef>(e);
+    return reinterpret_cast<JSPropertyNameAccumulatorRef>(l);
 }
 
 #endif // APICast_h
index b9fc487..d40323f 100644 (file)
@@ -43,11 +43,11 @@ typedef struct __JSString* JSStringRef;
 /*! @typedef JSClassRef A JavaScript class. Used with JSObjectMake to construct objects with custom behavior. */
 typedef struct __JSClass* JSClassRef;
 
-/*! @typedef JSPropertyListRef A JavaScript property list. Used for listing the properties in an object so they can be enumerated. */
-typedef struct __JSPropertyList* JSPropertyListRef;
+/*! @typedef JSPropertyNameArrayRef An array of JavaScript property names. */
+typedef struct __JSPropertyNameArray* JSPropertyNameArrayRef;
 
-/*! @typedef JSPropertyEnumeratorRef A JavaScript property enumerator. Used for enumerating the properties in an object. */
-typedef struct __JSPropertyEnumerator* JSPropertyEnumeratorRef;
+/*! @typedef JSPropertyNameAccumulatorRef A data type used to collect a JavaScript object's property names. */
+typedef struct __JSPropertyNameAccumulator* JSPropertyNameAccumulatorRef;
 
 
 /* JavaScript data types */
index 892efc6..47e6114 100644 (file)
@@ -30,8 +30,7 @@
 #include "JSClassRef.h"
 #include "JSObjectRef.h"
 #include "internal.h"
-#include "reference.h"
-#include "reference_list.h"
+#include "PropertyNameArray.h"
 
 namespace KJS {
 
@@ -290,13 +289,14 @@ JSValue* JSCallbackObject::callAsFunction(ExecState* exec, JSObject* thisObj, co
     return 0;
 }
 
-void JSCallbackObject::getPropertyList(ReferenceList& propertyList, bool recursive)
+void JSCallbackObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
 {
+    JSContextRef execRef = toRef(exec);
     JSObjectRef thisRef = toRef(this);
 
     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
-        if (JSObjectAddPropertiesToListCallback addPropertiesToList = jsClass->addPropertiesToList)
-            addPropertiesToList(thisRef, toRef(&propertyList));
+        if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames)
+            getPropertyNames(execRef, thisRef, toRef(&propertyNames));
 
         if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
             typedef __JSClass::StaticValuesTable::const_iterator iterator;
@@ -305,7 +305,7 @@ void JSCallbackObject::getPropertyList(ReferenceList& propertyList, bool recursi
                 UString::Rep* name = it->first.get();
                 StaticValueEntry* entry = it->second;
                 if (entry->getProperty && !(entry->attributes & kJSPropertyAttributeDontEnum))
-                    propertyList.append(Reference(this, Identifier(name)));
+                    propertyNames.add(Identifier(name));
             }
         }
 
@@ -316,12 +316,12 @@ void JSCallbackObject::getPropertyList(ReferenceList& propertyList, bool recursi
                 UString::Rep* name = it->first.get();
                 StaticFunctionEntry* entry = it->second;
                 if (!(entry->attributes & kJSPropertyAttributeDontEnum))
-                    propertyList.append(Reference(this, Identifier(name)));
+                    propertyNames.add(Identifier(name));
             }
         }
     }
 
-    JSObject::getPropertyList(propertyList, recursive);
+    JSObject::getPropertyNames(exec, propertyNames);
 }
 
 double JSCallbackObject::toNumber(ExecState* exec) const
index a622e8a..f549a91 100644 (file)
@@ -60,7 +60,7 @@ public:
     virtual bool implementsCall() const;
     virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List &args);
 
-    virtual void getPropertyList(ReferenceList& propertyList, bool recursive);
+    virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
     virtual double toNumber(ExecState*) const;
     virtual UString toString(ExecState*) const;
index 09cc0bb..cf4be36 100644 (file)
@@ -44,7 +44,7 @@ __JSClass::__JSClass(JSClassDefinition* definition)
     , getProperty(definition->getProperty)
     , setProperty(definition->setProperty)
     , deleteProperty(definition->deleteProperty)
-    , addPropertiesToList(definition->addPropertiesToList)
+    , getPropertyNames(definition->getPropertyNames)
     , callAsFunction(definition->callAsFunction)
     , callAsConstructor(definition->callAsConstructor)
     , hasInstance(definition->hasInstance)
index 8290d13..0fc8a60 100644 (file)
@@ -73,7 +73,7 @@ struct __JSClass {
     JSObjectGetPropertyCallback getProperty;
     JSObjectSetPropertyCallback setProperty;
     JSObjectDeletePropertyCallback deleteProperty;
-    JSObjectAddPropertiesToListCallback addPropertiesToList;
+    JSObjectGetPropertyNamesCallback getPropertyNames;
     JSObjectCallAsFunctionCallback callAsFunction;
     JSObjectCallAsConstructorCallback callAsConstructor;
     JSObjectHasInstanceCallback hasInstance;
index b678702..563f192 100644 (file)
@@ -37,7 +37,7 @@
 #include "nodes.h"
 #include "internal.h"
 #include "object.h"
-#include "reference_list.h"
+#include "PropertyNameArray.h"
 
 using namespace KJS;
 
@@ -306,58 +306,55 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef context, JSObjectRef object,
     return result;
 }
 
-struct __JSPropertyEnumerator
+struct __JSPropertyNameArray
 {
-    __JSPropertyEnumerator() : refCount(0), iterator(list.end())
+    __JSPropertyNameArray() : refCount(0)
     {
     }
     
     unsigned refCount;
-    ReferenceList list;
-    ReferenceListIterator iterator;
+    PropertyNameArray array;
 };
 
-JSPropertyEnumeratorRef JSObjectCreatePropertyEnumerator(JSObjectRef object)
+JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef context, JSObjectRef object)
 {
     JSLock lock;
     JSObject* jsObject = toJS(object);
+    ExecState* exec = toJS(context);
     
-    JSPropertyEnumeratorRef enumerator = new __JSPropertyEnumerator();
-    jsObject->getPropertyList(enumerator->list);
-    enumerator->iterator = enumerator->list.begin();
+    JSPropertyNameArrayRef propertyNames = new __JSPropertyNameArray();
+    jsObject->getPropertyNames(exec, propertyNames->array);
     
-    return JSPropertyEnumeratorRetain(enumerator);
+    return JSPropertyNameArrayRetain(propertyNames);
 }
 
-JSStringRef JSPropertyEnumeratorGetNextName(JSPropertyEnumeratorRef enumerator)
+JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array)
 {
-    ReferenceListIterator& iterator = enumerator->iterator;
-    if (iterator != enumerator->list.end()) {
-        JSStringRef result = toRef(iterator->getPropertyName().ustring().rep());
-        iterator++;
-        return result;
-    }
-    return 0;
+    ++array->refCount;
+    return array;
+}
+
+void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array)
+{
+    if (--array->refCount == 0)
+        delete array;
 }
 
-JSPropertyEnumeratorRef JSPropertyEnumeratorRetain(JSPropertyEnumeratorRef enumerator)
+size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array)
 {
-    ++enumerator->refCount;
-    return enumerator;
+    return array->array.size();
 }
 
-void JSPropertyEnumeratorRelease(JSPropertyEnumeratorRef enumerator)
+JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index)
 {
-    if (--enumerator->refCount == 0)
-        delete enumerator;
+    return toRef(array->array[index].ustring().rep());
 }
 
-void JSPropertyListAdd(JSPropertyListRef propertyList, JSObjectRef thisObject, JSStringRef propertyName)
+void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array, JSStringRef propertyName)
 {
     JSLock lock;
-    ReferenceList* jsPropertyList = toJS(propertyList);
-    JSObject* jsObject = toJS(thisObject);
+    PropertyNameArray* propertyNames = toJS(array);
     UString::Rep* rep = toJS(propertyName);
     
-    jsPropertyList->append(Reference(jsObject, Identifier(rep)));
+    propertyNames->add(Identifier(rep));
 }
index c8eaacf..f54e7f4 100644 (file)
@@ -154,20 +154,26 @@ typedef bool
 (*JSObjectDeletePropertyCallback) (JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);
 
 /*! 
-@typedef JSObjectAddPropertiesToListCallback
-@abstract The callback invoked when adding an object's properties to a property list.
-@param object The JSObject whose properties need to be added to propertyList.
-@param propertyList A JavaScript property list that will be used to enumerate object's properties.
-@discussion If you named your function GetPropertyList, you would declare it like this:
+@typedef JSObjectGetPropertyNamesCallback
+@abstract The callback invoked to get the names of an object's properties.
+@param context The current execution context.
+@param object The JSObject whose property names need to be appended to propertyNames.
+@param accumulator A JavaScript property name accumulator, to which the object should add the names of its properties.
+@discussion If you named your function GetPropertyNames, you would declare it like this:
+
+void GetPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef accumulator);
 
-void AddPropertiesToList(JSObjectRef object, JSPropertyListRef propertyList);
+Use JSPropertyNameAccumulatorAddName to add property names to accumulator.
 
-Use JSPropertyListAdd to add properties to propertyList.
+Property lists are used by JSPropertyEnumerators and JavaScript for...in loops. 
 
-Property lists are used by JSPropertyEnumerators and JavaScript for...in loops.
+It's only necessary to add names of properties that you handle
+specially in your own get / set callbacks. Static property names,
+names of standard JS properties, and properties from the prototype
+will be added automatically.
 */
 typedef void
-(*JSObjectAddPropertiesToListCallback) (JSObjectRef object, JSPropertyListRef propertyList);
+(*JSObjectGetPropertyNamesCallback) (JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames);
 
 /*! 
 @typedef JSObjectCallAsFunctionCallback
@@ -326,7 +332,7 @@ typedef struct {
     JSObjectGetPropertyCallback         getProperty;
     JSObjectSetPropertyCallback         setProperty;
     JSObjectDeletePropertyCallback      deleteProperty;
-    JSObjectAddPropertiesToListCallback addPropertiesToList;
+    JSObjectGetPropertyNamesCallback    getPropertyNames;
     JSObjectCallAsFunctionCallback      callAsFunction;
     JSObjectCallAsConstructorCallback   callAsConstructor;
     JSObjectHasInstanceCallback         hasInstance;
@@ -485,10 +491,9 @@ JSValueRef JSObjectGetPropertyAtIndex(JSContextRef context, JSObjectRef object,
 @param object The JSObject whose property you want to set.
 @param propertyIndex The property's name as a number
 @param value A JSValue to use as the property's value.
-@param attributes A logically ORed set of JSPropertyAttributes to give to the property.
 @discussion This is equivalent to setting a property by a string name containing the number, but allows faster access to JS arrays.
 */
-void JSObjectSetPropertyAtIndex(JSContextRef context, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSPropertyAttributes attributes);
+void JSObjectSetPropertyAtIndex(JSContextRef context, JSObjectRef object, unsigned propertyIndex, JSValueRef value);
 
 /*!
 @function
@@ -549,41 +554,52 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef context, JSObjectRef object,
 
 /*!
 @function
-@abstract Creates an enumerator for an object's properties.
-@param object The object whose properties you want to enumerate.
-@result A JSPropertyEnumerator with a list of object's properties. Ownership follows the Create Rule.
+@abstract Get the names of all enumerable properties of an object.
+@param context The execution context to use.
+@param object The object from which to get property names. 
+@result A JSPropertyNameArray containing the names of all the object's enumerable properties.
 */
-JSPropertyEnumeratorRef JSObjectCreatePropertyEnumerator(JSObjectRef object);
+JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef context, JSObjectRef object);
+
 /*!
 @function
-@abstract Retains a property enumerator.
-@param enumerator The JSPropertyEnumerator to retain.
-@result A JSPropertyEnumerator that is the same as enumerator.
+@abstract         Retains a JavaScript property name array.
+@param array      The JSPropertyNameArray to retain.
+@result           A JSPropertyNameArray that is the same as array.
 */
-JSPropertyEnumeratorRef JSPropertyEnumeratorRetain(JSPropertyEnumeratorRef enumerator);
+JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array);
+
 /*!
 @function
-@abstract Releases a property enumerator.
-@param enumerator The JSPropertyEnumerator to release.
+@abstract         Releases a JavaScript property name array.
+@param array      The JSPropetyNameArray to release.
 */
-void JSPropertyEnumeratorRelease(JSPropertyEnumeratorRef enumerator);
+void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array);
+
+/*!
+@function
+@abstract      Get the number of items in a JavaScript property name array.
+@param array   The array from which to retrieve the count.
+@result        The count of items in the array.
+*/
+size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array);
+
 /*!
 @function
-@abstract Gets a property enumerator's next property.
-@param enumerator The JSPropertyEnumerator whose next property you want to get.
-@result A JSString containing the property's name, or NULL if all properties have been enumerated.
+@abstract      Get a single item from a JavaScript property name array.
+@param array   The array from which to retrieve a property name.
+@param index   The index of the property name to retrieve.
+@result        A JSStringRef containing the name of the property.
 */
-JSStringRef JSPropertyEnumeratorGetNextName(JSPropertyEnumeratorRef enumerator);
+JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index);
 
 /*!
 @function
-@abstract Adds a property to a property list.
-@discussion Use this method inside a JSObjectAddPropertiesToListCallback to add a property to an object's property list.
-@param propertyList The JSPropertyList to which you want to add a property.
-@param thisObject The JSObject to which the property belongs.
-@param propertyName A JSString specifying the property's name.
+@abstract           Add a property name - useful while getting the property names for an object.
+@param accumulator  The accumulator object to which to add the property.
+@param propertyName The new property to add.
 */
-void JSPropertyListAdd(JSPropertyListRef propertyList, JSObjectRef thisObject, JSStringRef propertyName);
+void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef accumulator, JSStringRef propertyName);
 
 #ifdef __cplusplus
 }
index b84ea27..35cbb7c 100644 (file)
@@ -169,18 +169,18 @@ static bool MyObject_deleteProperty(JSContextRef context, JSObjectRef object, JS
     return false;
 }
 
-static void MyObject_addPropertiesToList(JSObjectRef object, JSPropertyListRef propertyList)
+static void MyObject_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames)
 {
     UNUSED_PARAM(context);
     
     JSStringRef propertyName;
     
     propertyName = JSStringCreateWithUTF8CString("alwaysOne");
-    JSPropertyListAdd(propertyList, object, propertyName);
+    JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
     JSStringRelease(propertyName);
     
     propertyName = JSStringCreateWithUTF8CString("myPropertyName");
-    JSPropertyListAdd(propertyList, object, propertyName);
+    JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
     JSStringRelease(propertyName);
 }
 
@@ -257,7 +257,7 @@ JSClassDefinition MyObject_definition = {
     MyObject_getProperty,
     MyObject_setProperty,
     MyObject_deleteProperty,
-    MyObject_addPropertiesToList,
+    MyObject_getPropertyNames,
     MyObject_callAsFunction,
     MyObject_callAsConstructor,
     MyObject_hasInstance,
@@ -588,11 +588,12 @@ int main(int argc, char* argv[])
     o = JSObjectMake(context, NULL, NULL);
     JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(1), kJSPropertyAttributeNone, NULL);
     JSObjectSetProperty(context, o, jsCFIString,  JSValueMakeNumber(1), kJSPropertyAttributeDontEnum, NULL);
-    JSPropertyEnumeratorRef enumerator = JSObjectCreatePropertyEnumerator(o);
-    int count = 0;
-    while (JSPropertyEnumeratorGetNextName(enumerator))
-        ++count;
-    JSPropertyEnumeratorRelease(enumerator);
+    JSPropertyNameArrayRef nameArray = JSObjectCopyPropertyNames(context, o);
+    size_t expectedCount = JSPropertyNameArrayGetCount(nameArray);
+    size_t count;
+    for (count = 0; count < expectedCount; ++count)
+        JSPropertyNameArrayGetNameAtIndex(nameArray, count);
+    JSPropertyNameArrayRelease(nameArray);
     assert(count == 1); // jsCFString should not be enumerated
 
     JSClassDefinition nullDefinition = kJSClassDefinitionNull;
index d4baa51..5b9667e 100644 (file)
@@ -1,3 +1,80 @@
+2006-07-15  Maciej Stachowiak  <mjs@apple.com>
+
+        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.
+
 2006-07-15  Darin Adler  <darin@apple.com>
 
         - oops, missed a few more arrays that had to be const
index 9662f2a..eae0499 100644 (file)
@@ -13,10 +13,11 @@ _JSGlobalContextRelease
 _JSGlobalContextRetain
 _JSObjectCallAsConstructor
 _JSObjectCallAsFunction
-_JSObjectCreatePropertyEnumerator
+_JSObjectCopyPropertyNames
 _JSObjectDeleteProperty
 _JSObjectGetPrivate
 _JSObjectGetProperty
+_JSObjectGetPropertyAtIndex
 _JSObjectGetPrototype
 _JSObjectHasProperty
 _JSObjectIsConstructor
@@ -27,11 +28,13 @@ _JSObjectMakeFunction
 _JSObjectMakeFunctionWithBody
 _JSObjectSetPrivate
 _JSObjectSetProperty
+_JSObjectSetPropertyAtIndex
 _JSObjectSetPrototype
-_JSPropertyEnumeratorGetNextName
-_JSPropertyEnumeratorRelease
-_JSPropertyEnumeratorRetain
-_JSPropertyListAdd
+_JSPropertyNameAccumulatorAddName
+_JSPropertyNameArrayGetCount
+_JSPropertyNameArrayGetNameAtIndex
+_JSPropertyNameArrayRelease
+_JSPropertyNameArrayRetain
 _JSStringCopyCFString
 _JSStringCreateWithCFString
 _JSStringCreateWithCharacters
@@ -138,20 +141,17 @@ __ZN3KJS11PropertyMapD1Ev
 __ZN3KJS12DateInstance4infoE
 __ZN3KJS12PropertySlot15undefinedGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKS0_
 __ZN3KJS12jsNumberCellEd
-__ZN3KJS13ReferenceList6appendERKNS_9ReferenceE
-__ZN3KJS13ReferenceListC1Ev
-__ZN3KJS13ReferenceListD1Ev
 __ZN3KJS13SavedBuiltinsC1Ev
 __ZN3KJS13SavedBuiltinsD1Ev
 __ZN3KJS15SavedPropertiesC1Ev
 __ZN3KJS15SavedPropertiesD1Ev
 __ZN3KJS16RuntimeObjectImpC1EPNS_8Bindings8InstanceE
+__ZN3KJS17PropertyNameArray3addERKNS_10IdentifierE
 __ZN3KJS18lengthPropertyNameE
 __ZN3KJS19InternalFunctionImp11hasInstanceEPNS_9ExecStateEPNS_7JSValueE
 __ZN3KJS19InternalFunctionImp4infoE
 __ZN3KJS19InternalFunctionImpC2EPNS_17FunctionPrototypeERKNS_10IdentifierE
 __ZN3KJS19messagePropertyNameE
-__ZN3KJS21ReferenceListIteratorppEi
 __ZN3KJS21prototypePropertyNameE
 __ZN3KJS4List6appendEPNS_7JSValueE
 __ZN3KJS4List7releaseEv
@@ -186,7 +186,7 @@ __ZN3KJS8JSObject11hasInstanceEPNS_9ExecStateEPNS_7JSValueE
 __ZN3KJS8JSObject14callAsFunctionEPNS_9ExecStateEPS0_RKNS_4ListE
 __ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateEj
-__ZN3KJS8JSObject15getPropertyListERNS_13ReferenceListEb
+__ZN3KJS8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
 __ZN3KJS8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
 __ZN3KJS8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPPNS_7JSValueE
 __ZN3KJS8JSObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
@@ -206,7 +206,6 @@ __ZN3KJS9Collector4sizeEv
 __ZN3KJS9Collector7collectEv
 __ZN3KJS9Collector7protectEPNS_7JSValueE
 __ZN3KJS9Collector9unprotectEPNS_7JSValueE
-__ZN3KJS9ReferenceC1EPNS_8JSObjectERKNS_10IdentifierE
 __ZN3KJSeqERKNS_7UStringEPKc
 __ZN3WTF10fastCallocEmm
 __ZN3WTF10fastMallocEm
@@ -221,12 +220,8 @@ __ZNK3KJS11Interpreter24builtinFunctionPrototypeEv
 __ZNK3KJS11PropertyMap3getERKNS_10IdentifierE
 __ZNK3KJS11PropertyMap4saveERNS_15SavedPropertiesE
 __ZNK3KJS12DateInstance7getTimeERdRi
-__ZNK3KJS13ReferenceList3endEv
-__ZNK3KJS13ReferenceList5beginEv
 __ZNK3KJS19InternalFunctionImp14implementsCallEv
 __ZNK3KJS19InternalFunctionImp21implementsHasInstanceEv
-__ZNK3KJS21ReferenceListIteratorneERKS0_
-__ZNK3KJS21ReferenceListIteratorptEv
 __ZNK3KJS4List2atEi
 __ZNK3KJS4List8copyTailEv
 __ZNK3KJS6JSCell9getNumberERd
@@ -257,7 +252,6 @@ __ZNK3KJS8JSObject9classInfoEv
 __ZNK3KJS8JSObject9classNameEv
 __ZNK3KJS8JSObject9toBooleanEPNS_9ExecStateE
 __ZNK3KJS9ExecState18lexicalInterpreterEv
-__ZNK3KJS9Reference15getPropertyNameEv
 __ZTVN3KJS19InternalFunctionImpE
 __ZTVN3KJS8JSObjectE
 _kJSClassDefinitionNull
index 25d57bc..5c3b25d 100644 (file)
@@ -77,7 +77,8 @@
                14BD5A360A3E91F600BAF59C /* JavaScriptCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BD5A2F0A3E91F600BAF59C /* JavaScriptCore.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14F137590A3A727E00F26F90 /* Context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14F137580A3A727E00F26F90 /* Context.cpp */; };
                14F137830A3A765B00F26F90 /* context.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F137820A3A765B00F26F90 /* context.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               652C107F08DA7B1E0020887D /* protected_reference.h in Headers */ = {isa = PBXBuildFile; fileRef = 652C107E08DA7B1E0020887D /* protected_reference.h */; };
+               65400C110A69BAF200509887 /* PropertyNameArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */; };
+               65400C120A69BAF200509887 /* PropertyNameArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 65400C100A69BAF200509887 /* PropertyNameArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6541BD7208E80A17002CBEE7 /* TCPageMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 6541BD6E08E80A17002CBEE7 /* TCPageMap.h */; };
                6541BD7308E80A17002CBEE7 /* TCSpinLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 6541BD6F08E80A17002CBEE7 /* TCSpinLock.h */; };
                6541BD7408E80A17002CBEE7 /* TCSystemAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6541BD7008E80A17002CBEE7 /* TCSystemAlloc.cpp */; };
                932F5B5C0822A1C700736975 /* ustring.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8860255597D01FF60F7 /* ustring.h */; settings = {ATTRIBUTES = (Private, ); }; };
                932F5B600822A1C700736975 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = F68EBB8C0255D4C601FF60F7 /* config.h */; settings = {ATTRIBUTES = (Private, ); }; };
                932F5B610822A1C700736975 /* JavaScriptCorePrefix.h in Headers */ = {isa = PBXBuildFile; fileRef = F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */; };
-               932F5B630822A1C700736975 /* reference_list.h in Headers */ = {isa = PBXBuildFile; fileRef = F54F0800030CD22001B5C2EB /* reference_list.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               932F5B640822A1C700736975 /* reference.h in Headers */ = {isa = PBXBuildFile; fileRef = F5341391030CEEB1018BE7F3 /* reference.h */; settings = {ATTRIBUTES = (Private, ); }; };
                932F5B650822A1C700736975 /* completion.h in Headers */ = {isa = PBXBuildFile; fileRef = F5BB2BC5030F772101FCFE1D /* completion.h */; settings = {ATTRIBUTES = (Private, ); }; };
                932F5B660822A1C700736975 /* identifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 933A349A038AE7C6008635CE /* identifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
                932F5B670822A1C700736975 /* array_instance.h in Headers */ = {isa = PBXBuildFile; fileRef = 938772E5038BFE19008635CE /* array_instance.h */; settings = {ATTRIBUTES = (Private, ); }; };
                932F5BA80822A1C700736975 /* ustring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8850255597D01FF60F7 /* ustring.cpp */; };
                932F5BA90822A1C700736975 /* value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8870255597D01FF60F7 /* value.cpp */; };
                932F5BAB0822A1C700736975 /* nodes2string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5FFE656026B47A6018635CA /* nodes2string.cpp */; };
-               932F5BAC0822A1C700736975 /* reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5341390030CEEB1018BE7F3 /* reference.cpp */; settings = {ATTRIBUTES = (Private, ); }; };
-               932F5BAD0822A1C700736975 /* reference_list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5341394030CF5F8018BE7F3 /* reference_list.cpp */; settings = {ATTRIBUTES = (Private, ); }; };
                932F5BAE0822A1C700736975 /* identifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 933A349D038AE80F008635CE /* identifier.cpp */; };
                932F5BAF0822A1C700736975 /* scope_chain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9374D3A8038D9D74008635CE /* scope_chain.cpp */; };
                932F5BB00822A1C700736975 /* list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 931C6CF0038EE8DE008635CE /* list.cpp */; };
                51F0EC9705C88DC700E6DF1B /* objc_utility.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = objc_utility.mm; path = bindings/objc/objc_utility.mm; sourceTree = "<group>"; tabWidth = 8; };
                651F6412039D5B5F0078395C /* dtoa.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dtoa.cpp; sourceTree = "<group>"; tabWidth = 8; };
                651F6413039D5B5F0078395C /* dtoa.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = dtoa.h; sourceTree = "<group>"; tabWidth = 8; };
-               652C107E08DA7B1E0020887D /* protected_reference.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = protected_reference.h; sourceTree = "<group>"; tabWidth = 8; };
+               65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyNameArray.cpp; sourceTree = "<group>"; };
+               65400C100A69BAF200509887 /* PropertyNameArray.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PropertyNameArray.h; sourceTree = "<group>"; };
                6541720E039E08B90058BFEB /* dftables.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = dftables.c; path = pcre/dftables.c; sourceTree = "<group>"; tabWidth = 8; };
                6541720F039E08B90058BFEB /* pcre.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = pcre.h; path = pcre/pcre.h; sourceTree = "<group>"; tabWidth = 8; };
                65417217039E0B280058BFEB /* pcre-config.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = "pcre-config.h"; path = "pcre/pcre-config.h"; sourceTree = "<group>"; tabWidth = 8; };
                E195678F09E7CF1200B89D13 /* UnicodeIcu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnicodeIcu.h; sourceTree = "<group>"; };
                E195679409E7CF1200B89D13 /* Unicode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Unicode.h; sourceTree = "<group>"; };
                E195679509E7CF1200B89D13 /* UnicodeCategory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnicodeCategory.h; sourceTree = "<group>"; };
-               F5341390030CEEB1018BE7F3 /* reference.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reference.cpp; sourceTree = "<group>"; tabWidth = 8; };
-               F5341391030CEEB1018BE7F3 /* reference.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = reference.h; sourceTree = "<group>"; tabWidth = 8; };
-               F5341394030CF5F8018BE7F3 /* reference_list.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reference_list.cpp; sourceTree = "<group>"; tabWidth = 8; };
-               F54F0800030CD22001B5C2EB /* reference_list.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = reference_list.h; sourceTree = "<group>"; tabWidth = 8; };
                F5BB2BC5030F772101FCFE1D /* completion.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = completion.h; sourceTree = "<group>"; tabWidth = 8; };
                F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = JavaScriptCorePrefix.h; path = ../JavaScriptCorePrefix.h; sourceTree = "<group>"; tabWidth = 8; };
                F5FFE656026B47A6018635CA /* nodes2string.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nodes2string.cpp; sourceTree = "<group>"; tabWidth = 8; };
                65417200039E01BA0058BFEB /* kjs */ = {
                        isa = PBXGroup;
                        children = (
+                               65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */,
+                               65400C100A69BAF200509887 /* PropertyNameArray.h */,
                                938772E5038BFE19008635CE /* array_instance.h */,
                                F692A84D0255597D01FF60F7 /* array_object.cpp */,
                                F692A84E0255597D01FF60F7 /* array_object.h */,
                                65621E6B089E859700760F35 /* property_slot.cpp */,
                                65621E6C089E859700760F35 /* property_slot.h */,
                                65C02FBB0637462A003E7EE6 /* protect.h */,
-                               652C107E08DA7B1E0020887D /* protected_reference.h */,
-                               F5341390030CEEB1018BE7F3 /* reference.cpp */,
-                               F5341391030CEEB1018BE7F3 /* reference.h */,
-                               F5341394030CF5F8018BE7F3 /* reference_list.cpp */,
-                               F54F0800030CD22001B5C2EB /* reference_list.h */,
                                F692A87D0255597D01FF60F7 /* regexp.cpp */,
                                F692A87E0255597D01FF60F7 /* regexp.h */,
                                F692A87B0255597D01FF60F7 /* regexp_object.cpp */,
                                932F5B5C0822A1C700736975 /* ustring.h in Headers */,
                                932F5B600822A1C700736975 /* config.h in Headers */,
                                932F5B610822A1C700736975 /* JavaScriptCorePrefix.h in Headers */,
-                               932F5B630822A1C700736975 /* reference_list.h in Headers */,
-                               932F5B640822A1C700736975 /* reference.h in Headers */,
                                932F5B650822A1C700736975 /* completion.h in Headers */,
                                932F5B660822A1C700736975 /* identifier.h in Headers */,
                                932F5B670822A1C700736975 /* array_instance.h in Headers */,
                                93E26BFD08B151D400F85226 /* ucp.h in Headers */,
                                93E26BFE08B151D400F85226 /* ucpinternal.h in Headers */,
                                93E26C1308B1523D00F85226 /* ucptable.c in Headers */,
-                               652C107F08DA7B1E0020887D /* protected_reference.h in Headers */,
                                65E217BD08E7EECC0023E5F6 /* Assertions.h in Headers */,
                                65E217C008E7EECC0023E5F6 /* FastMalloc.h in Headers */,
                                6541BD7208E80A17002CBEE7 /* TCPageMap.h in Headers */,
                                1440F8910A508B100005F061 /* JSCallbackFunction.h in Headers */,
                                1440F8AE0A508D200005F061 /* JSCallbackConstructor.h in Headers */,
                                1440FCE30A51E46B0005F061 /* JSClassRef.h in Headers */,
+                               65400C120A69BAF200509887 /* PropertyNameArray.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                932F5BA80822A1C700736975 /* ustring.cpp in Sources */,
                                932F5BA90822A1C700736975 /* value.cpp in Sources */,
                                932F5BAB0822A1C700736975 /* nodes2string.cpp in Sources */,
-                               932F5BAC0822A1C700736975 /* reference.cpp in Sources */,
-                               932F5BAD0822A1C700736975 /* reference_list.cpp in Sources */,
                                932F5BAE0822A1C700736975 /* identifier.cpp in Sources */,
                                932F5BAF0822A1C700736975 /* scope_chain.cpp in Sources */,
                                932F5BB00822A1C700736975 /* list.cpp in Sources */,
                                1440F8AF0A508D200005F061 /* JSCallbackConstructor.cpp in Sources */,
                                1440FCE40A51E46B0005F061 /* JSClassRef.cpp in Sources */,
                                1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */,
+                               65400C110A69BAF200509887 /* PropertyNameArray.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/JavaScriptCore/kjs/PropertyNameArray.cpp b/JavaScriptCore/kjs/PropertyNameArray.cpp
new file mode 100644 (file)
index 0000000..5bb242e
--- /dev/null
@@ -0,0 +1,36 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ *  Copyright (C) 2006 Apple Computer, Inc
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "PropertyNameArray.h"
+
+namespace KJS {
+
+void PropertyNameArray::add(const Identifier& ident)
+{
+    if (!m_set.add(ident.ustring().rep()).second)
+        return;
+    
+    m_vector.append(ident);
+}
+
+} // namespace KJS
+
diff --git a/JavaScriptCore/kjs/PropertyNameArray.h b/JavaScriptCore/kjs/PropertyNameArray.h
new file mode 100644 (file)
index 0000000..be3da34
--- /dev/null
@@ -0,0 +1,58 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ *  Copyright (C) 2006 Apple Computer, Inc
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef KJS_PROPERTY_NAME_ARRAY_H
+#define KJS_PROPERTY_NAME_ARRAY_H
+
+#include "identifier.h"
+
+#include <wtf/HashSet.h>
+#include <wtf/Vector.h>
+
+namespace KJS {
+
+    class PropertyNameArray;
+
+    typedef Vector<Identifier>::const_iterator PropertyNameArrayIterator;
+
+    class PropertyNameArray {
+    public:
+        typedef PropertyNameArrayIterator iterator;
+
+        void add(const Identifier&);
+        iterator begin() const { return m_vector.begin(); }
+        iterator end() const { return m_vector.end(); }
+        int size() const { return m_vector.size(); }
+
+        Identifier& operator[](unsigned i) { return m_vector[i]; }
+        const Identifier& operator[](unsigned i) const { return m_vector[i]; }
+            
+    private:
+        typedef HashSet<UString::Rep*, PtrHash<UString::Rep*> > IdentifierSet;
+        IdentifierSet m_set;
+        Vector<Identifier> m_vector;
+    };
+
+
+} // namespace KJS
+
+
+#endif // KJS_PROPERTY_NAME_ARRAY_H
index a71bcf1..54341a5 100644 (file)
@@ -39,7 +39,7 @@ namespace KJS {
     virtual void put(ExecState *exec, unsigned propertyName, JSValue *value, int attr = None);
     virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
     virtual bool deleteProperty(ExecState *exec, unsigned propertyName);
-    virtual void getPropertyList(ReferenceList& propertyList, bool recursive);
+    virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
     virtual void mark();
 
index 8f5b1c1..8034098 100644 (file)
@@ -28,7 +28,7 @@
 #include "error_object.h"
 #include "lookup.h"
 #include "operations.h"
-#include "reference_list.h"
+#include "PropertyNameArray.h"
 #include <wtf/HashSet.h>
 #include <stdio.h>
 
@@ -199,19 +199,18 @@ bool ArrayInstance::deleteProperty(ExecState *exec, unsigned index)
   return JSObject::deleteProperty(exec, Identifier::from(index));
 }
 
-void ArrayInstance::getPropertyList(ReferenceList& propertyList, bool recursive)
+void ArrayInstance::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
 {
   // avoid fetching this every time through the loop
-  JSValue *undefined = jsUndefined();
-
-  //### FIXME: should avoid duplicates with prototype
+  JSValue* undefined = jsUndefined();
+  
   for (unsigned i = 0; i < storageLength; ++i) {
-    JSValue *imp = storage[i];
-    if (imp && imp != undefined) {
-      propertyList.append(Reference(this, i));
-    }
+    JSValue* value = storage[i];
+    if (value && value != undefined)
+      propertyNames.add(Identifier::from(i));
   }
-  return JSObject::getPropertyList(propertyList, recursive);
+  JSObject::getPropertyNames(exec, propertyNames);
 }
 
 void ArrayInstance::resizeStorage(unsigned newLength)
@@ -243,18 +242,18 @@ void ArrayInstance::setLength(unsigned newLength, ExecState *exec)
   }
 
   if (newLength < length) {
-    ReferenceList sparseProperties;
+    PropertyNameArray sparseProperties;
     
-    _prop.addSparseArrayPropertiesToReferenceList(sparseProperties, this);
+    _prop.getSparseArrayPropertyNames(sparseProperties);
     
-    ReferenceListIterator it = sparseProperties.begin();
-    while (it != sparseProperties.end()) {
-      Reference ref = it++;
+    PropertyNameArrayIterator end = sparseProperties.end();
+    
+    for (PropertyNameArrayIterator it = sparseProperties.begin(); it != end; ++it) {
+      Identifier name = *it;
       bool ok;
-      unsigned index = ref.getPropertyName().toArrayIndex(&ok);
-      if (ok && index > newLength) {
-        ref.deleteValue(exec);
-      }
+      unsigned index = name.toArrayIndex(&ok);
+      if (ok && index > newLength)
+        deleteProperty(exec, name);
     }
   }
   
@@ -360,21 +359,20 @@ unsigned ArrayInstance::pushUndefinedObjectsToEnd(ExecState *exec)
             o++;
         }
     }
+   
+    PropertyNameArray sparseProperties;
+    _prop.getSparseArrayPropertyNames(sparseProperties);
+    unsigned newLength = o + sparseProperties.size();
+    
+    if (newLength > storageLength)
+        resizeStorage(newLength);
     
-    ReferenceList sparseProperties;
-    _prop.addSparseArrayPropertiesToReferenceList(sparseProperties, this);
-    unsigned newLength = o + sparseProperties.length();
-
-    if (newLength > storageLength) {
-      resizeStorage(newLength);
-    } 
-
-    ReferenceListIterator it = sparseProperties.begin();
-    while (it != sparseProperties.end()) {
-      Reference ref = it++;
-      storage[o] = ref.getValue(exec);
-      JSObject::deleteProperty(exec, ref.getPropertyName());
-      o++;
+    PropertyNameArrayIterator end = sparseProperties.end();
+    for (PropertyNameArrayIterator it = sparseProperties.begin(); it != end; ++it) {
+        Identifier name = *it;
+        storage[o] = get(exec, name);
+        JSObject::deleteProperty(exec, name);
+        o++;
     }
     
     if (newLength != storageLength)
index ef11c70..01209ca 100644 (file)
@@ -35,7 +35,7 @@
 #include "function_object.h"
 #include "lexer.h"
 #include "operations.h"
-#include "reference_list.h"
+#include "PropertyNameArray.h"
 #include <wtf/HashSet.h>
 #include <wtf/HashCountedSet.h>
 #include <wtf/MathExtras.h>
@@ -1859,7 +1859,7 @@ Completion ForInNode::execute(ExecState *exec)
   JSValue *retval = 0;
   JSObject *v;
   Completion c;
-  ReferenceList propertyList;
+  PropertyNameArray propertyNames;
 
   if (varDecl) {
     varDecl->evaluate(exec);
@@ -1878,20 +1878,17 @@ Completion ForInNode::execute(ExecState *exec)
 
   KJS_CHECKEXCEPTION
   v = e->toObject(exec);
-  v->getPropertyList(propertyList);
-
-  ReferenceListIterator propIt = propertyList.begin();
-
-  while (propIt != propertyList.end()) {
-    Identifier name = propIt->getPropertyName();
-    if (!v->hasProperty(exec, name)) {
-      propIt++;
-      continue;
-    }
+  v->getPropertyNames(exec, propertyNames);
+  
+  PropertyNameArrayIterator end = propertyNames.end();
+  for (PropertyNameArrayIterator it = propertyNames.begin(); it != end; ++it) {
+      const Identifier &name = *it;
+      if (!v->hasProperty(exec, name))
+          continue;
 
-    JSValue *str = jsString(name.ustring());
+      JSValue *str = jsString(name.ustring());
 
-    if (lexpr->isResolveNode()) {
+      if (lexpr->isResolveNode()) {
         const Identifier &ident = static_cast<ResolveNode *>(lexpr.get())->identifier();
 
         const ScopeChain& chain = exec->context()->scopeChain();
@@ -1950,8 +1947,6 @@ Completion ForInNode::execute(ExecState *exec)
         return c;
       }
     }
-
-    propIt++;
   }
 
   // bail out on error
index c3ecf7f..8484389 100644 (file)
@@ -34,7 +34,6 @@ namespace KJS {
   class ProgramNode;
   class PropertyNameNode;
   class PropertyListNode;
-  class Reference;
   class RegExp;
   class SourceElementsNode;
   class SourceStream;
index e11df88..0e0649f 100644 (file)
@@ -29,7 +29,7 @@
 #include "lookup.h"
 #include "nodes.h"
 #include "operations.h"
-#include "reference_list.h"
+#include "PropertyNameArray.h"
 #include <math.h>
 
 // maximum global call stack size. Protects against accidental or
@@ -475,9 +475,9 @@ bool JSObject::getPropertyAttributes(const Identifier& propertyName, unsigned& a
   return false;
 }
 
-void JSObject::getPropertyList(ReferenceList& propertyList, bool recursive)
+void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
 {
-  _prop.addEnumerablesToReferenceList(propertyList, this);
+   _prop.getEnumerablePropertyNames(propertyNames);
 
   // Add properties from the static hashtable of properties
   const ClassInfo *info = classInfo();
@@ -486,14 +486,14 @@ void JSObject::getPropertyList(ReferenceList& propertyList, bool recursive)
       int size = info->propHashTable->size;
       const HashEntry *e = info->propHashTable->entries;
       for (int i = 0; i < size; ++i, ++e) {
-        if ( e->s && !(e->attr & DontEnum) )
-          propertyList.append(Reference(this, e->s)); /// ######### check for duplicates with the propertymap
+        if (e->s && !(e->attr & DontEnum))
+          propertyNames.add(e->s);
       }
     }
     info = info->parentClass;
   }
-  if (_proto->isObject() && recursive)
-      static_cast<JSObject*>(_proto)->getPropertyList(propertyList, recursive);
+  if (_proto->isObject())
+     static_cast<JSObject*>(_proto)->getPropertyNames(exec, propertyNames);
 }
 
 bool JSObject::toBoolean(ExecState */*exec*/) const
index cd7319f..b830631 100644 (file)
@@ -38,6 +38,7 @@ namespace KJS {
   class HashEntry;
   class ListImp;
   class InternalFunctionImp;
+  class PropertyNameArray;
 
   // ECMA 262-3 8.6.1
   // Property attributes
@@ -440,23 +441,7 @@ namespace KJS {
     const ScopeChain &scope() const { return _scope; }
     void setScope(const ScopeChain &s) { _scope = s; }
 
-    /**
-     * Returns a List of References to all the properties of the object. Used
-     * in "for x in y" statements. The list is created new, so it can be freely
-     * modified without affecting the object's properties. It should be deleted
-     * by the caller.
-     *
-     * Subclasses can override this method in ObjectImpl to provide the
-     * appearance of
-     * having extra properties other than those set specifically with put().
-     *
-     * @param exec The current execution state
-     * @param recursive Whether or not properties in the object's prototype
-     * chain should be
-     * included in the list.
-     * @return A List of References to properties of the object.
-     **/
-    virtual void getPropertyList(ReferenceList& propertyList, bool recursive = true);
+    virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
     /**
      * Returns the internal value of the object. This is used for objects such
index 7b3cba5..d2e6111 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "object.h"
 #include "protect.h"
-#include "reference_list.h"
+#include "PropertyNameArray.h"
 #include <algorithm>
 #include <wtf/FastMalloc.h>
 #include <wtf/Vector.h>
@@ -74,7 +74,7 @@ PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger()
 #endif
 
 // lastIndexUsed is an ever-increasing index used to identify the order items
-// were inserted into the property map. It's vital that addEnumerablesToReferenceList
+// were inserted into the property map. It's vital that getEnumerablePropertyNames
 // return the properties in the order they were added for compatibility with other
 // browsers' JavaScript implementations.
 struct PropertyMapHashTable
@@ -583,13 +583,13 @@ bool PropertyMap::containsGettersOrSetters() const
     return false;
 }
 
-void PropertyMap::addEnumerablesToReferenceList(ReferenceList &list, JSObject *base) const
+void PropertyMap::getEnumerablePropertyNames(PropertyNameArray& propertyNames) const
 {
     if (!_table) {
 #if USE_SINGLE_ENTRY
         UString::Rep *key = _singleEntry.key;
         if (key && !(_singleEntry.attributes & DontEnum))
-            list.append(Reference(base, Identifier(key)));
+            propertyNames.add(Identifier(key));
 #endif
         return;
     }
@@ -610,12 +610,12 @@ void PropertyMap::addEnumerablesToReferenceList(ReferenceList &list, JSObject *b
     // Sort the entries by index.
     qsort(sortedEnumerables.data(), p - sortedEnumerables.data(), sizeof(Entry*), comparePropertyMapEntryIndices);
 
-    // Put the keys of the sorted entries into the reference list.
+    // Put the keys of the sorted entries into the list.
     for (Entry** q = sortedEnumerables.data(); q != p; ++q)
-        list.append(Reference(base, Identifier((*q)->key)));
+        propertyNames.add(Identifier(q[0]->key));
 }
 
-void PropertyMap::addSparseArrayPropertiesToReferenceList(ReferenceList &list, JSObject *base) const
+void PropertyMap::getSparseArrayPropertyNames(PropertyNameArray& propertyNames) const
 {
     if (!_table) {
 #if USE_SINGLE_ENTRY
@@ -625,7 +625,7 @@ void PropertyMap::addSparseArrayPropertiesToReferenceList(ReferenceList &list, J
             bool fitsInUInt32;
             k.toUInt32(&fitsInUInt32);
             if (fitsInUInt32)
-                list.append(Reference(base, Identifier(key)));
+                propertyNames.add(Identifier(key));
         }
 #endif
         return;
@@ -640,7 +640,7 @@ void PropertyMap::addSparseArrayPropertiesToReferenceList(ReferenceList &list, J
             bool fitsInUInt32;
             k.toUInt32(&fitsInUInt32);
             if (fitsInUInt32)
-                list.append(Reference(base, Identifier(key)));
+                propertyNames.add(Identifier(key));
         }
     }
 }
index 7591b7e..afc40b0 100644 (file)
@@ -28,8 +28,8 @@
 
 namespace KJS {
 
+    class PropertyNameArray;
     class JSObject;
-    class ReferenceList;
     class JSValue;
     
     class SavedProperty;
@@ -80,8 +80,8 @@ namespace KJS {
         JSValue **getLocation(const Identifier &name);
 
         void mark() const;
-        void addEnumerablesToReferenceList(ReferenceList &, JSObject *) const;
-        void addSparseArrayPropertiesToReferenceList(ReferenceList &, JSObject *) const;
+        void getEnumerablePropertyNames(PropertyNameArray&) const;
+        void getSparseArrayPropertyNames(PropertyNameArray&) const;
 
         void save(SavedProperties &) const;
         void restore(const SavedProperties &p);
diff --git a/JavaScriptCore/kjs/protected_reference.h b/JavaScriptCore/kjs/protected_reference.h
deleted file mode 100644 (file)
index 2229c01..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// -*- c-basic-offset: 4 -*-
-/*
- *  This file is part of the KDE libraries
- *  Copyright (C) 2005 Apple Computer, Inc.
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef KJS_PROTECTED_REFERENCE_H
-#define KJS_PROTECTED_REFERENCE_H
-
-#include "protect.h"
-
-namespace KJS {
-
-    class ProtectedReference : public Reference {
-    public:
-        ProtectedReference(const Reference& r) 
-            : Reference(r) 
-        {
-            JSLock lock;
-            gcProtectNullTolerant(base); 
-        }
-
-        ~ProtectedReference()
-        { 
-            JSLock lock;
-            gcUnprotectNullTolerant(base);
-        }
-
-        ProtectedReference& operator=(const Reference &r)
-        {
-            JSLock lock;
-            JSValue *old = base;
-            Reference::operator=(r); 
-            gcProtectNullTolerant(base);
-            gcUnprotectNullTolerant(old); 
-            return *this;
-        }
-
-    private:
-        ProtectedReference();
-        ProtectedReference(JSObject *b, const Identifier& p);
-        ProtectedReference(JSObject *b, unsigned p);
-        ProtectedReference(const Identifier& p);
-        ProtectedReference(unsigned p);
-    };
-
-} // namespace
-
-#endif
diff --git a/JavaScriptCore/kjs/reference.cpp b/JavaScriptCore/kjs/reference.cpp
deleted file mode 100644 (file)
index b285c0a..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-// -*- c-basic-offset: 2 -*-
-/*
- *  This file is part of the KDE libraries
- *  Copyright (C) 2004 Apple Computer, Inc
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#include "JSType.h"
-#include "config.h"
-#include "internal.h"
-#include "reference.h"
-
-namespace KJS {
-
-// ------------------------------ Reference ------------------------------------
-
-Reference::Reference(JSObject *b, const Identifier& p)
-  : base(b),
-    propertyNameIsNumber(false),
-    prop(p)
-{
-}
-
-Reference::Reference(JSObject *b, unsigned p)
-  : base(b),
-    propertyNameAsNumber(p),
-    propertyNameIsNumber(true)
-{
-}
-
-Identifier Reference::getPropertyName() const
-{
-  if (propertyNameIsNumber && prop.isNull())
-    prop = Identifier::from(propertyNameAsNumber);
-  return prop;
-}
-
-JSValue *Reference::getValue(ExecState *exec) const 
-{
-  JSValue *o = base;
-  if (!o || !o->isObject()) {
-    if (!o || o->isNull())
-      return throwError(exec, ReferenceError, "Can't find variable: " + getPropertyName().ustring());
-    return throwError(exec, ReferenceError, "Base is not an object");
-  }
-
-  if (propertyNameIsNumber)
-    return static_cast<JSObject*>(o)->get(exec, propertyNameAsNumber);
-  return static_cast<JSObject*>(o)->get(exec, prop);
-}
-
-bool Reference::deleteValue(ExecState *exec)
-{
-  JSValue *o = base;
-  JSType t = o ? o->type() : NullType;
-
-  // The spec doesn't mention what to do if the base is null... just return true
-  if (t != ObjectType) {
-    assert(t == NullType);
-    return true;
-  }
-
-  if (propertyNameIsNumber)
-    return static_cast<JSObject*>(o)->deleteProperty(exec,propertyNameAsNumber);
-  return static_cast<JSObject*>(o)->deleteProperty(exec,prop);
-}
-
-}
diff --git a/JavaScriptCore/kjs/reference.h b/JavaScriptCore/kjs/reference.h
deleted file mode 100644 (file)
index 7c0dca4..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-// -*- c-basic-offset: 2 -*-
-/*
- *  This file is part of the KDE libraries
- *  Copyright (C) 2003 Apple Computer, Inc
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef KJS_REFERENCE_H_
-#define KJS_REFERENCE_H_
-
-#include "object.h"
-
-namespace KJS {
-
-  class JSObject;
-
-  class Reference {
-    friend class ReferenceList;
-    friend class ReferenceListIterator;
-  public:
-    Reference(JSObject *b, const Identifier& p);
-    Reference(JSObject *b, unsigned p);
-    
-    /**
-     * Performs the GetPropertyName type conversion operation on this value
-     * (ECMA 8.7)
-     */
-    Identifier getPropertyName() const;
-
-    /**
-     * Performs the GetValue type conversion operation on this value
-     * (ECMA 8.7.1)
-     */
-    JSValue *getValue(ExecState *exec) const;
-
-    /**
-     * Performs the PutValue type conversion operation on this value
-     * (ECMA 8.7.1)
-     */
-    bool deleteValue(ExecState *exec);
-
-  protected:
-    JSValue *base;
-
-  private:
-    Reference() { }
-
-    unsigned propertyNameAsNumber;
-    bool propertyNameIsNumber;
-    mutable Identifier prop;
-  };
-
-}
-
-#endif
diff --git a/JavaScriptCore/kjs/reference_list.cpp b/JavaScriptCore/kjs/reference_list.cpp
deleted file mode 100644 (file)
index 149f394..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-// -*- c-basic-offset: 2 -*-
-/*
- *  This file is part of the KDE libraries
- *  Copyright (C) 2003 Apple Computer, Inc
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "reference_list.h"
-
-#include "protected_reference.h"
-
-namespace KJS {
-  class ReferenceListNode {
-    friend class ReferenceList;
-    friend class ReferenceListIterator;
-
-  protected:
-    ReferenceListNode(const Reference &ref) : reference(ref), next(NULL) {}
-
-  private:
-    ProtectedReference reference;
-    ReferenceListNode *next;
-  };
-
-  class ReferenceListHeadNode : ReferenceListNode {
-    friend class ReferenceList;
-    friend class ReferenceListIterator;
-    
-    ReferenceListHeadNode(const Reference &ref) : ReferenceListNode(ref), refcount(1) {}
-    int refcount;
-    int length;
-  };
-
-}
-
-using namespace KJS;
-
-// ReferenceList
-
-ReferenceList::ReferenceList() : 
-  head(NULL),
-  tail(NULL)
-{
-}
-
-ReferenceList::ReferenceList(const ReferenceList &list)
-{
-  head = list.head;
-  tail = list.tail;
-  if (head != NULL) {
-    head->refcount++;
-  }
-}
-
-ReferenceList &ReferenceList::operator=(const ReferenceList &list)
-{
-  ReferenceList tmp(list);
-  tmp.swap(*this);
-
-  return *this;
-}
-
-void ReferenceList::swap(ReferenceList &list)
-{
-  ReferenceListHeadNode *tmpHead = list.head;
-  list.head = head;
-  head = tmpHead;
-
-  ReferenceListNode *tmpTail = list.tail;
-  list.tail = tail;
-  tail = tmpTail;
-}
-
-
-void ReferenceList::append(const Reference& ref)
-{
-  if (tail == NULL) {
-    tail = head = new ReferenceListHeadNode(ref);
-  } else {
-    tail->next = new ReferenceListNode(ref);
-    tail = tail->next;
-  }
-  head->length++;
-}
-
-int ReferenceList::length()
-{
-  return head ? head->length : 0;
-}
-
-ReferenceList::~ReferenceList()
-{
-  if (head != NULL && --(head->refcount) == 0) {
-    ReferenceListNode *next;
-    
-    for (ReferenceListNode *p = head; p != NULL; p = next) {
-      next = p->next;
-      if (p == head) {
-        delete (ReferenceListHeadNode *)p;
-      } else {
-        delete p;
-      }
-    }
-  }
-}
-    
-ReferenceListIterator ReferenceList::begin() const
-{
-  return ReferenceListIterator(head);
-}
-
-ReferenceListIterator ReferenceList::end() const
-{
-  return ReferenceListIterator(NULL);
-}
-
-
-// ReferenceListIterator
-
-
-ReferenceListIterator::ReferenceListIterator(ReferenceListNode *n) :
-  node(n)
-{
-}
-
-bool ReferenceListIterator::operator!=(const ReferenceListIterator &it) const 
-{ 
-  return node != it.node;
-}
-
-const Reference *ReferenceListIterator::operator->() const 
-{ 
-  return &node->reference;
-}
-
-const Reference &ReferenceListIterator::operator++(int) 
-{
-  const Reference &ref = node->reference;
-  node = node->next;
-  return ref;
-}
diff --git a/JavaScriptCore/kjs/reference_list.h b/JavaScriptCore/kjs/reference_list.h
deleted file mode 100644 (file)
index dcd4891..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-// -*- c-basic-offset: 2 -*-
-/*
- *  This file is part of the KDE libraries
- *  Copyright (C) 2003 Apple Computer, Inc
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef KJS_REFERENCE_LIST_H_
-#define KJS_REFERENCE_LIST_H_
-
-#include "reference.h"
-
-namespace KJS {
-
-  class ReferenceListNode;
-  class ReferenceListHeadNode;
-
-  class ReferenceListIterator {
-    friend class ReferenceList;
-  
-  public:
-    bool operator!=(const ReferenceListIterator &it) const;
-    const Reference *operator->() const;
-    const Reference &operator++(int i);
-    
-  private:
-    ReferenceListIterator(ReferenceListNode *n);
-    ReferenceListIterator();
-    ReferenceListNode *node;
-  };
-  
-  class ReferenceList {
-  public:
-    ReferenceList();
-    ReferenceList(const ReferenceList &list);
-    ReferenceList &operator=(const ReferenceList &list);
-    ~ReferenceList();
-
-    void append(const Reference& val);
-    int length();
-
-    ReferenceListIterator begin() const;
-    ReferenceListIterator end() const;
-    
-  private:
-    void swap(ReferenceList &list);
-    ReferenceListHeadNode *head;
-    ReferenceListNode *tail;
-  }; 
-  
-}
-
-#endif
index 19b662e..3a50f44 100644 (file)
@@ -21,7 +21,8 @@
 
 #include "config.h"
 #include "scope_chain.h"
-#include "reference_list.h"
+#include "PropertyNameArray.h"
+#include "object.h"
 
 namespace KJS {
 
@@ -42,13 +43,14 @@ void ScopeChain::print()
     ScopeChainIterator scopeEnd = end();
     for (ScopeChainIterator scopeIter = begin(); scopeIter != scopeEnd; ++scopeIter) {
         JSObject* o = *scopeIter;
-        ReferenceList propertyList;
-        o->getPropertyList(propertyList, false);
-        ReferenceListIterator propEnd = propertyList.end();
+        PropertyNameArray propertyNames;
+        // FIXME: should pass ExecState here!
+        o->getPropertyNames(0, propertyNames);
+        PropertyNameArrayIterator propEnd = propertyNames.end();
 
         fprintf(stderr, "----- [scope %p] -----\n", o);
-        for (ReferenceListIterator propIter = propertyList.begin(); propIter != propEnd; propIter++) {
-            Identifier name = propIter->getPropertyName();
+        for (PropertyNameArrayIterator propIter = propertyNames.begin(); propIter != propEnd; propIter++) {
+            Identifier name = *propIter;
             fprintf(stderr, "%s, ", name.ascii());
         }
         fprintf(stderr, "\n");
index 564e2e1..6419edc 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "error_object.h"
 #include "operations.h"
-#include "reference_list.h"
+#include "PropertyNameArray.h"
 #include "regexp_object.h"
 #include <wtf/unicode/Unicode.h>
 
@@ -94,13 +94,12 @@ bool StringInstance::deleteProperty(ExecState *exec, const Identifier &propertyN
   return JSObject::deleteProperty(exec, propertyName);
 }
 
-void StringInstance::getPropertyList(ReferenceList& propertyList, bool recursive)
+void StringInstance::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
 {
-  //### FIXME: should avoid duplicates with prototype
   int size = internalValue()->getString().size();
   for (int i = 0; i < size; i++)
-    propertyList.append(Reference(this, i));
-  return JSObject::getPropertyList(propertyList, recursive);
+    propertyNames.add(Identifier(UString(i)));
+  return JSObject::getPropertyNames(exec, propertyNames);
 }
 
 // ------------------------------ StringPrototype ---------------------------
index 77ef403..a4e208a 100644 (file)
@@ -31,10 +31,10 @@ namespace KJS {
     StringInstance(JSObject *proto);
     StringInstance(JSObject *proto, const UString &string);
 
-    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
-    virtual void put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr = None);
-    virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
-    virtual void getPropertyList(ReferenceList& propertyList, bool recursive);
+    virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+    virtual void put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr = None);
+    virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName);
+    virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
     virtual const ClassInfo *classInfo() const { return &info; }
     static const ClassInfo info;
index 53a0827..ecd513d 100644 (file)
@@ -132,6 +132,7 @@ namespace KJS {
      * @return Higher byte.
      */
     unsigned char high() const { return ref().uc >> 8; }
+
   private:
     // not implemented, can only be constructed from UString
     UCharReference();
@@ -215,6 +216,7 @@ namespace KJS {
     };
 
   public:
+
     /**
      * Constructs a null string.
      */
index 4194f48..2795035 100644 (file)
@@ -1,3 +1,17 @@
+2006-07-15  Maciej Stachowiak  <mjs@apple.com>
+
+        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:
+
 === Safari-521.17 ===
 
 2006-07-14  Geoffrey Garen  <ggaren@apple.com>
index 7cfbd72..22d52f3 100644 (file)
@@ -34,7 +34,7 @@
 #include "UserObjectImp.h"
 #include "JSValueWrapper.h"
 #include "JSObject.h"
-#include <JavaScriptCore/reference_list.h>
+#include <JavaScriptCore/PropertyNameArray.h>
 
 struct ObjectImpList {
     JSObject* imp;
@@ -294,13 +294,13 @@ CFTypeRef KJSValueToCFTypeInternal(JSValue *inValue, ExecState *exec, ObjectImpL
                         isArray = true;
                         JSInterpreter* intrepreter = (JSInterpreter*)exec->dynamicInterpreter();
                         if (intrepreter && (intrepreter->Flags() & kJSFlagConvertAssociativeArray)) {
-                            ReferenceList propList;
-                            object->getPropertyList(propList);
-                            ReferenceListIterator iter = propList.begin();
-                            ReferenceListIterator end = propList.end();
+                            PropertyNameArray propNames;
+                            object->getPropertyNames(exec, propNames);
+                            PropertyNameArrayIterator iter = propNames.begin();
+                            PropertyNameArrayIterator end = propNames.end();
                             while(iter != end && isArray)
                             {
-                                Identifier propName = iter->getPropertyName();
+                                Identifier propName = *iter;
                                 UString ustr = propName.ustring();
                                 const UniChar* uniChars = (const UniChar*)ustr.data();
                                 int size = ustr.size();
@@ -333,8 +333,8 @@ CFTypeRef KJSValueToCFTypeInternal(JSValue *inValue, ExecState *exec, ObjectImpL
                     else
                     {
                         // Not an array, just treat it like a dictionary which contains (property name, property value) pairs
-                        ReferenceList propList;
-                        object->getPropertyList(propList);
+                        PropertyNameArray propNames;
+                        object->getPropertyNames(exec, propNames);
                         {
                             result = CFDictionaryCreateMutable(0,
                                                                0,
@@ -342,11 +342,11 @@ CFTypeRef KJSValueToCFTypeInternal(JSValue *inValue, ExecState *exec, ObjectImpL
                                                                &kCFTypeDictionaryValueCallBacks);
                             if (result)
                             {
-                                ReferenceListIterator iter = propList.begin();
-                                ReferenceListIterator end = propList.end();
+                                PropertyNameArrayIterator iter = propNames.begin();
+                                PropertyNameArrayIterator end = propNames.end();
                                 while(iter != end)
                                 {
-                                    Identifier propName = iter->getPropertyName();
+                                    Identifier propName = *iter;
                                     if (object->hasProperty(exec, propName))
                                     {
                                         CFStringRef cfKey = IdentifierToCFString(propName);
index b4b6dd2..9f8fa3e 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "config.h"
 #include "JSValueWrapper.h"
-#include "JavaScriptCore/reference_list.h"
+#include <JavaScriptCore/PropertyNameArray.h>
 #include <pthread.h>
 
 JSValueWrapper::JSValueWrapper(JSValue *inValue)
@@ -118,12 +118,12 @@ CFArrayRef JSValueWrapper::JSObjectCopyPropertyNames(void *data)
     {
         ExecState* exec = getThreadGlobalExecState();
         JSObject *object = ptr->GetValue()->toObject(exec);
-        ReferenceList propList;
-        object->getPropertyList(propList);
-        ReferenceListIterator iterator = propList.begin();
+        PropertyNameArray propNames;
+        object->getPropertyNames(exec, propNames);
+        PropertyNameArrayIterator iterator = propNames.begin();
 
-        while (iterator != propList.end()) {
-            Identifier name = iterator->getPropertyName();
+        while (iterator != propNames.end()) {
+            Identifier name = *iterator;
             CFStringRef nameStr = IdentifierToCFString(name);
 
             if (!result)
index a569925..247dde6 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "config.h"
 #include "UserObjectImp.h"
-#include <JavaScriptCore/reference_list.h>
+#include <JavaScriptCore/PropertyNameArray.h>
 
 const ClassInfo UserObjectImp::info = {"UserObject", 0, 0, 0};
 
@@ -122,7 +122,7 @@ JSValue *UserObjectImp::callAsFunction(ExecState *exec, JSObject *thisObj, const
 }
 
 
-void UserObjectImp::getPropertyList(ExecState *exec, ReferenceList& propertyList, bool recursive)
+void UserObjectImp::getPropertyNames(ExecState *exec, PropertyNameArray& propertyNames)
 {
     JSUserObject* ptr = GetJSUserObject();
     if (ptr) {
@@ -132,12 +132,12 @@ void UserObjectImp::getPropertyList(ExecState *exec, ReferenceList& propertyList
             CFIndex i;
             for (i = 0; i < count; i++) {
                 CFStringRef propertyName = (CFStringRef)CFArrayGetValueAtIndex(cfPropertyNames, i);
-                propertyList.append(Reference(this, CFStringToIdentifier(propertyName)));
+                propertyNames.add(CFStringToIdentifier(propertyName));
             }
             CFRelease(cfPropertyNames);
         }
     }
-    JSObject::getPropertyList(propertyList, recursive);
+    JSObject::getPropertyNames(exec, propertyNames);
 }
 
 JSValue *UserObjectImp::userObjectGetter(ExecState *, JSObject *, const Identifier& propertyName, const PropertySlot& slot)
index e046123..5ac0f99 100644 (file)
@@ -44,7 +44,7 @@ public:
 
     virtual bool implementsCall() const;
 
-    virtual void getPropertyList(ExecState *exec, ReferenceList& propertyList, bool recursive = true);
+    virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
     virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
     virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
index 848a0c5..ba38d6e 100644 (file)
@@ -1,3 +1,14 @@
+2006-07-16  Maciej Stachowiak  <mjs@apple.com>
+
+        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.
+
 2006-07-15  Darin Adler  <darin@apple.com>
 
         Reviewed by John Sullivan.
diff --git a/LayoutTests/fast/js/for-in-avoid-duplicates-expected.txt b/LayoutTests/fast/js/for-in-avoid-duplicates-expected.txt
new file mode 100644 (file)
index 0000000..9b63196
--- /dev/null
@@ -0,0 +1,10 @@
+This tests that for/in statements don't report properties that are in both an object ant its prototype more than once.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS i is 2
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/for-in-avoid-duplicates.html b/LayoutTests/fast/js/for-in-avoid-duplicates.html
new file mode 100644 (file)
index 0000000..31ccf82
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="resources/js-test-style.css">
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/for-in-avoid-duplicates.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
index d541eb9..3559843 100644 (file)
@@ -65,10 +65,10 @@ PASS arr.length is 40
 PASS arr[maxint] is undefined
 PASS arr.length is maxint
 PASS arr[maxint-1] is "test2"
-FAIL propnames.length should be 3 (of type number). Was 4 (of type number).
+PASS propnames.length is 3
 PASS propnames[0] is '0'
 PASS propnames[1] is '1'
-FAIL propnames[2] should be 2 (of type string). Was 1 (of type string).
+PASS propnames[2] is '2'
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/fast/js/resources/for-in-avoid-duplicates.js b/LayoutTests/fast/js/resources/for-in-avoid-duplicates.js
new file mode 100644 (file)
index 0000000..3358fa8
--- /dev/null
@@ -0,0 +1,22 @@
+description(
+"This tests that for/in statements don't report properties that are in both an object and its prototype more than once."
+);
+
+
+function constr() {
+    this.xxx = "foo";
+    this.yyy = "bar";
+}
+
+constructor.prototype = { xxx: "baz", yyy: "quux" };
+
+var obj = new constr();
+
+var i = 0;
+for (var prop in obj) {
+    ++i;
+}
+
+shouldBe("i", "2");
+
+var successfullyParsed = true;