aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations1
38 files changed, 195 insertions, 264 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();
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 7ed69d9ecf..4204cbf877 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -858,7 +858,6 @@ built-ins/Reflect/set/creates-a-data-descriptor.js fails
built-ins/Reflect/set/different-property-descriptors.js fails
built-ins/Reflect/set/receiver-is-not-object.js fails
built-ins/Reflect/set/return-false-if-target-is-not-writable.js fails
-built-ins/Reflect/set/set-value-on-accessor-descriptor-with-receiver.js fails
built-ins/Reflect/set/set-value-on-data-descriptor.js fails
built-ins/Reflect/set/symbol-property.js fails
built-ins/RegExp/15.10.4.1-1.js fails