зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1143704 part 12 - Move remaining functions to BytecodeEmitter. r=bhackett
--HG-- extra : rebase_source : d707ed9dededc0adaabce0ba45747def58b9655a
This commit is contained in:
Родитель
052d0eb78e
Коммит
dd8f6429b6
|
@ -527,7 +527,7 @@ frontend::CompileLazyFunction(JSContext *cx, Handle<LazyScript*> lazy, const cha
|
|||
if (!bce.init())
|
||||
return false;
|
||||
|
||||
return EmitFunctionScript(cx, &bce, pn->pn_body);
|
||||
return bce.emitFunctionScript(pn->pn_body);
|
||||
}
|
||||
|
||||
// Compile a JS function body, which might appear as the value of an event
|
||||
|
@ -652,7 +652,7 @@ CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, const ReadOnlyComp
|
|||
if (!funbce.init())
|
||||
return false;
|
||||
|
||||
if (!EmitFunctionScript(cx, &funbce, fn->pn_body))
|
||||
if (!funbce.emitFunctionScript(fn->pn_body))
|
||||
return false;
|
||||
} else {
|
||||
fun.set(fn->pn_funbox->function());
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -83,6 +83,7 @@ struct CGYieldOffsetList {
|
|||
void finish(YieldOffsetArray &array, uint32_t prologLength);
|
||||
};
|
||||
|
||||
struct LoopStmtInfo;
|
||||
struct StmtInfoBCE;
|
||||
|
||||
// Use zero inline elements because these go on the stack and affect how many
|
||||
|
@ -269,13 +270,50 @@ struct BytecodeEmitter
|
|||
bool reportStrictWarning(ParseNode *pn, unsigned errorNumber, ...);
|
||||
bool reportStrictModeError(ParseNode *pn, unsigned errorNumber, ...);
|
||||
|
||||
// If pn contains a useful expression, return true with *answer set to true.
|
||||
// If pn contains a useless expression, return true with *answer set to
|
||||
// false. Return false on error.
|
||||
//
|
||||
// The caller should initialize *answer to false and invoke this function on
|
||||
// an expression statement or similar subtree to decide whether the tree
|
||||
// could produce code that has any side effects. For an expression
|
||||
// statement, we define useless code as code with no side effects, because
|
||||
// the main effect, the value left on the stack after the code executes,
|
||||
// will be discarded by a pop bytecode.
|
||||
bool checkSideEffects(ParseNode *pn, bool *answer);
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
// source note count is stored in the out outparam.
|
||||
bool finishTakingSrcNotes(uint32_t *out);
|
||||
|
||||
void setJumpOffsetAt(ptrdiff_t off);
|
||||
|
||||
// Emit code for the tree rooted at pn.
|
||||
bool emitTree(ParseNode *pn);
|
||||
|
||||
// Emit function code for the tree rooted at body.
|
||||
bool emitFunctionScript(ParseNode *body);
|
||||
|
||||
// If op is JOF_TYPESET (see the type barriers comment in TypeInference.h),
|
||||
// reserve a type set to store its result.
|
||||
void checkTypeSet(JSOp op);
|
||||
|
@ -285,10 +323,47 @@ struct BytecodeEmitter
|
|||
bool updateSourceCoordNotes(uint32_t offset);
|
||||
|
||||
bool bindNameToSlot(ParseNode *pn);
|
||||
bool bindNameToSlotHelper(ParseNode *pn);
|
||||
|
||||
void strictifySetNameNode(ParseNode *pn);
|
||||
JSOp strictifySetNameOp(JSOp op);
|
||||
|
||||
bool tryConvertFreeName(ParseNode *pn);
|
||||
|
||||
void popStatement();
|
||||
void pushStatement(StmtInfoBCE *stmt, StmtType type, ptrdiff_t top);
|
||||
void pushStatementInner(StmtInfoBCE *stmt, StmtType type, ptrdiff_t top);
|
||||
void pushLoopStatement(LoopStmtInfo *stmt, StmtType type, ptrdiff_t top);
|
||||
|
||||
// Return the enclosing lexical scope, which is the innermost enclosing static
|
||||
// block object or compiler created function.
|
||||
JSObject *enclosingStaticScope();
|
||||
|
||||
// Compute the number of nested scope objects that will actually be on the
|
||||
// scope chain at runtime, given the current staticScope.
|
||||
unsigned dynamicNestedScopeDepth();
|
||||
|
||||
bool enterNestedScope(StmtInfoBCE *stmt, ObjectBox *objbox, StmtType stmtType);
|
||||
bool leaveNestedScope(StmtInfoBCE *stmt);
|
||||
|
||||
bool enterBlockScope(StmtInfoBCE *stmtInfo, ObjectBox *objbox, JSOp initialValueOp,
|
||||
unsigned alreadyPushed = 0);
|
||||
|
||||
bool computeAliasedSlots(Handle<StaticBlockObject *> blockObj);
|
||||
|
||||
bool lookupAliasedName(HandleScript script, PropertyName *name, uint32_t *pslot,
|
||||
ParseNode *pn = nullptr);
|
||||
bool lookupAliasedNameSlot(PropertyName *name, ScopeCoordinate *sc);
|
||||
|
||||
// Use this function instead of assigning directly to 'hops' to guard for
|
||||
// uint8_t overflows.
|
||||
bool assignHops(ParseNode *pn, unsigned src, ScopeCoordinate *dst);
|
||||
|
||||
// In a function, block-scoped locals go after the vars, and form part of the
|
||||
// fixed part of a stack frame. Outside a function, there are no fixed vars,
|
||||
// but block-scoped locals still form part of the fixed part of a stack frame
|
||||
// and are thus addressable via GETLOCAL and friends.
|
||||
void computeLocalOffset(Handle<StaticBlockObject *> blockObj);
|
||||
|
||||
bool flushPops(int *npops);
|
||||
|
||||
|
@ -353,6 +428,7 @@ struct BytecodeEmitter
|
|||
bool emitObjectPairOp(ObjectBox *objbox1, ObjectBox *objbox2, JSOp op);
|
||||
bool emitRegExp(uint32_t index);
|
||||
|
||||
MOZ_NEVER_INLINE bool emitFunction(ParseNode *pn, bool needsProto = false);
|
||||
MOZ_NEVER_INLINE bool emitObject(ParseNode *pn);
|
||||
|
||||
bool emitPropertyList(ParseNode *pn, MutableHandlePlainObject objp, PropListType type);
|
||||
|
@ -383,6 +459,7 @@ struct BytecodeEmitter
|
|||
|
||||
bool emitPrepareIteratorResult();
|
||||
bool emitFinishIteratorResult(bool done);
|
||||
bool iteratorResultShape(unsigned *shape);
|
||||
|
||||
bool emitYield(ParseNode *pn);
|
||||
bool emitYieldOp(JSOp op);
|
||||
|
@ -405,6 +482,9 @@ struct BytecodeEmitter
|
|||
bool emitIf(ParseNode *pn);
|
||||
bool emitWith(ParseNode *pn);
|
||||
|
||||
MOZ_NEVER_INLINE bool emitLabeledStatement(const LabeledStatement *pn);
|
||||
MOZ_NEVER_INLINE bool emitLet(ParseNode *pnLet);
|
||||
MOZ_NEVER_INLINE bool emitLexicalScope(ParseNode *pn);
|
||||
MOZ_NEVER_INLINE bool emitSwitch(ParseNode *pn);
|
||||
MOZ_NEVER_INLINE bool emitTry(ParseNode *pn);
|
||||
|
||||
|
@ -420,6 +500,23 @@ struct BytecodeEmitter
|
|||
// lhs expression. (Same post-condition as EmitDestructuringOpsHelper)
|
||||
bool emitDestructuringLHS(ParseNode *target, VarEmitOption emitOption);
|
||||
|
||||
bool emitDestructuringOps(ParseNode *pattern, bool isLet = false);
|
||||
bool emitDestructuringOpsHelper(ParseNode *pattern, VarEmitOption emitOption);
|
||||
bool emitDestructuringOpsArrayHelper(ParseNode *pattern, VarEmitOption emitOption);
|
||||
bool emitDestructuringOpsObjectHelper(ParseNode *pattern, VarEmitOption emitOption);
|
||||
|
||||
typedef bool
|
||||
(*DestructuringDeclEmitter)(BytecodeEmitter *bce, JSOp prologOp, ParseNode *pn);
|
||||
|
||||
template <DestructuringDeclEmitter EmitName>
|
||||
bool emitDestructuringDeclsWithEmitter(JSOp prologOp, ParseNode *pattern);
|
||||
|
||||
bool emitDestructuringDecls(JSOp prologOp, ParseNode *pattern);
|
||||
|
||||
// Emit code to initialize all destructured names to the value on the top of
|
||||
// the stack.
|
||||
bool emitInitializeDestructuringDecls(JSOp prologOp, ParseNode *pattern);
|
||||
|
||||
// emitIterator expects the iterable to already be on the stack.
|
||||
// It will replace that stack value with the corresponding iterator
|
||||
bool emitIterator();
|
||||
|
@ -439,6 +536,7 @@ struct BytecodeEmitter
|
|||
bool emitReturn(ParseNode *pn);
|
||||
bool emitStatement(ParseNode *pn);
|
||||
bool emitStatementList(ParseNode *pn, ptrdiff_t top);
|
||||
bool emitSyntheticStatements(ParseNode *pn, ptrdiff_t top);
|
||||
|
||||
bool emitDelete(ParseNode *pn);
|
||||
bool emitLogical(ParseNode *pn);
|
||||
|
@ -466,6 +564,9 @@ struct BytecodeEmitter
|
|||
bool emitDefaults(ParseNode *pn);
|
||||
bool emitLexicalInitialization(ParseNode *pn, JSOp globalDefOp);
|
||||
|
||||
bool pushInitialConstants(JSOp op, unsigned n);
|
||||
bool initializeBlockScopedLocalsFromStack(Handle<StaticBlockObject *> blockObj);
|
||||
|
||||
// emitSpread expects the current index (I) of the array, the array itself
|
||||
// and the iterator to be on the stack in that order (iterator on the bottom).
|
||||
// It will pop the iterator and I, then iterate over the iterator by calling
|
||||
|
@ -487,38 +588,6 @@ struct BytecodeEmitter
|
|||
bool emitClass(ParseNode *pn);
|
||||
};
|
||||
|
||||
/*
|
||||
* Emit function code using bce for the tree rooted at body.
|
||||
*/
|
||||
bool
|
||||
EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *body);
|
||||
|
||||
/*
|
||||
* Append a new source note of the given type (and therefore size) to bce's
|
||||
* notes dynamic array, updating bce->noteCount. Return the new note's index
|
||||
* within the array pointed at by bce->current->notes. Return -1 if out of
|
||||
* memory.
|
||||
*/
|
||||
int
|
||||
NewSrcNote(ExclusiveContext *cx, BytecodeEmitter *bce, SrcNoteType type);
|
||||
|
||||
int
|
||||
NewSrcNote2(ExclusiveContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptrdiff_t offset);
|
||||
|
||||
int
|
||||
NewSrcNote3(ExclusiveContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptrdiff_t offset1,
|
||||
ptrdiff_t offset2);
|
||||
|
||||
/* NB: this function can add at most one extra extended delta note. */
|
||||
bool
|
||||
AddToSrcNoteDelta(ExclusiveContext *cx, BytecodeEmitter *bce, jssrcnote *sn, ptrdiff_t delta);
|
||||
|
||||
bool
|
||||
FinishTakingSrcNotes(ExclusiveContext *cx, BytecodeEmitter *bce, uint32_t *out);
|
||||
|
||||
void
|
||||
CopySrcNotes(BytecodeEmitter *bce, jssrcnote *destination, uint32_t nsrcnotes);
|
||||
|
||||
} /* namespace frontend */
|
||||
} /* namespace js */
|
||||
|
||||
|
|
|
@ -2566,7 +2566,7 @@ JSScript::fullyInitFromEmitter(ExclusiveContext *cx, HandleScript script, Byteco
|
|||
uint32_t mainLength = bce->offset();
|
||||
uint32_t prologLength = bce->prologOffset();
|
||||
uint32_t nsrcnotes;
|
||||
if (!FinishTakingSrcNotes(cx, bce, &nsrcnotes))
|
||||
if (!bce->finishTakingSrcNotes(&nsrcnotes))
|
||||
return false;
|
||||
uint32_t natoms = bce->atomIndices->count();
|
||||
if (!partiallyInit(cx, script,
|
||||
|
@ -2591,7 +2591,7 @@ JSScript::fullyInitFromEmitter(ExclusiveContext *cx, HandleScript script, Byteco
|
|||
jsbytecode *code = ssd->data;
|
||||
PodCopy<jsbytecode>(code, bce->prolog.code.begin(), prologLength);
|
||||
PodCopy<jsbytecode>(code + prologLength, bce->code().begin(), mainLength);
|
||||
CopySrcNotes(bce, (jssrcnote *)(code + script->length()), nsrcnotes);
|
||||
bce->copySrcNotes((jssrcnote *)(code + script->length()), nsrcnotes);
|
||||
InitAtomMap(bce->atomIndices.getMap(), ssd->atoms());
|
||||
|
||||
if (!SaveSharedScriptData(cx, script, ssd, nsrcnotes))
|
||||
|
|
Загрузка…
Ссылка в новой задаче