aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/jsruntime.pri2
-rw-r--r--src/qml/jsruntime/qv4global_p.h1
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp17
-rw-r--r--src/qml/jsruntime/qv4propertykey.cpp60
-rw-r--r--src/qml/jsruntime/qv4propertykey_p.h120
-rw-r--r--src/qml/jsruntime/qv4reflect.cpp17
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp31
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h29
-rw-r--r--src/qml/jsruntime/qv4value.cpp17
-rw-r--r--src/qml/jsruntime/qv4value_p.h2
10 files changed, 260 insertions, 36 deletions
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri
index 8b8732590f..243c912266 100644
--- a/src/qml/jsruntime/jsruntime.pri
+++ b/src/qml/jsruntime/jsruntime.pri
@@ -30,6 +30,7 @@ SOURCES += \
$$PWD/qv4numberobject.cpp \
$$PWD/qv4object.cpp \
$$PWD/qv4objectproto.cpp \
+ $$PWD/qv4propertykey.cpp \
$$PWD/qv4proxy.cpp \
$$PWD/qv4qmlcontext.cpp \
$$PWD/qv4reflect.cpp \
@@ -91,6 +92,7 @@ HEADERS += \
$$PWD/qv4numberobject_p.h \
$$PWD/qv4object_p.h \
$$PWD/qv4objectproto_p.h \
+ $$PWD/qv4propertykey_p.h \
$$PWD/qv4proxy_p.h \
$$PWD/qv4qmlcontext_p.h \
$$PWD/qv4reflect_p.h \
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 607f8b4d28..e3b3423a9d 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -200,6 +200,7 @@ namespace Heap {
struct CppStackFrame;
class MemoryManager;
class ExecutableAllocator;
+struct PropertyKey;
struct StringOrSymbol;
struct String;
struct Symbol;
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index daf31833d7..3287912c7d 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -48,6 +48,7 @@
#include "qv4string_p.h"
#include "qv4jscall_p.h"
#include "qv4symbol_p.h"
+#include "qv4propertykey_p.h"
#include <QtCore/QDateTime>
#include <QtCore/QStringList>
@@ -163,12 +164,12 @@ ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(const FunctionObj
static_cast<ArgumentsObject *>(O.getPointer())->fullyCreate();
ScopedValue v(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
- ScopedStringOrSymbol name(scope, v->toPropertyKey(scope.engine));
+ ScopedPropertyKey name(scope, v->toPropertyKey(scope.engine));
if (scope.engine->hasException)
return QV4::Encode::undefined();
ScopedProperty desc(scope);
- PropertyAttributes attrs = O->getOwnProperty(name->toPropertyKey(), desc);
+ PropertyAttributes attrs = O->getOwnProperty(name->toIdentifier(), desc);
return fromPropertyDescriptor(scope.engine, desc, attrs);
}
@@ -284,7 +285,7 @@ ReturnedValue ObjectPrototype::method_defineProperty(const FunctionObject *b, co
return scope.engine->throwTypeError();
ScopedObject O(scope, argv[0]);
- ScopedStringOrSymbol name(scope, (argc > 1 ? argv[1] : Primitive::undefinedValue()).toPropertyKey(scope.engine));
+ ScopedPropertyKey name(scope, (argc > 1 ? argv[1] : Primitive::undefinedValue()).toPropertyKey(scope.engine));
if (scope.engine->hasException)
return QV4::Encode::undefined();
@@ -295,7 +296,7 @@ ReturnedValue ObjectPrototype::method_defineProperty(const FunctionObject *b, co
if (scope.engine->hasException)
return QV4::Encode::undefined();
- if (!O->defineOwnProperty(name->toPropertyKey(), pd, attrs))
+ if (!O->defineOwnProperty(name->toIdentifier(), pd, attrs))
THROW_TYPE_ERROR();
return O.asReturnedValue();
@@ -577,13 +578,13 @@ ReturnedValue ObjectPrototype::method_valueOf(const FunctionObject *b, const Val
ReturnedValue ObjectPrototype::method_hasOwnProperty(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
- ScopedStringOrSymbol P(scope, (argc ? argv[0] : Primitive::undefinedValue()).toPropertyKey(scope.engine));
+ ScopedPropertyKey P(scope, (argc ? argv[0] : Primitive::undefinedValue()).toPropertyKey(scope.engine));
if (scope.engine->hasException)
return QV4::Encode::undefined();
ScopedObject O(scope, thisObject->toObject(scope.engine));
if (scope.engine->hasException)
return QV4::Encode::undefined();
- bool r = O->getOwnProperty(P->toPropertyKey()) != Attr_Invalid;
+ bool r = O->getOwnProperty(P->toIdentifier()) != Attr_Invalid;
return Encode(r);
}
@@ -609,14 +610,14 @@ ReturnedValue ObjectPrototype::method_isPrototypeOf(const FunctionObject *b, con
ReturnedValue ObjectPrototype::method_propertyIsEnumerable(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
- ScopedStringOrSymbol p(scope, (argc ? argv[0] : Primitive::undefinedValue()).toPropertyKey(scope.engine));
+ ScopedPropertyKey p(scope, (argc ? argv[0] : Primitive::undefinedValue()).toPropertyKey(scope.engine));
if (scope.engine->hasException)
return QV4::Encode::undefined();
ScopedObject o(scope, thisObject->toObject(scope.engine));
if (scope.engine->hasException)
return QV4::Encode::undefined();
- PropertyAttributes attrs = o->getOwnProperty(p->toPropertyKey());
+ PropertyAttributes attrs = o->getOwnProperty(p->toIdentifier());
return Encode(attrs.isEnumerable());
}
diff --git a/src/qml/jsruntime/qv4propertykey.cpp b/src/qml/jsruntime/qv4propertykey.cpp
new file mode 100644
index 0000000000..4678748ee8
--- /dev/null
+++ b/src/qml/jsruntime/qv4propertykey.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv4propertykey_p.h"
+
+#include <QtCore/qstring.h>
+#include <qv4string_p.h>
+
+QV4::Heap::StringOrSymbol *QV4::PropertyKey::toStringOrSymbol(QV4::ExecutionEngine *e)
+{
+ if (isArrayIndex())
+ return Primitive::fromUInt32(asArrayIndex()).toString(e);
+ return static_cast<Heap::StringOrSymbol *>(asStringOrSymbol());
+}
+
+QString QV4::PropertyKey::toQString() const
+{
+ if (isArrayIndex())
+ return QString::number(asArrayIndex());
+ Heap::Base *b = asStringOrSymbol();
+ Q_ASSERT(b->internalClass->vtable->isStringOrSymbol);
+ Heap::StringOrSymbol *s = static_cast<Heap::StringOrSymbol *>(b);
+ return s->toQString();
+}
diff --git a/src/qml/jsruntime/qv4propertykey_p.h b/src/qml/jsruntime/qv4propertykey_p.h
new file mode 100644
index 0000000000..2e33562514
--- /dev/null
+++ b/src/qml/jsruntime/qv4propertykey_p.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4PROPERTYKEY_H
+#define QV4PROPERTYKEY_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qv4value_p.h>
+#include <private/qv4identifier_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+
+namespace QV4 {
+
+struct PropertyKey : private Value
+{
+ // Property keys are Strings, Symbols or unsigned integers.
+ // For convenience we derive them from Values, allowing us to store them
+ // on the JS stack
+ //
+ // They do however behave somewhat different than a Value:
+ // * If the key is a String, the pointer to the string is stored in the identifier
+ // table and thus unique.
+ // * If the key is a Symbol it simply points to the referenced symbol object
+ // * if the key is an array index (a uint < UINT_MAX), it's encoded as an
+ // integer value
+ int id;
+
+ static PropertyKey invalid() { PropertyKey key; key.setRawValue(0); return key; }
+ static PropertyKey fromArrayIndex(uint idx) { PropertyKey key; key.setInt_32(static_cast<int>(idx)); return key; }
+ bool isStringOrSymbol() const { return isManaged(); }
+ uint asArrayIndex() const { return isManaged() ? std::numeric_limits<uint>::max() : value(); }
+ uint isArrayIndex() const { return !isManaged(); }
+ static PropertyKey fromStringOrSymbol(Heap::StringOrSymbol *b)
+ { PropertyKey key; key.setM(reinterpret_cast<Heap::Base *>(b)); return key; }
+ Heap::StringOrSymbol *asStringOrSymbol() const { return reinterpret_cast<Heap::StringOrSymbol *>(heapObject()); }
+
+ bool isString() const {
+ Heap::Base *s = heapObject();
+ return s && s->internalClass->vtable->isString;
+ }
+
+ bool isSymbol() const {
+ Heap::Base *s = heapObject();
+ return s && s->internalClass->vtable->isString && s->internalClass->vtable->isStringOrSymbol;
+ }
+
+ // ### temporary until we transitioned Identifier to PropertyKey
+ static PropertyKey fromIdentifier(Identifier id) {
+ if (id.isArrayIndex())
+ return PropertyKey::fromArrayIndex(id.asArrayIndex());
+ return PropertyKey::fromStringOrSymbol(id.asStringOrSymbol());
+ }
+
+ Identifier toIdentifier() const {
+ if (isArrayIndex())
+ return Identifier::fromArrayIndex(asArrayIndex());
+ return Identifier::fromStringOrSymbol(asStringOrSymbol());
+ }
+
+ Q_QML_EXPORT QString toQString() const;
+ Heap::StringOrSymbol *toStringOrSymbol(ExecutionEngine *e);
+
+ bool operator ==(const PropertyKey &other) const { return id == other.id; }
+ bool operator !=(const PropertyKey &other) const { return id != other.id; }
+ bool operator <(const PropertyKey &other) const { return id < other.id; }
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/jsruntime/qv4reflect.cpp b/src/qml/jsruntime/qv4reflect.cpp
index 7d8c8db089..41aa4b402e 100644
--- a/src/qml/jsruntime/qv4reflect.cpp
+++ b/src/qml/jsruntime/qv4reflect.cpp
@@ -41,6 +41,7 @@
#include "qv4symbol_p.h"
#include "qv4runtimeapi_p.h"
#include "qv4objectproto_p.h"
+#include "qv4propertykey_p.h"
using namespace QV4;
@@ -120,7 +121,7 @@ ReturnedValue Reflect::method_defineProperty(const FunctionObject *f, const Valu
return scope.engine->throwTypeError();
ScopedObject O(scope, argv[0]);
- ScopedStringOrSymbol name(scope, (argc > 1 ? argv[1] : Primitive::undefinedValue()).toPropertyKey(scope.engine));
+ ScopedPropertyKey name(scope, (argc > 1 ? argv[1] : Primitive::undefinedValue()).toPropertyKey(scope.engine));
if (scope.engine->hasException)
return QV4::Encode::undefined();
@@ -131,7 +132,7 @@ ReturnedValue Reflect::method_defineProperty(const FunctionObject *f, const Valu
if (scope.engine->hasException)
return QV4::Encode::undefined();
- bool result = O->defineOwnProperty(name->toPropertyKey(), pd, attrs);
+ bool result = O->defineOwnProperty(name->toIdentifier(), pd, attrs);
return Encode(result);
}
@@ -155,12 +156,12 @@ ReturnedValue Reflect::method_get(const FunctionObject *f, const Value *, const
ScopedObject o(scope, static_cast<const Object *>(argv));
Value undef = Primitive::undefinedValue();
const Value *index = argc > 1 ? &argv[1] : &undef;
- ScopedStringOrSymbol name(scope, index->toPropertyKey(scope.engine));
+ ScopedPropertyKey name(scope, index->toPropertyKey(scope.engine));
if (scope.hasException())
return Encode::undefined();
ScopedValue receiver(scope, argc > 2 ? argv[2] : *o);
- return Encode(o->get(name->toPropertyKey(), receiver));
+ return Encode(o->get(name->toIdentifier(), receiver));
}
ReturnedValue Reflect::method_getOwnPropertyDescriptor(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
@@ -198,10 +199,10 @@ ReturnedValue Reflect::method_has(const FunctionObject *f, const Value *, const
return Encode(hasProperty);
}
- ScopedStringOrSymbol name(scope, index->toPropertyKey(scope.engine));
+ ScopedPropertyKey name(scope, index->toPropertyKey(scope.engine));
if (scope.engine->hasException)
return false;
- (void) o->get(name, &hasProperty);
+ (void) o->get(name->toIdentifier(), nullptr, &hasProperty);
return Encode(hasProperty);
}
@@ -245,10 +246,10 @@ ReturnedValue Reflect::method_set(const FunctionObject *f, const Value *, const
const Value &val = argc > 2 ? argv[2] : undef;
ScopedValue receiver(scope, argc >3 ? argv[3] : argv[0]);
- Scoped<StringOrSymbol> propertyKey(scope, index->toPropertyKey(scope.engine));
+ ScopedPropertyKey propertyKey(scope, index->toPropertyKey(scope.engine));
if (scope.engine->hasException)
return false;
- bool result = o->put(propertyKey->toPropertyKey(), val, receiver);
+ bool result = o->put(propertyKey->toIdentifier(), val, receiver);
return Encode(result);
}
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 87a1f665b5..eee94a2f60 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -333,11 +333,10 @@ bool Runtime::method_deleteProperty(ExecutionEngine *engine, const Value &base,
if (n < UINT_MAX)
return o->deleteProperty(Identifier::fromArrayIndex(n));
- Scoped<StringOrSymbol> key(scope, index.toPropertyKey(engine));
+ ScopedPropertyKey key(scope, index.toPropertyKey(engine));
if (engine->hasException)
return false;
- Identifier id = key->toPropertyKey();
- return o->deleteProperty(id);
+ return o->deleteProperty(key->toIdentifier());
}
bool Runtime::method_deleteName(ExecutionEngine *engine, int nameIndex)
@@ -372,10 +371,10 @@ QV4::ReturnedValue Runtime::method_in(ExecutionEngine *engine, const Value &left
if (!ro)
return engine->throwTypeError();
Scope scope(engine);
- ScopedStringOrSymbol s(scope, left.toPropertyKey(engine));
+ ScopedPropertyKey s(scope, left.toPropertyKey(engine));
if (scope.hasException())
return Encode::undefined();
- bool r = ro->hasProperty(s->toPropertyKey());
+ bool r = ro->hasProperty(s->toIdentifier());
return Encode(r);
}
@@ -638,10 +637,10 @@ static Q_NEVER_INLINE ReturnedValue getElementFallback(ExecutionEngine *engine,
Q_ASSERT(!!o); // can't fail as null/undefined is covered above
}
- ScopedStringOrSymbol name(scope, index.toPropertyKey(engine));
+ ScopedPropertyKey name(scope, index.toPropertyKey(engine));
if (scope.hasException())
return Encode::undefined();
- return o->get(name);
+ return o->get(name->toIdentifier());
}
ReturnedValue Runtime::method_loadElement(ExecutionEngine *engine, const Value &object, const Value &index)
@@ -684,10 +683,10 @@ static Q_NEVER_INLINE bool setElementFallback(ExecutionEngine *engine, const Val
return o->put(idx, value);
}
- ScopedStringOrSymbol name(scope, index.toPropertyKey(engine));
+ ScopedPropertyKey name(scope, index.toPropertyKey(engine));
if (engine->hasException)
return false;
- return o->put(name, value);
+ return o->put(name->toIdentifier(), value);
}
void Runtime::method_storeElement(ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)
@@ -1202,11 +1201,11 @@ ReturnedValue Runtime::method_callElement(ExecutionEngine *engine, Value *base,
ScopedValue thisObject(scope, base->toObject(engine));
base = thisObject;
- ScopedStringOrSymbol str(scope, index.toPropertyKey(engine));
+ ScopedPropertyKey str(scope, index.toPropertyKey(engine));
if (engine->hasException)
return Encode::undefined();
- ScopedFunctionObject f(scope, static_cast<Object *>(base)->get(str));
+ ScopedFunctionObject f(scope, static_cast<Object *>(base)->get(str->toIdentifier()));
if (!f)
return engine->throwTypeError();
@@ -1452,7 +1451,7 @@ ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, int classId
if (!additionalArgs)
return o->asReturnedValue();
- Scoped<StringOrSymbol> name(scope);
+ ScopedPropertyKey name(scope);
ScopedProperty pd(scope);
for (int i = 0; i < additionalArgs; ++i) {
Q_ASSERT(args->isInteger());
@@ -1468,7 +1467,7 @@ ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, int classId
pd->value = Primitive::emptyValue();
pd->set = args[2];
}
- bool ok = o->defineOwnProperty(name->toPropertyKey(), pd, (arg == ObjectLiteralArgument::Value ? Attr_Data : Attr_Accessor));
+ bool ok = o->defineOwnProperty(name->toIdentifier(), pd, (arg == ObjectLiteralArgument::Value ? Attr_Data : Attr_Accessor));
if (!ok)
return engine->throwTypeError();
@@ -1523,7 +1522,7 @@ ReturnedValue Runtime::method_createClass(ExecutionEngine *engine, int classInde
ScopedObject receiver(scope, *constructor);
- ScopedStringOrSymbol propertyName(scope);
+ ScopedPropertyKey propertyName(scope);
ScopedFunctionObject function(scope);
ScopedProperty property(scope);
const CompiledData::Method *methods = cls->methodTable();
@@ -1536,9 +1535,9 @@ ReturnedValue Runtime::method_createClass(ExecutionEngine *engine, int classInde
return Encode::undefined();
++computedNames;
} else {
- propertyName = unit->runtimeStrings[methods[i].name];
+ propertyName = PropertyKey::fromStringOrSymbol(unit->runtimeStrings[methods[i].name]);
}
- Identifier id = propertyName->toPropertyKey();
+ Identifier id = propertyName->toIdentifier();
QV4::Function *f = unit->runtimeFunctions[methods[i].function];
Q_ASSERT(f);
function = FunctionObject::createMemberFunction(current, f);
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 73ee17cd40..1a5837935c 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -53,6 +53,7 @@
#include "qv4engine_p.h"
#include "qv4value_p.h"
#include "qv4property_p.h"
+#include "qv4propertykey_p.h"
#ifdef V4_USE_VALGRIND
#include <valgrind/memcheck.h>
@@ -240,6 +241,34 @@ struct ScopedValue
Value *ptr;
};
+
+struct ScopedPropertyKey
+{
+ ScopedPropertyKey(const Scope &scope)
+ {
+ ptr = reinterpret_cast<PropertyKey *>(scope.alloc<Scope::Uninitialized>());
+ *ptr = PropertyKey::invalid();
+ }
+
+ ScopedPropertyKey(const Scope &scope, const PropertyKey &v)
+ {
+ ptr = reinterpret_cast<PropertyKey *>(scope.alloc<Scope::Uninitialized>());
+ *ptr = v;
+ }
+
+ ScopedPropertyKey &operator=(const PropertyKey &other) {
+ *ptr = other;
+ return *this;
+ }
+
+ PropertyKey *operator->() {
+ return ptr;
+ }
+
+ PropertyKey *ptr;
+};
+
+
template<typename T>
struct Scoped
{
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index 9febd41a00..6b22967bfa 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -39,6 +39,7 @@
#include <qv4engine_p.h>
#include <qv4runtime_p.h>
#include <qv4string_p.h>
+#include <qv4propertykey_p.h>
#ifndef V4_BOOTSTRAP
#include <qv4symbol_p.h>
#include <qv4object_p.h>
@@ -229,15 +230,25 @@ QString Value::toQString() const
} // switch
}
-Heap::StringOrSymbol *Value::toPropertyKey(ExecutionEngine *e) const
+QV4::PropertyKey Value::toPropertyKey(ExecutionEngine *e) const
{
+ if (isInteger() && int_32() >= 0)
+ return PropertyKey::fromArrayIndex(static_cast<uint>(int_32()));
+ if (isStringOrSymbol()) {
+ Scope scope(e);
+ ScopedStringOrSymbol s(scope, this);
+ s->makeIdentifier();
+ return PropertyKey::fromIdentifier(s->identifier());
+ }
Scope scope(e);
ScopedValue v(scope, RuntimeHelpers::toPrimitive(*this, STRING_HINT));
if (!v->isStringOrSymbol())
v = v->toString(e);
if (e->hasException)
- return nullptr;
- return static_cast<Heap::StringOrSymbol *>(v->m());
+ return PropertyKey::invalid();
+ ScopedStringOrSymbol s(scope, v);
+ s->makeIdentifier();
+ return PropertyKey::fromIdentifier(s->identifier());
}
#endif // V4_BOOTSTRAP
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 16bbf241ff..ac0a52f7a8 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -415,7 +415,7 @@ public:
return reinterpret_cast<Heap::String *>(m());
return toString(e, *this);
}
- Heap::StringOrSymbol *toPropertyKey(ExecutionEngine *e) const;
+ QV4::PropertyKey toPropertyKey(ExecutionEngine *e) const;
static Heap::String *toString(ExecutionEngine *e, Value val);
Heap::Object *toObject(ExecutionEngine *e) const {