Bug 1143704 part 14 - Change newSrcNote* to return bool instead of int. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 24 Mar 2015 09:45:24 +0100
changeset 265807 b6044f33b3e438638270ee9f981227d5b2710be2
parent 265806 5e2113e373009f9a0aa9ac48d26e061fbf1521ee
child 265808 48d6322d42b7128627eb6683597a567135b197b6
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1143704
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1143704 part 14 - Change newSrcNote* to return bool instead of int. r=luke
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -447,21 +447,21 @@ BytecodeEmitter::updateLineNumberNotes(u
          * loops where the update part is emitted after the body, but its
          * line number is <= any line number in the body) here by letting
          * unsigned delta_ wrap to a very large number, which triggers a
          * SRC_SETLINE.
          */
         current->currentLine = line;
         current->lastColumn  = 0;
         if (delta >= LengthOfSetLine(line)) {
-            if (newSrcNote2(SRC_SETLINE, ptrdiff_t(line)) < 0)
+            if (!newSrcNote2(SRC_SETLINE, ptrdiff_t(line)))
                 return false;
         } else {
             do {
-                if (newSrcNote(SRC_NEWLINE) < 0)
+                if (!newSrcNote(SRC_NEWLINE))
                     return false;
             } while (--delta != 0);
         }
     }
     return true;
 }
 
 /* Updates the line number and column number information in the source notes. */
@@ -476,17 +476,17 @@ BytecodeEmitter::updateSourceCoordNotes(
     if (colspan != 0) {
         // If the column span is so large that we can't store it, then just
         // discard this information. This can happen with minimized or otherwise
         // machine-generated code. Even gigantic column numbers are still
         // valuable if you have a source map to relate them to something real;
         // but it's better to fail soft here.
         if (!SN_REPRESENTABLE_COLSPAN(colspan))
             return true;
-        if (newSrcNote2(SRC_COLSPAN, SN_COLSPAN_TO_OFFSET(colspan)) < 0)
+        if (!newSrcNote2(SRC_COLSPAN, SN_COLSPAN_TO_OFFSET(colspan)))
             return false;
         current->lastColumn = columnIndex;
     }
     return true;
 }
 
 bool
 BytecodeEmitter::emitLoopHead(ParseNode *nextpn)
@@ -683,17 +683,17 @@ bool
 BytecodeEmitter::emitGoto(StmtInfoBCE *toStmt, ptrdiff_t *lastp, SrcNoteType noteType)
 {
     NonLocalExitScope nle(this);
 
     if (!nle.prepareForNonLocalJump(toStmt))
         return false;
 
     if (noteType != SRC_NULL) {
-        if (newSrcNote(noteType) < 0)
+        if (!newSrcNote(noteType))
             return false;
     }
 
     return emitBackPatchOp(lastp);
 }
 
 void
 BytecodeEmitter::backPatch(ptrdiff_t last, jsbytecode *target, jsbytecode op)
