зеркало из https://github.com/mozilla/gecko-dev.git
Bug 890192 (part 1) - Slim down jsopcodeinlines.h. r=terrence.
--HG-- extra : rebase_source : 15755ff706fbbde8933fd083723faaafc9458613
This commit is contained in:
Родитель
b42053d054
Коммит
7d9cc8d540
|
@ -15,6 +15,8 @@
|
|||
#include "jspubtd.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
#include "frontend/SourceNotes.h"
|
||||
|
||||
/*
|
||||
* JS operation bytecodes.
|
||||
*/
|
||||
|
@ -235,6 +237,114 @@ js_QuoteString(JSContext *cx, JSString *str, jschar quote);
|
|||
|
||||
namespace js {
|
||||
|
||||
static inline bool
|
||||
IsJumpOpcode(JSOp op)
|
||||
{
|
||||
uint32_t type = JOF_TYPE(js_CodeSpec[op].format);
|
||||
|
||||
/*
|
||||
* LABEL opcodes have type JOF_JUMP but are no-ops, don't treat them as
|
||||
* jumps to avoid degrading precision.
|
||||
*/
|
||||
return type == JOF_JUMP && op != JSOP_LABEL;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
BytecodeFallsThrough(JSOp op)
|
||||
{
|
||||
switch (op) {
|
||||
case JSOP_GOTO:
|
||||
case JSOP_DEFAULT:
|
||||
case JSOP_RETURN:
|
||||
case JSOP_STOP:
|
||||
case JSOP_RETRVAL:
|
||||
case JSOP_THROW:
|
||||
case JSOP_TABLESWITCH:
|
||||
return false;
|
||||
case JSOP_GOSUB:
|
||||
/* These fall through indirectly, after executing a 'finally'. */
|
||||
return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class SrcNoteLineScanner
|
||||
{
|
||||
/* offset of the current JSOp in the bytecode */
|
||||
ptrdiff_t offset;
|
||||
|
||||
/* next src note to process */
|
||||
jssrcnote *sn;
|
||||
|
||||
/* line number of the current JSOp */
|
||||
uint32_t lineno;
|
||||
|
||||
/*
|
||||
* Is the current op the first one after a line change directive? Note that
|
||||
* multiple ops may be "first" if a line directive is used to return to a
|
||||
* previous line (eg, with a for loop increment expression.)
|
||||
*/
|
||||
bool lineHeader;
|
||||
|
||||
public:
|
||||
SrcNoteLineScanner(jssrcnote *sn, uint32_t lineno)
|
||||
: offset(0), sn(sn), lineno(lineno)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called repeatedly with always-advancing relpc values. The src
|
||||
* notes are tuples of <PC offset from prev src note, type, args>. Scan
|
||||
* through, updating the lineno, until the next src note is for a later
|
||||
* bytecode.
|
||||
*
|
||||
* When looking at the desired PC offset ('relpc'), the op is first in that
|
||||
* line iff there is a SRC_SETLINE or SRC_NEWLINE src note for that exact
|
||||
* bytecode.
|
||||
*
|
||||
* Note that a single bytecode may have multiple line-modifying notes (even
|
||||
* though only one should ever be needed.)
|
||||
*/
|
||||
void advanceTo(ptrdiff_t relpc) {
|
||||
// Must always advance! If the same or an earlier PC is erroneously
|
||||
// passed in, we will already be past the relevant src notes
|
||||
JS_ASSERT_IF(offset > 0, relpc > offset);
|
||||
|
||||
// Next src note should be for after the current offset
|
||||
JS_ASSERT_IF(offset > 0, SN_IS_TERMINATOR(sn) || SN_DELTA(sn) > 0);
|
||||
|
||||
// The first PC requested is always considered to be a line header
|
||||
lineHeader = (offset == 0);
|
||||
|
||||
if (SN_IS_TERMINATOR(sn))
|
||||
return;
|
||||
|
||||
ptrdiff_t nextOffset;
|
||||
while ((nextOffset = offset + SN_DELTA(sn)) <= relpc && !SN_IS_TERMINATOR(sn)) {
|
||||
offset = nextOffset;
|
||||
SrcNoteType type = (SrcNoteType) SN_TYPE(sn);
|
||||
if (type == SRC_SETLINE || type == SRC_NEWLINE) {
|
||||
if (type == SRC_SETLINE)
|
||||
lineno = js_GetSrcNoteOffset(sn, 0);
|
||||
else
|
||||
lineno++;
|
||||
|
||||
if (offset == relpc)
|
||||
lineHeader = true;
|
||||
}
|
||||
|
||||
sn = SN_NEXT(sn);
|
||||
}
|
||||
}
|
||||
|
||||
bool isLineHeader() const {
|
||||
return lineHeader;
|
||||
}
|
||||
|
||||
uint32_t getLine() const { return lineno; }
|
||||
};
|
||||
|
||||
extern unsigned
|
||||
StackUses(JSScript *script, jsbytecode *pc);
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
#include "jsautooplen.h"
|
||||
|
||||
#include "frontend/SourceNotes.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
static inline unsigned
|
||||
|
@ -53,38 +51,6 @@ GetUseCount(JSScript *script, unsigned offset)
|
|||
return js_CodeSpec[*pc].nuses;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsJumpOpcode(JSOp op)
|
||||
{
|
||||
uint32_t type = JOF_TYPE(js_CodeSpec[op].format);
|
||||
|
||||
/*
|
||||
* LABEL opcodes have type JOF_JUMP but are no-ops, don't treat them as
|
||||
* jumps to avoid degrading precision.
|
||||
*/
|
||||
return type == JOF_JUMP && op != JSOP_LABEL;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
BytecodeFallsThrough(JSOp op)
|
||||
{
|
||||
switch (op) {
|
||||
case JSOP_GOTO:
|
||||
case JSOP_DEFAULT:
|
||||
case JSOP_RETURN:
|
||||
case JSOP_STOP:
|
||||
case JSOP_RETRVAL:
|
||||
case JSOP_THROW:
|
||||
case JSOP_TABLESWITCH:
|
||||
return false;
|
||||
case JSOP_GOSUB:
|
||||
/* These fall through indirectly, after executing a 'finally'. */
|
||||
return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class BytecodeRange {
|
||||
public:
|
||||
BytecodeRange(JSContext *cx, JSScript *script)
|
||||
|
@ -100,82 +66,6 @@ class BytecodeRange {
|
|||
jsbytecode *pc, *end;
|
||||
};
|
||||
|
||||
class SrcNoteLineScanner
|
||||
{
|
||||
/* offset of the current JSOp in the bytecode */
|
||||
ptrdiff_t offset;
|
||||
|
||||
/* next src note to process */
|
||||
jssrcnote *sn;
|
||||
|
||||
/* line number of the current JSOp */
|
||||
uint32_t lineno;
|
||||
|
||||
/*
|
||||
* Is the current op the first one after a line change directive? Note that
|
||||
* multiple ops may be "first" if a line directive is used to return to a
|
||||
* previous line (eg, with a for loop increment expression.)
|
||||
*/
|
||||
bool lineHeader;
|
||||
|
||||
public:
|
||||
SrcNoteLineScanner(jssrcnote *sn, uint32_t lineno)
|
||||
: offset(0), sn(sn), lineno(lineno)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called repeatedly with always-advancing relpc values. The src
|
||||
* notes are tuples of <PC offset from prev src note, type, args>. Scan
|
||||
* through, updating the lineno, until the next src note is for a later
|
||||
* bytecode.
|
||||
*
|
||||
* When looking at the desired PC offset ('relpc'), the op is first in that
|
||||
* line iff there is a SRC_SETLINE or SRC_NEWLINE src note for that exact
|
||||
* bytecode.
|
||||
*
|
||||
* Note that a single bytecode may have multiple line-modifying notes (even
|
||||
* though only one should ever be needed.)
|
||||
*/
|
||||
void advanceTo(ptrdiff_t relpc) {
|
||||
// Must always advance! If the same or an earlier PC is erroneously
|
||||
// passed in, we will already be past the relevant src notes
|
||||
JS_ASSERT_IF(offset > 0, relpc > offset);
|
||||
|
||||
// Next src note should be for after the current offset
|
||||
JS_ASSERT_IF(offset > 0, SN_IS_TERMINATOR(sn) || SN_DELTA(sn) > 0);
|
||||
|
||||
// The first PC requested is always considered to be a line header
|
||||
lineHeader = (offset == 0);
|
||||
|
||||
if (SN_IS_TERMINATOR(sn))
|
||||
return;
|
||||
|
||||
ptrdiff_t nextOffset;
|
||||
while ((nextOffset = offset + SN_DELTA(sn)) <= relpc && !SN_IS_TERMINATOR(sn)) {
|
||||
offset = nextOffset;
|
||||
SrcNoteType type = (SrcNoteType) SN_TYPE(sn);
|
||||
if (type == SRC_SETLINE || type == SRC_NEWLINE) {
|
||||
if (type == SRC_SETLINE)
|
||||
lineno = js_GetSrcNoteOffset(sn, 0);
|
||||
else
|
||||
lineno++;
|
||||
|
||||
if (offset == relpc)
|
||||
lineHeader = true;
|
||||
}
|
||||
|
||||
sn = SN_NEXT(sn);
|
||||
}
|
||||
}
|
||||
|
||||
bool isLineHeader() const {
|
||||
return lineHeader;
|
||||
}
|
||||
|
||||
uint32_t getLine() const { return lineno; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* jsopcodeinlines_h */
|
||||
|
|
Загрузка…
Ссылка в новой задаче