Bug 854137 - Don't hold pointers to yield nodes in the parse tree (second attempt). r=jorendorff.

--HG--
extra : rebase_source : 1fc784f2b123f1606b8f612adff6725555dbbb34
This commit is contained in:
Nicholas Nethercote 2013-03-25 15:52:09 -07:00
parent c2cba1e7b9
commit 6104956560
4 changed files with 51 additions and 16 deletions

View File

@ -46,7 +46,7 @@ ParseContext<ParseHandler>::ParseContext(Parser<ParseHandler> *prs, SharedContex
decls_(prs->context),
args_(prs->context),
vars_(prs->context),
yieldNode(ParseHandler::null()),
yieldOffset(0),
parserPC(&prs->pc),
lexdeps(prs->context),
parent(prs->pc),

View File

@ -332,12 +332,9 @@ ParseContext<ParseHandler>::generateFunctionBindings(JSContext *cx, InternalHand
template <typename ParseHandler>
bool
Parser<ParseHandler>::report(ParseReportKind kind, bool strict, Node pn, unsigned errorNumber, ...)
Parser<ParseHandler>::reportHelper(ParseReportKind kind, bool strict, uint32_t offset,
unsigned errorNumber, va_list args)
{
uint32_t offset = (pn ? handler.getPosition(pn) : tokenStream.currentToken().pos).begin;
va_list args;
va_start(args, errorNumber);
bool result = false;
switch (kind) {
case ParseError:
@ -354,6 +351,30 @@ Parser<ParseHandler>::report(ParseReportKind kind, bool strict, Node pn, unsigne
result = tokenStream.reportStrictModeErrorNumberVA(offset, strict, errorNumber, args);
break;
}
return result;
}
template <typename ParseHandler>
bool
Parser<ParseHandler>::report(ParseReportKind kind, bool strict, Node pn, unsigned errorNumber, ...)
{
uint32_t offset = (pn ? handler.getPosition(pn) : tokenStream.currentToken().pos).begin;
va_list args;
va_start(args, errorNumber);
bool result = reportHelper(kind, strict, offset, errorNumber, args);
va_end(args);
return result;
}
template <typename ParseHandler>
bool
Parser<ParseHandler>::reportWithOffset(ParseReportKind kind, bool strict, uint32_t offset,
unsigned errorNumber, ...)
{
va_list args;
va_start(args, errorNumber);
bool result = reportHelper(kind, strict, offset, errorNumber, args);
va_end(args);
return result;
}
@ -2882,7 +2903,7 @@ Parser<ParseHandler>::returnOrYield(bool useAssignExpr)
pc->sc->asFunctionBox()->setIsGenerator();
} else {
pc->yieldCount++;
pc->yieldNode = pn;
pc->yieldOffset = handler.getPosition(pn).begin;
}
}
#endif
@ -5215,7 +5236,7 @@ class GenexpGuard
ParseContext<ParseHandler> *pc = parser->pc;
if (pc->parenDepth == 0) {
pc->yieldCount = 0;
pc->yieldNode = ParseHandler::null();
pc->yieldOffset = 0;
}
startYieldCount = pc->yieldCount;
pc->parenDepth++;
@ -5246,10 +5267,12 @@ GenexpGuard<ParseHandler>::checkValidBody(Node pn, unsigned err)
{
ParseContext<ParseHandler> *pc = parser->pc;
if (pc->yieldCount > startYieldCount) {
Node errorNode = pc->yieldNode;
if (!errorNode)
errorNode = pn;
parser->report(ParseError, false, errorNode, err, js_yield_str);
uint32_t offset = pc->yieldOffset
? pc->yieldOffset
: (pn ? parser->handler.getPosition(pn)
: parser->tokenStream.currentToken().pos).begin;
parser->reportWithOffset(ParseError, false, offset, err, js_yield_str);
return false;
}

View File

@ -155,10 +155,10 @@ struct ParseContext /* tree context for semantic checks */
bool generateFunctionBindings(JSContext *cx, InternalHandle<Bindings*> bindings) const;
public:
Node yieldNode; /* parse node for a yield expression that might
be an error if we turn out to be inside a
generator expression */
uint32_t yieldOffset; /* offset of a yield expression that might
be an error if we turn out to be inside
a generator expression. Zero means
there isn't one. */
private:
ParseContext **parserPC; /* this points to the Parser's active pc
and holds either |this| or one of
@ -296,7 +296,13 @@ struct Parser : private AutoGCRooter, public StrictModeGetter
/* State specific to the kind of parse being performed. */
ParseHandler handler;
private:
bool reportHelper(ParseReportKind kind, bool strict, uint32_t offset,
unsigned errorNumber, va_list args);
public:
bool report(ParseReportKind kind, bool strict, Node pn, unsigned errorNumber, ...);
bool reportWithOffset(ParseReportKind kind, bool strict, uint32_t offset, unsigned errorNumber,
...);
Parser(JSContext *cx, const CompileOptions &options,
const jschar *chars, size_t length, bool foldConstants);

View File

@ -0,0 +1,6 @@
// Don't assert.
try {
eval("function x(y = {\
x: (7) ? 0 : yield(0)\
}");
} catch (e) {}