mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 20:47:44 +00:00
Bug 788096 (part 2) - Introduce CGTryNoteList for storing try notes in the bytecode mitter. r=jorendorff.
--HG-- extra : rebase_source : 7f6618f65628932a4bdb875a0c3bdf8dae46f0e6
This commit is contained in:
parent
b36beedfc1
commit
5b7fbddbf1
@ -58,10 +58,6 @@ using namespace js;
|
||||
using namespace js::gc;
|
||||
using namespace js::frontend;
|
||||
|
||||
static bool
|
||||
NewTryNote(JSContext *cx, BytecodeEmitter *bce, JSTryNoteKind kind, unsigned stackDepth,
|
||||
size_t start, size_t end);
|
||||
|
||||
static bool
|
||||
SetSrcNoteOffset(JSContext *cx, BytecodeEmitter *bce, unsigned index, unsigned which, ptrdiff_t offset);
|
||||
|
||||
@ -114,7 +110,7 @@ BytecodeEmitter::BytecodeEmitter(BytecodeEmitter *parent, Parser *parser, Shared
|
||||
blockChain(sc->context),
|
||||
atomIndices(sc->context),
|
||||
stackDepth(0), maxStackDepth(0),
|
||||
ntrynotes(0), lastTryNode(NULL),
|
||||
tryNoteList(sc->context),
|
||||
arrayCompDepth(0),
|
||||
emitLevel(0),
|
||||
constList(sc->context),
|
||||
@ -4128,7 +4124,7 @@ EmitTry(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* Add the try note last, to let post-order give us the right ordering
|
||||
* (first to last for a given nesting level, inner to outer by level).
|
||||
*/
|
||||
if (pn->pn_kid2 && !NewTryNote(cx, bce, JSTRY_CATCH, depth, tryStart, tryEnd))
|
||||
if (pn->pn_kid2 && !bce->tryNoteList.append(JSTRY_CATCH, depth, tryStart, tryEnd))
|
||||
return false;
|
||||
|
||||
/*
|
||||
@ -4136,7 +4132,7 @@ EmitTry(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* trynote to catch exceptions (re)thrown from a catch block or
|
||||
* for the try{}finally{} case.
|
||||
*/
|
||||
if (pn->pn_kid3 && !NewTryNote(cx, bce, JSTRY_FINALLY, depth, tryStart, finallyStart))
|
||||
if (pn->pn_kid3 && !bce->tryNoteList.append(JSTRY_FINALLY, depth, tryStart, finallyStart))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -4658,7 +4654,7 @@ EmitForIn(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NewTryNote(cx, bce, JSTRY_ITER, bce->stackDepth, top, bce->offset()))
|
||||
if (!bce->tryNoteList.append(JSTRY_ITER, bce->stackDepth, top, bce->offset()))
|
||||
return false;
|
||||
if (Emit1(cx, bce, JSOP_ENDITER) < 0)
|
||||
return false;
|
||||
@ -6959,44 +6955,30 @@ frontend::FinishTakingSrcNotes(JSContext *cx, BytecodeEmitter *bce, jssrcnote *n
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
NewTryNote(JSContext *cx, BytecodeEmitter *bce, JSTryNoteKind kind, unsigned stackDepth,
|
||||
size_t start, size_t end)
|
||||
bool
|
||||
CGTryNoteList::append(JSTryNoteKind kind, unsigned stackDepth, size_t start, size_t end)
|
||||
{
|
||||
JS_ASSERT((unsigned)(uint16_t)stackDepth == stackDepth);
|
||||
JS_ASSERT(unsigned(uint16_t(stackDepth)) == stackDepth);
|
||||
JS_ASSERT(start <= end);
|
||||
JS_ASSERT((size_t)(uint32_t)start == start);
|
||||
JS_ASSERT((size_t)(uint32_t)end == end);
|
||||
JS_ASSERT(size_t(uint32_t(start)) == start);
|
||||
JS_ASSERT(size_t(uint32_t(end)) == end);
|
||||
|
||||
TryNode *tryNode = cx->tempLifoAlloc().new_<TryNode>();
|
||||
if (!tryNode) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
JSTryNote note;
|
||||
note.kind = kind;
|
||||
note.stackDepth = uint16_t(stackDepth);
|
||||
note.start = uint32_t(start);
|
||||
note.length = uint32_t(end - start);
|
||||
|
||||
tryNode->note.kind = kind;
|
||||
tryNode->note.stackDepth = (uint16_t)stackDepth;
|
||||
tryNode->note.start = (uint32_t)start;
|
||||
tryNode->note.length = (uint32_t)(end - start);
|
||||
tryNode->prev = bce->lastTryNode;
|
||||
bce->lastTryNode = tryNode;
|
||||
bce->ntrynotes++;
|
||||
return true;
|
||||
return list.append(note);
|
||||
}
|
||||
|
||||
void
|
||||
frontend::FinishTakingTryNotes(BytecodeEmitter *bce, TryNoteArray *array)
|
||||
CGTryNoteList::finish(TryNoteArray *array)
|
||||
{
|
||||
TryNode *tryNode;
|
||||
JSTryNote *tn;
|
||||
JS_ASSERT(length() == array->length);
|
||||
|
||||
JS_ASSERT(array->length > 0 && array->length == bce->ntrynotes);
|
||||
tn = array->vector + array->length;
|
||||
tryNode = bce->lastTryNode;
|
||||
do {
|
||||
*--tn = tryNode->note;
|
||||
} while ((tryNode = tryNode->prev) != NULL);
|
||||
JS_ASSERT(tn == array->vector);
|
||||
for (unsigned i = 0; i < length(); i++)
|
||||
array->vector[i] = list[i];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -27,9 +27,13 @@
|
||||
namespace js {
|
||||
namespace frontend {
|
||||
|
||||
struct TryNode {
|
||||
JSTryNote note;
|
||||
TryNode *prev;
|
||||
struct CGTryNoteList {
|
||||
Vector<JSTryNote> list;
|
||||
CGTryNoteList(JSContext *cx) : list(cx) {}
|
||||
|
||||
bool append(JSTryNoteKind kind, unsigned stackDepth, size_t start, size_t end);
|
||||
size_t length() const { return list.length(); }
|
||||
void finish(TryNoteArray *array);
|
||||
};
|
||||
|
||||
struct CGObjectList {
|
||||
@ -91,8 +95,7 @@ struct BytecodeEmitter
|
||||
int stackDepth; /* current stack depth in script frame */
|
||||
unsigned maxStackDepth; /* maximum stack depth so far */
|
||||
|
||||
unsigned ntrynotes; /* number of allocated so far try notes */
|
||||
TryNode *lastTryNode; /* the last allocated try node */
|
||||
CGTryNoteList tryNoteList; /* list of emitted try notes */
|
||||
|
||||
unsigned arrayCompDepth; /* stack depth of array in comprehension */
|
||||
|
||||
@ -400,9 +403,6 @@ AddToSrcNoteDelta(JSContext *cx, BytecodeEmitter *bce, jssrcnote *sn, ptrdiff_t
|
||||
bool
|
||||
FinishTakingSrcNotes(JSContext *cx, BytecodeEmitter *bce, jssrcnote *notes);
|
||||
|
||||
void
|
||||
FinishTakingTryNotes(BytecodeEmitter *bce, TryNoteArray *array);
|
||||
|
||||
/*
|
||||
* Finish taking source notes in cx's notePool, copying final notes to the new
|
||||
* stable store allocated by the caller and passed in via notes. Return false
|
||||
|
@ -1623,8 +1623,8 @@ JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, Bytecode
|
||||
uint32_t prologLength = bce->prologOffset();
|
||||
uint32_t nsrcnotes = uint32_t(bce->countFinalSourceNotes());
|
||||
if (!partiallyInit(cx, script, prologLength + mainLength, nsrcnotes, bce->atomIndices->count(),
|
||||
bce->objectList.length(), bce->regexpList.length(), bce->ntrynotes,
|
||||
bce->constList.length(), bce->typesetCount))
|
||||
bce->objectList.length(), bce->regexpList.length(),
|
||||
bce->tryNoteList.length(), bce->constList.length(), bce->typesetCount))
|
||||
return false;
|
||||
|
||||
JS_ASSERT(script->mainOffset == 0);
|
||||
@ -1651,8 +1651,8 @@ JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, Bytecode
|
||||
|
||||
if (!FinishTakingSrcNotes(cx, bce, script->notes()))
|
||||
return false;
|
||||
if (bce->ntrynotes != 0)
|
||||
FinishTakingTryNotes(bce, script->trynotes());
|
||||
if (bce->tryNoteList.length() != 0)
|
||||
bce->tryNoteList.finish(script->trynotes());
|
||||
if (bce->objectList.length() != 0)
|
||||
bce->objectList.finish(script->objects());
|
||||
if (bce->regexpList.length() != 0)
|
||||
|
Loading…
Reference in New Issue
Block a user