@@ -2616,17 +2616,16 @@ BytecodeEmitter::enterBlockScope(StmtInf
 MOZ_NEVER_INLINE bool
 BytecodeEmitter::emitSwitch(ParseNode *pn)
 {
     JSOp switchOp;
     bool hasDefault;
     ptrdiff_t top, off, defaultOffset;
     ParseNode *pn2, *pn3, *pn4;
     int32_t low, high;
-    int noteIndex;
     size_t switchSize;
     jsbytecode *pc;
 
     /* Try for most optimal, fall back if not dense ints. */
     switchOp = JSOP_TABLESWITCH;
     hasDefault = false;
     defaultOffset = -1;
 
@@ -2758,82 +2757,82 @@ BytecodeEmitter::emitSwitch(ParseNode *p
                 switchOp = JSOP_CONDSWITCH;
         }
     }
 
     /*
      * The note has one or two offsets: first tells total switch code length;
      * second (if condswitch) tells offset to first JSOP_CASE.
      */
+    unsigned noteIndex;
     if (switchOp == JSOP_CONDSWITCH) {
         /* 0 bytes of immediate for unoptimized switch. */
         switchSize = 0;
-        noteIndex = newSrcNote3(SRC_CONDSWITCH, 0, 0);
+        if (!newSrcNote3(SRC_CONDSWITCH, 0, 0, &noteIndex))
+            return false;
     } else {
         MOZ_ASSERT(switchOp == JSOP_TABLESWITCH);
 
         /* 3 offsets (len, low, high) before the table, 1 per entry. */
         switchSize = (size_t)(JUMP_OFFSET_LEN * (3 + tableLength));
-        noteIndex = newSrcNote2(SRC_TABLESWITCH, 0);
-    }
-    if (noteIndex < 0)
-        return false;
+        if (!newSrcNote2(SRC_TABLESWITCH, 0, &noteIndex))
+            return false;
+    }
 
     /* Emit switchOp followed by switchSize bytes of jump or lookup table. */
     if (!emitN(switchOp, switchSize))
         return false;
 
     off = -1;
     if (switchOp == JSOP_CONDSWITCH) {
-        int caseNoteIndex = -1;
+        unsigned caseNoteIndex;
         bool beforeCases = true;
 
         /* Emit code for evaluating cases and jumping to case statements. */
         for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
             pn4 = pn3->pn_left;
             if (pn4 && !emitTree(pn4))
                 return false;
-            if (caseNoteIndex >= 0) {
+            if (!beforeCases) {
                 /* off is the previous JSOP_CASE's bytecode offset. */
-                if (!setSrcNoteOffset(unsigned(caseNoteIndex), 0, offset() - off))
+                if (!setSrcNoteOffset(caseNoteIndex, 0, offset() - off))
                     return false;
             }
             if (!pn4) {
                 MOZ_ASSERT(pn3->isKind(PNK_DEFAULT));
                 continue;
             }
-            caseNoteIndex = newSrcNote2(SRC_NEXTCASE, 0);
-            if (caseNoteIndex < 0)
+            if (!newSrcNote2(SRC_NEXTCASE, 0, &caseNoteIndex))
                 return false;
             if (!emitJump(JSOP_CASE, 0, &off))
                 return false;
             pn3->pn_offset = off;
             if (beforeCases) {
                 unsigned noteCount, noteCountDelta;
 
                 /* Switch note's second offset is to first JSOP_CASE. */
                 noteCount = notes().length();
-                if (!setSrcNoteOffset(unsigned(noteIndex), 1, off - top))
+                if (!setSrcNoteOffset(noteIndex, 1, off - top))
                     return false;
                 noteCountDelta = notes().length() - noteCount;
                 if (noteCountDelta != 0)
                     caseNoteIndex += noteCountDelta;
                 beforeCases = false;
             }
         }
 
         /*
          * If we didn't have an explicit default (which could fall in between
          * cases, preventing us from fusing this setSrcNoteOffset with the call
          * in the loop above), link the last case to the implicit default for
          * the benefit of IonBuilder.
          */
         if (!hasDefault &&
-            caseNoteIndex >= 0 &&
-            !setSrcNoteOffset(unsigned(caseNoteIndex), 0, offset() - off))
+            caseNoteIndex != UINT_MAX &&
+            !setSrcNoteOffset(caseNoteIndex, 0, offset() - off))
         {
             return false;
         }
 
         /* Emit default even if no explicit default statement. */
         if (!emitJump(JSOP_DEFAULT, 0, &defaultOffset))
             return false;
     } else {
@@ -3374,17 +3373,17 @@ BytecodeEmitter::emitDefault(ParseNode *
 {
     if (!emit1(JSOP_DUP))                                 // VALUE VALUE
         return false;
     if (!emit1(JSOP_UNDEFINED))                           // VALUE VALUE UNDEFINED
         return false;
     if (!emit1(JSOP_STRICTEQ))                            // VALUE EQL?
         return false;
     // Emit source note to enable ion compilation.
-    if (newSrcNote(SRC_IF) < 0)
+    if (!newSrcNote(SRC_IF))
         return false;
     ptrdiff_t jump;
     if (!emitJump(JSOP_IFEQ, 0, &jump))                   // VALUE
         return false;
     if (!emit1(JSOP_POP))                                 // .
         return false;
     if (!emitTree(defaultExpr))                           // DEFAULTVALUE
         return false;
@@ -3448,18 +3447,18 @@ BytecodeEmitter::emitDestructuringOpsArr
             if (!emit1(JSOP_DUP))                                 // ... OBJ? ITER RESULT RESULT
                 return false;
             if (!emitAtomOp(cx->names().done, JSOP_GETPROP))      // ... OBJ? ITER RESULT DONE?
                 return false;
 
             // Emit (result.done ? undefined : result.value)
             // This is mostly copied from emitConditionalExpression, except that this code
             // does not push new values onto the stack.
-            ptrdiff_t noteIndex = newSrcNote(SRC_COND);
-            if (noteIndex < 0)
+            unsigned noteIndex;
+            if (!newSrcNote(SRC_COND, &noteIndex))
                 return false;
             ptrdiff_t beq;
             if (!emitJump(JSOP_IFEQ, 0, &beq))
                 return false;
 
             if (!emit1(JSOP_POP))                                 // ... OBJ? ITER
                 return false;
             if (!emit1(JSOP_UNDEFINED))                           // ... OBJ? ITER UNDEFINED
@@ -4038,17 +4037,17 @@ BytecodeEmitter::emitAssignment(ParseNod
     /* If += etc., emit the binary operator with a source note. */
     if (op != JSOP_NOP) {
         /*
          * Take care to avoid SRC_ASSIGNOP if the left-hand side is a const
          * declared in the current compilation unit, as in this case (just
          * a bit further below) we will avoid emitting the assignment op.
          */
         if (!lhs->isKind(PNK_NAME) || !lhs->isConst()) {
-            if (newSrcNote(SRC_ASSIGNOP) < 0)
+            if (!newSrcNote(SRC_ASSIGNOP))
                 return false;
         }
         if (!emit1(op))
             return false;
     }
 
     /* Finally, emit the specialized assignment bytecode. */
     switch (lhs->getKind()) {
@@ -4386,19 +4385,22 @@ BytecodeEmitter::emitTry(ParseNode *pn)
     //
     // For that we store in a try note associated with the catch or
     // finally block the stack depth upon the try entry. The interpreter
     // uses this depth to properly unwind the stack and the scope chain.
     //
     int depth = stackDepth;
 
     // Record the try location, then emit the try block.
-    ptrdiff_t noteIndex = newSrcNote(SRC_TRY);
-    if (noteIndex < 0 || !emit1(JSOP_TRY))
-        return false;
+    unsigned noteIndex;
+    if (!newSrcNote(SRC_TRY, &noteIndex))
+        return false;
+    if (!emit1(JSOP_TRY))
+        return false;
+
     ptrdiff_t tryStart = offset();
     if (!emitTree(pn->pn_kid1))
         return false;
     MOZ_ASSERT(depth == stackDepth);
 
     // GOSUB to finally, if present.
     if (pn->pn_kid3) {
         if (!emitBackPatchOp(&stmtInfo.gosubs()))
@@ -4535,17 +4537,17 @@ bool
 BytecodeEmitter::emitIf(ParseNode *pn)
 {
     StmtInfoBCE stmtInfo(cx);
 
     /* Initialize so we can detect else-if chains and avoid recursion. */
     stmtInfo.type = STMT_IF;
     ptrdiff_t beq = -1;
     ptrdiff_t jmp = -1;
-    ptrdiff_t noteIndex = -1;
+    unsigned noteIndex = -1;
 
   if_again:
     /* Emit code for the condition before pushing stmtInfo. */
     if (!emitTree(pn->pn_kid1))
         return false;
     ptrdiff_t top = offset();
     if (stmtInfo.type == STMT_IF) {
         pushStatement(&stmtInfo, STMT_IF, top);
@@ -4559,18 +4561,17 @@ BytecodeEmitter::emitIf(ParseNode *pn)
         stmtInfo.type = STMT_IF;
         stmtInfo.update = top;
         if (!setSrcNoteOffset(noteIndex, 0, jmp - beq))
             return false;
     }
 
     /* Emit an annotated branch-if-false around the then part. */
     ParseNode *pn3 = pn->pn_kid3;
-    noteIndex = newSrcNote(pn3 ? SRC_IF_ELSE : SRC_IF);
-    if (noteIndex < 0)
+    if (!newSrcNote(pn3 ? SRC_IF_ELSE : SRC_IF, &noteIndex))
         return false;
     if (!emitJump(JSOP_IFEQ, 0, &beq))
         return false;
 
     /* Emit code for the then and optional else parts. */
     if (!emitTree(pn->pn_kid2))
         return false;
     if (pn3) {
@@ -4805,18 +4806,18 @@ BytecodeEmitter::emitForOf(StmtType type
     }
 
     LoopStmtInfo stmtInfo(cx);
     pushLoopStatement(&stmtInfo, type, top);
 
     // Jump down to the loop condition to minimize overhead assuming at least
     // one iteration, as the other loop forms do.  Annotate so IonMonkey can
     // find the loop-closing jump.
-    int noteIndex = newSrcNote(SRC_FOR_OF);
-    if (noteIndex < 0)
+    unsigned noteIndex;
+    if (!newSrcNote(SRC_FOR_OF, &noteIndex))
         return false;
     ptrdiff_t jmp;
     if (!emitJump(JSOP_GOTO, 0, &jmp))
         return false;
 
     top = offset();
     SET_STATEMENT_TOP(&stmtInfo, top);
     if (!emitLoopHead(nullptr))
@@ -4886,17 +4887,17 @@ BytecodeEmitter::emitForOf(StmtType type
 
     ptrdiff_t beq;
     if (!emitJump(JSOP_IFEQ, top - offset(), &beq))       // ... RESULT
         return false;
 
     MOZ_ASSERT(this->stackDepth == loopDepth);
 
     // Let Ion know where the closing jump of this loop is.
-    if (!setSrcNoteOffset(unsigned(noteIndex), 0, beq - jmp))
+    if (!setSrcNoteOffset(noteIndex, 0, beq - jmp))
         return false;
 
     // Fixup breaks and continues.
     // For STMT_SPREAD, just pop pc->topStmt.
     popStatement();
 
     if (!tryNoteList.append(JSTRY_FOR_OF, stackDepth, top, offset()))
         return false;
@@ -4952,18 +4953,18 @@ BytecodeEmitter::emitForIn(ParseNode *pn
         if (!enterBlockScope(&letStmt, pn1->pn_objbox, JSOP_UNDEFINED, 0))
             return false;
     }
 
     LoopStmtInfo stmtInfo(cx);
     pushLoopStatement(&stmtInfo, STMT_FOR_IN_LOOP, top);
 
     /* Annotate so IonMonkey can find the loop-closing jump. */
-    int noteIndex = newSrcNote(SRC_FOR_IN);
-    if (noteIndex < 0)
+    unsigned noteIndex;
+    if (!newSrcNote(SRC_FOR_IN, &noteIndex))
         return false;
 
     /*
      * Jump down to the loop condition to minimize overhead assuming at
      * least one iteration, as the other loop forms do.
      */
     ptrdiff_t jmp;
     if (!emitJump(JSOP_GOTO, 0, &jmp))
@@ -5008,17 +5009,17 @@ BytecodeEmitter::emitForIn(ParseNode *pn
         return false;
     if (!emit1(JSOP_ISNOITER))
         return false;
     ptrdiff_t beq;
     if (!emitJump(JSOP_IFEQ, top - offset(), &beq))
         return false;
 
     /* Set the srcnote offset so we can find the closing jump. */
-    if (!setSrcNoteOffset(unsigned(noteIndex), 0, beq - jmp))
+    if (!setSrcNoteOffset(noteIndex, 0, beq - jmp))
         return false;
 
     // Fix up breaks and continues.
     popStatement();
 
     // Pop the enumeration value.
     if (!emit1(JSOP_POP))
         return false;
@@ -5062,18 +5063,20 @@ BytecodeEmitter::emitNormalFor(ParseNode
     }
 
     /*
      * NB: the SRC_FOR note has offsetBias 1 (JSOP_{NOP,POP}_LENGTH).
      * Use tmp to hold the biased srcnote "top" offset, which differs
      * from the top local variable by the length of the JSOP_GOTO
      * emitted in between tmp and top if this loop has a condition.
      */
-    int noteIndex = newSrcNote(SRC_FOR);
-    if (noteIndex < 0 || !emit1(op))
+    unsigned noteIndex;
+    if (!newSrcNote(SRC_FOR, &noteIndex))
+        return false;
+    if (!emit1(op))
         return false;
     ptrdiff_t tmp = offset();
 
     ptrdiff_t jmp = -1;
     if (forHead->pn_kid2) {
         /* Goto the loop condition, which branches back to iterate. */
         if (!emitJump(JSOP_GOTO, 0, &jmp))
             return false;
@@ -5089,17 +5092,16 @@ BytecodeEmitter::emitNormalFor(ParseNode
     if (!emitLoopHead(forBody))
         return false;
     if (jmp == -1 && !emitLoopEntry(forBody))
         return false;
     if (!emitTree(forBody))
         return false;
 
     /* Set the second note offset so we can find the update part. */
-    MOZ_ASSERT(noteIndex != -1);
     ptrdiff_t tmp2 = offset();
 
     /* Set loop and enclosing "update" offsets, for continue. */
     StmtInfoBCE *stmt = &stmtInfo;
     do {
         stmt->update = offset();
     } while ((stmt = stmt->down) != nullptr && stmt->type == STMT_LABEL);
 
@@ -5114,17 +5116,17 @@ BytecodeEmitter::emitNormalFor(ParseNode
 
         /* Always emit the POP or NOP to help IonBuilder. */
         if (!emit1(op))
             return false;
 
         /* Restore the absolute line number for source note readers. */
         uint32_t lineNum = parser->tokenStream.srcCoords.lineNum(pn->pn_pos.end);
         if (currentLine() != lineNum) {
-            if (newSrcNote2(SRC_SETLINE, ptrdiff_t(lineNum)) < 0)
+            if (!newSrcNote2(SRC_SETLINE, ptrdiff_t(lineNum)))
                 return false;
             current->currentLine = lineNum;
             current->lastColumn = 0;
         }
     }
 
     ptrdiff_t tmp3 = offset();
 
@@ -5135,22 +5137,22 @@ BytecodeEmitter::emitNormalFor(ParseNode
         if (!emitLoopEntry(forHead->pn_kid2))
             return false;
 
         if (!emitTree(forHead->pn_kid2))
             return false;
     }
 
     /* Set the first note offset so we can find the loop condition. */
-    if (!setSrcNoteOffset(unsigned(noteIndex), 0, tmp3 - tmp))
-        return false;
-    if (!setSrcNoteOffset(unsigned(noteIndex), 1, tmp2 - tmp))
+    if (!setSrcNoteOffset(noteIndex, 0, tmp3 - tmp))
+        return false;
+    if (!setSrcNoteOffset(noteIndex, 1, tmp2 - tmp))
         return false;
     /* The third note offset helps us find the loop-closing jump. */
-    if (!setSrcNoteOffset(unsigned(noteIndex), 2, offset() - tmp))
+    if (!setSrcNoteOffset(noteIndex, 2, offset() - tmp))
         return false;
 
     /* If no loop condition, just emit a loop-closing jump. */
     op = forHead->pn_kid2 ? JSOP_IFNE : JSOP_GOTO;
     if (!emitJump(op, top - offset()))
         return false;
 
     if (!tryNoteList.append(JSTRY_LOOP, stackDepth, top, offset()))
@@ -5324,22 +5326,24 @@ BytecodeEmitter::emitFunction(ParseNode 
 
     return true;
 }
 
 bool
 BytecodeEmitter::emitDo(ParseNode *pn)
 {
     /* Emit an annotated nop so IonBuilder can recognize the 'do' loop. */
-    ptrdiff_t noteIndex = newSrcNote(SRC_WHILE);
-    if (noteIndex < 0 || !emit1(JSOP_NOP))
-        return false;
-
-    ptrdiff_t noteIndex2 = newSrcNote(SRC_WHILE);
-    if (noteIndex2 < 0)
+    unsigned noteIndex;
+    if (!newSrcNote(SRC_WHILE, &noteIndex))
+        return false;
+    if (!emit1(JSOP_NOP))
+        return false;
+
+    unsigned noteIndex2;
+    if (!newSrcNote(SRC_WHILE, &noteIndex2))
         return false;
 
     /* Compile the loop body. */
     ptrdiff_t top = offset();
     if (!emitLoopHead(pn->pn_left))
         return false;
 
     LoopStmtInfo stmtInfo(cx);
@@ -5399,18 +5403,18 @@ BytecodeEmitter::emitWhile(ParseNode *pn
      *  1    ifeq-fail; goto; ifne-pass      goto; ifne-pass; ifne-fail
      *  2    2*(ifeq-fail; goto); ifeq-pass  goto; 2*ifne-pass; ifne-fail
      *  . . .
      *  N    N*(ifeq-fail; goto); ifeq-pass  goto; N*ifne-pass; ifne-fail
      */
     LoopStmtInfo stmtInfo(cx);
     pushLoopStatement(&stmtInfo, STMT_WHILE_LOOP, top);
 
-    ptrdiff_t noteIndex = newSrcNote(SRC_WHILE);
-    if (noteIndex < 0)
+    unsigned noteIndex;
+    if (!newSrcNote(SRC_WHILE, &noteIndex))
         return false;
 
     ptrdiff_t jmp;
     if (!emitJump(JSOP_GOTO, 0, &jmp))
         return false;
 
     top = offset();
     if (!emitLoopHead(pn->pn_right))
@@ -5637,19 +5641,21 @@ BytecodeEmitter::emitYieldStar(ParseNode
 
     ptrdiff_t initialSend = -1;
     if (!emitBackPatchOp(&initialSend))                          // goto initialSend
         return false;
 
     // Try prologue.                                             // ITER RESULT
     StmtInfoBCE stmtInfo(cx);
     pushStatement(&stmtInfo, STMT_TRY, offset());
-    ptrdiff_t noteIndex = newSrcNote(SRC_TRY);
+    unsigned noteIndex;
+    if (!newSrcNote(SRC_TRY, &noteIndex))
+        return false;
     ptrdiff_t tryStart = offset();                               // tryStart:
-    if (noteIndex < 0 || !emit1(JSOP_TRY))
+    if (!emit1(JSOP_TRY))
         return false;
     MOZ_ASSERT(this->stackDepth == depth);
 
     // Load the generator object.
     if (!emitTree(gen))                                          // ITER RESULT GENOBJ
         return false;
 
     // Yield RESULT as-is, without re-boxing.
@@ -6345,18 +6351,18 @@ BytecodeEmitter::emitSyntheticStatements
 
 bool
 BytecodeEmitter::emitConditionalExpression(ConditionalExpression &conditional)
 {
     /* Emit the condition, then branch if false to the else part. */
     if (!emitTree(&conditional.condition()))
         return false;
 
-    ptrdiff_t noteIndex = newSrcNote(SRC_COND);
-    if (noteIndex < 0)
+    unsigned noteIndex;
+    if (!newSrcNote(SRC_COND, &noteIndex))
         return false;
 
     ptrdiff_t beq;
     if (!emitJump(JSOP_IFEQ, 0, &beq))
         return false;
 
     if (!emitTree(&conditional.thenExpression()))
         return false;
@@ -6686,17 +6692,17 @@ BytecodeEmitter::emitDefaults(ParseNode 
             return false;
         if (!emitVarOp(arg, JSOP_GETARG))
             return false;
         if (!emit1(JSOP_UNDEFINED))
             return false;
         if (!emit1(JSOP_STRICTEQ))
             return false;
         // Emit source note to enable ion compilation.
-        if (newSrcNote(SRC_IF) < 0)
+        if (!newSrcNote(SRC_IF))
             return false;
         ptrdiff_t jump;
         if (!emitJump(JSOP_IFEQ, 0, &jump))
             return false;
         if (!emitTree(arg->expr()))
             return false;
         if (!emitVarOp(arg, JSOP_SETARG))
             return false;
@@ -7300,93 +7306,101 @@ BytecodeEmitter::emitTree(ParseNode *pn)
     if (ok && emitLevel == 1) {
         if (!updateSourceCoordNotes(pn->pn_pos.end))
             return false;
     }
 
     return ok;
 }
 
-static int
-AllocSrcNote(ExclusiveContext *cx, SrcNotesVector &notes)
+static bool
+AllocSrcNote(ExclusiveContext *cx, SrcNotesVector &notes, unsigned *index)
 {
     // Start it off moderately large to avoid repeated resizings early on.
     // ~99% of cases fit within 256 bytes.
     if (notes.capacity() == 0 && !notes.reserve(256))
-        return -1;
-
-    jssrcnote dummy = 0;
-    if (!notes.append(dummy)) {
+        return false;
+
+    if (!notes.growBy(1)) {
         ReportOutOfMemory(cx);
-        return -1;
-    }
-    return notes.length() - 1;
-}
-
-int
-BytecodeEmitter::newSrcNote(SrcNoteType type)
+        return false;
+    }
+
+    *index = notes.length() - 1;
+    return true;
+}
+
+bool
+BytecodeEmitter::newSrcNote(SrcNoteType type, unsigned *indexp)
 {
     SrcNotesVector &notes = this->notes();
-    int index = AllocSrcNote(cx, notes);
-    if (index < 0)
-        return -1;
+    unsigned index;
+    if (!AllocSrcNote(cx, notes, &index))
+        return false;
 
     /*
      * Compute delta from the last annotated bytecode's offset.  If it's too
      * big to fit in sn, allocate one or more xdelta notes and reset sn.
      */
     ptrdiff_t offset = this->offset();
     ptrdiff_t delta = offset - lastNoteOffset();
     current->lastNoteOffset = offset;
     if (delta >= SN_DELTA_LIMIT) {
         do {
             ptrdiff_t xdelta = Min(delta, SN_XDELTA_MASK);
             SN_MAKE_XDELTA(&notes[index], xdelta);
             delta -= xdelta;
-            index = AllocSrcNote(cx, notes);
-            if (index < 0)
-                return -1;
+            if (!AllocSrcNote(cx, notes, &index))
+                return false;
         } while (delta >= SN_DELTA_LIMIT);
     }
 
     /*
      * Initialize type and delta, then allocate the minimum number of notes
      * needed for type's arity.  Usually, we won't need more, but if an offset
      * does take two bytes, setSrcNoteOffset will grow notes.
      */
     SN_MAKE_NOTE(&notes[index], type, delta);
     for (int n = (int)js_SrcNoteSpec[type].arity; n > 0; n--) {
-        if (newSrcNote(SRC_NULL) < 0)
-            return -1;
-    }
-    return index;
-}
-
-int
-BytecodeEmitter::newSrcNote2(SrcNoteType type, ptrdiff_t offset)
-{
-    int index = newSrcNote(type);
-    if (index >= 0) {
-        if (!setSrcNoteOffset(index, 0, offset))
-            return -1;
-    }
-    return index;
-}
-
-int
-BytecodeEmitter::newSrcNote3(SrcNoteType type, ptrdiff_t offset1, ptrdiff_t offset2)
-{
-    int index = newSrcNote(type);
-    if (index >= 0) {
-        if (!setSrcNoteOffset(index, 0, offset1))
-            return -1;
-        if (!setSrcNoteOffset(index, 1, offset2))
-            return -1;
-    }
-    return index;
+        if (!newSrcNote(SRC_NULL))
+            return false;
+    }
+
+    if (indexp)
+        *indexp = index;
+    return true;
+}
+
+bool
+BytecodeEmitter::newSrcNote2(SrcNoteType type, ptrdiff_t offset, unsigned *indexp)
+{
+    unsigned index;
+    if (!newSrcNote(type, &index))
+        return false;
+    if (!setSrcNoteOffset(index, 0, offset))
+        return false;
+    if (indexp)
+        *indexp = index;
+    return true;
+}
+
+bool
+BytecodeEmitter::newSrcNote3(SrcNoteType type, ptrdiff_t offset1, ptrdiff_t offset2,
+                             unsigned *indexp)
+{
+    unsigned index;
+    if (!newSrcNote(type, &index))
+        return false;
+    if (!setSrcNoteOffset(index, 0, offset1))
+        return false;
+    if (!setSrcNoteOffset(index, 1, offset2))
+        return false;
+    if (indexp)
+        *indexp = index;
+    return true;
 }
 
 bool
 BytecodeEmitter::addToSrcNoteDelta(jssrcnote *sn, ptrdiff_t delta)
 {
     /*
      * Called only from finishTakingSrcNotes to add to main script note
      * deltas, and only by a small positive amount.
@@ -7414,17 +7428,17 @@ BytecodeEmitter::setSrcNoteOffset(unsign
     if (!SN_REPRESENTABLE_OFFSET(offset)) {
         ReportStatementTooLarge(parser->tokenStream, topStmt);
         return false;
     }
 
     SrcNotesVector &notes = this->notes();
 
     /* Find the offset numbered which (i.e., skip exactly which offsets). */
-    jssrcnote *sn = notes.begin() + index;
+    jssrcnote *sn = &notes[index];
     MOZ_ASSERT(SN_TYPE(sn) != SRC_XDELTA);
     MOZ_ASSERT((int) which < js_SrcNoteSpec[SN_TYPE(sn)].arity);
     for (sn++; which; sn++, which--) {
         if (*sn & SN_4BYTE_OFFSET_FLAG)
             sn += 3;
     }
 
     /*
@@ -7456,17 +7470,17 @@ BytecodeEmitter::setSrcNoteOffset(unsign
 bool
 BytecodeEmitter::finishTakingSrcNotes(uint32_t *out)
 {
     MOZ_ASSERT(current == &main);
 
     unsigned prologCount = prolog.notes.length();
     if (prologCount && prolog.currentLine != firstLine) {
         switchToProlog();
-        if (newSrcNote2(SRC_SETLINE, ptrdiff_t(firstLine)) < 0)
+        if (!newSrcNote2(SRC_SETLINE, ptrdiff_t(firstLine)))
             return false;
         switchToMain();
     } else {
         /*
          * Either no prolog srcnotes, or no line number change over prolog.
          * We don't need a SRC_SETLINE, but we may need to adjust the offset
          * of the first main note, by adding to its delta and possibly even
          * prepending SRC_XDELTA notes to it to account for prolog bytecodes
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -285,21 +285,21 @@ struct BytecodeEmitter
     bool inTryBlockWithFinally();
 
 #ifdef DEBUG
     bool checkStrictOrSloppy(JSOp op);
 #endif
 
     // Append a new source note of the given type (and therefore size) to the
     // notes dynamic array, updating noteCount. Return the new note's index
-    // within the array pointed at by current->notes. Return -1 if out of
-    // memory.
-    int newSrcNote(SrcNoteType type);
-    int newSrcNote2(SrcNoteType type, ptrdiff_t offset);
-    int newSrcNote3(SrcNoteType type, ptrdiff_t offset1, ptrdiff_t offset2);
+    // within the array pointed at by current->notes as outparam.
+    bool newSrcNote(SrcNoteType type, unsigned *indexp = nullptr);
+    bool newSrcNote2(SrcNoteType type, ptrdiff_t offset, unsigned *indexp = nullptr);
+    bool newSrcNote3(SrcNoteType type, ptrdiff_t offset1, ptrdiff_t offset2,
+                     unsigned *indexp = nullptr);
 
     void copySrcNotes(jssrcnote *destination, uint32_t nsrcnotes);
     bool setSrcNoteOffset(unsigned index, unsigned which, ptrdiff_t offset);
 
     // NB: this function can add at most one extra extended delta note.
     bool addToSrcNoteDelta(jssrcnote *sn, ptrdiff_t delta);
 
     // Finish taking source notes in cx's notePool. If successful, the final