aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-04-07 13:28:59 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-02 14:18:27 +0000
commitd1af494793961a31747b689cf307b65d99367486 (patch)
tree1e89898065334e841ded62499331274cb9d0b230 /src/qml/jsruntime
parent3c090c80c58d99f1bd29493ef747a4f6fa915a71 (diff)
Change Objects vtable methods to take a StringOrSymbol
This is needed for symbol support. Change-Id: I83db21f232168710d18999fd97d912016e86d630 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4object.cpp25
-rw-r--r--src/qml/jsruntime/qv4object_p.h38
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp14
-rw-r--r--src/qml/jsruntime/qv4qmlcontext_p.h4
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp23
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h6
-rw-r--r--src/qml/jsruntime/qv4string_p.h29
-rw-r--r--src/qml/jsruntime/qv4value_p.h14
8 files changed, 101 insertions, 52 deletions
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index fc8131d99c..59540611b1 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -246,7 +246,7 @@ void Heap::Object::markObjects(Heap::Base *b, MarkStack *stack)
}
}
-void Object::insertMember(String *s, const Property *p, PropertyAttributes attributes)
+void Object::insertMember(StringOrSymbol *s, const Property *p, PropertyAttributes attributes)
{
uint idx;
s->makeIdentifier();
@@ -305,7 +305,7 @@ void Object::getOwnProperty(uint index, PropertyAttributes *attrs, Property *p)
}
// Section 8.12.2
-PropertyIndex Object::getValueOrSetter(String *name, PropertyAttributes *attrs)
+PropertyIndex Object::getValueOrSetter(StringOrSymbol *name, PropertyAttributes *attrs)
{
Q_ASSERT(name->asArrayIndex() == UINT_MAX);
@@ -423,7 +423,7 @@ ReturnedValue Object::call(const FunctionObject *f, const Value *, const Value *
return f->engine()->throwTypeError();
}
-ReturnedValue Object::get(const Managed *m, String *name, bool *hasProperty)
+ReturnedValue Object::get(const Managed *m, StringOrSymbol *name, bool *hasProperty)
{
return static_cast<const Object *>(m)->internalGet(name, hasProperty);
}
@@ -433,7 +433,7 @@ ReturnedValue Object::getIndexed(const Managed *m, uint index, bool *hasProperty
return static_cast<const Object *>(m)->internalGetIndexed(index, hasProperty);
}
-bool Object::put(Managed *m, String *name, const Value &value)
+bool Object::put(Managed *m, StringOrSymbol *name, const Value &value)
{
return static_cast<Object *>(m)->internalPut(name, value);
}
@@ -443,7 +443,7 @@ bool Object::putIndexed(Managed *m, uint index, const Value &value)
return static_cast<Object *>(m)->internalPutIndexed(index, value);
}
-PropertyAttributes Object::query(const Managed *m, String *name)
+PropertyAttributes Object::query(const Managed *m, StringOrSymbol *name)
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@@ -473,7 +473,7 @@ PropertyAttributes Object::queryIndexed(const Managed *m, uint index)
return Attr_Invalid;
}
-bool Object::deleteProperty(Managed *m, String *name)
+bool Object::deleteProperty(Managed *m, StringOrSymbol *name)
{
return static_cast<Object *>(m)->internalDeleteProperty(name);
}
@@ -554,7 +554,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *
}
// Section 8.12.3
-ReturnedValue Object::internalGet(String *name, bool *hasProperty) const
+ReturnedValue Object::internalGet(StringOrSymbol *name, bool *hasProperty) const
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@@ -617,7 +617,7 @@ ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty) const
// Section 8.12.5
-bool Object::internalPut(String *name, const Value &value)
+bool Object::internalPut(StringOrSymbol *name, const Value &value)
{
ExecutionEngine *engine = this->engine();
if (engine->hasException)
@@ -646,7 +646,7 @@ bool Object::internalPut(String *name, const Value &value)
return false;
} else if (!attrs.isWritable())
return false;
- else if (isArrayObject() && name->equals(engine->id_length())) {
+ else if (isArrayObject() && id == engine->id_length()->identifier()) {
bool ok;
uint l = value.asArrayLength(&ok);
if (!ok) {
@@ -764,7 +764,7 @@ bool Object::internalPutIndexed(uint index, const Value &value)
}
// Section 8.12.7
-bool Object::internalDeleteProperty(String *name)
+bool Object::internalDeleteProperty(StringOrSymbol *name)
{
if (internalClass()->engine->hasException)
return false;
@@ -774,11 +774,12 @@ bool Object::internalDeleteProperty(String *name)
return deleteIndexedProperty(idx);
name->makeIdentifier();
+ Identifier id = name->identifier();
- uint memberIdx = internalClass()->find(name->identifier());
+ uint memberIdx = internalClass()->find(id);
if (memberIdx != UINT_MAX) {
if (internalClass()->propertyData[memberIdx].isConfigurable()) {
- Heap::InternalClass::removeMember(this, name->identifier());
+ Heap::InternalClass::removeMember(this, id);
return true;
}
return false;
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 885ae020f2..5d46e0e74b 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -166,13 +166,13 @@ struct ObjectVTable
VTable vTable;
ReturnedValue (*call)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
ReturnedValue (*callAsConstructor)(const FunctionObject *, const Value *argv, int argc);
- ReturnedValue (*get)(const Managed *, String *name, bool *hasProperty);
+ ReturnedValue (*get)(const Managed *, StringOrSymbol *name, bool *hasProperty);
ReturnedValue (*getIndexed)(const Managed *, uint index, bool *hasProperty);
- bool (*put)(Managed *, String *name, const Value &value);
+ bool (*put)(Managed *, StringOrSymbol *name, const Value &value);
bool (*putIndexed)(Managed *, uint index, const Value &value);
- PropertyAttributes (*query)(const Managed *, String *name);
+ PropertyAttributes (*query)(const Managed *, StringOrSymbol *name);
PropertyAttributes (*queryIndexed)(const Managed *, uint index);
- bool (*deleteProperty)(Managed *m, String *name);
+ bool (*deleteProperty)(Managed *m, StringOrSymbol *name);
bool (*deleteIndexedProperty)(Managed *m, uint index);
qint64 (*getLength)(const Managed *m);
void (*advanceIterator)(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
@@ -243,7 +243,7 @@ struct Q_QML_EXPORT Object: Managed {
void getOwnProperty(String *name, PropertyAttributes *attrs, Property *p = nullptr);
void getOwnProperty(uint index, PropertyAttributes *attrs, Property *p = nullptr);
- PropertyIndex getValueOrSetter(String *name, PropertyAttributes *attrs);
+ PropertyIndex getValueOrSetter(StringOrSymbol *name, PropertyAttributes *attrs);
PropertyIndex getValueOrSetter(uint index, PropertyAttributes *attrs);
bool hasProperty(String *name) const;
@@ -289,13 +289,13 @@ struct Q_QML_EXPORT Object: Managed {
void defineReadonlyConfigurableProperty(const QString &name, const Value &value);
void defineReadonlyConfigurableProperty(String *name, const Value &value);
- void insertMember(String *s, const Value &v, PropertyAttributes attributes = Attr_Data) {
+ void insertMember(StringOrSymbol *s, const Value &v, PropertyAttributes attributes = Attr_Data) {
Scope scope(engine());
ScopedProperty p(scope);
p->value = v;
insertMember(s, p, attributes);
}
- void insertMember(String *s, const Property *p, PropertyAttributes attributes);
+ void insertMember(StringOrSymbol *s, const Property *p, PropertyAttributes attributes);
bool isExtensible() const { return d()->internalClass->extensible; }
@@ -364,13 +364,13 @@ public:
return false;
}
- inline ReturnedValue get(String *name, bool *hasProperty = nullptr) const
+ inline ReturnedValue get(StringOrSymbol *name, bool *hasProperty = nullptr) const
{ return vtable()->get(this, name, hasProperty); }
inline ReturnedValue getIndexed(uint idx, bool *hasProperty = nullptr) const
{ return vtable()->getIndexed(this, idx, hasProperty); }
// use the set variants instead, to customize throw behavior
- inline bool put(String *name, const Value &v)
+ inline bool put(StringOrSymbol *name, const Value &v)
{ return vtable()->put(this, name, v); }
inline bool putIndexed(uint idx, const Value &v)
{ return vtable()->putIndexed(this, idx, v); }
@@ -381,7 +381,7 @@ public:
};
// ES6: 7.3.3 Set (O, P, V, Throw)
- inline bool set(String *name, const Value &v, ThrowOnFailure shouldThrow)
+ inline bool set(StringOrSymbol *name, const Value &v, ThrowOnFailure shouldThrow)
{
bool ret = vtable()->put(this, name, v);
// ES6: 7.3.3, 6: If success is false and Throw is true, throw a TypeError exception.
@@ -396,11 +396,11 @@ public:
return ret;
}
- PropertyAttributes query(String *name) const
+ PropertyAttributes query(StringOrSymbol *name) const
{ return vtable()->query(this, name); }
PropertyAttributes queryIndexed(uint index) const
{ return vtable()->queryIndexed(this, index); }
- bool deleteProperty(String *name)
+ bool deleteProperty(StringOrSymbol *name)
{ return vtable()->deleteProperty(this, name); }
bool deleteIndexedProperty(uint index)
{ return vtable()->deleteIndexedProperty(this, index); }
@@ -413,24 +413,24 @@ public:
protected:
static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
- static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue get(const Managed *m, StringOrSymbol *name, bool *hasProperty);
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
- static bool put(Managed *m, String *name, const Value &value);
+ static bool put(Managed *m, StringOrSymbol *name, const Value &value);
static bool putIndexed(Managed *m, uint index, const Value &value);
- static PropertyAttributes query(const Managed *m, String *name);
+ static PropertyAttributes query(const Managed *m, StringOrSymbol *name);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
- static bool deleteProperty(Managed *m, String *name);
+ static bool deleteProperty(Managed *m, StringOrSymbol *name);
static bool deleteIndexedProperty(Managed *m, uint index);
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);
private:
- ReturnedValue internalGet(String *name, bool *hasProperty) const;
+ ReturnedValue internalGet(StringOrSymbol *name, bool *hasProperty) const;
ReturnedValue internalGetIndexed(uint index, bool *hasProperty) const;
- bool internalPut(String *name, const Value &value);
+ bool internalPut(StringOrSymbol *name, const Value &value);
bool internalPutIndexed(uint index, const Value &value);
- bool internalDeleteProperty(String *name);
+ bool internalDeleteProperty(StringOrSymbol *name);
bool internalDeleteIndexedProperty(uint index);
friend struct ObjectIterator;
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index 785c4bc717..8f87f24745 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -78,9 +78,14 @@ void Heap::QQmlContextWrapper::destroy()
Object::destroy();
}
-ReturnedValue QQmlContextWrapper::get(const Managed *m, String *name, bool *hasProperty)
+ReturnedValue QQmlContextWrapper::get(const Managed *m, StringOrSymbol *n, bool *hasProperty)
{
Q_ASSERT(m->as<QQmlContextWrapper>());
+
+ if (n->isSymbol())
+ return Object::get(m, n, hasProperty);
+ String *name = static_cast<String *>(n);
+
const QQmlContextWrapper *resource = static_cast<const QQmlContextWrapper *>(m);
QV4::ExecutionEngine *v4 = resource->engine();
QV4::Scope scope(v4);
@@ -224,9 +229,14 @@ ReturnedValue QQmlContextWrapper::get(const Managed *m, String *name, bool *hasP
return Encode::undefined();
}
-bool QQmlContextWrapper::put(Managed *m, String *name, const Value &value)
+bool QQmlContextWrapper::put(Managed *m, StringOrSymbol *n, const Value &value)
{
Q_ASSERT(m->as<QQmlContextWrapper>());
+
+ if (n->isSymbol())
+ return Object::put(m, n, value);
+ String *name = static_cast<String *>(n);
+
QQmlContextWrapper *resource = static_cast<QQmlContextWrapper *>(m);
ExecutionEngine *v4 = resource->engine();
QV4::Scope scope(v4);
diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h
index 647bef7fc1..86c5b62da2 100644
--- a/src/qml/jsruntime/qv4qmlcontext_p.h
+++ b/src/qml/jsruntime/qv4qmlcontext_p.h
@@ -98,8 +98,8 @@ struct Q_QML_EXPORT QQmlContextWrapper : Object
void setReadOnly(bool b) { d()->readOnly = b; }
- static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
- static bool put(Managed *m, String *name, const Value &value);
+ static ReturnedValue get(const Managed *m, StringOrSymbol *name, bool *hasProperty);
+ static bool put(Managed *m, StringOrSymbol *name, const Value &value);
};
struct Q_QML_EXPORT QmlContext : public ExecutionContext
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index c49abd6fef..f57a7861ed 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -693,15 +693,22 @@ ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QObject *object)
return (engine->memoryManager->allocate<QV4::QObjectWrapper>(object))->asReturnedValue();
}
-QV4::ReturnedValue QObjectWrapper::get(const Managed *m, String *name, bool *hasProperty)
+QV4::ReturnedValue QObjectWrapper::get(const Managed *m, StringOrSymbol *name, bool *hasProperty)
{
+ if (name->isSymbol())
+ return Object::get(m, name, hasProperty);
+ String *n = static_cast<String *>(name);
const QObjectWrapper *that = static_cast<const QObjectWrapper*>(m);
QQmlContextData *qmlContext = that->engine()->callingQmlContext();
- return that->getQmlProperty(qmlContext, name, IgnoreRevision, hasProperty, /*includeImports*/ true);
+ return that->getQmlProperty(qmlContext, n, IgnoreRevision, hasProperty, /*includeImports*/ true);
}
-bool QObjectWrapper::put(Managed *m, String *name, const Value &value)
+bool QObjectWrapper::put(Managed *m, StringOrSymbol *n, const Value &value)
{
+ if (n->isSymbol())
+ return Object::put(m, n, value);
+ String *name = static_cast<String *>(n);
+
QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
ExecutionEngine *v4 = that->engine();
@@ -726,8 +733,12 @@ bool QObjectWrapper::put(Managed *m, String *name, const Value &value)
return true;
}
-PropertyAttributes QObjectWrapper::query(const Managed *m, String *name)
+PropertyAttributes QObjectWrapper::query(const Managed *m, StringOrSymbol *name)
{
+ if (name->isSymbol())
+ return QV4::Object::query(m, name);
+ String *n = static_cast<String *>(name);
+
const QObjectWrapper *that = static_cast<const QObjectWrapper*>(m);
const QObject *thatObject = that->d()->object();
if (QQmlData::wasDeleted(thatObject))
@@ -736,8 +747,8 @@ PropertyAttributes QObjectWrapper::query(const Managed *m, String *name)
ExecutionEngine *engine = that->engine();
QQmlContextData *qmlContext = engine->callingQmlContext();
QQmlPropertyData local;
- if (that->findProperty(engine, qmlContext, name, IgnoreRevision, &local)
- || name->equals(engine->id_destroy()) || name->equals(engine->id_toString()))
+ if (that->findProperty(engine, qmlContext, n, IgnoreRevision, &local)
+ || n->equals(engine->id_destroy()) || n->equals(engine->id_toString()))
return QV4::Attr_Data;
else
return QV4::Object::query(m, name);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 1455acc1b3..56e20adbfa 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -193,9 +193,9 @@ protected:
static QQmlPropertyData *findProperty(ExecutionEngine *engine, QObject *o, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local);
QQmlPropertyData *findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const;
- static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
- static bool put(Managed *m, String *name, const Value &value);
- static PropertyAttributes query(const Managed *, String *name);
+ static ReturnedValue get(const Managed *m, StringOrSymbol *name, bool *hasProperty);
+ static bool put(Managed *m, StringOrSymbol *name, const Value &value);
+ static PropertyAttributes query(const Managed *, StringOrSymbol *name);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
static ReturnedValue method_connect(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 0a316d85b5..a1763522b5 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -160,6 +160,12 @@ struct Q_QML_PRIVATE_EXPORT StringOrSymbol : public Managed {
enum {
IsStringOrSymbol = true
};
+
+ inline void makeIdentifier() const;
+ Identifier identifier() const { return d()->identifier; }
+
+ uint asArrayIndex() const;
+
#endif
};
@@ -204,12 +210,6 @@ struct Q_QML_PRIVATE_EXPORT String : public StringOrSymbol {
}
uint toUInt(bool *ok) const;
- void makeIdentifier() const {
- if (d()->identifier.isValid())
- return;
- makeIdentifierImpl();
- }
-
// slow path
Q_NEVER_INLINE void makeIdentifierImpl() const;
@@ -227,8 +227,6 @@ struct Q_QML_PRIVATE_EXPORT String : public StringOrSymbol {
bool startsWithUpper() const { return d()->startsWithUpper(); }
- Identifier identifier() const { return d()->identifier; }
-
protected:
static bool isEqualTo(Managed *that, Managed *o);
static uint getLength(const Managed *m);
@@ -297,6 +295,21 @@ struct ComplexString : String {
}
};
+inline
+void StringOrSymbol::makeIdentifier() const {
+ if (d()->identifier.isValid())
+ return;
+ Q_ASSERT(isString());
+ static_cast<const String *>(this)->makeIdentifierImpl();
+}
+
+inline
+uint StringOrSymbol::asArrayIndex() const {
+ if (isString())
+ return static_cast<const String *>(this)->asArrayIndex();
+ return UINT_MAX;
+}
+
template<>
inline const StringOrSymbol *Value::as() const {
return isManaged() && m()->internalClass->vtable->isStringOrSymbol ? static_cast<const String *>(this) : nullptr;
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 03c9eda0f2..85c345f645 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -332,6 +332,8 @@ public:
Q_ASSERT(isDouble());
}
inline bool isString() const;
+ inline bool isStringOrSymbol() const;
+ inline bool isSymbol() const;
inline bool isObject() const;
inline bool isFunctionObject() const;
inline bool isInt32() {
@@ -504,6 +506,18 @@ inline bool Value::isString() const
Heap::Base *b = heapObject();
return b && b->internalClass->vtable->isString;
}
+
+bool Value::isStringOrSymbol() const
+{
+ Heap::Base *b = heapObject();
+ return b && b->internalClass->vtable->isStringOrSymbol;
+}
+
+bool Value::isSymbol() const
+{
+ Heap::Base *b = heapObject();
+ return b && b->internalClass->vtable->isStringOrSymbol && !b->internalClass->vtable->isString;
+}
inline bool Value::isObject() const
{
Heap::Base *b = heapObject();