[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