#551: M1536768 M1546327

This commit is contained in:
Cameron Kaiser 2019-05-09 14:17:00 -07:00
parent f6dd8303f6
commit 4af72ac8c0
3 changed files with 36 additions and 26 deletions

View File

@ -195,15 +195,21 @@ BytecodeEmitter::updateLocalsToFrameSlots()
bool
BytecodeEmitter::emitCheck(ptrdiff_t delta, ptrdiff_t* offset)
{
*offset = code().length();
// Start it off moderately large to avoid repeated resizings early on.
// ~98% of cases fit within 1024 bytes.
if (code().capacity() == 0 && !code().reserve(1024))
return false;
size_t oldLength = code().length();
*offset = ptrdiff_t(oldLength);
size_t newLength = oldLength + size_t(delta);
if (MOZ_UNLIKELY(newLength > MaxBytecodeLength)) {
ReportAllocationOverflow(cx);
return false;
}
if (!code().growBy(delta)) {
ReportOutOfMemory(cx);
return false;
}
return true;
@ -8791,12 +8797,18 @@ AllocSrcNote(ExclusiveContext* cx, SrcNotesVector& notes, unsigned* index)
if (notes.capacity() == 0 && !notes.reserve(256))
return false;
if (!notes.growBy(1)) {
ReportOutOfMemory(cx);
size_t oldLength = notes.length();
if (MOZ_UNLIKELY(oldLength + 1 > MaxSrcNotesLength)) {
ReportAllocationOverflow(cx);
return false;
}
*index = notes.length() - 1;
if (!notes.growBy(1)) {
return false;
}
*index = oldLength;
return true;
}
@ -8922,12 +8934,15 @@ BytecodeEmitter::setSrcNoteOffset(unsigned index, unsigned which, ptrdiff_t offs
/* Maybe this offset was already set to a four-byte value. */
if (!(*sn & SN_4BYTE_OFFSET_FLAG)) {
/* Insert three dummy bytes that will be overwritten shortly. */
if (MOZ_UNLIKELY(notes.length() + 3 > MaxSrcNotesLength)) {
ReportAllocationOverflow(cx);
return false;
}
jssrcnote dummy = 0;
if (!(sn = notes.insert(sn, dummy)) ||
!(sn = notes.insert(sn, dummy)) ||
!(sn = notes.insert(sn, dummy)))
{
ReportOutOfMemory(cx);
return false;
}
}

View File

@ -659,6 +659,9 @@ struct BytecodeEmitter
bool emitSuperElemOp(ParseNode* pn, JSOp op, bool isCall = false);
};
static constexpr size_t MaxBytecodeLength = INT32_MAX;
static constexpr size_t MaxSrcNotesLength = INT32_MAX;
} /* namespace frontend */
} /* namespace js */

View File

@ -844,21 +844,8 @@ CodeGenerator::visitFunctionDispatch(LFunctionDispatch* lir)
{
MFunctionDispatch* mir = lir->mir();
Register input = ToRegister(lir->input());
Label* lastLabel;
size_t casesWithFallback;
// Determine if the last case is fallback or an ordinary case.
if (!mir->hasFallback()) {
MOZ_ASSERT(mir->numCases() > 0);
casesWithFallback = mir->numCases();
lastLabel = skipTrivialBlocks(mir->getCaseBlock(mir->numCases() - 1))->lir()->label();
} else {
casesWithFallback = mir->numCases() + 1;
lastLabel = skipTrivialBlocks(mir->getFallback())->lir()->label();
}
// Compare function pointers, except for the last case.
for (size_t i = 0; i < casesWithFallback - 1; i++) {
// Compare function pointers
for (size_t i = 0; i < mir->numCases(); i++) {
MOZ_ASSERT(i < mir->numCases());
LBlock* target = skipTrivialBlocks(mir->getCaseBlock(i))->lir();
if (ObjectGroup* funcGroup = mir->getCaseObjectGroup(i)) {
@ -870,8 +857,14 @@ CodeGenerator::visitFunctionDispatch(LFunctionDispatch* lir)
}
}
// Jump to the last case.
masm.jump(lastLabel);
// If at the end, and we have a fallback, we can jump to the fallback block.
if (mir->hasFallback()) {
masm.jump(skipTrivialBlocks(mir->getFallback())->lir()->label());
return;
}
// Otherwise, crash.
masm.assumeUnreachable("Did not match input function!");
}
void
@ -914,13 +907,12 @@ CodeGenerator::visitObjectGroupDispatch(LObjectGroupDispatch* lir)
if (!mir->hasFallback()) {
MOZ_ASSERT(lastBranch.isInitialized());
#ifdef DEBUG
Label ok;
lastBranch.relink(&ok);
lastBranch.emit(masm);
masm.assumeUnreachable("Unexpected ObjectGroup");
masm.bind(&ok);
#endif
if (!isNextBlock(lastBlock))
masm.jump(lastBlock->label());
return;