import change from rmottola/Arctic-Fox:

- Bug 1133085 - PropDesc::initFromPropertyDescriptor should understand JSPROP_GETTER without JSPROP_SETTER and vice versa. (d83f16200)
This commit is contained in:
2019-03-30 07:48:34 +08:00
parent c1ae338aef
commit d86d78c8b6
3 changed files with 42 additions and 8 deletions
@@ -0,0 +1,17 @@
// Bug 1133085 - Test that descriptors are properly reconstituted
// when only .get or only .set is present.
load(libdir + "asserts.js");
var input, output;
var p = new Proxy({x: 0}, {
defineProperty(t, k, desc) { output = desc; print("ok"); return true; }
});
input = {get: function () {}};
Object.defineProperty(p, "x", input);
assertDeepEq(output, input);
input = {set: function () {}};
Object.defineProperty(p, "x", input);
assertDeepEq(output, input);
+23 -6
View File
@@ -154,12 +154,12 @@ PropDesc::initFromPropertyDescriptor(Handle<PropertyDescriptor> desc)
attrs = uint8_t(desc.attributes());
MOZ_ASSERT_IF(attrs & JSPROP_READONLY, !(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
if (desc.hasGetterOrSetterObject()) {
hasGet_ = true;
get_ = desc.hasGetterObject() && desc.getterObject()
hasGet_ = desc.hasGetterObject();
get_ = hasGet_ && desc.getterObject()
? ObjectValue(*desc.getterObject())
: UndefinedValue();
hasSet_ = true;
set_ = desc.hasSetterObject() && desc.setterObject()
hasSet_ = desc.hasSetterObject();
set_ = hasSet_ && desc.setterObject()
? ObjectValue(*desc.setterObject())
: UndefinedValue();
hasValue_ = false;
@@ -3210,10 +3210,27 @@ js::GetOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id,
if (desc.hasGetterOrSetterObject()) {
MOZ_ASSERT(desc.isShared());
doGet = false;
if (desc.hasGetterObject())
// The result of GetOwnPropertyDescriptor() must be either undefined or
// a complete property descriptor (per ES6 draft rev 32 (2015 Feb 2)
// 6.1.7.3, Invariants of the Essential Internal Methods).
//
// It is an unfortunate fact that in SM, properties can exist that have
// JSPROP_GETTER or JSPROP_SETTER but not both. In these cases, rather
// than return true with desc incomplete, we fill out the missing
// getter or setter with a null, following CompletePropertyDescriptor.
if (desc.hasGetterObject()) {
desc.setGetterObject(shape->getterObject());
if (desc.hasSetterObject())
} else {
desc.setGetterObject(nullptr);
desc.attributesRef() |= JSPROP_GETTER;
}
if (desc.hasSetterObject()) {
desc.setSetterObject(shape->setterObject());
} else {
desc.setSetterObject(nullptr);
desc.attributesRef() |= JSPROP_SETTER;
}
} else {
// This is either a straight-up data property or (rarely) a
// property with a JSPropertyOp getter/setter. The latter must be
+2 -2
View File
@@ -912,7 +912,7 @@ ScriptedDirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject
}
}
if (IsAccessorDescriptor(desc) && desc.isPermanent() && !desc.hasGetterObject()) {
if (IsAccessorDescriptor(desc) && desc.isPermanent() && desc.getterObject() == nullptr) {
if (!trapResult.isUndefined()) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_MUST_REPORT_UNDEFINED);
return false;
@@ -982,7 +982,7 @@ ScriptedDirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject
}
}
if (IsAccessorDescriptor(desc) && desc.isPermanent() && !desc.hasSetterObject()) {
if (IsAccessorDescriptor(desc) && desc.isPermanent() && desc.setterObject() == nullptr) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_SET_WO_SETTER);
return false;
}