зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1184922 - Part 0: Make it possible to emit ParseNode twice. r=shu
This commit is contained in:
Родитель
01b5b42b6e
Коммит
dd643324f9
|
@ -6674,13 +6674,14 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
RootedFunction fun(cx, funbox->function());
|
||||
RootedAtom name(cx, fun->name());
|
||||
MOZ_ASSERT_IF(fun->isInterpretedLazy(), fun->lazyScript());
|
||||
MOZ_ASSERT_IF(pn->isOp(JSOP_FUNWITHPROTO), needsProto);
|
||||
|
||||
/*
|
||||
* Set the |wasEmitted| flag in the funbox once the function has been
|
||||
* emitted. Function definitions that need hoisting to the top of the
|
||||
* function will be seen by emitFunction in two places.
|
||||
*/
|
||||
if (funbox->wasEmitted) {
|
||||
if (funbox->wasEmitted && pn->functionIsHoisted()) {
|
||||
// Annex B block-scoped functions are hoisted like any other
|
||||
// block-scoped function to the top of their scope. When their
|
||||
// definitions are seen for the second time, we need to emit the
|
||||
|
@ -6804,7 +6805,7 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
}
|
||||
|
||||
if (needsProto) {
|
||||
MOZ_ASSERT(pn->getOp() == JSOP_LAMBDA);
|
||||
MOZ_ASSERT(pn->getOp() == JSOP_FUNWITHPROTO || pn->getOp() == JSOP_LAMBDA);
|
||||
pn->setOp(JSOP_FUNWITHPROTO);
|
||||
}
|
||||
return emitIndex32(pn->getOp(), index);
|
||||
|
@ -9651,6 +9652,15 @@ CGConstList::finish(ConstArray* array)
|
|||
array->vector[i] = list[i];
|
||||
}
|
||||
|
||||
bool
|
||||
CGObjectList::isAdded(ObjectBox* objbox)
|
||||
{
|
||||
// An objbox added to CGObjectList as non-first element has non-null
|
||||
// emitLink member. The first element has null emitLink.
|
||||
// Check for firstbox to cover the first element.
|
||||
return objbox->emitLink || objbox == firstbox;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the index of the given object for code generator.
|
||||
*
|
||||
|
@ -9662,9 +9672,15 @@ CGConstList::finish(ConstArray* array)
|
|||
unsigned
|
||||
CGObjectList::add(ObjectBox* objbox)
|
||||
{
|
||||
MOZ_ASSERT(!objbox->emitLink);
|
||||
if (isAdded(objbox))
|
||||
return indexOf(objbox->object);
|
||||
|
||||
objbox->emitLink = lastbox;
|
||||
lastbox = objbox;
|
||||
|
||||
// See the comment in CGObjectList::isAdded.
|
||||
if (!firstbox)
|
||||
firstbox = objbox;
|
||||
return length++;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,10 +43,12 @@ class CGConstList {
|
|||
|
||||
struct CGObjectList {
|
||||
uint32_t length; /* number of emitted so far objects */
|
||||
ObjectBox* firstbox; /* first emitted object */
|
||||
ObjectBox* lastbox; /* last emitted object */
|
||||
|
||||
CGObjectList() : length(0), lastbox(nullptr) {}
|
||||
CGObjectList() : length(0), firstbox(nullptr), lastbox(nullptr) {}
|
||||
|
||||
bool isAdded(ObjectBox* objbox);
|
||||
unsigned add(ObjectBox* objbox);
|
||||
unsigned indexOf(JSObject* obj);
|
||||
void finish(ObjectArray* array);
|
||||
|
|
|
@ -635,12 +635,14 @@ class ParseNode
|
|||
MOZ_ASSERT(pn_arity == PN_CODE && getKind() == PNK_FUNCTION);
|
||||
MOZ_ASSERT(isOp(JSOP_LAMBDA) || // lambda, genexpr
|
||||
isOp(JSOP_LAMBDA_ARROW) || // arrow function
|
||||
isOp(JSOP_FUNWITHPROTO) || // already emitted lambda with needsProto
|
||||
isOp(JSOP_DEFFUN) || // non-body-level function statement
|
||||
isOp(JSOP_NOP) || // body-level function stmt in global code
|
||||
isOp(JSOP_GETLOCAL) || // body-level function stmt in function code
|
||||
isOp(JSOP_GETARG) || // body-level function redeclaring formal
|
||||
isOp(JSOP_INITLEXICAL)); // block-level function stmt
|
||||
return !isOp(JSOP_LAMBDA) && !isOp(JSOP_LAMBDA_ARROW) && !isOp(JSOP_DEFFUN);
|
||||
return !isOp(JSOP_LAMBDA) && !isOp(JSOP_LAMBDA_ARROW) &&
|
||||
!isOp(JSOP_FUNWITHPROTO) && !isOp(JSOP_DEFFUN);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче