[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

commit-queue at webkit.org commit-queue at webkit.org
Wed Dec 22 11:10:41 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 7d451b73af769652b059a0e62cdbb3c55f92be72
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Jul 14 14:35:08 2010 +0000

    2010-07-14  Jedrzej Nowacki  <jedrzej.nowacki at nokia.com>
    
            Reviewed by Kenneth Rohde Christiansen.
    
            Introduce QScriptOriginalGlobalObject.
    
            QtScript exposes more functionality than JSC C API. Sometimes it is
            necessary to take a shortcut in implementation. Really often we have
            to use a standard JS function. These function could be changed or
            even deleted by a script, so a backup of a reference to an object is needed.
    
            In them same time this is rather a workaround then real fix, so the code
            should be separated and changed easily in future. It is why we need
            the new internal class.
    
            The patch fixes a few crashes.
    
            [Qt] QScriptEngine should work correctly even after global object changes
            https://bugs.webkit.org/show_bug.cgi?id=41839
    
            * api/QtScript.pro:
            * api/qscriptengine_p.cpp:
            (QScriptEnginePrivate::QScriptEnginePrivate):
            (QScriptEnginePrivate::~QScriptEnginePrivate):
            * api/qscriptengine_p.h:
            (QScriptEnginePrivate::isArray):
            (QScriptEnginePrivate::isError):
            (QScriptEnginePrivate::objectHasOwnProperty):
            (QScriptEnginePrivate::objectGetOwnPropertyNames):
            * api/qscriptoriginalglobalobject_p.h: Added.
            (QScriptOriginalGlobalObject::QScriptOriginalGlobalObject):
            (QScriptOriginalGlobalObject::initializeMember):
            (QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject):
            (QScriptOriginalGlobalObject::objectHasOwnProperty):
            (QScriptOriginalGlobalObject::objectGetOwnPropertyNames):
            (QScriptOriginalGlobalObject::isArray):
            (QScriptOriginalGlobalObject::isError):
            (QScriptOriginalGlobalObject::isType):
            * api/qscriptvalue_p.h:
            (QScriptValuePrivate::isError):
            (QScriptValuePrivate::hasOwnProperty):
            * api/qscriptvalueiterator_p.h:
            (QScriptValueIteratorPrivate::QScriptValueIteratorPrivate):
            * tests/qscriptvalue/tst_qscriptvalue.cpp:
            (tst_QScriptValue::globalObjectChanges):
            * tests/qscriptvalue/tst_qscriptvalue.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@63318 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/qt/ChangeLog b/JavaScriptCore/qt/ChangeLog
index 2599aed..448a59e 100644
--- a/JavaScriptCore/qt/ChangeLog
+++ b/JavaScriptCore/qt/ChangeLog
@@ -1,3 +1,50 @@
+2010-07-14  Jedrzej Nowacki  <jedrzej.nowacki at nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        Introduce QScriptOriginalGlobalObject.
+
+        QtScript exposes more functionality than JSC C API. Sometimes it is
+        necessary to take a shortcut in implementation. Really often we have
+        to use a standard JS function. These function could be changed or
+        even deleted by a script, so a backup of a reference to an object is needed.
+
+        In them same time this is rather a workaround then real fix, so the code
+        should be separated and changed easily in future. It is why we need
+        the new internal class.
+
+        The patch fixes a few crashes.
+
+        [Qt] QScriptEngine should work correctly even after global object changes
+        https://bugs.webkit.org/show_bug.cgi?id=41839
+
+        * api/QtScript.pro:
+        * api/qscriptengine_p.cpp:
+        (QScriptEnginePrivate::QScriptEnginePrivate):
+        (QScriptEnginePrivate::~QScriptEnginePrivate):
+        * api/qscriptengine_p.h:
+        (QScriptEnginePrivate::isArray):
+        (QScriptEnginePrivate::isError):
+        (QScriptEnginePrivate::objectHasOwnProperty):
+        (QScriptEnginePrivate::objectGetOwnPropertyNames):
+        * api/qscriptoriginalglobalobject_p.h: Added.
+        (QScriptOriginalGlobalObject::QScriptOriginalGlobalObject):
+        (QScriptOriginalGlobalObject::initializeMember):
+        (QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject):
+        (QScriptOriginalGlobalObject::objectHasOwnProperty):
+        (QScriptOriginalGlobalObject::objectGetOwnPropertyNames):
+        (QScriptOriginalGlobalObject::isArray):
+        (QScriptOriginalGlobalObject::isError):
+        (QScriptOriginalGlobalObject::isType):
+        * api/qscriptvalue_p.h:
+        (QScriptValuePrivate::isError):
+        (QScriptValuePrivate::hasOwnProperty):
+        * api/qscriptvalueiterator_p.h:
+        (QScriptValueIteratorPrivate::QScriptValueIteratorPrivate):
+        * tests/qscriptvalue/tst_qscriptvalue.cpp:
+        (tst_QScriptValue::globalObjectChanges):
+        * tests/qscriptvalue/tst_qscriptvalue.h:
+
 2010-07-13  Jedrzej Nowacki  <jedrzej.nowacki at nokia.com>
 
         Reviewed by Simon Hausmann.
diff --git a/JavaScriptCore/qt/api/QtScript.pro b/JavaScriptCore/qt/api/QtScript.pro
index fb49cfe..c2c6f83 100644
--- a/JavaScriptCore/qt/api/QtScript.pro
+++ b/JavaScriptCore/qt/api/QtScript.pro
@@ -42,6 +42,7 @@ HEADERS +=  $$PWD/qtscriptglobal.h \
             $$PWD/qscriptprogram.h \
             $$PWD/qscriptprogram_p.h \
             $$PWD/qscriptsyntaxcheckresult.h \
+            $$PWD/qscriptoriginalglobalobject_p.h \
 
 
 !static: DEFINES += QT_MAKEDLL
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.cpp b/JavaScriptCore/qt/api/qscriptengine_p.cpp
index 360de29..e3311ed 100644
--- a/JavaScriptCore/qt/api/qscriptengine_p.cpp
+++ b/JavaScriptCore/qt/api/qscriptengine_p.cpp
@@ -32,32 +32,12 @@ QScriptEnginePrivate::QScriptEnginePrivate(const QScriptEngine* engine)
     : q_ptr(const_cast<QScriptEngine*>(engine))
     , m_context(JSGlobalContextCreate(0))
     , m_exception(0)
-    , m_arrayConstructor(0)
-    , m_arrayPrototype(0)
+    , m_originalGlobalObject(m_context)
 {
-    JSObjectRef globalObject = JSContextGetGlobalObject(m_context);
-
-    // Save references to the Array constructor and prototype.
-    JSRetainPtr<JSStringRef> arrayName(Adopt, JSStringCreateWithUTF8CString("Array"));
-    JSValueRef arrayConstructor = JSObjectGetProperty(m_context, globalObject, arrayName.get(), /* exception */ 0);
-    Q_ASSERT(JSValueIsObject(m_context, arrayConstructor));
-    m_arrayConstructor = JSValueToObject(m_context, arrayConstructor, /* exception */ 0);
-    JSValueProtect(m_context, m_arrayConstructor);
-
-    // Note that this is not the [[Prototype]] internal property (which we could
-    // get via JSObjectGetPrototype), but the Array.prototype, that will be set
-    // as [[Prototype]] of Array instances.
-    JSRetainPtr<JSStringRef> prototypeName(Adopt, JSStringCreateWithUTF8CString("prototype"));
-    JSValueRef arrayPrototype = JSObjectGetProperty(m_context, m_arrayConstructor, prototypeName.get(), /* exception */ 0);
-    Q_ASSERT(JSValueIsObject(m_context, arrayPrototype));
-    m_arrayPrototype = arrayPrototype;
-    JSValueProtect(m_context, m_arrayPrototype);
 }
 
 QScriptEnginePrivate::~QScriptEnginePrivate()
 {
-    JSValueUnprotect(m_context, m_arrayConstructor);
-    JSValueUnprotect(m_context, m_arrayPrototype);
     if (m_exception)
         JSValueUnprotect(m_context, m_exception);
     JSGlobalContextRelease(m_context);
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.h b/JavaScriptCore/qt/api/qscriptengine_p.h
index 401c051..d54cdcc 100644
--- a/JavaScriptCore/qt/api/qscriptengine_p.h
+++ b/JavaScriptCore/qt/api/qscriptengine_p.h
@@ -22,6 +22,7 @@
 
 #include "qscriptconverter_p.h"
 #include "qscriptengine.h"
+#include "qscriptoriginalglobalobject_p.h"
 #include "qscriptstring_p.h"
 #include "qscriptsyntaxcheckresult_p.h"
 #include "qscriptvalue.h"
@@ -79,13 +80,15 @@ public:
     inline operator JSGlobalContextRef() const;
 
     inline bool isArray(JSValueRef value) const;
+    inline bool isError(JSValueRef value) const;
+    inline bool objectHasOwnProperty(JSObjectRef object, JSStringRef property) const;
+    inline QVector<JSStringRef> objectGetOwnPropertyNames(JSObjectRef object) const;
 private:
     QScriptEngine* q_ptr;
     JSGlobalContextRef m_context;
     JSValueRef m_exception;
 
-    JSObjectRef m_arrayConstructor;
-    JSValueRef m_arrayPrototype;
+    QScriptOriginalGlobalObject m_originalGlobalObject;
 };
 
 
@@ -218,9 +221,24 @@ QScriptEnginePrivate::operator JSGlobalContextRef() const
 
 bool QScriptEnginePrivate::isArray(JSValueRef value) const
 {
-    // JSC API doesn't export the [[Class]] information for the builtins. But we know that a value
-    // is an array if it was created with the Array constructor or if it is the Array.prototype.
-    return JSValueIsInstanceOfConstructor(m_context, value, m_arrayConstructor, /* exception */ 0) || JSValueIsStrictEqual(m_context, value, m_arrayPrototype);
+    return m_originalGlobalObject.isArray(value);
+}
+
+bool QScriptEnginePrivate::isError(JSValueRef value) const
+{
+    return m_originalGlobalObject.isError(value);
+}
+
+inline bool QScriptEnginePrivate::objectHasOwnProperty(JSObjectRef object, JSStringRef property) const
+{
+    // FIXME We need a JSC C API function for this.
+    return m_originalGlobalObject.objectHasOwnProperty(object, property);
+}
+
+inline QVector<JSStringRef> QScriptEnginePrivate::objectGetOwnPropertyNames(JSObjectRef object) const
+{
+    // FIXME We can't use C API function JSObjectGetPropertyNames as it returns only enumerable properties.
+    return m_originalGlobalObject.objectGetOwnPropertyNames(object);
 }
 
 #endif
diff --git a/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h b/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h
new file mode 100644
index 0000000..8d080fb
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h
@@ -0,0 +1,186 @@
+/*
+    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 qscriptoriginalglobalobject_p_h
+#define qscriptoriginalglobalobject_p_h
+
+#include <JavaScriptCore/JavaScript.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <QtCore/qvector.h>
+
+/*!
+    \internal
+    This class is a workaround for missing JSC C API functionality. This class keeps all important
+    properties of an original (default) global object, so we can use it even if the global object was
+    changed.
+
+    FIXME this class is a container for workarounds :-) it should be replaced by proper JSC C API calls.
+
+    The class have to be created on the QScriptEnginePrivate creation time (before any change got applied to
+    global object).
+*/
+class QScriptOriginalGlobalObject {
+public:
+    inline QScriptOriginalGlobalObject(JSGlobalContextRef context);
+    inline ~QScriptOriginalGlobalObject();
+
+    inline bool objectHasOwnProperty(JSObjectRef object, JSStringRef property) const;
+    inline QVector<JSStringRef> objectGetOwnPropertyNames(JSObjectRef object) const;
+
+    inline bool isArray(JSValueRef value) const;
+    inline bool isError(JSValueRef value) const;
+private:
+    inline bool isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const;
+    inline void initializeMember(JSObjectRef globalObject, JSStringRef prototypeName, const char* type, JSObjectRef& constructor, JSValueRef& prototype);
+
+    // Copy of the global context reference (the same as in QScriptEnginePrivate).
+    JSGlobalContextRef m_context;
+
+    // Copy of constructors and prototypes used in isType functions.
+    JSObjectRef m_arrayConstructor;
+    JSValueRef m_arrayPrototype;
+    JSObjectRef m_errorConstructor;
+    JSValueRef m_errorPrototype;
+
+    // Reference to standard JS functions that are not exposed by JSC C API.
+    JSObjectRef m_hasOwnPropertyFunction;
+    JSObjectRef m_getOwnPropertyNamesFunction;
+};
+
+QScriptOriginalGlobalObject::QScriptOriginalGlobalObject(JSGlobalContextRef context)
+    : m_context(JSGlobalContextRetain(context))
+{
+    JSObjectRef globalObject = JSContextGetGlobalObject(m_context);
+    JSValueRef exception = 0;
+    JSRetainPtr<JSStringRef> propertyName;
+
+    propertyName.adopt(JSStringCreateWithUTF8CString("prototype"));
+    initializeMember(globalObject, propertyName.get(), "Array", m_arrayConstructor, m_arrayPrototype);
+    initializeMember(globalObject, propertyName.get(), "Error", m_errorConstructor, m_errorPrototype);
+
+    propertyName.adopt(JSStringCreateWithUTF8CString("hasOwnProperty"));
+    m_hasOwnPropertyFunction = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, globalObject, propertyName.get(), &exception));
+    JSValueProtect(m_context, m_hasOwnPropertyFunction);
+    Q_ASSERT(JSValueIsObject(m_context, m_hasOwnPropertyFunction));
+    Q_ASSERT(JSObjectIsFunction(m_context, m_hasOwnPropertyFunction));
+    Q_ASSERT(!exception);
+
+    propertyName.adopt(JSStringCreateWithUTF8CString("Object"));
+    JSObjectRef objectConstructor
+            = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, globalObject, propertyName.get(), &exception));
+    propertyName.adopt(JSStringCreateWithUTF8CString("getOwnPropertyNames"));
+    m_getOwnPropertyNamesFunction
+            = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, objectConstructor, propertyName.get(), &exception));
+    JSValueProtect(m_context, m_getOwnPropertyNamesFunction);
+    Q_ASSERT(JSValueIsObject(m_context, m_getOwnPropertyNamesFunction));
+    Q_ASSERT(JSObjectIsFunction(m_context, m_getOwnPropertyNamesFunction));
+    Q_ASSERT(!exception);
+}
+
+inline void QScriptOriginalGlobalObject::initializeMember(JSObjectRef globalObject, JSStringRef prototypeName, const char* type, JSObjectRef& constructor, JSValueRef& prototype)
+{
+    JSRetainPtr<JSStringRef> typeName(Adopt, JSStringCreateWithUTF8CString(type));
+    JSValueRef exception = 0;
+
+    // Save references to the Type constructor and prototype.
+    JSValueRef typeConstructor = JSObjectGetProperty(m_context, globalObject, typeName.get(), &exception);
+    Q_ASSERT(JSValueIsObject(m_context, typeConstructor));
+    constructor = JSValueToObject(m_context, typeConstructor, &exception);
+    JSValueProtect(m_context, constructor);
+
+    // Note that this is not the [[Prototype]] internal property (which we could
+    // get via JSObjectGetPrototype), but the Type.prototype, that will be set
+    // as [[Prototype]] of Type instances.
+    prototype = JSObjectGetProperty(m_context, constructor, prototypeName, &exception);
+    Q_ASSERT(JSValueIsObject(m_context, prototype));
+    JSValueProtect(m_context, prototype);
+    Q_ASSERT(!exception);
+}
+
+QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject()
+{
+    JSValueUnprotect(m_context, m_arrayConstructor);
+    JSValueUnprotect(m_context, m_arrayPrototype);
+    JSValueUnprotect(m_context, m_errorConstructor);
+    JSValueUnprotect(m_context, m_errorPrototype);
+    JSValueUnprotect(m_context, m_hasOwnPropertyFunction);
+    JSValueUnprotect(m_context, m_getOwnPropertyNamesFunction);
+    JSGlobalContextRelease(m_context);
+}
+
+inline bool QScriptOriginalGlobalObject::objectHasOwnProperty(JSObjectRef object, JSStringRef property) const
+{
+    // FIXME This function should be replaced by JSC C API.
+    JSValueRef exception = 0;
+    JSValueRef propertyName[] = { JSValueMakeString(m_context, property) };
+    JSValueRef result = JSObjectCallAsFunction(m_context, m_hasOwnPropertyFunction, object, 1, propertyName, &exception);
+    return exception ? false : JSValueToBoolean(m_context, result);
+}
+
+/*!
+    \internal
+    This method gives ownership of all JSStringRefs.
+*/
+inline QVector<JSStringRef> QScriptOriginalGlobalObject::objectGetOwnPropertyNames(JSObjectRef object) const
+{
+    JSValueRef exception = 0;
+    JSObjectRef propertyNames
+            = const_cast<JSObjectRef>(JSObjectCallAsFunction(m_context,
+                                                            m_getOwnPropertyNamesFunction,
+                                                            /* thisObject */ 0,
+                                                            /* argumentCount */ 1,
+                                                            &object,
+                                                            &exception));
+    Q_ASSERT(JSValueIsObject(m_context, propertyNames));
+    Q_ASSERT(!exception);
+    JSStringRef lengthName = QScriptConverter::toString("length");
+    int count = JSValueToNumber(m_context, JSObjectGetProperty(m_context, propertyNames, lengthName, &exception), &exception);
+
+    Q_ASSERT(!exception);
+    QVector<JSStringRef> names;
+    names.reserve(count);
+    for (int i = 0; i < count; ++i) {
+        JSValueRef tmp = JSObjectGetPropertyAtIndex(m_context, propertyNames, i, &exception);
+        names.append(JSValueToStringCopy(m_context, tmp, &exception));
+        Q_ASSERT(!exception);
+    }
+    return names;
+}
+
+inline bool QScriptOriginalGlobalObject::isArray(JSValueRef value) const
+{
+    return isType(value, m_arrayConstructor, m_arrayPrototype);
+}
+
+inline bool QScriptOriginalGlobalObject::isError(JSValueRef value) const
+{
+    return isType(value, m_errorConstructor, m_errorPrototype);
+}
+
+inline bool QScriptOriginalGlobalObject::isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const
+{
+    // JSC API doesn't export the [[Class]] information for the builtins. But we know that a value
+    // is an object of the Type if it was created with the Type constructor or if it is the Type.prototype.
+    JSValueRef exception = 0;
+    bool result = JSValueIsInstanceOfConstructor(m_context, value, constructor, &exception) || JSValueIsStrictEqual(m_context, value, prototype);
+    Q_ASSERT(!exception);
+    return result;
+}
+
+#endif // qscriptoriginalglobalobject_p_h
diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h
index 1d319ba..6e93a07 100644
--- a/JavaScriptCore/qt/api/qscriptvalue_p.h
+++ b/JavaScriptCore/qt/api/qscriptvalue_p.h
@@ -184,7 +184,6 @@ private:
         Value(QString* string) : m_string(string) {}
     } u;
 
