| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index a7c27c1c649153dc250bbadb3b005c5d75bcdc69..1bc1903760a25adde3a7a76c19224ca6db53e40c 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -51,6 +51,8 @@ namespace internal {
|
| // typedef Literal;
|
| // typedef ExpressionList;
|
| // typedef PropertyList;
|
| +// typedef FormalParameter;
|
| +// typedef FormalParameterList;
|
| // // For constructing objects returned by the traversing functions.
|
| // typedef Factory;
|
| // };
|
| @@ -63,6 +65,8 @@ class ParserBase : public Traits {
|
| // Shorten type names defined by Traits.
|
| typedef typename Traits::Type::Expression ExpressionT;
|
| typedef typename Traits::Type::Identifier IdentifierT;
|
| + typedef typename Traits::Type::FormalParameter FormalParameterT;
|
| + typedef typename Traits::Type::FormalParameterList FormalParameterListT;
|
| typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
|
| typedef typename Traits::Type::Literal LiteralT;
|
| typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
|
| @@ -606,6 +610,20 @@ class ParserBase : public Traits {
|
| void AddTemplateExpression(ExpressionT);
|
| ExpressionT ParseSuperExpression(bool is_new, bool* ok);
|
|
|
| + FormalParameterT ParseFormalParameter(DuplicateFinder* duplicate_finder,
|
| + Scanner::Location* eval_args_error_loc,
|
| + Scanner::Location* undefined_error_loc,
|
| + Scanner::Location* dupe_error_loc,
|
| + Scanner::Location* reserved_error_loc,
|
| + bool* ok);
|
| + FormalParameterListT ParseFormalParameterList(
|
| + Scanner::Location* eval_args_error_loc,
|
| + Scanner::Location* undefined_error_loc, Scanner::Location* dupe_error_loc,
|
| + Scanner::Location* reserved_error_loc, bool* is_rest, bool* ok);
|
| + void CheckArityRestrictions(
|
| + int param_count, FunctionLiteral::ArityRestriction arity_restriction,
|
| + int formals_start_pos, int formals_end_pos, bool* ok);
|
| +
|
| // Checks if the expression is a valid reference expression (e.g., on the
|
| // left-hand side of assignments). Although ruled out by ECMA as early errors,
|
| // we allow calls for web compatibility and rewrite them to a runtime throw.
|
| @@ -1040,20 +1058,25 @@ class PreParserExpression {
|
| };
|
|
|
|
|
| -// PreParserExpressionList doesn't actually store the expressions because
|
| -// PreParser doesn't need to.
|
| -class PreParserExpressionList {
|
| +// The pre-parser doesn't need to build lists of expressions, identifiers, or
|
| +// the like.
|
| +template <typename T>
|
| +class PreParserList {
|
| public:
|
| // These functions make list->Add(some_expression) work (and do nothing).
|
| - PreParserExpressionList() : length_(0) {}
|
| - PreParserExpressionList* operator->() { return this; }
|
| - void Add(PreParserExpression, void*) { ++length_; }
|
| + PreParserList() : length_(0) {}
|
| + PreParserList* operator->() { return this; }
|
| + void Add(T, void*) { ++length_; }
|
| int length() const { return length_; }
|
| private:
|
| int length_;
|
| };
|
|
|
|
|
| +typedef PreParserList<PreParserExpression> PreParserExpressionList;
|
| +typedef PreParserList<PreParserIdentifier> PreParserFormalParameterList;
|
| +
|
| +
|
| class PreParserStatement {
|
| public:
|
| static PreParserStatement Default() {
|
| @@ -1109,16 +1132,7 @@ class PreParserStatement {
|
| };
|
|
|
|
|
| -
|
| -// PreParserStatementList doesn't actually store the statements because
|
| -// the PreParser does not need them.
|
| -class PreParserStatementList {
|
| - public:
|
| - // These functions make list->Add(some_expression) work as no-ops.
|
| - PreParserStatementList() {}
|
| - PreParserStatementList* operator->() { return this; }
|
| - void Add(PreParserStatement, void*) {}
|
| -};
|
| +typedef PreParserList<PreParserStatement> PreParserStatementList;
|
|
|
|
|
| class PreParserFactory {
|
| @@ -1283,6 +1297,8 @@ class PreParserTraits {
|
| typedef PreParserExpression Literal;
|
| typedef PreParserExpressionList ExpressionList;
|
| typedef PreParserExpressionList PropertyList;
|
| + typedef PreParserIdentifier FormalParameter;
|
| + typedef PreParserFormalParameterList FormalParameterList;
|
| typedef PreParserStatementList StatementList;
|
|
|
| // For constructing objects returned by the traversing functions.
|
| @@ -1441,6 +1457,12 @@ class PreParserTraits {
|
| static PreParserExpressionList NullExpressionList() {
|
| return PreParserExpressionList();
|
| }
|
| + static PreParserIdentifier EmptyFormalParameter() {
|
| + return PreParserIdentifier::Default();
|
| + }
|
| + static PreParserFormalParameterList NullFormalParameterList() {
|
| + return PreParserFormalParameterList();
|
| + }
|
|
|
| // Odd-ball literal creators.
|
| static PreParserExpression GetLiteralTheHole(int position,
|
| @@ -1505,6 +1527,11 @@ class PreParserTraits {
|
| return PreParserExpressionList();
|
| }
|
|
|
| + static PreParserFormalParameterList NewFormalParameterList(int size,
|
| + Zone* zone) {
|
| + return PreParserFormalParameterList();
|
| + }
|
| +
|
| V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name,
|
| int* materialized_literal_count,
|
| int* expected_property_count, bool* ok) {
|
| @@ -3026,6 +3053,113 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
|
|
|
|
|
| template <class Traits>
|
| +typename ParserBase<Traits>::FormalParameterT
|
| +ParserBase<Traits>::ParseFormalParameter(DuplicateFinder* duplicate_finder,
|
| + Scanner::Location* eval_args_error_loc,
|
| + Scanner::Location* undefined_error_loc,
|
| + Scanner::Location* dupe_error_loc,
|
| + Scanner::Location* reserved_error_loc,
|
| + bool* ok) {
|
| + // FormalParameter[Yield,GeneratorParameter] :
|
| + // BindingElement[?Yield, ?GeneratorParameter]
|
| + bool is_strict_reserved;
|
| + IdentifierT name =
|
| + ParseIdentifierOrStrictReservedWord(&is_strict_reserved, ok);
|
| + if (!*ok) return this->EmptyFormalParameter();
|
| +
|
| + // Store locations for possible future error reports.
|
| + if (!eval_args_error_loc->IsValid() && this->IsEvalOrArguments(name)) {
|
| + *eval_args_error_loc = scanner()->location();
|
| + }
|
| + if (!undefined_error_loc->IsValid() && this->IsUndefined(name)) {
|
| + *undefined_error_loc = scanner()->location();
|
| + }
|
| + if (!reserved_error_loc->IsValid() && is_strict_reserved) {
|
| + *reserved_error_loc = scanner()->location();
|
| + }
|
| + if (!dupe_error_loc->IsValid()) {
|
| + int prev_value = scanner()->FindSymbol(duplicate_finder, 1);
|
| + if (prev_value != 0) *dupe_error_loc = scanner()->location();
|
| + }
|
| +
|
| + return name;
|
| +}
|
| +
|
| +
|
| +template <class Traits>
|
| +typename ParserBase<Traits>::FormalParameterListT
|
| +ParserBase<Traits>::ParseFormalParameterList(
|
| + Scanner::Location* eval_args_error_loc,
|
| + Scanner::Location* undefined_error_loc, Scanner::Location* dupe_error_loc,
|
| + Scanner::Location* reserved_error_loc, bool* is_rest, bool* ok) {
|
| + // FormalParameters[Yield,GeneratorParameter] :
|
| + // [empty]
|
| + // FormalParameterList[?Yield, ?GeneratorParameter]
|
| + //
|
| + // FormalParameterList[Yield,GeneratorParameter] :
|
| + // FunctionRestParameter[?Yield]
|
| + // FormalsList[?Yield, ?GeneratorParameter]
|
| + // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield]
|
| + //
|
| + // FormalsList[Yield,GeneratorParameter] :
|
| + // FormalParameter[?Yield, ?GeneratorParameter]
|
| + // FormalsList[?Yield, ?GeneratorParameter] ,
|
| + // FormalParameter[?Yield,?GeneratorParameter]
|
| +
|
| + FormalParameterListT result = this->NewFormalParameterList(4, zone_);
|
| + DuplicateFinder duplicate_finder(scanner()->unicode_cache());
|
| +
|
| + if (peek() != Token::RPAREN) {
|
| + do {
|
| + *is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS);
|
| + FormalParameterT param = ParseFormalParameter(
|
| + &duplicate_finder, eval_args_error_loc, undefined_error_loc,
|
| + dupe_error_loc, reserved_error_loc, ok);
|
| + if (!*ok) return this->NullFormalParameterList();
|
| + result->Add(param, zone());
|
| + if (result->length() > Code::kMaxArguments) {
|
| + ReportMessage("too_many_parameters");
|
| + *ok = false;
|
| + return this->NullFormalParameterList();
|
| + }
|
| + } while (!*is_rest && Check(Token::COMMA));
|
| + }
|
| +
|
| + if (is_rest && peek() == Token::COMMA) {
|
| + ReportMessageAt(scanner()->peek_location(), "param_after_rest");
|
| + *ok = false;
|
| + return this->NullFormalParameterList();
|
| + }
|
| +
|
| + return result;
|
| +}
|
| +
|
| +
|
| +template <class Traits>
|
| +void ParserBase<Traits>::CheckArityRestrictions(
|
| + int param_count, FunctionLiteral::ArityRestriction arity_restriction,
|
| + int formals_start_pos, int formals_end_pos, bool* ok) {
|
| + switch (arity_restriction) {
|
| + case FunctionLiteral::GETTER_ARITY:
|
| + if (param_count != 0) {
|
| + ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
|
| + "bad_getter_arity");
|
| + *ok = false;
|
| + }
|
| + break;
|
| + case FunctionLiteral::SETTER_ARITY:
|
| + if (param_count != 1) {
|
| + ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
|
| + "bad_setter_arity");
|
| + *ok = false;
|
| + }
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| +}
|
| +
|
| +template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
|
| ExpressionT params_ast,
|
|
|