From e3cf10e22bc5eeabfe08cef2904ee1a9bf55da92 Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Mon, 9 Feb 2015 16:07:45 -0800 Subject: [PATCH] Bug 1130811 - Actually use PNK_CATCHLIST so that PNK_CATCH isn't used for multiple arities and situations in practice. r=shu --HG-- extra : rebase_source : 123c0e24385b70984557964e73ec9bc30050fe24 --- js/src/frontend/BytecodeEmitter.cpp | 9 ++++++--- js/src/frontend/FullParseHandler.h | 3 +++ js/src/frontend/ParseNode.h | 7 ++++--- js/src/frontend/Parser.cpp | 2 +- js/src/frontend/SyntaxParseHandler.h | 4 ++++ js/src/jsreflect.cpp | 6 +++--- 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 817376ec8c23..4533ef90b7c8 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -4575,7 +4575,10 @@ EmitTry(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn) ptrdiff_t tryEnd = bce->offset(); // If this try has a catch block, emit it. - if (ParseNode *pn2 = pn->pn_kid2) { + ParseNode *catchList = pn->pn_kid2; + if (catchList) { + MOZ_ASSERT(catchList->isKind(PNK_CATCHLIST)); + // The emitted code for a catch block looks like: // // [pushblockscope] only if any local aliased @@ -4601,7 +4604,7 @@ EmitTry(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn) // code if appropriate, and is also used for the catch-all trynote for // capturing exceptions thrown from catch{} blocks. // - for (ParseNode *pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) { + for (ParseNode *pn3 = catchList->pn_head; pn3; pn3 = pn3->pn_next) { MOZ_ASSERT(bce->stackDepth == depth); // Emit the lexical scope and catch body. @@ -4676,7 +4679,7 @@ EmitTry(ExclusiveContext *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 && !bce->tryNoteList.append(JSTRY_CATCH, depth, tryStart, tryEnd)) + if (catchList && !bce->tryNoteList.append(JSTRY_CATCH, depth, tryStart, tryEnd)) return false; // If we've got a finally, mark try+catch region with additional diff --git a/js/src/frontend/FullParseHandler.h b/js/src/frontend/FullParseHandler.h index 2c9193e8734d..9c706369f876 100644 --- a/js/src/frontend/FullParseHandler.h +++ b/js/src/frontend/FullParseHandler.h @@ -600,6 +600,9 @@ class FullParseHandler return new_(kind, op, kid); } + ParseNode *newCatchList() { + return new_(PNK_CATCHLIST, JSOP_NOP, pos()); + } ParseNode *newCommaExpressionList(ParseNode *kid) { return newList(PNK_COMMA, kid, JSOP_NOP); diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h index 3ad2364fb7c2..dd11e58557b1 100644 --- a/js/src/frontend/ParseNode.h +++ b/js/src/frontend/ParseNode.h @@ -286,10 +286,11 @@ enum ParseNodeKind * pn_kid3: update expr after second ';' or nullptr * PNK_THROW unary pn_op: JSOP_THROW, pn_kid: exception * PNK_TRY ternary pn_kid1: try block - * pn_kid2: null or PNK_CATCHLIST list of - * PNK_LEXICALSCOPE nodes, each with pn_expr pointing - * to a PNK_CATCH node + * pn_kid2: null or PNK_CATCHLIST list * pn_kid3: null or finally block + * PNK_CATCHLIST list pn_head: list of PNK_LEXICALSCOPE nodes, one per + * catch-block, each with pn_expr pointing + * to a PNK_CATCH node * PNK_CATCH ternary pn_kid1: PNK_NAME, PNK_ARRAY, or PNK_OBJECT catch var node * (PNK_ARRAY or PNK_OBJECT if destructuring) * pn_kid2: null or the catch guard expression diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 3018d52f666e..9a6f8a8180da 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -5629,7 +5629,7 @@ Parser::tryStatement() if (!tokenStream.getToken(&tt)) return null(); if (tt == TOK_CATCH) { - catchList = handler.newList(PNK_CATCH); + catchList = handler.newCatchList(); if (!catchList) return null(); diff --git a/js/src/frontend/SyntaxParseHandler.h b/js/src/frontend/SyntaxParseHandler.h index d020aa403747..75914b7cef73 100644 --- a/js/src/frontend/SyntaxParseHandler.h +++ b/js/src/frontend/SyntaxParseHandler.h @@ -267,6 +267,10 @@ class SyntaxParseHandler return NodeGeneric; } + Node newCatchList() { + return newList(PNK_CATCHLIST, JSOP_NOP); + } + Node newCommaExpressionList(Node kid) { return NodeUnparenthesizedCommaExpr; } diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp index e183a5375015..ef57b9fae8e3 100644 --- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -2302,11 +2302,11 @@ ASTSerializer::tryStatement(ParseNode *pn, MutableHandleValue dst) NodeVector guarded(cx); RootedValue unguarded(cx, NullValue()); - if (pn->pn_kid2) { - if (!guarded.reserve(pn->pn_kid2->pn_count)) + if (ParseNode *catchList = pn->pn_kid2) { + if (!guarded.reserve(catchList->pn_count)) return false; - for (ParseNode *next = pn->pn_kid2->pn_head; next; next = next->pn_next) { + for (ParseNode *next = catchList->pn_head; next; next = next->pn_next) { RootedValue clause(cx); bool isGuarded; if (!catchClause(next->pn_expr, &isGuarded, &clause))