if (!data.m_key.m_source) { - minNode = 0; + // data.m_key.m_source being null means that we're comparing against int32 constants (see rangeKeyAndAddend()). + // Since CheckInBounds does an unsigned comparison, if the minBound >= 0, it is also covered by the + // maxBound comparison. However, if minBound < 0, then CheckInBounds should always fail its speculation check. + // We'll force an OSR exit in that case. + minNode = nullptr; + if (range.m_minBound < 0) + m_insertionSet.insertNode(nodeIndex, SpecNone, ForceOSRExit, node->origin); maxNode = m_insertionSet.insertConstant( nodeIndex, maxOrigin, jsNumber(range.m_maxBound)); } else { (END)
case ArrayBounds: { Node* minNode; Node* maxNode; if (!data.m_key.m_source) { // data.m_key.m_source being null means that we're comparing against int32 constants (see rangeKeyAndAddend()). // Since CheckInBounds does an unsigned comparison, if the minBound >= 0, it is also covered by the // maxBound comparison. However, if minBound < 0, then CheckInBounds should always fail its speculation check. // We'll force an OSR exit in that case. minNode = nullptr; if (range.m_minBound < 0) m_insertionSet.insertNode(nodeIndex, SpecNone, ForceOSRExit, node->origin); maxNode = m_insertionSet.insertConstant( nodeIndex, maxOrigin, jsNumber(range.m_maxBound)); } else { minNode = insertAdd( nodeIndex, minOrigin, data.m_key.m_source, range.m_minBound, Arith::Unchecked); maxNode = insertAdd( nodeIndex, maxOrigin, data.m_key.m_source, range.m_maxBound, Arith::Unchecked); } ....