Bug 1322314 - Disallow emitting ParseNode twice

Issue #73
[Depends on] Bug 1147371: Implement IteratorClose
This commit is contained in:
janekptacijarabaci 2018-03-20 10:27:23 +01:00 • committed by Roy Tam
commit 4d3e61136f
3 changed files with 6 additions and 31 deletions

View file

@ -6975,14 +6975,13 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
RootedFunction fun(cx, funbox->function()); RootedFunction fun(cx, funbox->function());
RootedAtom name(cx, fun->explicitName()); RootedAtom name(cx, fun->explicitName());
MOZ_ASSERT_IF(fun->isInterpretedLazy(), fun->lazyScript()); 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 * Set the |wasEmitted| flag in the funbox once the function has been
* emitted. Function definitions that need hoisting to the top of the * emitted. Function definitions that need hoisting to the top of the
* function will be seen by emitFunction in two places. * function will be seen by emitFunction in two places.
*/ */
if (funbox->wasEmitted && pn->functionIsHoisted()) { if (funbox->wasEmitted) {
// Annex B block-scoped functions are hoisted like any other // Annex B block-scoped functions are hoisted like any other
// block-scoped function to the top of their scope. When their // block-scoped function to the top of their scope. When their
// definitions are seen for the second time, we need to emit the // definitions are seen for the second time, we need to emit the
@ -7111,7 +7110,7 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
} }
if (needsProto) { if (needsProto) {
MOZ_ASSERT(pn->getOp() == JSOP_FUNWITHPROTO || pn->getOp() == JSOP_LAMBDA); MOZ_ASSERT(pn->getOp() == JSOP_LAMBDA);
pn->setOp(JSOP_FUNWITHPROTO); pn->setOp(JSOP_FUNWITHPROTO);
} }
@ -10047,15 +10046,6 @@ CGConstList::finish(ConstArray* array)
array->vector[i] = list[i]; 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. * Find the index of the given object for code generator.
* *
@ -10067,15 +10057,9 @@ CGObjectList::isAdded(ObjectBox* objbox)
unsigned unsigned
CGObjectList::add(ObjectBox* objbox) CGObjectList::add(ObjectBox* objbox)
{ {
if (isAdded(objbox)) MOZ_ASSERT(!objbox->emitLink);
return indexOf(objbox->object);
objbox->emitLink = lastbox; objbox->emitLink = lastbox;
lastbox = objbox; lastbox = objbox;
// See the comment in CGObjectList::isAdded.
if (!firstbox)
firstbox = objbox;
return length++; return length++;
} }
@ -10102,12 +10086,7 @@ CGObjectList::finish(ObjectArray* array)
MOZ_ASSERT(!*cursor); MOZ_ASSERT(!*cursor);
MOZ_ASSERT(objbox->object->isTenured()); MOZ_ASSERT(objbox->object->isTenured());
*cursor = objbox->object; *cursor = objbox->object;
} while ((objbox = objbox->emitLink) != nullptr);
ObjectBox* tmp = objbox->emitLink;
// Clear emitLink for CGObjectList::isAdded.
objbox->emitLink = nullptr;
objbox = tmp;
} while (objbox != nullptr);
MOZ_ASSERT(cursor == array->vector); MOZ_ASSERT(cursor == array->vector);
} }

View file

@ -43,12 +43,10 @@ class CGConstList {
struct CGObjectList { struct CGObjectList {
uint32_t length; /* number of emitted so far objects */ uint32_t length; /* number of emitted so far objects */
ObjectBox* firstbox; /* first emitted object */
ObjectBox* lastbox; /* last emitted object */ ObjectBox* lastbox; /* last emitted object */
CGObjectList() : length(0), firstbox(nullptr), lastbox(nullptr) {} CGObjectList() : length(0), lastbox(nullptr) {}
bool isAdded(ObjectBox* objbox);
unsigned add(ObjectBox* objbox); unsigned add(ObjectBox* objbox);
unsigned indexOf(JSObject* obj); unsigned indexOf(JSObject* obj);
void finish(ObjectArray* array); void finish(ObjectArray* array);

View file

@ -649,14 +649,12 @@ class ParseNode
MOZ_ASSERT(pn_arity == PN_CODE && getKind() == PNK_FUNCTION); MOZ_ASSERT(pn_arity == PN_CODE && getKind() == PNK_FUNCTION);
MOZ_ASSERT(isOp(JSOP_LAMBDA) || // lambda, genexpr MOZ_ASSERT(isOp(JSOP_LAMBDA) || // lambda, genexpr
isOp(JSOP_LAMBDA_ARROW) || // arrow function isOp(JSOP_LAMBDA_ARROW) || // arrow function
isOp(JSOP_FUNWITHPROTO) || // already emitted lambda with needsProto
isOp(JSOP_DEFFUN) || // non-body-level function statement isOp(JSOP_DEFFUN) || // non-body-level function statement
isOp(JSOP_NOP) || // body-level function stmt in global code isOp(JSOP_NOP) || // body-level function stmt in global code
isOp(JSOP_GETLOCAL) || // body-level function stmt in function code isOp(JSOP_GETLOCAL) || // body-level function stmt in function code
isOp(JSOP_GETARG) || // body-level function redeclaring formal isOp(JSOP_GETARG) || // body-level function redeclaring formal
isOp(JSOP_INITLEXICAL)); // block-level function stmt isOp(JSOP_INITLEXICAL)); // block-level function stmt
return !isOp(JSOP_LAMBDA) && !isOp(JSOP_LAMBDA_ARROW) && return !isOp(JSOP_LAMBDA) && !isOp(JSOP_LAMBDA_ARROW) && !isOp(JSOP_DEFFUN);
!isOp(JSOP_FUNWITHPROTO) && !isOp(JSOP_DEFFUN);
} }
/* /*