diff options
author | Robin Burchell <robin.burchell@crimson.no> | 2017-02-08 23:16:12 +0100 |
---|---|---|
committer | Robin Burchell <robin.burchell@crimson.no> | 2017-02-09 14:53:06 +0000 |
commit | 62268fb2a025fee49d0ac8bcf965cc989b583cae (patch) | |
tree | 0139e9019bcef78d14d75d3ff856dd5c86e73a1a /src | |
parent | 5f83e6dfe698d65a0c145ccfd09c9f00609311ca (diff) |
Object: Introduce set and setIndexed
These names are what the ES6 spec uses for this operation. We also
introduce a bool to allow throwing unconditionally if a set fails (which
the spec requires the Set operation to do in a number of places). This
requirement was also present in ES5, but we ignored it, and thus far got
away with it.
Long term, put and putIndexed should go away, but I don't feel
comfortable porting everything over blindly, as some operations do
require throwing, namely:
* Various Array & TypedArray methods that alter 'length'
* Various RegExp methods that alter 'lastIndex'
This change also ports the new Object.assign to use the must-throw
version of set(), which coincidentally fixes the one test failure in
non-strict mode.
Change-Id: Ida641a552d805af0fd9de3333eb62cc6adb3713c
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 37 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4objectproto.cpp | 2 |
3 files changed, 40 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 0ef53d5703..b95bfb85a7 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -790,6 +790,7 @@ bool Object::internalPut(String *name, const Value &value) return true; reject: + // ### this should be removed once everything is ported to use Object::set() if (engine()->current->strictMode) { QString message = QLatin1String("Cannot assign to read-only property \"") + name->toQString() + QLatin1Char('\"'); @@ -861,6 +862,7 @@ bool Object::internalPutIndexed(uint index, const Value &value) return true; reject: + // ### this should be removed once everything is ported to use Object::setIndexed() if (engine()->current->strictMode) engine()->throwTypeError(); return false; diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index d321df2451..0d17afbf41 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -336,10 +336,47 @@ public: { return vtable()->get(this, name, hasProperty); } inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0) const { return vtable()->getIndexed(this, idx, hasProperty); } + + // use the set variants instead, to customize throw behavior 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); } + + enum ThrowOnFailure { + DoThrowOnRejection, + DoNotThrow + }; + + // ES6: 7.3.3 Set (O, P, V, Throw) + inline bool set(String *name, const Value &v, ThrowOnFailure shouldThrow) + { + bool ret = vtable()->put(this, name, v); + // ES6: 7.3.3, 6: If success is false and Throw is true, throw a TypeError exception. + if (!ret && shouldThrow == ThrowOnFailure::DoThrowOnRejection) { + ExecutionEngine *e = engine(); + if (!e->hasException) { // allow a custom set impl to throw itself + QString message = QLatin1String("Cannot assign to read-only property \"") + + name->toQString() + QLatin1Char('\"'); + e->throwTypeError(message); + } + } + return ret; + } + + inline bool setIndexed(uint idx, const Value &v, ThrowOnFailure shouldThrow) + { + bool ret = vtable()->putIndexed(this, idx, v); + if (!ret && shouldThrow == ThrowOnFailure::DoThrowOnRejection) { + ExecutionEngine *e = engine(); + if (!e->hasException) { // allow a custom set impl to throw itself + e->throwTypeError(); + } + } + return ret; + } + + PropertyAttributes query(String *name) const { return vtable()->query(this, name); } PropertyAttributes queryIndexed(uint index) const diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index d8063c64de..f650ffc7b1 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -194,7 +194,7 @@ void ObjectPrototype::method_assign(const BuiltinFunction *, Scope &scope, CallD continue; propValue = from->get(nextKey); - to->put(nextKey, propValue); + to->set(nextKey, propValue, Object::DoThrowOnRejection); CHECK_EXCEPTION(); } } |