diff options
-rw-r--r-- | src/qml/jsruntime/qv4property_p.h | 34 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4proxy.cpp | 13 | ||||
-rw-r--r-- | tests/auto/qml/ecmascripttests/TestExpectations | 3 |
3 files changed, 42 insertions, 8 deletions
diff --git a/src/qml/jsruntime/qv4property_p.h b/src/qml/jsruntime/qv4property_p.h index 26dc7a83c3..bad8eeb078 100644 --- a/src/qml/jsruntime/qv4property_p.h +++ b/src/qml/jsruntime/qv4property_p.h @@ -92,6 +92,40 @@ struct Property { set = other->set; } + // ES8, section 9.1.6.2/9,.1.6.3 + bool isCompatible(PropertyAttributes &attrs, const Property *other, PropertyAttributes otherAttrs) const { + if (otherAttrs.isEmpty()) + return true; + if (!attrs.isConfigurable()) { + if (otherAttrs.hasConfigurable() && otherAttrs.isConfigurable()) + return false; + if (otherAttrs.hasEnumerable() && otherAttrs.isEnumerable() != attrs.isEnumerable()) + return false; + } + if (otherAttrs.isGeneric()) + return true; + if (attrs.isData() != otherAttrs.isData()) { + if (!attrs.isConfigurable()) + return false; + } else if (attrs.isData() && otherAttrs.isData()) { + if (!attrs.isConfigurable() && !attrs.isWritable()) { + if (otherAttrs.hasWritable() && otherAttrs.isWritable()) + return false; + if (!other->value.isEmpty() && !value.sameValue(other->value)) + return false; + } + } else if (attrs.isAccessor() && otherAttrs.isAccessor()) { + if (!attrs.isConfigurable()) { + if (!other->value.isEmpty() && !value.sameValue(other->value)) + return false; + if (!other->set.isEmpty() && !set.sameValue(other->set)) + return false; + } + } + return true; + } + + explicit Property() { value = Encode::undefined(); set = Value::fromHeapObject(nullptr); } Property(Heap::FunctionObject *getter, Heap::FunctionObject *setter) { value.setM(reinterpret_cast<Heap::Base *>(getter)); diff --git a/src/qml/jsruntime/qv4proxy.cpp b/src/qml/jsruntime/qv4proxy.cpp index d4f342c50e..19e46304af 100644 --- a/src/qml/jsruntime/qv4proxy.cpp +++ b/src/qml/jsruntime/qv4proxy.cpp @@ -277,9 +277,10 @@ PropertyAttributes ProxyObject::virtualGetOwnProperty(Managed *m, PropertyKey id ObjectPrototype::toPropertyDescriptor(scope.engine, trapResult, resultDesc, &resultAttributes); resultDesc->fullyPopulated(&resultAttributes); - // ### - //Let valid be IsCompatiblePropertyDescriptor(extensibleTarget, resultDesc, targetDesc). - //If valid is false, throw a TypeError exception. + if (!targetDesc->isCompatible(targetAttributes, resultDesc, resultAttributes)) { + scope.engine->throwTypeError(); + return Attr_Invalid; + } if (!resultAttributes.isConfigurable()) { if (targetAttributes == Attr_Invalid || !targetAttributes.isConfigurable()) { @@ -336,8 +337,10 @@ bool ProxyObject::virtualDefineOwnProperty(Managed *m, PropertyKey id, const Pro return false; } } else { - // ### - // if IsCompatiblePropertyDescriptor(extensibleTarget, Desc, targetDesc) is false throw a type error. + if (!targetDesc->isCompatible(targetAttributes, p, attrs)) { + scope.engine->throwTypeError(); + return false; + } if (settingConfigFalse && targetAttributes.isConfigurable()) { scope.engine->throwTypeError(); return false; diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index b5d89ca545..e066b816ae 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -372,9 +372,7 @@ built-ins/Proxy/defineProperty/desc-realm.js fails built-ins/Proxy/defineProperty/null-handler-realm.js fails built-ins/Proxy/defineProperty/targetdesc-configurable-desc-not-configurable-realm.js fails built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-not-configurable-target-realm.js fails -built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-not-configurable-target.js fails built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-realm.js fails -built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor.js fails built-ins/Proxy/defineProperty/targetdesc-undefined-not-configurable-descriptor-realm.js fails built-ins/Proxy/defineProperty/targetdesc-undefined-target-is-not-extensible-realm.js fails built-ins/Proxy/defineProperty/trap-is-not-callable-realm.js fails @@ -385,7 +383,6 @@ built-ins/Proxy/get/trap-is-not-callable-realm.js fails built-ins/Proxy/get/trap-is-undefined-receiver.js fails built-ins/Proxy/getOwnPropertyDescriptor/result-type-is-not-object-nor-undefined-realm.js fails built-ins/Proxy/getOwnPropertyDescriptor/result-type-is-not-object-nor-undefined.js fails -built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-invalid-descriptor.js fails built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-configurable.js fails built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-not-configurable.js fails built-ins/Proxy/getOwnPropertyDescriptor/trap-is-not-callable-realm.js fails |