From 8ca51dad9f04b1d56743ea2c14d26c2853665d5f Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Sat, 21 Mar 2015 12:28:22 -0700 Subject: [PATCH] Bug 1146033 - Fix Reflect.parse default parameters (r=Waldo) --- js/src/jsreflect.cpp | 16 +++++++++++++++- js/src/tests/js1_8_5/extensions/reflect-parse.js | 4 ++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp index dea877a234ce..a441c0ee7b1a 100644 --- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -3498,6 +3498,10 @@ ASTSerializer::functionArgs(ParseNode* pn, ParseNode* pnargs, ParseNode* pndestr ParseNode* arg = pnargs ? pnargs->pn_head : nullptr; ParseNode* destruct = pndestruct ? pndestruct->pn_head : nullptr; RootedValue node(cx); + bool defaultsNull = true; + MOZ_ASSERT(defaults.empty(), + "must be initially empty for it to be proper to clear this " + "when there are no defaults"); /* * Arguments are found in potentially two different places: 1) the @@ -3509,8 +3513,11 @@ ASTSerializer::functionArgs(ParseNode* pn, ParseNode* pnargs, ParseNode* pndestr */ while ((arg && arg != pnbody) || destruct) { if (destruct && destruct->pn_right->frameSlot() == i) { - if (!pattern(destruct->pn_left, &node) || !args.append(node)) + if (!pattern(destruct->pn_left, &node) || + !args.append(node) || !defaults.append(NullValue())) + { return false; + } destruct = destruct->pn_next; } else if (arg && arg != pnbody) { /* @@ -3533,10 +3540,14 @@ ASTSerializer::functionArgs(ParseNode* pn, ParseNode* pnargs, ParseNode* pndestr else if (!args.append(node)) return false; if (arg->pn_dflags & PND_DEFAULT) { + defaultsNull = false; ParseNode* expr = arg->expr(); RootedValue def(cx); if (!expression(expr, &def) || !defaults.append(def)) return false; + } else { + if (!defaults.append(NullValue())) + return false; } arg = arg->pn_next; } else { @@ -3546,6 +3557,9 @@ ASTSerializer::functionArgs(ParseNode* pn, ParseNode* pnargs, ParseNode* pndestr } MOZ_ASSERT(!rest.isUndefined()); + if (defaultsNull) + defaults.clear(); + return true; } diff --git a/js/src/tests/js1_8_5/extensions/reflect-parse.js b/js/src/tests/js1_8_5/extensions/reflect-parse.js index 50b160f33e5f..cfc15d2237dc 100644 --- a/js/src/tests/js1_8_5/extensions/reflect-parse.js +++ b/js/src/tests/js1_8_5/extensions/reflect-parse.js @@ -252,9 +252,9 @@ assertDecl("function foo(...rest) { }", funDecl(ident("foo"), [], blockStmt([]), [], ident("rest"))); assertDecl("function foo(a=4) { }", funDecl(ident("foo"), [ident("a")], blockStmt([]), [lit(4)])); -assertDecl("function foo(a, b=4) { }", funDecl(ident("foo"), [ident("a"), ident("b")], blockStmt([]), [lit(4)])); +assertDecl("function foo(a, b=4) { }", funDecl(ident("foo"), [ident("a"), ident("b")], blockStmt([]), [null, lit(4)])); assertDecl("function foo(a, b=4, ...rest) { }", - funDecl(ident("foo"), [ident("a"), ident("b")], blockStmt([]), [lit(4)], ident("rest"))); + funDecl(ident("foo"), [ident("a"), ident("b")], blockStmt([]), [null, lit(4), null], ident("rest"))); assertDecl("function foo(a=(function () {})) { function a() {} }", funDecl(ident("foo"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))]), [funExpr(null, [], blockStmt([]))]));