mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Bug 1477621 - Part 1: Add source note field constants for switch. r=jandem
This commit is contained in:
parent
8fe894f60c
commit
53c7a51a17
@ -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. */ \
|
||||
@ -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. */ \
|
||||
|
@ -233,8 +233,11 @@ 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_))
|
||||
@ -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.
|
||||
|
@ -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)
|
||||
@ -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);
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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…
Reference in New Issue
Block a user