[webkit-qt] Accessing QObject properties in 2.3.1

Andrew Webster apwebster at gmail.com
Thu Apr 25 08:19:08 PDT 2013


I have ended up enabling
InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero in
RuntimeObject, and implementing getOwnPropertySlotByIndex, which first
attempts to look for a field with that name in the bridged object (much the
same as getOwnPropertySlot).  This seems to solve my specific problem, but
I don't know what other impacts this change might have.  Any comments are
welcome.  Here is the patch:

diff --git a/Source/WebCore/bridge/jsc/BridgeJSC.h
b/Source/WebCore/bridge/jsc/BridgeJSC.h
index 39e6c98..f55c68c 100644
--- a/Source/WebCore/bridge/jsc/BridgeJSC.h
+++ b/Source/WebCore/bridge/jsc/BridgeJSC.h
@@ -104,6 +104,7 @@ public:
     virtual ~Instance();

     virtual bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName,
PropertySlot&) { return false; }
+    virtual bool getOwnPropertySlotByIndex(JSObject*, ExecState*,
unsigned, PropertySlot&) { return false; }
     virtual bool getOwnPropertyDescriptor(JSObject*, ExecState*,
PropertyName, PropertyDescriptor&) { return false; }
     virtual void put(JSObject*, ExecState*, PropertyName, JSValue,
PutPropertySlot&) { }

diff --git a/Source/WebCore/bridge/qt/qt_instance.cpp
b/Source/WebCore/bridge/qt/qt_instance.cpp
index dd1e407..f95eaef 100644
--- a/Source/WebCore/bridge/qt/qt_instance.cpp
+++ b/Source/WebCore/bridge/qt/qt_instance.cpp
@@ -143,6 +143,11 @@ bool QtInstance::getOwnPropertySlot(JSObject* object,
ExecState* exec, PropertyN
     return JSObject::getOwnPropertySlot(object, exec, propertyName, slot);
 }

+bool QtInstance::getOwnPropertySlotByIndex(JSObject* object, ExecState*
exec, unsigned property, PropertySlot& slot)
+{
+    return JSObject::getOwnPropertySlotByIndex(object, exec, property,
slot);
+}
+
 void QtInstance::put(JSObject* object, ExecState* exec, PropertyName
propertyName, JSValue value, PutPropertySlot& slot)
 {
     JSObject::put(object, exec, propertyName, value, slot);
diff --git a/Source/WebCore/bridge/qt/qt_instance.h
b/Source/WebCore/bridge/qt/qt_instance.h
index 09d43bc..bf6bede 100644
--- a/Source/WebCore/bridge/qt/qt_instance.h
+++ b/Source/WebCore/bridge/qt/qt_instance.h
@@ -91,6 +91,7 @@ public:
     static PassRefPtr<QtInstance> getQtInstance(QObject*,
PassRefPtr<RootObject>, ValueOwnership);

     virtual bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName,
PropertySlot&);
+    virtual bool getOwnPropertySlotByIndex(JSObject*, ExecState*,
unsigned, PropertySlot&);
     virtual void put(JSObject*, ExecState*, PropertyName, JSValue,
PutPropertySlot&);

     static QtInstance* getInstance(JSObject*);
diff --git a/Source/WebCore/bridge/runtime_object.cpp
b/Source/WebCore/bridge/runtime_object.cpp
index 783787c7..2667999 100644
--- a/Source/WebCore/bridge/runtime_object.cpp
+++ b/Source/WebCore/bridge/runtime_object.cpp
@@ -161,6 +161,52 @@ bool RuntimeObject::getOwnPropertySlot(JSCell* cell,
ExecState *exec, PropertyNa
     return instance->getOwnPropertySlot(thisObject, exec, propertyName,
slot);
 }

