Diff
Modified: branches/safari-605-branch/Source/_javascript_Core/ChangeLog (227472 => 227473)
--- branches/safari-605-branch/Source/_javascript_Core/ChangeLog 2018-01-24 05:22:25 UTC (rev 227472)
+++ branches/safari-605-branch/Source/_javascript_Core/ChangeLog 2018-01-24 05:22:30 UTC (rev 227473)
@@ -1,5 +1,33 @@
2018-01-23 Jason Marcell <jmarc...@apple.com>
+ Cherry-pick r227462. rdar://problem/36807140
+
+ 2018-01-23 Filip Pizlo <fpi...@apple.com>
+
+ Use precise index masking for FTL GetByArgumentByVal
+ https://bugs.webkit.org/show_bug.cgi?id=182006
+
+ Reviewed by Keith Miller.
+
+ This protects speculative out-of-bounds on arguments[index].
+
+ Making this work right involved fixing a possible overflow situation with
+ numberOfArgumentsToSkip.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::findArgumentPositionForLocal):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasNumberOfArgumentsToSkip):
+ (JSC::DFG::Node::numberOfArgumentsToSkip):
+ * dfg/DFGStackLayoutPhase.cpp:
+ (JSC::DFG::StackLayoutPhase::run):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileGetMyArgumentByVal):
+
+2018-01-23 Jason Marcell <jmarc...@apple.com>
+
Cherry-pick r227434. rdar://problem/36791632
2018-01-23 Mark Lam <mark....@apple.com>
Modified: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (227472 => 227473)
--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2018-01-24 05:22:25 UTC (rev 227472)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2018-01-24 05:22:30 UTC (rev 227473)
@@ -502,8 +502,6 @@
break;
if (operand.offset() < static_cast<int>(inlineCallFrame->stackOffset + CallFrame::headerSizeInRegisters))
continue;
- if (operand.offset() == inlineCallFrame->stackOffset + CallFrame::thisArgumentOffset())
- continue;
if (operand.offset() >= static_cast<int>(inlineCallFrame->stackOffset + CallFrame::thisArgumentOffset() + inlineCallFrame->argumentsWithFixup.size()))
continue;
int argument = VirtualRegister(operand.offset() - inlineCallFrame->stackOffset).toArgument();
Modified: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGGraph.cpp (227472 => 227473)
--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGGraph.cpp 2018-01-24 05:22:25 UTC (rev 227472)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGGraph.cpp 2018-01-24 05:22:30 UTC (rev 227473)
@@ -217,6 +217,8 @@
out.print(comma, NodeFlagsDump(node->flags()));
if (node->prediction())
out.print(comma, SpeculationDump(node->prediction()));
+ if (node->hasNumberOfArgumentsToSkip())
+ out.print(comma, "numberOfArgumentsToSkip = ", node->numberOfArgumentsToSkip());
if (node->hasArrayMode())
out.print(comma, node->arrayMode());
if (node->hasArithUnaryType())
Modified: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGNode.h (227472 => 227473)
--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGNode.h 2018-01-24 05:22:25 UTC (rev 227472)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGNode.h 2018-01-24 05:22:30 UTC (rev 227473)
@@ -2619,10 +2619,15 @@
{
m_misc.epoch = epoch.toUnsigned();
}
+
+ bool hasNumberOfArgumentsToSkip()
+ {
+ return op() == CreateRest || op() == PhantomCreateRest || op() == GetRestLength || op() == GetMyArgumentByVal || op() == GetMyArgumentByValOutOfBounds;
+ }
unsigned numberOfArgumentsToSkip()
{
- ASSERT(op() == CreateRest || op() == PhantomCreateRest || op() == GetRestLength || op() == GetMyArgumentByVal || op() == GetMyArgumentByValOutOfBounds);
+ ASSERT(hasNumberOfArgumentsToSkip());
return m_opInfo.as<unsigned>();
}
Modified: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGStackLayoutPhase.cpp (227472 => 227473)
--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGStackLayoutPhase.cpp 2018-01-24 05:22:25 UTC (rev 227472)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGStackLayoutPhase.cpp 2018-01-24 05:22:30 UTC (rev 227473)
@@ -112,7 +112,7 @@
CallFrameSlot::argumentCount + inlineCallFrame->stackOffset).toLocal());
}
- for (unsigned argument = inlineCallFrame->argumentsWithFixup.size(); argument-- > 1;) {
+ for (unsigned argument = inlineCallFrame->argumentsWithFixup.size(); argument--;) {
usedLocals.set(VirtualRegister(
virtualRegisterForArgument(argument).offset() +
inlineCallFrame->stackOffset).toLocal());
@@ -178,7 +178,7 @@
allocation, VirtualRegister(inlineCallFrame->stackOffset + CallFrameSlot::argumentCount));
}
- for (unsigned argument = inlineCallFrame->argumentsWithFixup.size(); argument-- > 1;) {
+ for (unsigned argument = inlineCallFrame->argumentsWithFixup.size(); argument--;) {
ArgumentPosition& position = m_graph.m_argumentPositions[
data.argumentPositionStart + argument];
VariableAccessData* variable = position.someVariable();
Modified: branches/safari-605-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (227472 => 227473)
--- branches/safari-605-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2018-01-24 05:22:25 UTC (rev 227472)
+++ branches/safari-605-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2018-01-24 05:22:30 UTC (rev 227473)
@@ -3965,17 +3965,20 @@
InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
LValue index = lowInt32(m_node->child2());
- if (m_node->numberOfArgumentsToSkip())
- index = m_out.add(index, m_out.constInt32(m_node->numberOfArgumentsToSkip()));
- LValue limit;
+ LValue originalLimit;
if (inlineCallFrame && !inlineCallFrame->isVarargs())
- limit = m_out.constInt32(inlineCallFrame->argumentCountIncludingThis - 1);
+ originalLimit = m_out.constInt32(inlineCallFrame->argumentCountIncludingThis);
else {
VirtualRegister argumentCountRegister = AssemblyHelpers::argumentCount(inlineCallFrame);
- limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
+ originalLimit = m_out.load32(payloadFor(argumentCountRegister));
}
+ LValue limit = m_out.sub(originalLimit, m_out.int32One);
+
+ if (m_node->numberOfArgumentsToSkip())
+ limit = m_out.sub(limit, m_out.constInt32(m_node->numberOfArgumentsToSkip()));
+
LValue isOutOfBounds = m_out.aboveOrEqual(index, limit);
LBasicBlock continuation = nullptr;
LBasicBlock lastNext = nullptr;
@@ -3991,17 +3994,30 @@
} else
speculate(OutOfBounds, noValue(), 0, isOutOfBounds);
+ if (m_node->numberOfArgumentsToSkip())
+ index = m_out.add(index, m_out.constInt32(m_node->numberOfArgumentsToSkip()));
+ index = m_out.add(index, m_out.int32One);
+
+ index = m_out.zeroExt(index, Int64);
+
+ index = m_out.bitAnd(
+ index,
+ m_out.aShr(
+ m_out.sub(
+ index,
+ m_out.opaque(m_out.zeroExt(originalLimit, Int64))),
+ m_out.constInt32(63)));
+
TypedPointer base;
if (inlineCallFrame) {
if (inlineCallFrame->argumentCountIncludingThis > 1)
- base = addressFor(inlineCallFrame->argumentsWithFixup[1].virtualRegister());
+ base = addressFor(inlineCallFrame->argumentsWithFixup[0].virtualRegister());
} else
- base = addressFor(virtualRegisterForArgument(1));
+ base = addressFor(virtualRegisterForArgument(0));
LValue result;
if (base) {
- LValue pointer = m_out.baseIndex(
- base.value(), m_out.zeroExt(index, pointerType()), ScaleEight);
+ LValue pointer = m_out.baseIndex(base.value(), index, ScaleEight);
result = m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer));
} else
result = m_out.constInt64(JSValue::encode(jsUndefined()));