diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-06-19 11:50:07 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-06-25 07:36:41 +0000 |
commit | 4094ce77af45427613e823a2a4d3c6087230d35a (patch) | |
tree | 027d8c054435016f1f478790fdcd4ac745ce8048 /src | |
parent | 4f5d83acf78c7e3e3f4b89190d6109a4c8fa574d (diff) |
Add support for isExtensible in proxy handlers
Change-Id: I580ff0ab33fa58bcd42f6cc500f4a20ee5b05e87
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4proxy.cpp | 31 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4proxy_p.h | 1 |
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); |