+bool RuntimeObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState*
exec, unsigned property, PropertySlot& slot)
+{
+    RuntimeObject* thisObject = jsCast<RuntimeObject*>(cell);
+    if (!thisObject->m_instance) {
+        throwInvalidAccessError(exec);
+        return false;
+    }
+
+    RefPtr<Instance> instance = thisObject->m_instance;
+
+    instance->begin();
+
+    Class *aClass = instance->getClass();
+
+    if (aClass) {
+        PropertyName propertyName(Identifier::from(exec, property));
+        // See if the instance has a field with the specified name.
+        Field *aField = aClass->fieldNamed(propertyName, instance.get());
+        if (aField) {
+            slot.setCustom(thisObject, thisObject->fieldGetter);
+            instance->end();
+            return true;
+        } else {
+            // Now check if a method with specified name exists, if so
return a function object for
+            // that method.
+            if (aClass->methodNamed(propertyName, instance.get())) {
+                slot.setCustom(thisObject, thisObject->methodGetter);
+
+                instance->end();
+                return true;
+            }
+        }
+
+        // Try a fallback object.
+        if (!aClass->fallbackObject(exec, instance.get(),
propertyName).isUndefined()) {
+            slot.setCustom(thisObject, thisObject->fallbackObjectGetter);
+            instance->end();
+            return true;
+        }
+    }
+
+    instance->end();
+
+    return instance->getOwnPropertySlotByIndex(thisObject, exec, property,
slot);
+}
+
 bool RuntimeObject::getOwnPropertyDescriptor(JSObject* object, ExecState
*exec, PropertyName propertyName, PropertyDescriptor& descriptor)
 {
     RuntimeObject* thisObject = jsCast<RuntimeObject*>(object);
diff --git a/Source/WebCore/bridge/runtime_object.h
b/Source/WebCore/bridge/runtime_object.h
index 8f49d61..ea37b67 100644
--- a/Source/WebCore/bridge/runtime_object.h
+++ b/Source/WebCore/bridge/runtime_object.h
@@ -46,6 +46,7 @@ public:
     static void destroy(JSCell*);

     static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName,
PropertySlot&);
+    static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned,
PropertySlot&);
     static bool getOwnPropertyDescriptor(JSObject*, ExecState*,
PropertyName, PropertyDescriptor&);
     static void put(JSCell*, ExecState*, PropertyName, JSValue,
PutPropertySlot&);
     static bool deleteProperty(JSCell*, ExecState*, PropertyName);
@@ -76,7 +77,7 @@ public:
 protected:
     RuntimeObject(ExecState*, JSGlobalObject*, Structure*,
PassRefPtr<Instance>);
     void finishCreation(JSGlobalObject*);
-    static const unsigned StructureFlags = OverridesGetOwnPropertySlot |
OverridesGetPropertyNames | Base::StructureFlags;
+    static const unsigned StructureFlags = OverridesGetOwnPropertySlot |
InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero |
OverridesGetPropertyNames | Base::StructureFlags;

 private:
     static JSValue fallbackObjectGetter(ExecState*, JSValue, PropertyName);



Thanks,
Andrew


On Tue, Apr 23, 2013 at 8:57 PM, Andrew Webster <apwebster at gmail.com> wrote:

> I very much appreciate the release of 2.3.1.  It's been working pretty
> well for us so far, but I've run into a problem with accessing properties
> under 2.3.1.
>
> Under the 2.2.0, it was possible to access a named child (or dynamic
> property) of a QObject whose name was a number using the JavaScript array
> syntax.  For example, myQObject[0] would return a QRuntimeObject.  Under
> 2.3.1, this returns undefined.  Quoting the number still works:
> myQObject['0'], however we unfortunately need to maintain backwards
> compatibility.
>
> I've been searching around the code trying to find out why this no longer
> works, but I'm not having much success.  I'm not familiar with how the
> JavaScript core works or how it bridges with Qt (e.g. why is
> QtClass::fieldNamed is not called when using [0]?).  Anyone have any ideas
> on where to look?
>
> Thanks,
> Andrew
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-qt/attachments/20130425/1c5f71dc/attachment.html>


More information about the webkit-qt mailing list