AbsenceOfSetEffect property condition should mind put() overrides
https://bugs.webkit.org/show_bug.cgi?id=241574
<rdar://91833733>
Reviewed by Yusuke Suzuki.
Since JSArray's "length" and RegExpObject's "lastIndex" may be reconfigured as non-writable,
we need to handle them separately in AbsenceOfSetEffect property condition to ensure that compiler
takes a slow path in that case, following the spec and throwing an exception in strict mode [1].
I'm not sure how to make a test case capturing this though.
[1]: https://tc39.es/ecma262/#sec-ordinarysetwithowndescriptor (step 2.a)
* Source/JavaScriptCore/bytecode/PropertyCondition.cpp:
(JSC::nonStructurePropertyMayBecomeReadOnlyWithoutTransition):
(JSC::PropertyCondition::isStillValidAssumingImpurePropertyWatchpoint const):
Canonical link: https://commits.webkit.org/251615@main
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@295610 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/PropertyCondition.cpp b/Source/JavaScriptCore/bytecode/PropertyCondition.cpp
index 8218fee..ee2b6d1 100644
--- a/Source/JavaScriptCore/bytecode/PropertyCondition.cpp
+++ b/Source/JavaScriptCore/bytecode/PropertyCondition.cpp
@@ -69,6 +69,21 @@
dumpInContext(out, nullptr);
}
+ALWAYS_INLINE static bool nonStructurePropertyMayBecomeReadOnlyWithoutTransition(Structure* structure, UniquedStringImpl* uid)
+{
+ switch (structure->typeInfo().type()) {
+ case ArrayType:
+ case DerivedArrayType:
+ return uid == structure->vm().propertyNames->length.impl();
+
+ case RegExpObjectType:
+ return uid == structure->vm().propertyNames->lastIndex.impl();
+
+ default:
+ return false;
+ }
+}
+
bool PropertyCondition::isStillValidAssumingImpurePropertyWatchpoint(
Concurrency concurrency, Structure* structure, JSObject* base) const
{
@@ -173,6 +188,10 @@
}
return false;
}
+ } else if (nonStructurePropertyMayBecomeReadOnlyWithoutTransition(structure, uid())) {
+ if (PropertyConditionInternal::verbose)
+ dataLog("Invalid because its put() override may treat ", uid(), " property as read-only.\n");
+ return false;
}
if (structure->hasPolyProto()) {