-    inline bool inherits(const char*);
     inline State refinedJSValue();
 
     inline bool isJSBased() const;
@@ -416,7 +415,7 @@ bool QScriptValuePrivate::isError()
             return false;
         // Fall-through.
     case JSObject:
-        return inherits("Error");
+        return m_engine->isError(*this);
     default:
         return false;
     }
@@ -868,13 +867,7 @@ inline bool QScriptValuePrivate::hasOwnProperty(quint32 property)
 inline bool QScriptValuePrivate::hasOwnProperty(JSStringRef property)
 {
     Q_ASSERT(isObject());
-    // FIXME it could be faster, but JSC C API doesn't expose needed functionality.
-    JSRetainPtr<JSStringRef> hasOwnPropertyName(Adopt, JSStringCreateWithUTF8CString("hasOwnProperty"));
-    JSValueRef exception = 0;
-    JSValueRef hasOwnProperty = JSObjectGetProperty(*m_engine, *this, hasOwnPropertyName.get(), &exception);
-    JSValueRef propertyName[] = { JSValueMakeString(*m_engine, property) };
-    JSValueRef result = JSObjectCallAsFunction(*m_engine, const_cast<JSObjectRef>(hasOwnProperty), *this, 1, propertyName, &exception);
-    return exception ? false : JSValueToBoolean(*m_engine, result);
+    return m_engine->objectHasOwnProperty(*this, property);
 }
 
 /*!
@@ -1124,24 +1117,6 @@ QScriptValuePrivate::operator JSObjectRef() const
 
 /*!
   \internal
-  Returns true if QSV is created from constructor with the given \a name, it has to be a
-  built-in type.
-*/
-bool QScriptValuePrivate::inherits(const char* name)
-{
-    Q_ASSERT(isJSBased());
-    JSObjectRef globalObject = JSContextGetGlobalObject(*m_engine);
-    JSStringRef errorAttrName = QScriptConverter::toString(name);
-    JSValueRef exception = 0;
-    JSValueRef error = JSObjectGetProperty(*m_engine, globalObject, errorAttrName, &exception);
-    JSStringRelease(errorAttrName);
-    bool result = JSValueIsInstanceOfConstructor(*m_engine, *this, JSValueToObject(*m_engine, error, &exception), &exception);
-    m_engine->setException(exception);
-    return result;
-}
-
-/*!
-  \internal
   Refines the state of this QScriptValuePrivate. Returns the new state.
 */
 QScriptValuePrivate::State QScriptValuePrivate::refinedJSValue()
