aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-06-19 11:50:07 +0200
committerLars Knoll <lars.knoll@qt.io>2018-06-25 07:36:41 +0000
commit4094ce77af45427613e823a2a4d3c6087230d35a (patch)
tree027d8c054435016f1f478790fdcd4ac745ce8048 /src/qml
parent4f5d83acf78c7e3e3f4b89190d6109a4c8fa574d (diff)
Add support for isExtensible in proxy handlers
Change-Id: I580ff0ab33fa58bcd42f6cc500f4a20ee5b05e87 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/jsruntime/qv4object.cpp5
-rw-r--r--src/qml/jsruntime/qv4object_p.h5
-rw-r--r--src/qml/jsruntime/qv4proxy.cpp31
-rw-r--r--src/qml/jsruntime/qv4proxy_p.h1
4 files changed, 41 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 618970b940..751010fa4e 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -1020,6 +1020,11 @@ PropertyAttributes Object::getOwnProperty(Managed *m, Identifier id, Property *p
return Attr_Invalid;
}
+bool Object::isExtensible(const Managed *m)
+{
+ return m->d()->internalClass->extensible;
+}
+
bool Object::setArrayLength(uint newLen)
{
Q_ASSERT(isArrayObject());
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 9354ae0571..a9851984e1 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -177,6 +177,7 @@ struct ObjectVTable
bool (*deleteIndexedProperty)(Managed *m, uint index);
bool (*hasProperty)(const Managed *m, Identifier id);
PropertyAttributes (*getOwnProperty)(Managed *m, Identifier id, Property *p);
+ bool (*isExtensible)(const Managed *);
qint64 (*getLength)(const Managed *m);
void (*advanceIterator)(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
ReturnedValue (*instanceOf)(const Object *typeObject, const Value &var);
@@ -196,6 +197,7 @@ const QV4::ObjectVTable classname::static_vtbl = \
deleteIndexedProperty, \
hasProperty, \
getOwnProperty, \
+ isExtensible, \
getLength, \
advanceIterator, \
instanceOf \
@@ -301,7 +303,7 @@ struct Q_QML_EXPORT Object: Managed {
}
void insertMember(StringOrSymbol *s, const Property *p, PropertyAttributes attributes);
- bool isExtensible() const { return d()->internalClass->extensible; }
+ bool isExtensible() const { return vtable()->isExtensible(this); }
// Array handling
@@ -438,6 +440,7 @@ protected:
static bool deleteIndexedProperty(Managed *m, uint index);
static bool hasProperty(const Managed *m, Identifier id);
static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p);
+ static bool isExtensible(const Managed *m);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
static qint64 getLength(const Managed *m);
static ReturnedValue instanceOf(const Object *typeObject, const Value &var);
diff --git a/src/qml/jsruntime/qv4proxy.cpp b/src/qml/jsruntime/qv4proxy.cpp
index 310e6b4dac..637a3c16df 100644
--- a/src/qml/jsruntime/qv4proxy.cpp
+++ b/src/qml/jsruntime/qv4proxy.cpp
@@ -299,6 +299,37 @@ PropertyAttributes ProxyObject::getOwnProperty(Managed *m, Identifier id, Proper
return resultAttributes;
}
+bool ProxyObject::isExtensible(const Managed *m)
+{
+ Scope scope(m);
+ const ProxyObject *o = static_cast<const ProxyObject *>(m);
+ if (!o->d()->handler)
+ return scope.engine->throwTypeError();
+
+ ScopedObject target(scope, o->d()->target);
+ Q_ASSERT(target);
+ ScopedObject handler(scope, o->d()->handler);
+ ScopedString hasProp(scope, scope.engine->newString(QStringLiteral("isExtensible")));
+ ScopedValue trap(scope, handler->get(hasProp));
+ if (scope.hasException())
+ return Encode::undefined();
+ if (trap->isUndefined())
+ return target->isExtensible();
+ if (!trap->isFunctionObject())
+ return scope.engine->throwTypeError();
+
+ JSCallData cdata(scope, 1, nullptr, handler);
+ cdata.args[0] = target;
+
+ ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
+ bool result = trapResult->toBoolean();
+ if (result != target->isExtensible()) {
+ scope.engine->throwTypeError();
+ return false;
+ }
+ return result;
+}
+
//ReturnedValue ProxyObject::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
//{
diff --git a/src/qml/jsruntime/qv4proxy_p.h b/src/qml/jsruntime/qv4proxy_p.h
index 12360edc8a..36cf00aa47 100644
--- a/src/qml/jsruntime/qv4proxy_p.h
+++ b/src/qml/jsruntime/qv4proxy_p.h
@@ -93,6 +93,7 @@ struct ProxyObject: Object {
static bool deleteIndexedProperty(Managed *m, uint index);
static bool hasProperty(const Managed *m, Identifier id);
static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p);
+ static bool isExtensible(const Managed *m);
// those might require a second proxy object that derives from FunctionObject...
// static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);