aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorRobin Burchell <robin.burchell@crimson.no>2017-02-08 22:57:11 +0100
committerRobin Burchell <robin.burchell@crimson.no>2017-02-09 14:53:01 +0000
commit5f83e6dfe698d65a0c145ccfd09c9f00609311ca (patch)
tree2499e0a9f2d10a2531219555795e25e6d3f29d25 /src/qml/jsruntime
parent60d67b4eb9cdac20c1a3458192c1306666352231 (diff)
Object: Allow put and putIndexed to return success or failure
Some parts of the ES6 (and even ES5!) spec specifically require handling of a property write failure. This will be introduced in followup changes, as it's going to be rather more involved than this. Change-Id: Ie482493fcf4780df0e23619650a856421d20bd55 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp9
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4object.cpp41
-rw-r--r--src/qml/jsruntime/qv4object_p.h22
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp27
-rw-r--r--src/qml/jsruntime/qv4qmlcontext_p.h2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp9
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h2
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp13
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp7
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h2
11 files changed, 70 insertions, 66 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 9354bcb1a3..7c1cc92a13 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -166,18 +166,17 @@ ReturnedValue ArgumentsObject::getIndexed(const Managed *m, uint index, bool *ha
return Encode::undefined();
}
-void ArgumentsObject::putIndexed(Managed *m, uint index, const Value &value)
+bool ArgumentsObject::putIndexed(Managed *m, uint index, const Value &value)
{
ArgumentsObject *args = static_cast<ArgumentsObject *>(m);
if (!args->fullyCreated() && index >= static_cast<uint>(args->context()->callData->argc))
args->fullyCreate();
- if (args->fullyCreated()) {
- Object::putIndexed(m, index, value);
- return;
- }
+ if (args->fullyCreated())
+ return Object::putIndexed(m, index, value);
args->context()->callData->args[index] = value;
+ return true;
}
bool ArgumentsObject::deleteIndexedProperty(Managed *m, uint index)
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index 0a2ea3b42a..f80ade9611 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -128,7 +128,7 @@ struct ArgumentsObject: Object {
bool defineOwnProperty(ExecutionEngine *engine, uint index, const Property *desc, PropertyAttributes attrs);
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
- static void putIndexed(Managed *m, uint index, const Value &value);
+ static bool putIndexed(Managed *m, uint index, const Value &value);
static bool deleteIndexedProperty(Managed *m, uint index);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
static void markObjects(Heap::Base *that, ExecutionEngine *e);
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 3d87675699..0ef53d5703 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -107,11 +107,11 @@ ReturnedValue Object::getValue(const Value &thisObject, const Value &v, Property
return scope.result.asReturnedValue();
}
-void Object::putValue(uint memberIndex, const Value &value)
+bool Object::putValue(uint memberIndex, const Value &value)
{
QV4::InternalClass *ic = internalClass();
if (ic->engine->hasException)
- return;
+ return false;
PropertyAttributes attrs = ic->propertyData[memberIndex];
@@ -124,7 +124,7 @@ void Object::putValue(uint memberIndex, const Value &value)
callData->args[0] = value;
callData->thisObject = this;
setter->call(scope, callData);
- return;
+ return !ic->engine->hasException;
}
goto reject;
}
@@ -133,11 +133,12 @@ void Object::putValue(uint memberIndex, const Value &value)
goto reject;
*propertyData(memberIndex) = value;
- return;
+ return true;
reject:
if (engine()->current->strictMode)
engine()->throwTypeError();
+ return false;
}
void Object::defineDefaultProperty(const QString &name, const Value &value)
@@ -446,14 +447,14 @@ ReturnedValue Object::getIndexed(const Managed *m, uint index, bool *hasProperty
return static_cast<const Object *>(m)->internalGetIndexed(index, hasProperty);
}
-void Object::put(Managed *m, String *name, const Value &value)
+bool Object::put(Managed *m, String *name, const Value &value)
{
- static_cast<Object *>(m)->internalPut(name, value);
+ return static_cast<Object *>(m)->internalPut(name, value);
}
-void Object::putIndexed(Managed *m, uint index, const Value &value)
+bool Object::putIndexed(Managed *m, uint index, const Value &value)
{
- static_cast<Object *>(m)->internalPutIndexed(index, value);
+ return static_cast<Object *>(m)->internalPutIndexed(index, value);
}
PropertyAttributes Object::query(const Managed *m, String *name)
@@ -711,10 +712,10 @@ ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty) const
// Section 8.12.5
-void Object::internalPut(String *name, const Value &value)
+bool Object::internalPut(String *name, const Value &value)
{
if (internalClass()->engine->hasException)
- return;
+ return false;
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@@ -743,7 +744,7 @@ void Object::internalPut(String *name, const Value &value)
uint l = value.asArrayLength(&ok);
if (!ok) {
engine()->throwRangeError(value);
- return;
+ return false;
}
ok = setArrayLength(l);
if (!ok)
@@ -751,7 +752,7 @@ void Object::internalPut(String *name, const Value &value)
} else {
*v = value;
}
- return;
+ return true;
} else if (!prototype()) {
if (!isExtensible())
goto reject;
@@ -782,11 +783,11 @@ void Object::internalPut(String *name, const Value &value)
callData->args[0] = value;
callData->thisObject = this;
setter->call(scope, callData);
- return;
+ return !internalClass()->engine->hasException;
}
insertMember(name, value);
- return;
+ return true;
reject:
if (engine()->current->strictMode) {
@@ -794,12 +795,13 @@ void Object::internalPut(String *name, const Value &value)
name->toQString() + QLatin1Char('\"');
engine()->throwTypeError(message);
}
+ return false;
}
-void Object::internalPutIndexed(uint index, const Value &value)
+bool Object::internalPutIndexed(uint index, const Value &value)
{
if (internalClass()->engine->hasException)
- return;
+ return false;
PropertyAttributes attrs;
@@ -821,7 +823,7 @@ void Object::internalPutIndexed(uint index, const Value &value)
goto reject;
else
*v = value;
- return;
+ return true;
} else if (!prototype()) {
if (!isExtensible())
goto reject;
@@ -852,15 +854,16 @@ void Object::internalPutIndexed(uint index, const Value &value)
callData->args[0] = value;
callData->thisObject = this;
setter->call(scope, callData);
- return;
+ return !internalClass()->engine->hasException;
}
arraySet(index, value);
- return;
+ return true;
reject:
if (engine()->current->strictMode)
engine()->throwTypeError();
+ return false;
}
// Section 8.12.7
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 33f29840df..d321df2451 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -130,8 +130,8 @@ struct ObjectVTable
void (*construct)(const Managed *, Scope &scope, CallData *data);
ReturnedValue (*get)(const Managed *, String *name, bool *hasProperty);
ReturnedValue (*getIndexed)(const Managed *, uint index, bool *hasProperty);
- void (*put)(Managed *, String *name, const Value &value);
- void (*putIndexed)(Managed *, uint index, const Value &value);
+ bool (*put)(Managed *, String *name, const Value &value);
+ bool (*putIndexed)(Managed *, uint index, const Value &value);
PropertyAttributes (*query)(const Managed *, String *name);
PropertyAttributes (*queryIndexed)(const Managed *, uint index);
bool (*deleteProperty)(Managed *m, String *name);
@@ -230,7 +230,7 @@ struct Q_QML_EXPORT Object: Managed {
return getValue(t, v, attrs);
}
- void putValue(uint memberIndex, const Value &value);
+ bool putValue(uint memberIndex, const Value &value);
/* The spec default: Writable: true, Enumerable: false, Configurable: true */
void defineDefaultProperty(String *name, const Value &value) {
@@ -336,10 +336,10 @@ public:
{ return vtable()->get(this, name, hasProperty); }
inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0) const
{ return vtable()->getIndexed(this, idx, hasProperty); }
- inline void put(String *name, const Value &v)
- { vtable()->put(this, name, v); }
- inline void putIndexed(uint idx, const Value &v)
- { vtable()->putIndexed(this, idx, v); }
+ inline bool put(String *name, const Value &v)
+ { return vtable()->put(this, name, v); }
+ inline bool putIndexed(uint idx, const Value &v)
+ { return vtable()->putIndexed(this, idx, v); }
PropertyAttributes query(String *name) const
{ return vtable()->query(this, name); }
PropertyAttributes queryIndexed(uint index) const
@@ -368,8 +368,8 @@ protected:
static void call(const Managed *m, Scope &scope, CallData *);
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
- static void put(Managed *m, String *name, const Value &value);
- static void putIndexed(Managed *m, uint index, const Value &value);
+ static bool put(Managed *m, String *name, const Value &value);
+ static bool putIndexed(Managed *m, uint index, const Value &value);
static PropertyAttributes query(const Managed *m, String *name);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
static bool deleteProperty(Managed *m, String *name);
@@ -383,8 +383,8 @@ protected:
private:
ReturnedValue internalGet(String *name, bool *hasProperty) const;
ReturnedValue internalGetIndexed(uint index, bool *hasProperty) const;
- void internalPut(String *name, const Value &value);
- void internalPutIndexed(uint index, const Value &value);
+ bool internalPut(String *name, const Value &value);
+ bool internalPutIndexed(uint index, const Value &value);
bool internalDeleteProperty(String *name);
bool internalDeleteIndexedProperty(uint index);
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index 889f4ea288..cdc29c8b9c 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -225,21 +225,19 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr
return Encode::undefined();
}
-void QmlContextWrapper::put(Managed *m, String *name, const Value &value)
+bool QmlContextWrapper::put(Managed *m, String *name, const Value &value)
{
Q_ASSERT(m->as<QmlContextWrapper>());
QmlContextWrapper *resource = static_cast<QmlContextWrapper *>(m);
ExecutionEngine *v4 = resource->engine();
QV4::Scope scope(v4);
if (scope.hasException())
- return;
+ return false;
QV4::Scoped<QmlContextWrapper> wrapper(scope, resource);
uint member = wrapper->internalClass()->find(name);
- if (member < UINT_MAX) {
- wrapper->putValue(member, value);
- return;
- }
+ if (member < UINT_MAX)
+ return wrapper->putValue(member, value);
if (wrapper->d()->isNullWrapper) {
if (wrapper && wrapper->d()->readOnly) {
@@ -247,11 +245,10 @@ void QmlContextWrapper::put(Managed *m, String *name, const Value &value)
QLatin1Char('"');
ScopedString e(scope, v4->newString(error));
v4->throwError(e);
- return;
+ return false;
}
- Object::put(m, name, value);
- return;
+ return Object::put(m, name, value);
}
// Its possible we could delay the calculation of the "actual" context (in the case
@@ -260,7 +257,7 @@ void QmlContextWrapper::put(Managed *m, String *name, const Value &value)
QQmlContextData *expressionContext = context;
if (!context)
- return;
+ return false;
// See QV8ContextWrapper::Getter for resolution order
@@ -270,18 +267,18 @@ void QmlContextWrapper::put(Managed *m, String *name, const Value &value)
const QV4::IdentifierHash<int> &properties = context->propertyNames();
// Search context properties
if (properties.count() && properties.value(name) != -1)
- return;
+ return false;
// Search scope object
if (scopeObject &&
QV4::QObjectWrapper::setQmlProperty(v4, context, scopeObject, name, QV4::QObjectWrapper::CheckRevision, value))
- return;
+ return true;
scopeObject = 0;
// Search context object
if (context->contextObject &&
QV4::QObjectWrapper::setQmlProperty(v4, context, context->contextObject, name, QV4::QObjectWrapper::CheckRevision, value))
- return;
+ return true;
context = context->parent;
}
@@ -292,10 +289,10 @@ void QmlContextWrapper::put(Managed *m, String *name, const Value &value)
QString error = QLatin1String("Invalid write to global property \"") + name->toQString() +
QLatin1Char('"');
v4->throwError(error);
- return;
+ return false;
}
- Object::put(m, name, value);
+ return Object::put(m, name, value);
}
void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QmlContextWrapper *qml)
diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h
index 9aec7467da..6e5e743609 100644
--- a/src/qml/jsruntime/qv4qmlcontext_p.h
+++ b/src/qml/jsruntime/qv4qmlcontext_p.h
@@ -100,7 +100,7 @@ struct Q_QML_EXPORT QmlContextWrapper : Object
void setReadOnly(bool b) { d()->readOnly = b; }
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
- static void put(Managed *m, String *name, const Value &value);
+ static bool put(Managed *m, String *name, const Value &value);
};
struct Q_QML_EXPORT QmlContext : public ExecutionContext
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 7260e71fab..283c3dad04 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -625,13 +625,13 @@ QV4::ReturnedValue QObjectWrapper::get(const Managed *m, String *name, bool *has
return that->getQmlProperty(qmlContext, name, IgnoreRevision, hasProperty, /*includeImports*/ true);
}
-void QObjectWrapper::put(Managed *m, String *name, const Value &value)
+bool QObjectWrapper::put(Managed *m, String *name, const Value &value)
{
QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
ExecutionEngine *v4 = that->engine();
if (v4->hasException || QQmlData::wasDeleted(that->d()->object()))
- return;
+ return false;
QQmlContextData *qmlContext = v4->callingQmlContext();
if (!setQmlProperty(v4, qmlContext, that->d()->object(), name, QV4::QObjectWrapper::IgnoreRevision, value)) {
@@ -642,10 +642,13 @@ void QObjectWrapper::put(Managed *m, String *name, const Value &value)
QString error = QLatin1String("Cannot assign to non-existent property \"") +
name->toQString() + QLatin1Char('\"');
v4->throwError(error);
+ return false;
} else {
- QV4::Object::put(m, name, value);
+ return QV4::Object::put(m, name, value);
}
}
+
+ return true;
}
PropertyAttributes QObjectWrapper::query(const Managed *m, String *name)
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index b09e06cec5..d81ef2a680 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -192,7 +192,7 @@ protected:
QQmlPropertyData *findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const;
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
- static void put(Managed *m, String *name, const Value &value);
+ static bool put(Managed *m, String *name, const Value &value);
static PropertyAttributes query(const Managed *, String *name);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e);
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 8ce10e326d..6d3110771e 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -274,20 +274,20 @@ public:
return Encode::undefined();
}
- void containerPutIndexed(uint index, const QV4::Value &value)
+ bool containerPutIndexed(uint index, const QV4::Value &value)
{
if (internalClass()->engine->hasException)
- return;
+ return false;
/* Qt containers have int (rather than uint) allowable indexes. */
if (index > INT_MAX) {
generateWarning(engine(), QLatin1String("Index out of range during indexed set"));
- return;
+ return false;
}
if (d()->isReference) {
if (!d()->object)
- return;
+ return false;
loadReference();
}
@@ -313,6 +313,7 @@ public:
if (d()->isReference)
storeReference();
+ return true;
}
QV4::PropertyAttributes containerQueryIndexed(uint index) const
@@ -540,8 +541,8 @@ public:
static QV4::ReturnedValue getIndexed(const QV4::Managed *that, uint index, bool *hasProperty)
{ return static_cast<const QQmlSequence<Container> *>(that)->containerGetIndexed(index, hasProperty); }
- static void putIndexed(Managed *that, uint index, const QV4::Value &value)
- { static_cast<QQmlSequence<Container> *>(that)->containerPutIndexed(index, value); }
+ static bool putIndexed(Managed *that, uint index, const QV4::Value &value)
+ { return static_cast<QQmlSequence<Container> *>(that)->containerPutIndexed(index, value); }
static QV4::PropertyAttributes queryIndexed(const QV4::Managed *that, uint index)
{ return static_cast<const QQmlSequence<Container> *>(that)->containerQueryIndexed(index); }
static bool deleteIndexedProperty(QV4::Managed *that, uint index)
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index cecd1e6958..5573a2e57f 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -398,11 +398,11 @@ ReturnedValue TypedArray::getIndexed(const Managed *m, uint index, bool *hasProp
return a->d()->type->read(a->d()->buffer->data->data(), byteOffset);
}
-void TypedArray::putIndexed(Managed *m, uint index, const Value &value)
+bool TypedArray::putIndexed(Managed *m, uint index, const Value &value)
{
ExecutionEngine *v4 = static_cast<Object *>(m)->engine();
if (v4->hasException)
- return;
+ return false;
Scope scope(v4);
Scoped<TypedArray> a(scope, static_cast<TypedArray *>(m));
@@ -413,11 +413,12 @@ void TypedArray::putIndexed(Managed *m, uint index, const Value &value)
goto reject;
a->d()->type->write(scope.engine, a->d()->buffer->data->data(), byteOffset, value);
- return;
+ return true;
reject:
if (scope.engine->current->strictMode)
scope.engine->throwTypeError();
+ return false;
}
void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor)
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index eefed2db4b..fbf13c9815 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -133,7 +133,7 @@ struct Q_QML_PRIVATE_EXPORT TypedArray : Object
static void markObjects(Heap::Base *that, ExecutionEngine *e);
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
- static void putIndexed(Managed *m, uint index, const Value &value);
+ static bool putIndexed(Managed *m, uint index, const Value &value);
};
struct TypedArrayCtor: FunctionObject