Title: [283232] trunk
- Revision
- 283232
- Author
- [email protected]
- Date
- 2021-09-29 10:03:29 -0700 (Wed, 29 Sep 2021)
Log Message
Code inside strength reduction can incorrectly prove that we know what lastIndex is
https://bugs.webkit.org/show_bug.cgi?id=230802
<rdar://problem/83543699>
Reviewed by Mark Lam.
JSTests:
* stress/dont-fold-regexp-exec-when-we-dont-know-last-index-and-regexp-is-constant.js: Added.
(assert):
(let.reg.RegExp.foo.g.doExec):
(noInline.doExec):
Source/_javascript_Core:
The phase was searching backwards in the graph to see if it found the RegExp
node. However, the RegExp node might be a JSConstant. Hence, the program
didn't allocate it. So we can't assume that we know what the lastIndex is.
We were incorrectly assuming it was "0" in a program like this:
a: JSConstant(RegExp)
b: RegExpExec(@a)
And we assumed we're invoking RegExpExec with lastIndex is 0, because we found
our RegExp in a backwards search. This is likely because we're also matching
NewRegExp nodes, in which case, it is valid to say lastIndex is 0.
This caused us to return a constant value that would've been the exec
result had we invoked it with a NewRegExpNode.
* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::run):
(JSC::DFG::StrengthReductionPhase::handleNode):
Modified Paths
Added Paths
Diff
Modified: trunk/JSTests/ChangeLog (283231 => 283232)
--- trunk/JSTests/ChangeLog 2021-09-29 16:56:07 UTC (rev 283231)
+++ trunk/JSTests/ChangeLog 2021-09-29 17:03:29 UTC (rev 283232)
@@ -1,5 +1,18 @@
2021-09-29 Saam Barati <[email protected]>
+ Code inside strength reduction can incorrectly prove that we know what lastIndex is
+ https://bugs.webkit.org/show_bug.cgi?id=230802
+ <rdar://problem/83543699>
+
+ Reviewed by Mark Lam.
+
+ * stress/dont-fold-regexp-exec-when-we-dont-know-last-index-and-regexp-is-constant.js: Added.
+ (assert):
+ (let.reg.RegExp.foo.g.doExec):
+ (noInline.doExec):
+
+2021-09-29 Saam Barati <[email protected]>
+
DoesGCCheck does not use enough bits for nodeIndex
https://bugs.webkit.org/show_bug.cgi?id=230915
<rdar://83297515>
Added: trunk/JSTests/stress/dont-fold-regexp-exec-when-we-dont-know-last-index-and-regexp-is-constant.js (0 => 283232)
--- trunk/JSTests/stress/dont-fold-regexp-exec-when-we-dont-know-last-index-and-regexp-is-constant.js (rev 0)
+++ trunk/JSTests/stress/dont-fold-regexp-exec-when-we-dont-know-last-index-and-regexp-is-constant.js 2021-09-29 17:03:29 UTC (rev 283232)
@@ -0,0 +1,19 @@
+function assert(b) {
+ if (!b)
+ throw new Error;
+}
+
+let reg = RegExp(/foo/g)
+function doExec() {
+ return reg.exec("-foo");
+}
+noInline(doExec)
+
+for (let i = 0; i < 1000; ++i) {
+ let r = doExec();
+ if ((i % 2) === 0)
+ assert(r[0] === "foo");
+ else
+ assert(r === null);
+}
+
Modified: trunk/Source/_javascript_Core/ChangeLog (283231 => 283232)
--- trunk/Source/_javascript_Core/ChangeLog 2021-09-29 16:56:07 UTC (rev 283231)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-09-29 17:03:29 UTC (rev 283232)
@@ -1,3 +1,29 @@
+2021-09-29 Saam Barati <[email protected]>
+
+ Code inside strength reduction can incorrectly prove that we know what lastIndex is
+ https://bugs.webkit.org/show_bug.cgi?id=230802
+ <rdar://problem/83543699>
+
+ Reviewed by Mark Lam.
+
+ The phase was searching backwards in the graph to see if it found the RegExp
+ node. However, the RegExp node might be a JSConstant. Hence, the program
+ didn't allocate it. So we can't assume that we know what the lastIndex is.
+ We were incorrectly assuming it was "0" in a program like this:
+ a: JSConstant(RegExp)
+ b: RegExpExec(@a)
+
+ And we assumed we're invoking RegExpExec with lastIndex is 0, because we found
+ our RegExp in a backwards search. This is likely because we're also matching
+ NewRegExp nodes, in which case, it is valid to say lastIndex is 0.
+
+ This caused us to return a constant value that would've been the exec
+ result had we invoked it with a NewRegExpNode.
+
+ * dfg/DFGStrengthReductionPhase.cpp:
+ (JSC::DFG::StrengthReductionPhase::run):
+ (JSC::DFG::StrengthReductionPhase::handleNode):
+
2021-09-29 Yusuke Suzuki <[email protected]>
[JSC] Use FixedVector in JITConstantPool
Modified: trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp (283231 => 283232)
--- trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp 2021-09-29 16:56:07 UTC (rev 283231)
+++ trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp 2021-09-29 17:03:29 UTC (rev 283232)
@@ -491,11 +491,13 @@
Node* regExpObjectNode = nullptr;
RegExp* regExp = nullptr;
+ bool regExpObjectNodeIsConstant = false;
if (m_node->op() == RegExpExec || m_node->op() == RegExpTest || m_node->op() == RegExpMatchFast) {
regExpObjectNode = m_node->child2().node();
- if (RegExpObject* regExpObject = regExpObjectNode->dynamicCastConstant<RegExpObject*>(vm()))
+ if (RegExpObject* regExpObject = regExpObjectNode->dynamicCastConstant<RegExpObject*>(vm())) {
regExp = regExpObject->regExp();
- else if (regExpObjectNode->op() == NewRegexp)
+ regExpObjectNodeIsConstant = true;
+ } else if (regExpObjectNode->op() == NewRegexp)
regExp = regExpObjectNode->castOperand<RegExp*>();
else {
if (verbose)
@@ -545,6 +547,8 @@
for (unsigned otherNodeIndex = m_nodeIndex; otherNodeIndex--;) {
Node* otherNode = m_block->at(otherNodeIndex);
if (otherNode == regExpObjectNode) {
+ if (regExpObjectNodeIsConstant)
+ break;
lastIndex = 0;
break;
}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes