aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-06-22 15:34:57 +0200
committerLars Knoll <lars.knoll@qt.io>2018-07-02 19:29:25 +0000
commit98263a01373f5b225d64da216537165ae27d7ff1 (patch)
tree60980c16c6cc6f6658355bcd428245819b4b732a /src
parentd21ef386ece52490d428daacb8f7f4658e9f78e5 (diff)
Unify put and putIndexed
Pass an Identifier through those virtual methods to unify the string and integer based versions. Also add the receiver that's required in ES7 Change-Id: I4e7f01b4c97cc80bcb3c485f6343f28213dc9e6b Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/particles/qquickcustomaffector.cpp2
-rw-r--r--src/particles/qquickparticleemitter.cpp2
-rw-r--r--src/particles/qquicktrailemitter.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp4
-rw-r--r--src/qml/jsapi/qjsvalue.cpp6
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp21
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp20
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4object.cpp197
-rw-r--r--src/qml/jsruntime/qv4object_p.h29
-rw-r--r--src/qml/jsruntime/qv4proxy.cpp17
-rw-r--r--src/qml/jsruntime/qv4proxy_p.h3
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp17
-rw-r--r--src/qml/jsruntime/qv4qmlcontext_p.h2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp20
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h2
-rw-r--r--src/qml/jsruntime/qv4reflect.cpp11
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp2
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp8
-rw-r--r--src/qml/jsruntime/qv4serialize.cpp2
-rw-r--r--src/qml/jsruntime/qv4symbol_p.h4
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp6
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h2
-rw-r--r--src/qml/qml/qqmldelayedcallqueue.cpp2
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp5
-rw-r--r--src/qml/qml/qqmllistwrapper_p.h2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp2
-rw-r--r--src/qml/qml/qqmltypeloader.cpp2
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp24
-rw-r--r--src/qml/qml/qqmltypewrapper_p.h2
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp11
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h2
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp2
-rw-r--r--src/qml/types/qqmllistmodel.cpp11
-rw-r--r--src/qml/types/qqmllistmodel_p_p.h2
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp8
37 files changed, 195 insertions, 263 deletions
diff --git a/src/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp
index 53557e1d0b..ccb00eeba2 100644
--- a/src/particles/qquickcustomaffector.cpp
+++ b/src/particles/qquickcustomaffector.cpp
@@ -154,7 +154,7 @@ void QQuickCustomAffector::affectSystem(qreal dt)
QV4::ScopedArrayObject array(scope, v4->newArrayObject(toAffect.size()));
QV4::ScopedValue v(scope);
for (int i=0; i<toAffect.size(); i++)
- array->putIndexed(i, (v = toAffect[i]->v4Value(m_system)));
+ array->put(i, (v = toAffect[i]->v4Value(m_system)));
if (dt >= simulationCutoff || dt <= simulationDelta) {
affectProperties(toAffect, dt);
diff --git a/src/particles/qquickparticleemitter.cpp b/src/particles/qquickparticleemitter.cpp
index cd4cdcf3ef..5ec834a463 100644
--- a/src/particles/qquickparticleemitter.cpp
+++ b/src/particles/qquickparticleemitter.cpp
@@ -494,7 +494,7 @@ void QQuickParticleEmitter::emitWindow(int timeStamp)
QV4::ScopedArrayObject array(scope, v4->newArrayObject(toEmit.size()));
QV4::ScopedValue v(scope);
for (int i=0; i<toEmit.size(); i++)
- array->putIndexed(i, (v = toEmit[i]->v4Value(m_system)));
+ array->put(i, (v = toEmit[i]->v4Value(m_system)));
emitParticles(QQmlV4Handle(array));//A chance for arbitrary JS changes
}
diff --git a/src/particles/qquicktrailemitter.cpp b/src/particles/qquicktrailemitter.cpp
index f0a0b297e2..ca3ebbd4ec 100644
--- a/src/particles/qquicktrailemitter.cpp
+++ b/src/particles/qquicktrailemitter.cpp
@@ -273,7 +273,7 @@ void QQuickTrailEmitter::emitWindow(int timeStamp)
QV4::ScopedArrayObject array(scope, v4->newArrayObject(toEmit.size()));
QV4::ScopedValue v(scope);
for (int i=0; i<toEmit.size(); i++)
- array->putIndexed(i, (v = toEmit[i]->v4Value(m_system)));
+ array->put(i, (v = toEmit[i]->v4Value(m_system)));
if (isEmitFollowConnected())
emitFollowParticles(QQmlV4Handle(array), d->v4Value(m_system));//A chance for many arbitrary JS changes
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index 0993390483..ff74cf8981 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -394,7 +394,7 @@ QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicat
{ std::swap(*hasExceptionLoc, hadException); }
};
- // if we wouldn't do this, the putIndexed won't work.
+ // if we wouldn't do this, the put won't work.
ExceptionStateSaver resetExceptionState(engine());
QV4::Scope scope(engine());
QV4::ScopedObject array(scope, m_values.value());
@@ -405,7 +405,7 @@ QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicat
}
}
Ref ref = array->getLength();
- array->putIndexed(ref, value);
+ array->put(ref, value);
Q_ASSERT(array->getLength() - 1 == ref);
return ref;
}
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index aa88530fe4..73e6243520 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -1209,10 +1209,8 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value)
}
QV4::ScopedValue v(scope, QJSValuePrivate::convertedToValue(engine, value));
- if (arrayIndex != UINT_MAX)
- o->putIndexed(arrayIndex, v);
- else
- o->put(engine->id_uintMax(), v);
+ Identifier id = arrayIndex != UINT_MAX ? Identifier::fromArrayIndex(arrayIndex) : engine->id_uintMax()->identifier();
+ o->put(id, v);
if (engine->hasException)
engine->catchException();
}
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index ba9bf9652d..c2a50a49ec 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -185,17 +185,20 @@ ReturnedValue ArgumentsObject::getIndexed(const Managed *m, uint index, bool *ha
return Encode::undefined();
}
-bool ArgumentsObject::putIndexed(Managed *m, uint index, const Value &value)
+bool ArgumentsObject::put(Managed *m, Identifier id, const Value &value, Value *receiver)
{
ArgumentsObject *args = static_cast<ArgumentsObject *>(m);
- if (!args->fullyCreated() && index >= static_cast<uint>(args->context()->argc()))
- args->fullyCreate();
-
- if (args->fullyCreated())
- return Object::putIndexed(m, index, value);
-
- args->context()->setArg(index, value);
- return true;
+ if (id.isArrayIndex()) {
+ uint index = id.asArrayIndex();
+ if (!args->fullyCreated() && index >= static_cast<uint>(args->context()->argc()))
+ args->fullyCreate();
+
+ if (!args->fullyCreated()) {
+ args->context()->setArg(index, value);
+ return true;
+ }
+ }
+ return Object::put(m, id, value, receiver);
}
bool ArgumentsObject::deleteProperty(Managed *m, Identifier id)
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index 46110e465f..69d136674b 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -148,7 +148,7 @@ struct ArgumentsObject: Object {
static bool defineOwnProperty(Managed *m, Identifier id, const Property *desc, PropertyAttributes attrs);
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
- static bool putIndexed(Managed *m, uint index, const Value &value);
+ static bool put(Managed *m, Identifier id, const Value &value, Value *receiver);
static bool deleteProperty(Managed *m, Identifier id);
static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p);
static qint64 getLength(const Managed *m);
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 481dfd22c6..9efb315b50 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -385,7 +385,7 @@ ReturnedValue ArrayPrototype::method_concat(const FunctionObject *b, const Value
for (int i = 0, len = eltAsObj->getLength(); i < len; ++i) {
entry = eltAsObj->getIndexed(i);
// spec says not to throw if this fails
- result->putIndexed(startIndex + i, entry);
+ result->put(startIndex + i, entry);
}
} else {
result->arraySet(result->getLength(), argv[i]);
@@ -675,7 +675,7 @@ ReturnedValue ArrayPrototype::method_push(const FunctionObject *b, const Value *
len = instance->arrayData()->length();
} else {
for (int i = 0, ei = argc; i < ei; ++i) {
- if (!instance->putIndexed(len + i, argv[i]))
+ if (!instance->put(len + i, argv[i]))
return scope.engine->throwTypeError();
}
len += argc;
@@ -713,12 +713,12 @@ ReturnedValue ArrayPrototype::method_reverse(const FunctionObject *b, const Valu
CHECK_EXCEPTION();
bool ok;
if (hiExists)
- ok = instance->putIndexed(lo, hval);
+ ok = instance->put(lo, hval);
else
ok = instance->deleteProperty(Identifier::fromArrayIndex(lo));
if (ok) {
if (loExists)
- ok = instance->putIndexed(hi, lval);
+ ok = instance->put(hi, lval);
else
ok = instance->deleteProperty(Identifier::fromArrayIndex(hi));
}
@@ -761,7 +761,7 @@ ReturnedValue ArrayPrototype::method_shift(const FunctionObject *b, const Value
CHECK_EXCEPTION();
bool ok;
if (exists)
- ok = instance->putIndexed(k - 1, v);
+ ok = instance->put(k - 1, v);
else
ok = instance->deleteProperty(Identifier::fromArrayIndex(k - 1));
if (!ok)
@@ -889,7 +889,7 @@ ReturnedValue ArrayPrototype::method_splice(const FunctionObject *b, const Value
CHECK_EXCEPTION();
bool ok;
if (exists)
- ok = instance->putIndexed(k + itemCount, v);
+ ok = instance->put(k + itemCount, v);
else
ok = instance->deleteProperty(Identifier::fromArrayIndex(k + itemCount));
if (!ok)
@@ -907,7 +907,7 @@ ReturnedValue ArrayPrototype::method_splice(const FunctionObject *b, const Value
CHECK_EXCEPTION();
bool ok;
if (exists)
- ok = instance->putIndexed(k + itemCount - 1, v);
+ ok = instance->put(k + itemCount - 1, v);
else
ok = instance->deleteProperty(Identifier::fromArrayIndex(k + itemCount - 1));
if (!ok)
@@ -917,7 +917,7 @@ ReturnedValue ArrayPrototype::method_splice(const FunctionObject *b, const Value
}
for (uint i = 0; i < itemCount; ++i)
- instance->putIndexed(start + i, argv[i + 2]);
+ instance->put(start + i, argv[i + 2]);
if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - deleteCount + itemCount))))
return scope.engine->throwTypeError();
@@ -947,14 +947,14 @@ ReturnedValue ArrayPrototype::method_unshift(const FunctionObject *b, const Valu
v = instance->getIndexed(k - 1, &exists);
bool ok;
if (exists)
- ok = instance->putIndexed(k + argc - 1, v);
+ ok = instance->put(k + argc - 1, v);
else
ok = instance->deleteProperty(Identifier::fromArrayIndex(k + argc - 1));
if (!ok)
return scope.engine->throwTypeError();
}
for (int i = 0, ei = argc; i < ei; ++i) {
- bool ok = instance->putIndexed(i, argv[i]);
+ bool ok = instance->put(i, argv[i]);
if (!ok)
return scope.engine->throwTypeError();
}
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 75a9bf4111..ed7d8611ee 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -264,7 +264,7 @@ bool JsonParser::parseMember(Object *o)
ScopedString s(scope, engine->newIdentifier(key));
uint idx = s->asArrayIndex();
if (idx < UINT_MAX) {
- o->putIndexed(idx, val);
+ o->put(idx, val);
} else {
o->insertMember(s, val);
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 1597c35319..7c375db1e1 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -268,50 +268,43 @@ void Object::setPrototypeUnchecked(const Object *p)
}
// Section 8.12.2
-PropertyIndex Object::getValueOrSetter(StringOrSymbol *name, PropertyAttributes *attrs)
+PropertyIndex Object::getValueOrSetter(Identifier id, PropertyAttributes *attrs)
{
- Q_ASSERT(name->asArrayIndex() == UINT_MAX);
-
- name->makeIdentifier();
- Identifier id = name->identifier();
-
- Heap::Object *o = d();
- while (o) {
- uint idx = o->internalClass->find(id);
- if (idx < UINT_MAX) {
- *attrs = o->internalClass->propertyData[idx];
- return o->writablePropertyData(attrs->isAccessor() ? idx + SetterOffset : idx );
- }
-
- o = o->prototype();
- }
- *attrs = Attr_Invalid;
- return { nullptr, nullptr };
-}
-
-PropertyIndex Object::getValueOrSetter(uint index, PropertyAttributes *attrs)
-{
- Heap::Object *o = d();
- while (o) {
- if (o->arrayData) {
- uint idx = o->arrayData->mappedIndex(index);
- if (idx != UINT_MAX) {
- *attrs = o->arrayData->attributes(index);
- return { o->arrayData , o->arrayData->values.values + (attrs->isAccessor() ? idx + SetterOffset : idx) };
+ if (id.isArrayIndex()) {
+ uint index = id.asArrayIndex();
+ Heap::Object *o = d();
+ while (o) {
+ if (o->arrayData) {
+ uint idx = o->arrayData->mappedIndex(index);
+ if (idx != UINT_MAX) {
+ *attrs = o->arrayData->attributes(index);
+ return { o->arrayData , o->arrayData->values.values + (attrs->isAccessor() ? idx + SetterOffset : idx) };
+ }
+ }
+ if (o->vtable()->type == Type_StringObject) {
+ if (index < static_cast<const Heap::StringObject *>(o)->length()) {
+ // this is an evil hack, but it works, as the method is only ever called from put,
+ // where we don't use the returned pointer there for non writable attributes
+ *attrs = (Attr_NotWritable|Attr_NotConfigurable);
+ return { reinterpret_cast<Heap::ArrayData *>(0x1), nullptr };
+ }
}
+ o = o->prototype();
}
- if (o->vtable()->type == Type_StringObject) {
- if (index < static_cast<const Heap::StringObject *>(o)->length()) {
- // this is an evil hack, but it works, as the method is only ever called from putIndexed,
- // where we don't use the returned pointer there for non writable attributes
- *attrs = (Attr_NotWritable|Attr_NotConfigurable);
- return { reinterpret_cast<Heap::ArrayData *>(0x1), 0 };
+ } else {
+ Heap::Object *o = d();
+ while (o) {
+ uint idx = o->internalClass->find(id);
+ if (idx < UINT_MAX) {
+ *attrs = o->internalClass->propertyData[idx];
+ return o->writablePropertyData(attrs->isAccessor() ? idx + SetterOffset : idx );
}
+
+ o = o->prototype();
}
- o = o->prototype();
}
*attrs = Attr_Invalid;
- return { nullptr, 0 };
+ return { nullptr, nullptr };
}
ReturnedValue Object::callAsConstructor(const FunctionObject *f, const Value *, int)
@@ -334,14 +327,9 @@ ReturnedValue Object::getIndexed(const Managed *m, uint index, bool *hasProperty
return static_cast<const Object *>(m)->internalGetIndexed(index, hasProperty);
}
-bool Object::put(Managed *m, StringOrSymbol *name, const Value &value)
-{
- return static_cast<Object *>(m)->internalPut(name, value);
-}
-
-bool Object::putIndexed(Managed *m, uint index, const Value &value)
+bool Object::put(Managed *m, Identifier id, const Value &value, Value *receiver)
{
- return static_cast<Object *>(m)->internalPutIndexed(index, value);
+ return static_cast<Object *>(m)->internalPut(id, value, receiver);
}
bool Object::deleteProperty(Managed *m, Identifier id)
@@ -484,31 +472,39 @@ ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty) const
// Section 8.12.5
-bool Object::internalPut(StringOrSymbol *name, const Value &value)
+bool Object::internalPut(Identifier id, const Value &value, Value *receiver)
{
ExecutionEngine *engine = this->engine();
if (engine->hasException)
return false;
- uint idx = name->asArrayIndex();
- if (idx != UINT_MAX)
- return putIndexed(idx, value);
-
- name->makeIdentifier();
- Identifier id = name->identifier();
+ uint index = id.asArrayIndex();
+ Scope scope(engine);
- PropertyIndex memberIndex{nullptr, nullptr};
- uint member = internalClass()->find(id);
PropertyAttributes attrs;
- if (member < UINT_MAX) {
- attrs = internalClass()->propertyData[member];
- memberIndex = d()->writablePropertyData(attrs.isAccessor() ? member + SetterOffset : member);
+ PropertyIndex propertyIndex{nullptr, nullptr};
+
+ if (index != UINT_MAX) {
+ if (arrayData())
+ propertyIndex = arrayData()->getValueOrSetter(index, &attrs);
+
+ if (propertyIndex.isNull() && isStringObject()) {
+ if (index < static_cast<StringObject *>(this)->length())
+ // not writable
+ return false;
+ }
+ } else {
+ uint member = internalClass()->find(id);
+ if (member < UINT_MAX) {
+ attrs = internalClass()->propertyData[member];
+ propertyIndex = d()->writablePropertyData(attrs.isAccessor() ? member + SetterOffset : member);
+ }
}
// clause 1
- if (!memberIndex.isNull()) {
+ if (!propertyIndex.isNull()) {
if (attrs.isAccessor()) {
- if (memberIndex->as<FunctionObject>())
+ if (propertyIndex->as<FunctionObject>())
goto cont;
return false;
} else if (!attrs.isWritable())
@@ -524,7 +520,7 @@ bool Object::internalPut(StringOrSymbol *name, const Value &value)
if (!ok)
return false;
} else {
- memberIndex.set(engine, value);
+ propertyIndex.set(engine, value);
}
return true;
} else if (!getPrototypeOf()) {
@@ -532,11 +528,10 @@ bool Object::internalPut(StringOrSymbol *name, const Value &value)
return false;
} else {
// clause 4
- Scope scope(engine);
- memberIndex = ScopedObject(scope, getPrototypeOf())->getValueOrSetter(name, &attrs);
- if (!memberIndex.isNull()) {
+ propertyIndex = ScopedObject(scope, getPrototypeOf())->getValueOrSetter(id, &attrs);
+ if (!propertyIndex.isNull()) {
if (attrs.isAccessor()) {
- if (!memberIndex->as<FunctionObject>())
+ if (!propertyIndex->as<FunctionObject>())
return false;
} else if (!isExtensible() || !attrs.isWritable()) {
return false;
@@ -549,84 +544,24 @@ bool Object::internalPut(StringOrSymbol *name, const Value &value)
cont:
// Clause 5
- if (!memberIndex.isNull() && attrs.isAccessor()) {
- Q_ASSERT(memberIndex->as<FunctionObject>());
+ if (!propertyIndex.isNull() && attrs.isAccessor()) {
+ Q_ASSERT(propertyIndex->as<FunctionObject>());
Scope scope(engine);
- ScopedFunctionObject setter(scope, *memberIndex);
+ ScopedFunctionObject setter(scope, *propertyIndex);
JSCallData jsCallData(scope, 1);
jsCallData->args[0] = value;
- *jsCallData->thisObject = this;
+ *jsCallData->thisObject = *receiver;
setter->call(jsCallData);
return !engine->hasException;
}
- insertMember(name, value);
- return true;
-}
-
-bool Object::internalPutIndexed(uint index, const Value &value)
-{
- ExecutionEngine *engine = this->engine();
- if (engine->hasException)
- return false;
-
- PropertyAttributes attrs;
-
- PropertyIndex arrayIndex = arrayData() ? arrayData()->getValueOrSetter(index, &attrs) : PropertyIndex{ nullptr, 0 };
-
- if (arrayIndex.isNull() && isStringObject()) {
- if (index < static_cast<StringObject *>(this)->length())
- // not writable
- return false;
- }
-
- // clause 1
- if (!arrayIndex.isNull()) {
- if (attrs.isAccessor()) {
- if (arrayIndex->as<FunctionObject>())
- goto cont;
- return false;
- } else if (!attrs.isWritable())
- return false;
-
- arrayIndex.set(engine, value);
- return true;
- } else if (!getPrototypeOf()) {
- if (!isExtensible())
- return false;
+ if (index != UINT_MAX) {
+ arraySet(index, value);
} else {
- // clause 4
- Scope scope(engine);
- arrayIndex = ScopedObject(scope, getPrototypeOf())->getValueOrSetter(index, &attrs);
- if (!arrayIndex.isNull()) {
- if (attrs.isAccessor()) {
- if (!arrayIndex->as<FunctionObject>())
- return false;
- } else if (!isExtensible() || !attrs.isWritable()) {
- return false;
- }
- } else if (!isExtensible()) {
- return false;
- }
+ Scoped<StringOrSymbol> name(scope, id.asHeapObject());
+ insertMember(name, value);
}
-
- cont:
-
- // Clause 5
- if (!arrayIndex.isNull() && attrs.isAccessor()) {
- Q_ASSERT(arrayIndex->as<FunctionObject>());
-
- Scope scope(engine);
- ScopedFunctionObject setter(scope, *arrayIndex);
- JSCallData jsCallData(scope, 1);
- jsCallData->args[0] = value;
- *jsCallData->thisObject = this;
- setter->call(jsCallData);
- return !engine->hasException;
- }
-
- arraySet(index, value);
return true;
}
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index e57708d8e4..88d07ef3f1 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -171,8 +171,7 @@ struct ObjectVTable
ReturnedValue (*callAsConstructor)(const FunctionObject *, const Value *argv, int argc);
ReturnedValue (*get)(const Managed *, StringOrSymbol *name, bool *hasProperty);
ReturnedValue (*getIndexed)(const Managed *, uint index, bool *hasProperty);
- bool (*put)(Managed *, StringOrSymbol *name, const Value &value);
- bool (*putIndexed)(Managed *, uint index, const Value &value);
+ bool (*put)(Managed *, Identifier id, const Value &value, Value *receiver);
bool (*deleteProperty)(Managed *m, Identifier id);
bool (*hasProperty)(const Managed *m, Identifier id);
PropertyAttributes (*getOwnProperty)(Managed *m, Identifier id, Property *p);
@@ -195,7 +194,6 @@ const QV4::ObjectVTable classname::static_vtbl = \
get, \
getIndexed, \
put, \
- putIndexed, \
deleteProperty, \
hasProperty, \
getOwnProperty, \
@@ -253,8 +251,7 @@ struct Q_QML_EXPORT Object: Managed {
return vtable()->getOwnProperty(this, id, p);
}
- PropertyIndex getValueOrSetter(StringOrSymbol *name, PropertyAttributes *attrs);
- PropertyIndex getValueOrSetter(uint index, PropertyAttributes *attrs);
+ PropertyIndex getValueOrSetter(Identifier id, PropertyAttributes *attrs);
bool hasProperty(Identifier id) const {
return vtable()->hasProperty(this, id);
@@ -382,10 +379,14 @@ public:
{ return vtable()->getIndexed(this, idx, hasProperty); }
// use the set variants instead, to customize throw behavior
- 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); }
+ inline bool put(StringOrSymbol *name, const Value &v, Value *receiver = nullptr)
+ { if (!receiver) receiver = this; return vtable()->put(this, name->toPropertyKey(), v, receiver); }
+ inline bool put(uint idx, const Value &v, Value *receiver = nullptr)
+ { if (!receiver) receiver = this; return vtable()->put(this, Identifier::fromArrayIndex(idx), v, receiver); }
+ QT_DEPRECATED inline bool putIndexed(uint idx, const Value &v)
+ { return put(idx, v); }
+ inline bool put(Identifier id, const Value &v, Value *receiver = nullptr)
+ { if (!receiver) receiver = this; return vtable()->put(this, id, v, receiver); }
enum ThrowOnFailure {
DoThrowOnRejection,
@@ -396,7 +397,7 @@ public:
// which is much more efficient for the array case.
inline bool setIndexed(uint idx, const Value &v, ThrowOnFailure shouldThrow)
{
- bool ret = vtable()->putIndexed(this, idx, v);
+ bool ret = vtable()->put(this, Identifier::fromArrayIndex(idx), v, this);
// ES6: 7.3.3, 6: If success is false and Throw is true, throw a TypeError exception.
if (!ret && shouldThrow == ThrowOnFailure::DoThrowOnRejection) {
ExecutionEngine *e = engine();
@@ -412,7 +413,7 @@ public:
// ES6: 7.3.3 Set (O, P, V, Throw)
inline bool set(StringOrSymbol *name, const Value &v, ThrowOnFailure shouldThrow)
{
- bool ret = vtable()->put(this, name, v);
+ bool ret = vtable()->put(this, name->toPropertyKey(), v, this);
// ES6: 7.3.3, 6: If success is false and Throw is true, throw a TypeError exception.
if (!ret && shouldThrow == ThrowOnFailure::DoThrowOnRejection) {
ExecutionEngine *e = engine();
@@ -438,8 +439,7 @@ protected:
static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
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, StringOrSymbol *name, const Value &value);
- static bool putIndexed(Managed *m, uint index, const Value &value);
+ static bool put(Managed *m, Identifier id, const Value &value, Value *receiver);
static bool deleteProperty(Managed *m, Identifier id);
static bool hasProperty(const Managed *m, Identifier id);
static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p);
@@ -456,8 +456,7 @@ private:
bool internalDefineOwnProperty(ExecutionEngine *engine, uint index, StringOrSymbol *member, const Property *p, PropertyAttributes attrs);
ReturnedValue internalGet(StringOrSymbol *name, bool *hasProperty) const;
ReturnedValue internalGetIndexed(uint index, bool *hasProperty) const;
- bool internalPut(StringOrSymbol *name, const Value &value);
- bool internalPutIndexed(uint index, const Value &value);
+ bool internalPut(Identifier id, const Value &value, Value *receiver);
bool internalDeleteProperty(Identifier id);
friend struct ObjectIterator;
diff --git a/src/qml/jsruntime/qv4proxy.cpp b/src/qml/jsruntime/qv4proxy.cpp
index 5b5149a2f4..11914e4feb 100644
--- a/src/qml/jsruntime/qv4proxy.cpp
+++ b/src/qml/jsruntime/qv4proxy.cpp
@@ -103,7 +103,7 @@ ReturnedValue ProxyObject::getIndexed(const Managed *m, uint index, bool *hasPro
return get(m, name, hasProperty);
}
-bool ProxyObject::put(Managed *m, StringOrSymbol *name, const Value &value)
+bool ProxyObject::put(Managed *m, Identifier id, const Value &value, Value *receiver)
{
Scope scope(m);
const ProxyObject *o = static_cast<const ProxyObject *>(m);
@@ -117,21 +117,21 @@ bool ProxyObject::put(Managed *m, StringOrSymbol *name, const Value &value)
if (scope.hasException())
return Encode::undefined();
if (trap->isNullOrUndefined())
- return target->put(name, value);
+ return target->put(id, value, receiver);
if (!trap->isFunctionObject())
return scope.engine->throwTypeError();
JSCallData cdata(scope, 4, nullptr, handler);
cdata.args[0] = target;
- cdata.args[1] = name;
+ cdata.args[1] = id.toStringOrSymbol(scope.engine);
cdata.args[2] = value;
- cdata.args[3] = o->d(); // ### fix receiver handling
+ cdata.args[3] = *receiver;
ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata));
if (!trapResult->toBoolean())
return false;
ScopedProperty targetDesc(scope);
- PropertyAttributes attributes = target->getOwnProperty(name->toPropertyKey(), targetDesc);
+ PropertyAttributes attributes = target->getOwnProperty(id, targetDesc);
if (attributes != Attr_Invalid && !attributes.isConfigurable()) {
if (attributes.isData() && !attributes.isWritable()) {
if (!value.sameValue(targetDesc->value))
@@ -143,13 +143,6 @@ bool ProxyObject::put(Managed *m, StringOrSymbol *name, const Value &value)
return true;
}
-bool ProxyObject::putIndexed(Managed *m, uint index, const Value &value)
-{
- Scope scope(m);
- ScopedString name(scope, Primitive::fromUInt32(index).toString(scope.engine));
- return put(m, name, value);
-}
-
bool ProxyObject::deleteProperty(Managed *m, Identifier id)
{
Scope scope(m);
diff --git a/src/qml/jsruntime/qv4proxy_p.h b/src/qml/jsruntime/qv4proxy_p.h
index 306f3f00cb..f605621210 100644
--- a/src/qml/jsruntime/qv4proxy_p.h
+++ b/src/qml/jsruntime/qv4proxy_p.h
@@ -87,8 +87,7 @@ struct ProxyObject: Object {
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, StringOrSymbol *name, const Value &value);
- static bool putIndexed(Managed *m, uint index, const Value &value);
+ static bool put(Managed *m, Identifier id, const Value &value, Value *receiver);
static bool deleteProperty(Managed *m, Identifier id);
static bool hasProperty(const Managed *m, Identifier id);
static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p);
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index 4226bf7972..a3e761050c 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -229,13 +229,12 @@ ReturnedValue QQmlContextWrapper::get(const Managed *m, StringOrSymbol *n, bool
return Encode::undefined();
}
-bool QQmlContextWrapper::put(Managed *m, StringOrSymbol *n, const Value &value)
+bool QQmlContextWrapper::put(Managed *m, Identifier id, const Value &value, Value *receiver)
{
Q_ASSERT(m->as<QQmlContextWrapper>());
- if (n->isSymbol())
- return Object::put(m, n, value);
- String *name = static_cast<String *>(n);
+ if (id.isSymbol() || id.isArrayIndex())
+ return Object::put(m, id, value, receiver);
QQmlContextWrapper *resource = static_cast<QQmlContextWrapper *>(m);
ExecutionEngine *v4 = resource->engine();
@@ -244,21 +243,20 @@ bool QQmlContextWrapper::put(Managed *m, StringOrSymbol *n, const Value &value)
return false;
QV4::Scoped<QQmlContextWrapper> wrapper(scope, resource);
- name->makeIdentifier();
- uint member = wrapper->internalClass()->find(name->identifier());
+ uint member = wrapper->internalClass()->find(id);
if (member < UINT_MAX)
return wrapper->putValue(member, value);
if (wrapper->d()->isNullWrapper) {
if (wrapper && wrapper->d()->readOnly) {
- QString error = QLatin1String("Invalid write to global property \"") + name->toQString() +
+ QString error = QLatin1String("Invalid write to global property \"") + id.toQString() +
QLatin1Char('"');
ScopedString e(scope, v4->newString(error));
v4->throwError(e);
return false;
}
- return Object::put(m, name, value);
+ return Object::put(m, id, value, receiver);
}
// It's possible we could delay the calculation of the "actual" context (in the case
@@ -272,6 +270,7 @@ bool QQmlContextWrapper::put(Managed *m, StringOrSymbol *n, const Value &value)
// See QV8ContextWrapper::Getter for resolution order
QObject *scopeObject = wrapper->getScopeObject();
+ ScopedString name(scope, id.asHeapObject());
while (context) {
const QV4::IdentifierHash &properties = context->propertyNames();
@@ -302,7 +301,7 @@ bool QQmlContextWrapper::put(Managed *m, StringOrSymbol *n, const Value &value)
return false;
}
- return Object::put(m, name, value);
+ return Object::put(m, id, value, receiver);
}
void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QQmlContextWrapper *qml)
diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h
index 86c5b62da2..2dc0e57008 100644
--- a/src/qml/jsruntime/qv4qmlcontext_p.h
+++ b/src/qml/jsruntime/qv4qmlcontext_p.h
@@ -99,7 +99,7 @@ struct Q_QML_EXPORT QQmlContextWrapper : Object
void setReadOnly(bool b) { d()->readOnly = b; }
static ReturnedValue get(const Managed *m, StringOrSymbol *name, bool *hasProperty);
- static bool put(Managed *m, StringOrSymbol *name, const Value &value);
+ static bool put(Managed *m, Identifier id, const Value &value, Value *receiver);
};
struct Q_QML_EXPORT QmlContext : public ExecutionContext
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 94d645ac2b..8476d01f67 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -703,30 +703,30 @@ QV4::ReturnedValue QObjectWrapper::get(const Managed *m, StringOrSymbol *name, b
return that->getQmlProperty(qmlContext, n, IgnoreRevision, hasProperty, /*includeImports*/ true);
}
-bool QObjectWrapper::put(Managed *m, StringOrSymbol *n, const Value &value)
+bool QObjectWrapper::put(Managed *m, Identifier id, const Value &value, Value *receiver)
{
- if (n->isSymbol())
- return Object::put(m, n, value);
- String *name = static_cast<String *>(n);
+ if (!id.isString())
+ return Object::put(m, id, value, receiver);
+ Scope scope(m);
QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
- ExecutionEngine *v4 = that->engine();
+ ScopedString name(scope, id.asHeapObject());
- if (v4->hasException || QQmlData::wasDeleted(that->d()->object()))
+ if (scope.engine->hasException || QQmlData::wasDeleted(that->d()->object()))
return false;
- QQmlContextData *qmlContext = v4->callingQmlContext();
- if (!setQmlProperty(v4, qmlContext, that->d()->object(), name, QV4::QObjectWrapper::IgnoreRevision, value)) {
+ QQmlContextData *qmlContext = scope.engine->callingQmlContext();
+ if (!setQmlProperty(scope.engine, qmlContext, that->d()->object(), name, QV4::QObjectWrapper::IgnoreRevision, value)) {
QQmlData *ddata = QQmlData::get(that->d()->object());
// Types created by QML are not extensible at run-time, but for other QObjects we can store them
// as regular JavaScript properties, like on JavaScript objects.
if (ddata && ddata->context) {
QString error = QLatin1String("Cannot assign to non-existent property \"") +
name->toQString() + QLatin1Char('\"');
- v4->throwError(error);
+ scope.engine->throwError(error);
return false;
} else {
- return QV4::Object::put(m, name, value);
+ return QV4::Object::put(m, id, value, receiver);
}
}
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 12272c2925..5d1f79fd39 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -194,7 +194,7 @@ protected:
QQmlPropertyData *findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const;
static ReturnedValue get(const Managed *m, StringOrSymbol *name, bool *hasProperty);
- static bool put(Managed *m, StringOrSymbol *name, const Value &value);
+ static bool put(Managed *m, Identifier id, const Value &value, Value *receiver);
static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
diff --git a/src/qml/jsruntime/qv4reflect.cpp b/src/qml/jsruntime/qv4reflect.cpp
index 2594f53b14..48920fd63c 100644
--- a/src/qml/jsruntime/qv4reflect.cpp
+++ b/src/qml/jsruntime/qv4reflect.cpp
@@ -248,17 +248,12 @@ ReturnedValue Reflect::method_set(const FunctionObject *f, const Value *, const
Value undef = Primitive::undefinedValue();
const Value *index = argc > 1 ? &argv[1] : &undef;
const Value &val = argc > 2 ? argv[2] : undef;
+ ScopedValue receiver(scope, argc >3 ? argv[3] : argv[0]);
- uint n = index->asArrayIndex();
- if (n < UINT_MAX) {
- bool result = o->putIndexed(n, val);
- return Encode(result);
- }
-
- ScopedStringOrSymbol name(scope, index->toPropertyKey(scope.engine));
+ Scoped<StringOrSymbol> propertyKey(scope, index->toPropertyKey(scope.engine));
if (scope.engine->hasException)
return false;
- bool result = o->put(name, val);
+ bool result = o->put(propertyKey->toPropertyKey(), val, receiver);
return Encode(result);
}
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 7f2738321c..948a002e46 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -689,7 +689,7 @@ static Q_NEVER_INLINE bool setElementFallback(ExecutionEngine *engine, const Val
return true;
}
}
- return o->putIndexed(idx, value);
+ return o->put(idx, value);
}
ScopedStringOrSymbol name(scope, index.toPropertyKey(engine));
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index f6f8e51e19..74964916ee 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -565,8 +565,12 @@ public:
static QV4::ReturnedValue getIndexed(const QV4::Managed *that, uint index, bool *hasProperty)
{ return static_cast<const QQmlSequence<Container> *>(that)->containerGetIndexed(index, hasProperty); }
- static bool putIndexed(Managed *that, uint index, const QV4::Value &value)
- { return static_cast<QQmlSequence<Container> *>(that)->containerPutIndexed(index, value); }
+ static bool put(Managed *that, Identifier id, const QV4::Value &value, Value *receiver)
+ {
+ if (id.isArrayIndex())
+ return static_cast<QQmlSequence<Container> *>(that)->containerPutIndexed(id.asArrayIndex(), value);
+ return Object::put(that, id, value, receiver);
+ }
static QV4::PropertyAttributes queryIndexed(const QV4::Managed *that, uint index)
{ return static_cast<const QQmlSequence<Container> *>(that)->containerQueryIndexed(index); }
static bool deleteProperty(QV4::Managed *that, Identifier id)
diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp
index 31b51cbfe3..0fb6044e7d 100644
--- a/src/qml/jsruntime/qv4serialize.cpp
+++ b/src/qml/jsruntime/qv4serialize.cpp
@@ -332,7 +332,7 @@ ReturnedValue Serialize::deserialize(const char *&data, ExecutionEngine *engine)
ScopedValue v(scope);
for (quint32 ii = 0; ii < size; ++ii) {
v = deserialize(data, engine);
- a->putIndexed(ii, v);
+ a->put(ii, v);
}
return a.asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4symbol_p.h b/src/qml/jsruntime/qv4symbol_p.h
index 3cf6bc5dde..ed04b436ef 100644
--- a/src/qml/jsruntime/qv4symbol_p.h
+++ b/src/qml/jsruntime/qv4symbol_p.h
@@ -117,9 +117,7 @@ struct SymbolObject : Object
V4_INTERNALCLASS(SymbolObject)
V4_PROTOTYPE(symbolPrototype)
- static bool put(Managed *, StringOrSymbol *, const Value &) { return false; }
- static bool putIndexed(Managed *, uint, const Value &) { return false; }
-
+ static bool put(Managed *, Identifier, const Value &, Value *) { return false; }
};
}
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 86aa18c3a4..bb679f7ea0 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -384,8 +384,12 @@ ReturnedValue TypedArray::getIndexed(const Managed *m, uint index, bool *hasProp
return a->d()->type->read(a->d()->buffer->data->data(), byteOffset);
}
-bool TypedArray::putIndexed(Managed *m, uint index, const Value &value)
+bool TypedArray::put(Managed *m, Identifier id, const Value &value, Value *receiver)
{
+ if (!id.isArrayIndex())
+ return Object::put(m, id, value, receiver);
+
+ uint index = id.asArrayIndex();
ExecutionEngine *v4 = static_cast<Object *>(m)->engine();
if (v4->hasException)
return false;
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index 43ff1ec5b7..cbc449471b 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -140,7 +140,7 @@ struct Q_QML_PRIVATE_EXPORT TypedArray : Object
}
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
- static bool putIndexed(Managed *m, uint index, const Value &value);
+ static bool put(Managed *m, Identifier id, const Value &value, Value *receiver);
};
struct IntrinsicTypedArrayCtor: FunctionObject
diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp
index 5bcf5cd586..d1f2286534 100644
--- a/src/qml/qml/qqmldelayedcallqueue.cpp
+++ b/src/qml/qml/qqmldelayedcallqueue.cpp
@@ -186,7 +186,7 @@ void QQmlDelayedCallQueue::storeAnyArguments(DelayedFunctionCall &dfc, const QV4
QV4::ScopedArrayObject array(scope, engine->newArrayObject(length));
uint i = 0;
for (int j = offset, ej = argc; j < ej; ++i, ++j)
- array->putIndexed(i, argv[j]);
+ array->put(i, argv[j]);
dfc.m_args.set(engine, array);
}
diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp
index 5e30f09eec..c2c8b796c3 100644
--- a/src/qml/qml/qqmllistwrapper.cpp
+++ b/src/qml/qml/qqmllistwrapper.cpp
@@ -145,12 +145,13 @@ ReturnedValue QmlListWrapper::getIndexed(const Managed *m, uint index, bool *has
return Primitive::undefinedValue().asReturnedValue();
}
-bool QmlListWrapper::put(Managed *m, StringOrSymbol *name, const Value &value)
+bool QmlListWrapper::put(Managed *m, Identifier id, const Value &value, Value *receiver)
{
// doesn't do anything. Should we throw?
Q_UNUSED(m);
- Q_UNUSED(name);
+ Q_UNUSED(id);
Q_UNUSED(value);
+ Q_UNUSED(receiver);
return false;
}
diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h
index 4b53d91933..3b80de473e 100644
--- a/src/qml/qml/qqmllistwrapper_p.h
+++ b/src/qml/qml/qqmllistwrapper_p.h
@@ -95,7 +95,7 @@ struct Q_QML_EXPORT QmlListWrapper : Object
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, StringOrSymbol *name, const Value &value);
+ static bool put(Managed *m, Identifier id, const Value &value, Value *receiver);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
};
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 264d7d9179..fb05201010 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -194,7 +194,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
QV4::ScopedValue v(scope);
for (int i = 0; i < compilationUnit->dependentScripts.count(); ++i) {
QQmlRefPointer<QQmlScriptData> s = compilationUnit->dependentScripts.at(i);
- scripts->putIndexed(i, (v = s->scriptValueForContext(context)));
+ scripts->put(i, (v = s->scriptValueForContext(context)));
}
} else if (sharedState->creationContext) {
context->importedScripts = sharedState->creationContext->importedScripts;
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index e886198e80..85167848fb 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -2897,7 +2897,7 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent
}
QV4::ScopedValue v(scope);
for (int ii = 0; ii < scripts.count(); ++ii)
- scriptsArray->putIndexed(ii, (v = scripts.at(ii)->scriptData()->scriptValueForContext(ctxt)));
+ scriptsArray->put(ii, (v = scripts.at(ii)->scriptData()->scriptValueForContext(ctxt)));
if (!hasEngine())
initialize(parentCtxt->engine);
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 144d077c44..943cbc80d3 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -304,20 +304,20 @@ ReturnedValue QQmlTypeWrapper::get(const Managed *m, StringOrSymbol *n, bool *ha
}
-bool QQmlTypeWrapper::put(Managed *m, StringOrSymbol *n, const Value &value)
+bool QQmlTypeWrapper::put(Managed *m, Identifier id, const Value &value, Value *receiver)
{
- if (n->isSymbol())
- return Object::put(m, n, value);
- String *name = static_cast<String *>(n);
+ if (!id.isString())
+ return Object::put(m, id, value, receiver);
+
Q_ASSERT(m->as<QQmlTypeWrapper>());
QQmlTypeWrapper *w = static_cast<QQmlTypeWrapper *>(m);
- QV4::ExecutionEngine *v4 = w->engine();
- if (v4->hasException)
+ QV4::Scope scope(w);
+ if (scope.engine->hasException)
return false;
- QV4::Scope scope(v4);
- QQmlContextData *context = v4->callingQmlContext();
+ ScopedString name(scope, id.asHeapObject());
+ QQmlContextData *context = scope.engine->callingQmlContext();
QQmlType type = w->d()->type();
if (type.isValid() && !type.isSingleton() && w->d()->object) {
@@ -325,7 +325,7 @@ bool QQmlTypeWrapper::put(Managed *m, StringOrSymbol *n, const Value &value)
QQmlEngine *e = scope.engine->qmlEngine();
QObject *ao = qmlAttachedPropertiesObjectById(type.attachedPropertiesId(QQmlEnginePrivate::get(e)), object);
if (ao)
- return QV4::QObjectWrapper::setQmlProperty(v4, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, value);
+ return QV4::QObjectWrapper::setQmlProperty(scope.engine, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, value);
return false;
} else if (type.isSingleton()) {
QQmlEngine *e = scope.engine->qmlEngine();
@@ -334,12 +334,12 @@ bool QQmlTypeWrapper::put(Managed *m, StringOrSymbol *n, const Value &value)
QObject *qobjectSingleton = siinfo->qobjectApi(e);
if (qobjectSingleton) {
- return QV4::QObjectWrapper::setQmlProperty(v4, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, value);
+ return QV4::QObjectWrapper::setQmlProperty(scope.engine, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, value);
} else if (!siinfo->scriptApi(e).isUndefined()) {
- QV4::ScopedObject apiprivate(scope, QJSValuePrivate::convertedToValue(v4, siinfo->scriptApi(e)));
+ QV4::ScopedObject apiprivate(scope, QJSValuePrivate::convertedToValue(scope.engine, siinfo->scriptApi(e)));
if (!apiprivate) {
QString error = QLatin1String("Cannot assign to read-only property \"") + name->toQString() + QLatin1Char('\"');
- v4->throwError(error);
+ scope.engine->throwError(error);
return false;
} else {
return apiprivate->put(name, value);
diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h
index b17d0e0868..e2684e438f 100644
--- a/src/qml/qml/qqmltypewrapper_p.h
+++ b/src/qml/qml/qqmltypewrapper_p.h
@@ -113,7 +113,7 @@ struct Q_QML_EXPORT QQmlTypeWrapper : Object
static ReturnedValue get(const Managed *m, StringOrSymbol *name, bool *hasProperty);
- static bool put(Managed *m, StringOrSymbol *name, const Value &value);
+ static bool put(Managed *m, Identifier id, const Value &value, Value *receiver);
static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p);
static bool isEqualTo(Managed *that, Managed *o);
static ReturnedValue instanceOf(const Object *typeObject, const Value &var);
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index aa716b8a73..190d76c1a1 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -422,11 +422,10 @@ ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, StringOrSymbol *n, boo
#undef VALUE_TYPE_ACCESSOR
}
-bool QQmlValueTypeWrapper::put(Managed *m, StringOrSymbol *n, const Value &value)
+bool QQmlValueTypeWrapper::put(Managed *m, Identifier id, const Value &value, Value *receiver)
{
- if (n->isSymbol())
- return Object::put(m, n, value);
- String *name = static_cast<String *>(n);
+ if (!id.isString())
+ return Object::put(m, id, value, receiver);
Q_ASSERT(m->as<QQmlValueTypeWrapper>());
ExecutionEngine *v4 = static_cast<QQmlValueTypeWrapper *>(m)->engine();
@@ -448,8 +447,10 @@ bool QQmlValueTypeWrapper::put(Managed *m, StringOrSymbol *n, const Value &value
writeBackPropertyType = writebackProperty.userType();
}
+ ScopedString name(scope, id.asHeapObject());
+
const QMetaObject *metaObject = r->d()->propertyCache()->metaObject();
- const QQmlPropertyData *pd = r->d()->propertyCache()->property(name, nullptr, nullptr);
+ const QQmlPropertyData *pd = r->d()->propertyCache()->property(name.getPointer(), nullptr, nullptr);
if (!pd)
return false;
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index 12d7114d2f..6270fa7c63 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -107,7 +107,7 @@ public:
bool write(QObject *target, int propertyIndex) const;
static ReturnedValue get(const Managed *m, StringOrSymbol *name, bool *hasProperty);
- static bool put(Managed *m, StringOrSymbol *name, const Value &value);
+ static bool put(Managed *m, Identifier id, const Value &value, Value *receiver);
static bool isEqualTo(Managed *m, Managed *other);
static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index e4fe84bf25..3cad4b97a2 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1110,7 +1110,7 @@ ReturnedValue QtObject::method_createQmlObject(const FunctionObject *b, const Va
qmlerror->put((s = v4->newString(QStringLiteral("columnNumber"))), (v = QV4::Primitive::fromInt32(error.column())));
qmlerror->put((s = v4->newString(QStringLiteral("fileName"))), (v = v4->newString(error.url().toString())));
qmlerror->put((s = v4->newString(QStringLiteral("message"))), (v = v4->newString(error.description())));
- qmlerrors->putIndexed(ii, qmlerror);
+ qmlerrors->put(ii, qmlerror);
}
v = v4->newString(errorstr);
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index 41c52e742c..a8f4708ff6 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -1564,24 +1564,23 @@ void ModelNodeMetaObject::emitDirectNotifies(const int *changedRoles, int roleCo
namespace QV4 {
-bool ModelObject::put(Managed *m, StringOrSymbol *n, const Value &value)
+bool ModelObject::put(Managed *m, Identifier id, const Value &value, Value *receiver)
{
- if (n->isSymbol())
- return Object::put(m, n, value);
- String *name = static_cast<String *>(n);
+ if (!id.isString())
+ return Object::put(m, id, value, receiver);
+ QString propName = id.toQString();
ModelObject *that = static_cast<ModelObject*>(m);
ExecutionEngine *eng = that->engine();
const int elementIndex = that->d()->elementIndex();
- const QString propName = name->toQString();
int roleIndex = that->d()->m_model->m_listModel->setExistingProperty(elementIndex, propName, value, eng);
if (roleIndex != -1)
that->d()->m_model->emitItemsChanged(elementIndex, 1, QVector<int>(1, roleIndex));
ModelNodeMetaObject *mo = ModelNodeMetaObject::get(that->object());
if (mo->initialized())
- mo->emitPropertyNotification(name->toQString().toUtf8());
+ mo->emitPropertyNotification(propName.toUtf8());
return true;
}
diff --git a/src/qml/types/qqmllistmodel_p_p.h b/src/qml/types/qqmllistmodel_p_p.h
index 75eeaeed0c..a271d9b4d2 100644
--- a/src/qml/types/qqmllistmodel_p_p.h
+++ b/src/qml/types/qqmllistmodel_p_p.h
@@ -173,7 +173,7 @@ struct ModelObject : public QObjectWrapper {
struct ModelObject : public QObjectWrapper
{
- static bool put(Managed *m, StringOrSymbol *name, const Value& value);
+ static bool put(Managed *m, Identifier id, const Value& value, Value *receiver);
static ReturnedValue get(const Managed *m, StringOrSymbol *name, bool *hasProperty);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 0ce62952d7..5588edf804 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -909,7 +909,7 @@ struct QQuickJSContext2DPixelData : public QV4::Object
V4_NEEDS_DESTROY
static QV4::ReturnedValue getIndexed(const QV4::Managed *m, uint index, bool *hasProperty);
- static bool putIndexed(QV4::Managed *m, uint index, const QV4::Value &value);
+ static bool put(QV4::Managed *m, QV4::Identifier id, const QV4::Value &value, Value *receiver);
static QV4::ReturnedValue proto_get_length(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
@@ -3161,14 +3161,18 @@ QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(const QV4::Managed *m,
return QV4::Encode::undefined();
}
-bool QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const QV4::Value &value)
+bool QQuickJSContext2DPixelData::put(QV4::Managed *m, QV4::Identifier id, const QV4::Value &value, QV4::Value *receiver)
{
+ if (!id.isArrayIndex())
+ return Object::put(m, id, value, receiver);
+
Q_ASSERT(m->as<QQuickJSContext2DPixelData>());
QV4::ExecutionEngine *v4 = static_cast<QQuickJSContext2DPixelData *>(m)->engine();
QV4::Scope scope(v4);
if (scope.hasException())
return false;
+ uint index = id.asArrayIndex();
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, static_cast<QQuickJSContext2DPixelData *>(m));
const int v = value.toInt32();