Loading js/src/frontend/SourceNotes.h +41 −5 Original line number Diff line number Diff line Loading @@ -34,6 +34,44 @@ namespace js { * NB: the js_SrcNoteSpec array in BytecodeEmitter.cpp is indexed by this * enum, so its initializers need to match the order here. */ class SrcNote { public: // SRC_TABLESWITCH: Source note for JSOP_TABLESWITCH. class TableSwitch { public: enum Fields { // The offset of the end of switch (the first non-JumpTarget op // after switch) from JSOP_TABLESWITCH. EndOffset, Count }; }; // SRC_CONDSWITCH: Source note for JSOP_CONDSWITCH. class CondSwitch { public: enum Fields { // The offset of the end of switch (the first non-JumpTarget op // after switch) from JSOP_CONDSWITCH. EndOffset, // The offset of JSOP_CASE for the first case from JSOP_CONDSWITCH. FirstCaseOffset, Count }; }; // SRC_NEXTCASE: Source note for JSOP_CASE in a JSOP_CONDSWITCH. class NextCase { public: enum Fields { // Offset of the next JSOP_CASE from this JSOP_CASE. This field is // 0 if this is the last JSOP_CASE. NextCaseOffset, Count }; }; }; #define FOR_EACH_SRC_NOTE_TYPE(M) \ M(SRC_NULL, "null", 0) /* Terminates a note vector. */ \ M(SRC_IF, "if", 0) /* JSOP_IFEQ bytecode is from an if-then. */ \ Loading @@ -50,11 +88,9 @@ namespace js { M(SRC_BREAK, "break", 0) /* JSOP_GOTO is a break. */ \ M(SRC_BREAK2LABEL, "break2label", 0) /* JSOP_GOTO for 'break label'. */ \ M(SRC_SWITCHBREAK, "switchbreak", 0) /* JSOP_GOTO is a break in a switch. */ \ M(SRC_TABLESWITCH, "tableswitch", 1) /* JSOP_TABLESWITCH; offset points to end of switch. */ \ M(SRC_CONDSWITCH, "condswitch", 2) /* JSOP_CONDSWITCH; 1st offset points to end of switch, \ 2nd points to first JSOP_CASE. */ \ M(SRC_NEXTCASE, "nextcase", 1) /* Distance forward from one CASE in a CONDSWITCH to \ the next. */ \ M(SRC_TABLESWITCH, "tableswitch", SrcNote::TableSwitch::Count) \ M(SRC_CONDSWITCH, "condswitch", SrcNote::CondSwitch::Count) \ M(SRC_NEXTCASE, "nextcase", SrcNote::NextCase::Count) \ M(SRC_ASSIGNOP, "assignop", 0) /* += or another assign-op follows. */ \ M(SRC_CLASS_SPAN, "class", 2) /* The starting and ending offsets for the class, used \ for toString correctness for default ctors. */ \ Loading js/src/frontend/SwitchEmitter.cpp +11 −2 Original line number Diff line number Diff line Loading @@ -233,9 +233,12 @@ SwitchEmitter::emitCaseOrDefaultJump(uint32_t caseIndex, bool isDefault) if (state_ == State::Case) { // Link the last JSOP_CASE's SRC_NEXTCASE to current JSOP_CASE for the // benefit of IonBuilder. if (!bce_->setSrcNoteOffset(caseNoteIndex_, 0, bce_->offset() - lastCaseOffset_)) if (!bce_->setSrcNoteOffset(caseNoteIndex_, SrcNote::NextCase::NextCaseOffset, bce_->offset() - lastCaseOffset_)) { return false; } } if (!bce_->newSrcNote2(SRC_NEXTCASE, 0, &caseNoteIndex_)) return false; Loading Loading @@ -392,8 +395,14 @@ SwitchEmitter::emitEnd() } // Set the SRC_SWITCH note's offset operand to tell end of switch. if (!bce_->setSrcNoteOffset(noteIndex_, 0, bce_->lastNonJumpTargetOffset() - top_)) // This code is shared between table switch and cond switch. static_assert(unsigned(SrcNote::TableSwitch::EndOffset) == unsigned(SrcNote::CondSwitch::EndOffset), "{TableSwitch,CondSwitch}::EndOffset should be same"); if (!bce_->setSrcNoteOffset(noteIndex_, SrcNote::TableSwitch::EndOffset, bce_->lastNonJumpTargetOffset() - top_)) { return false; } if (kind_ == Kind::Table) { // Skip over the already-initialized switch bounds. Loading js/src/jit/IonControlFlow.cpp +6 −6 Original line number Diff line number Diff line Loading @@ -1118,8 +1118,8 @@ ControlFlowGenerator::processCondSwitch() MOZ_ASSERT(SN_TYPE(sn) == SRC_CONDSWITCH); // Get the exit pc jsbytecode* exitpc = pc + GetSrcNoteOffset(sn, 0); jsbytecode* firstCase = pc + GetSrcNoteOffset(sn, 1); jsbytecode* exitpc = pc + GetSrcNoteOffset(sn, SrcNote::CondSwitch::EndOffset); jsbytecode* firstCase = pc + GetSrcNoteOffset(sn, SrcNote::CondSwitch::FirstCaseOffset); // Iterate all cases in the conditional switch. // - Stop at the default case. (always emitted after the last case) Loading @@ -1134,7 +1134,7 @@ ControlFlowGenerator::processCondSwitch() // Fetch the next case. jssrcnote* caseSn = GetSrcNote(gsn, script, curCase); MOZ_ASSERT(caseSn && SN_TYPE(caseSn) == SRC_NEXTCASE); ptrdiff_t off = GetSrcNoteOffset(caseSn, 0); ptrdiff_t off = GetSrcNoteOffset(caseSn, SrcNote::NextCase::NextCaseOffset); MOZ_ASSERT_IF(off == 0, JSOp(*GetNextPc(curCase)) == JSOP_JUMPTARGET); curCase = off ? curCase + off : GetNextPc(GetNextPc(curCase)); MOZ_ASSERT(pc < curCase && curCase <= exitpc); Loading Loading @@ -1167,7 +1167,7 @@ ControlFlowGenerator::processCondSwitch() defaultIdx++; jssrcnote* caseSn = GetSrcNote(gsn, script, curCase); ptrdiff_t off = GetSrcNoteOffset(caseSn, 0); ptrdiff_t off = GetSrcNoteOffset(caseSn, SrcNote::NextCase::NextCaseOffset); curCase = off ? curCase + off : GetNextPc(GetNextPc(curCase)); lastTarget = curTarget; } Loading Loading @@ -1223,7 +1223,7 @@ ControlFlowGenerator::processCondSwitchCase(CFGState& state) // Fetch the following case in which we will continue. jssrcnote* sn = GetSrcNote(gsn, script, pc); ptrdiff_t off = GetSrcNoteOffset(sn, 0); ptrdiff_t off = GetSrcNoteOffset(sn, SrcNote::NextCase::NextCaseOffset); MOZ_ASSERT_IF(off == 0, JSOp(*GetNextPc(pc)) == JSOP_JUMPTARGET); jsbytecode* casePc = off ? pc + off : GetNextPc(GetNextPc(pc)); bool nextIsDefault = JSOp(*casePc) == JSOP_DEFAULT; Loading Loading @@ -1849,7 +1849,7 @@ ControlFlowGenerator::processTableSwitch(JSOp op, jssrcnote* sn) MOZ_ASSERT(SN_TYPE(sn) == SRC_TABLESWITCH); // Get the default and exit pc jsbytecode* exitpc = pc + GetSrcNoteOffset(sn, 0); jsbytecode* exitpc = pc + GetSrcNoteOffset(sn, SrcNote::TableSwitch::EndOffset); jsbytecode* defaultpc = pc + GET_JUMP_OFFSET(pc); MOZ_ASSERT(defaultpc > pc && defaultpc <= exitpc); Loading js/src/shell/js.cpp +19 −4 Original line number Diff line number Diff line Loading @@ -2757,16 +2757,26 @@ SrcNotes(JSContext* cx, HandleScript script, Sprinter* sp) break; case SRC_WHILE: case SRC_NEXTCASE: if (!sp->jsprintf(" offset %u", unsigned(GetSrcNoteOffset(sn, 0)))) return false; break; case SRC_NEXTCASE: if (!sp->jsprintf(" next case offset %u", unsigned(GetSrcNoteOffset(sn, SrcNote::NextCase::NextCaseOffset)))) { return false; } break; case SRC_TABLESWITCH: { mozilla::DebugOnly<JSOp> op = JSOp(script->code()[offset]); MOZ_ASSERT(op == JSOP_TABLESWITCH); if (!sp->jsprintf(" length %u", unsigned(GetSrcNoteOffset(sn, 0)))) if (!sp->jsprintf(" end offset %u", unsigned(GetSrcNoteOffset(sn, SrcNote::TableSwitch::EndOffset)))) { return false; } UpdateSwitchTableBounds(cx, script, offset, &switchTableStart, &switchTableEnd); break; Loading @@ -2774,9 +2784,14 @@ SrcNotes(JSContext* cx, HandleScript script, Sprinter* sp) case SRC_CONDSWITCH: { mozilla::DebugOnly<JSOp> op = JSOp(script->code()[offset]); MOZ_ASSERT(op == JSOP_CONDSWITCH); if (!sp->jsprintf(" length %u", unsigned(GetSrcNoteOffset(sn, 0)))) if (!sp->jsprintf(" end offset %u", unsigned(GetSrcNoteOffset(sn, SrcNote::CondSwitch::EndOffset)))) { return false; if (unsigned caseOff = (unsigned) GetSrcNoteOffset(sn, 1)) { } if (unsigned caseOff = unsigned(GetSrcNoteOffset(sn, SrcNote::CondSwitch::FirstCaseOffset))) { if (!sp->jsprintf(" first case offset %u", caseOff)) return false; } Loading js/src/vm/CodeCoverage.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -200,7 +200,7 @@ LCovSource::writeScript(JSScript* script) else if (type == SRC_NEWLINE) lineno++; else if (type == SRC_TABLESWITCH) tableswitchExitOffset = GetSrcNoteOffset(sn, 0); tableswitchExitOffset = GetSrcNoteOffset(sn, SrcNote::TableSwitch::EndOffset); sn = SN_NEXT(sn); snpc += SN_DELTA(sn); Loading Loading
js/src/frontend/SourceNotes.h +41 −5 Original line number Diff line number Diff line Loading @@ -34,6 +34,44 @@ namespace js { * NB: the js_SrcNoteSpec array in BytecodeEmitter.cpp is indexed by this * enum, so its initializers need to match the order here. */ class SrcNote { public: // SRC_TABLESWITCH: Source note for JSOP_TABLESWITCH. class TableSwitch { public: enum Fields { // The offset of the end of switch (the first non-JumpTarget op // after switch) from JSOP_TABLESWITCH. EndOffset, Count }; }; // SRC_CONDSWITCH: Source note for JSOP_CONDSWITCH. class CondSwitch { public: enum Fields { // The offset of the end of switch (the first non-JumpTarget op // after switch) from JSOP_CONDSWITCH. EndOffset, // The offset of JSOP_CASE for the first case from JSOP_CONDSWITCH. FirstCaseOffset, Count }; }; // SRC_NEXTCASE: Source note for JSOP_CASE in a JSOP_CONDSWITCH. class NextCase { public: enum Fields { // Offset of the next JSOP_CASE from this JSOP_CASE. This field is // 0 if this is the last JSOP_CASE. NextCaseOffset, Count }; }; }; #define FOR_EACH_SRC_NOTE_TYPE(M) \ M(SRC_NULL, "null", 0) /* Terminates a note vector. */ \ M(SRC_IF, "if", 0) /* JSOP_IFEQ bytecode is from an if-then. */ \ Loading @@ -50,11 +88,9 @@ namespace js { M(SRC_BREAK, "break", 0) /* JSOP_GOTO is a break. */ \ M(SRC_BREAK2LABEL, "break2label", 0) /* JSOP_GOTO for 'break label'. */ \ M(SRC_SWITCHBREAK, "switchbreak", 0) /* JSOP_GOTO is a break in a switch. */ \ M(SRC_TABLESWITCH, "tableswitch", 1) /* JSOP_TABLESWITCH; offset points to end of switch. */ \ M(SRC_CONDSWITCH, "condswitch", 2) /* JSOP_CONDSWITCH; 1st offset points to end of switch, \ 2nd points to first JSOP_CASE. */ \ M(SRC_NEXTCASE, "nextcase", 1) /* Distance forward from one CASE in a CONDSWITCH to \ the next. */ \ M(SRC_TABLESWITCH, "tableswitch", SrcNote::TableSwitch::Count) \ M(SRC_CONDSWITCH, "condswitch", SrcNote::CondSwitch::Count) \ M(SRC_NEXTCASE, "nextcase", SrcNote::NextCase::Count) \ M(SRC_ASSIGNOP, "assignop", 0) /* += or another assign-op follows. */ \ M(SRC_CLASS_SPAN, "class", 2) /* The starting and ending offsets for the class, used \ for toString correctness for default ctors. */ \ Loading
js/src/frontend/SwitchEmitter.cpp +11 −2 Original line number Diff line number Diff line Loading @@ -233,9 +233,12 @@ SwitchEmitter::emitCaseOrDefaultJump(uint32_t caseIndex, bool isDefault) if (state_ == State::Case) { // Link the last JSOP_CASE's SRC_NEXTCASE to current JSOP_CASE for the // benefit of IonBuilder. if (!bce_->setSrcNoteOffset(caseNoteIndex_, 0, bce_->offset() - lastCaseOffset_)) if (!bce_->setSrcNoteOffset(caseNoteIndex_, SrcNote::NextCase::NextCaseOffset, bce_->offset() - lastCaseOffset_)) { return false; } } if (!bce_->newSrcNote2(SRC_NEXTCASE, 0, &caseNoteIndex_)) return false; Loading Loading @@ -392,8 +395,14 @@ SwitchEmitter::emitEnd() } // Set the SRC_SWITCH note's offset operand to tell end of switch. if (!bce_->setSrcNoteOffset(noteIndex_, 0, bce_->lastNonJumpTargetOffset() - top_)) // This code is shared between table switch and cond switch. static_assert(unsigned(SrcNote::TableSwitch::EndOffset) == unsigned(SrcNote::CondSwitch::EndOffset), "{TableSwitch,CondSwitch}::EndOffset should be same"); if (!bce_->setSrcNoteOffset(noteIndex_, SrcNote::TableSwitch::EndOffset, bce_->lastNonJumpTargetOffset() - top_)) { return false; } if (kind_ == Kind::Table) { // Skip over the already-initialized switch bounds. Loading
js/src/jit/IonControlFlow.cpp +6 −6 Original line number Diff line number Diff line Loading @@ -1118,8 +1118,8 @@ ControlFlowGenerator::processCondSwitch() MOZ_ASSERT(SN_TYPE(sn) == SRC_CONDSWITCH); // Get the exit pc jsbytecode* exitpc = pc + GetSrcNoteOffset(sn, 0); jsbytecode* firstCase = pc + GetSrcNoteOffset(sn, 1); jsbytecode* exitpc = pc + GetSrcNoteOffset(sn, SrcNote::CondSwitch::EndOffset); jsbytecode* firstCase = pc + GetSrcNoteOffset(sn, SrcNote::CondSwitch::FirstCaseOffset); // Iterate all cases in the conditional switch. // - Stop at the default case. (always emitted after the last case) Loading @@ -1134,7 +1134,7 @@ ControlFlowGenerator::processCondSwitch() // Fetch the next case. jssrcnote* caseSn = GetSrcNote(gsn, script, curCase); MOZ_ASSERT(caseSn && SN_TYPE(caseSn) == SRC_NEXTCASE); ptrdiff_t off = GetSrcNoteOffset(caseSn, 0); ptrdiff_t off = GetSrcNoteOffset(caseSn, SrcNote::NextCase::NextCaseOffset); MOZ_ASSERT_IF(off == 0, JSOp(*GetNextPc(curCase)) == JSOP_JUMPTARGET); curCase = off ? curCase + off : GetNextPc(GetNextPc(curCase)); MOZ_ASSERT(pc < curCase && curCase <= exitpc); Loading Loading @@ -1167,7 +1167,7 @@ ControlFlowGenerator::processCondSwitch() defaultIdx++; jssrcnote* caseSn = GetSrcNote(gsn, script, curCase); ptrdiff_t off = GetSrcNoteOffset(caseSn, 0); ptrdiff_t off = GetSrcNoteOffset(caseSn, SrcNote::NextCase::NextCaseOffset); curCase = off ? curCase + off : GetNextPc(GetNextPc(curCase)); lastTarget = curTarget; } Loading Loading @@ -1223,7 +1223,7 @@ ControlFlowGenerator::processCondSwitchCase(CFGState& state) // Fetch the following case in which we will continue. jssrcnote* sn = GetSrcNote(gsn, script, pc); ptrdiff_t off = GetSrcNoteOffset(sn, 0); ptrdiff_t off = GetSrcNoteOffset(sn, SrcNote::NextCase::NextCaseOffset); MOZ_ASSERT_IF(off == 0, JSOp(*GetNextPc(pc)) == JSOP_JUMPTARGET); jsbytecode* casePc = off ? pc + off : GetNextPc(GetNextPc(pc)); bool nextIsDefault = JSOp(*casePc) == JSOP_DEFAULT; Loading Loading @@ -1849,7 +1849,7 @@ ControlFlowGenerator::processTableSwitch(JSOp op, jssrcnote* sn) MOZ_ASSERT(SN_TYPE(sn) == SRC_TABLESWITCH); // Get the default and exit pc jsbytecode* exitpc = pc + GetSrcNoteOffset(sn, 0); jsbytecode* exitpc = pc + GetSrcNoteOffset(sn, SrcNote::TableSwitch::EndOffset); jsbytecode* defaultpc = pc + GET_JUMP_OFFSET(pc); MOZ_ASSERT(defaultpc > pc && defaultpc <= exitpc); Loading
js/src/shell/js.cpp +19 −4 Original line number Diff line number Diff line Loading @@ -2757,16 +2757,26 @@ SrcNotes(JSContext* cx, HandleScript script, Sprinter* sp) break; case SRC_WHILE: case SRC_NEXTCASE: if (!sp->jsprintf(" offset %u", unsigned(GetSrcNoteOffset(sn, 0)))) return false; break; case SRC_NEXTCASE: if (!sp->jsprintf(" next case offset %u", unsigned(GetSrcNoteOffset(sn, SrcNote::NextCase::NextCaseOffset)))) { return false; } break; case SRC_TABLESWITCH: { mozilla::DebugOnly<JSOp> op = JSOp(script->code()[offset]); MOZ_ASSERT(op == JSOP_TABLESWITCH); if (!sp->jsprintf(" length %u", unsigned(GetSrcNoteOffset(sn, 0)))) if (!sp->jsprintf(" end offset %u", unsigned(GetSrcNoteOffset(sn, SrcNote::TableSwitch::EndOffset)))) { return false; } UpdateSwitchTableBounds(cx, script, offset, &switchTableStart, &switchTableEnd); break; Loading @@ -2774,9 +2784,14 @@ SrcNotes(JSContext* cx, HandleScript script, Sprinter* sp) case SRC_CONDSWITCH: { mozilla::DebugOnly<JSOp> op = JSOp(script->code()[offset]); MOZ_ASSERT(op == JSOP_CONDSWITCH); if (!sp->jsprintf(" length %u", unsigned(GetSrcNoteOffset(sn, 0)))) if (!sp->jsprintf(" end offset %u", unsigned(GetSrcNoteOffset(sn, SrcNote::CondSwitch::EndOffset)))) { return false; if (unsigned caseOff = (unsigned) GetSrcNoteOffset(sn, 1)) { } if (unsigned caseOff = unsigned(GetSrcNoteOffset(sn, SrcNote::CondSwitch::FirstCaseOffset))) { if (!sp->jsprintf(" first case offset %u", caseOff)) return false; } Loading
js/src/vm/CodeCoverage.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -200,7 +200,7 @@ LCovSource::writeScript(JSScript* script) else if (type == SRC_NEWLINE) lineno++; else if (type == SRC_TABLESWITCH) tableswitchExitOffset = GetSrcNoteOffset(sn, 0); tableswitchExitOffset = GetSrcNoteOffset(sn, SrcNote::TableSwitch::EndOffset); sn = SN_NEXT(sn); snpc += SN_DELTA(sn); Loading