diff --git a/JavaScriptCore/qt/api/qscriptvalueiterator_p.h b/JavaScriptCore/qt/api/qscriptvalueiterator_p.h
index 66fc001..b93b518 100644
--- a/JavaScriptCore/qt/api/qscriptvalueiterator_p.h
+++ b/JavaScriptCore/qt/api/qscriptvalueiterator_p.h
@@ -63,42 +63,8 @@ inline QScriptValueIteratorPrivate::QScriptValueIteratorPrivate(const QScriptVal
     : m_object(const_cast<QScriptValuePrivate*>(value))
     , m_idx(m_names)
 {
-    // FIXME There is assumption that global object wasn't changed (bug 41839).
-    // FIXME We can't use C API function JSObjectGetPropertyNames as it returns only enumerable properties.
-    if (const_cast<QScriptValuePrivate*>(value)->isObject()) {
-        static JSStringRef objectName = QScriptConverter::toString("Object");
-        static JSStringRef getOwnPropertyNamesName = QScriptConverter::toString("getOwnPropertyNames");
-
-        JSValueRef exception = 0;
-        JSObjectRef globalObject = JSContextGetGlobalObject(*engine());
-        Q_ASSERT(JSValueIsObject(*engine(), globalObject));
-        JSValueRef objectConstructor = JSObjectGetProperty(*engine(), globalObject, objectName, &exception);
-        Q_ASSERT(JSValueIsObject(*engine(), objectConstructor));
-        Q_ASSERT(!exception);
-        JSValueRef propertyNamesGetter = JSObjectGetProperty(*engine(), const_cast<JSObjectRef>(objectConstructor), getOwnPropertyNamesName, &exception);
-        Q_ASSERT(JSValueIsObject(*engine(), propertyNamesGetter));
-        Q_ASSERT(!exception);
-
-        JSValueRef arguments[] = { *m_object };
-        JSObjectRef propertyNames
-                = const_cast<JSObjectRef>(JSObjectCallAsFunction(*engine(),
-                                                                const_cast<JSObjectRef>(propertyNamesGetter),
-                                                                /* thisObject */ 0,
-                                                                /* argumentCount */ 1,
-                                                                arguments,
-                                                                &exception));
-        Q_ASSERT(JSValueIsObject(*engine(), propertyNames));
-        Q_ASSERT(!exception);
-        static JSStringRef lengthName = QScriptConverter::toString("length");
-        int count = JSValueToNumber(*engine(), JSObjectGetProperty(*engine(), propertyNames, lengthName, &exception), &exception);
-
-        Q_ASSERT(!exception);
-        m_names.reserve(count);
-        for (int i = 0; i < count; ++i) {
-            JSValueRef tmp = JSObjectGetPropertyAtIndex(*engine(), propertyNames, i, &exception);
-            m_names.append(JSValueToStringCopy(*engine(), tmp, &exception));
-            Q_ASSERT(!exception);
-        }
+    if (m_object->isObject()) {
+        m_names = engine()->objectGetOwnPropertyNames(*m_object);
         m_idx = m_names;
     } else
         m_object = 0;
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
index 73b57dc..a82347e 100644
--- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
+++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
@@ -1261,4 +1261,28 @@ void tst_QScriptValue::propertyFlag()
     QVERIFY(!object.propertyFlags(protoNameHandle, QScriptValue::ResolveLocal));
 }
 
+void tst_QScriptValue::globalObjectChanges()
+{
+    // API functionality shouldn't depend on Global Object.
+    QScriptEngine engine;
+    QScriptValue array = engine.newArray();
+    QScriptValue error = engine.evaluate("new Error");
+    QScriptValue object = engine.newObject();
+
+    object.setProperty("foo", 512);
+
+    // Remove properties form global object.
+    engine.evaluate("delete Object; delete Error; delete Array;");
+
+    QVERIFY(array.isArray());
+    QVERIFY(error.isError());
+    QVERIFY(object.isObject());
+
+    QVERIFY(object.property("foo").isValid());
+    QVERIFY(object.property("foo", QScriptValue::ResolveLocal).isValid());
+    object.setProperty("foo", QScriptValue());
+    QVERIFY(!object.property("foo").isValid());
+    QVERIFY(!object.property("foo", QScriptValue::ResolveLocal).isValid());
+}
+
 QTEST_MAIN(tst_QScriptValue)
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
index 6108423..41b99cd 100644
--- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
+++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
@@ -60,6 +60,7 @@ private slots:
     void getPropertyResolveFlag();
     void propertyFlag_data();
     void propertyFlag();
+    void globalObjectChanges();
 
     // Generated test functions.
     void isBool_data();

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list