From: marja@chromium.org Date: Wed, 19 Mar 2014 13:58:15 +0000 (+0000) Subject: Revert "Move ParseUnaryExpression into ParserBase and add tests." X-Git-Tag: upstream/4.7.83~10164 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c04dd3fb7ff754cae2261d4cdb2cbb139427c7d4;p=platform%2Fupstream%2Fv8.git Revert "Move ParseUnaryExpression into ParserBase and add tests." This reverts revision 20077. Reason: build fail on some compilers. BUG= TBR=marja@chromium.org,rossberg@chromium.org Review URL: https://codereview.chromium.org/203413009 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20078 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/parser.cc b/src/parser.cc index 0d1ba00..01bd853 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -433,12 +433,6 @@ bool ParserTraits::IsThisProperty(Expression* expression) { } -bool ParserTraits::IsIdentifier(Expression* expression) { - VariableProxy* operand = expression->AsVariableProxy(); - return operand != NULL && !operand->is_this(); -} - - void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, Expression* right) { ASSERT(left != NULL); @@ -531,52 +525,6 @@ bool ParserTraits::ShortcutNumericLiteralBinaryExpression( } -Expression* ParserTraits::BuildUnaryExpression( - Expression* expression, Token::Value op, int pos, - AstNodeFactory* factory) { - ASSERT(expression != NULL); - if (expression->AsLiteral() != NULL) { - Handle literal = expression->AsLiteral()->value(); - if (op == Token::NOT) { - // Convert the literal to a boolean condition and negate it. - bool condition = literal->BooleanValue(); - Handle result = - parser_->isolate()->factory()->ToBoolean(!condition); - return factory->NewLiteral(result, pos); - } else if (literal->IsNumber()) { - // Compute some expressions involving only number literals. - double value = literal->Number(); - switch (op) { - case Token::ADD: - return expression; - case Token::SUB: - return factory->NewNumberLiteral(-value, pos); - case Token::BIT_NOT: - return factory->NewNumberLiteral(~DoubleToInt32(value), pos); - default: - break; - } - } - } - // Desugar '+foo' => 'foo*1' - if (op == Token::ADD) { - return factory->NewBinaryOperation( - Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos); - } - // The same idea for '-foo' => 'foo*(-1)'. - if (op == Token::SUB) { - return factory->NewBinaryOperation( - Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos); - } - // ...and one more time for '~foo' => 'foo^(~0)'. - if (op == Token::BIT_NOT) { - return factory->NewBinaryOperation( - Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); - } - return factory->NewUnaryOperation(op, expression, pos); -} - - void ParserTraits::ReportMessageAt(Scanner::Location source_location, const char* message, Vector args, @@ -740,8 +688,8 @@ FunctionLiteral* ParserTraits::ParseFunctionLiteral( } -Expression* ParserTraits::ParsePostfixExpression(bool* ok) { - return parser_->ParsePostfixExpression(ok); +Expression* ParserTraits::ParseUnaryExpression(bool* ok) { + return parser_->ParseUnaryExpression(ok); } @@ -3042,6 +2990,111 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { } +Expression* Parser::ParseUnaryExpression(bool* ok) { + // UnaryExpression :: + // PostfixExpression + // 'delete' UnaryExpression + // 'void' UnaryExpression + // 'typeof' UnaryExpression + // '++' UnaryExpression + // '--' UnaryExpression + // '+' UnaryExpression + // '-' UnaryExpression + // '~' UnaryExpression + // '!' UnaryExpression + + Token::Value op = peek(); + if (Token::IsUnaryOp(op)) { + op = Next(); + int pos = position(); + Expression* expression = ParseUnaryExpression(CHECK_OK); + + if (expression != NULL && (expression->AsLiteral() != NULL)) { + Handle literal = expression->AsLiteral()->value(); + if (op == Token::NOT) { + // Convert the literal to a boolean condition and negate it. + bool condition = literal->BooleanValue(); + Handle result = isolate()->factory()->ToBoolean(!condition); + return factory()->NewLiteral(result, pos); + } else if (literal->IsNumber()) { + // Compute some expressions involving only number literals. + double value = literal->Number(); + switch (op) { + case Token::ADD: + return expression; + case Token::SUB: + return factory()->NewNumberLiteral(-value, pos); + case Token::BIT_NOT: + return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); + default: + break; + } + } + } + + // "delete identifier" is a syntax error in strict mode. + if (op == Token::DELETE && strict_mode() == STRICT) { + VariableProxy* operand = expression->AsVariableProxy(); + if (operand != NULL && !operand->is_this()) { + ReportMessage("strict_delete", Vector::empty()); + *ok = false; + return NULL; + } + } + + // Desugar '+foo' into 'foo*1', this enables the collection of type feedback + // without any special stub and the multiplication is removed later in + // Crankshaft's canonicalization pass. + if (op == Token::ADD) { + return factory()->NewBinaryOperation(Token::MUL, + expression, + factory()->NewNumberLiteral(1, pos), + pos); + } + // The same idea for '-foo' => 'foo*(-1)'. + if (op == Token::SUB) { + return factory()->NewBinaryOperation(Token::MUL, + expression, + factory()->NewNumberLiteral(-1, pos), + pos); + } + // ...and one more time for '~foo' => 'foo^(~0)'. + if (op == Token::BIT_NOT) { + return factory()->NewBinaryOperation(Token::BIT_XOR, + expression, + factory()->NewNumberLiteral(~0, pos), + pos); + } + + return factory()->NewUnaryOperation(op, expression, pos); + + } else if (Token::IsCountOp(op)) { + op = Next(); + Scanner::Location lhs_location = scanner()->peek_location(); + Expression* expression = ParseUnaryExpression(CHECK_OK); + if (expression == NULL || !expression->IsValidLeftHandSide()) { + ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true); + *ok = false; + return NULL; + } + + if (strict_mode() == STRICT) { + // Prefix expression operand in strict mode may not be eval or arguments. + CheckStrictModeLValue(expression, CHECK_OK); + } + MarkExpressionAsLValue(expression); + + return factory()->NewCountOperation(op, + true /* prefix */, + expression, + position()); + + } else { + return ParsePostfixExpression(ok); + } +} + + Expression* Parser::ParsePostfixExpression(bool* ok) { // PostfixExpression :: // LeftHandSideExpression ('++' | '--')? diff --git a/src/parser.h b/src/parser.h index 3d2f032..072658e 100644 --- a/src/parser.h +++ b/src/parser.h @@ -460,8 +460,6 @@ class ParserTraits { // Returns true if the expression is of type "this.foo". static bool IsThisProperty(Expression* expression); - static bool IsIdentifier(Expression* expression); - static bool IsBoilerplateProperty(ObjectLiteral::Property* property) { return ObjectLiteral::IsBoilerplateProperty(property); } @@ -511,21 +509,6 @@ class ParserTraits { Expression** x, Expression* y, Token::Value op, int pos, AstNodeFactory* factory); - // Rewrites the following types of unary expressions: - // not -> true / false - // + -> - // - -> - // ! -> true / false - // The following rewriting rules enable the collection of type feedback - // without any special stub and the multiplication is removed later in - // Crankshaft's canonicalization pass. - // + foo -> foo * 1 - // - foo -> foo * (-1) - // ~ foo -> foo ^(~0) - Expression* BuildUnaryExpression( - Expression* expression, Token::Value op, int pos, - AstNodeFactory* factory); - // Reporting errors. void ReportMessageAt(Scanner::Location source_location, const char* message, @@ -589,7 +572,7 @@ class ParserTraits { int function_token_position, FunctionLiteral::FunctionType type, bool* ok); - Expression* ParsePostfixExpression(bool* ok); + Expression* ParseUnaryExpression(bool* ok); private: Parser* parser_; diff --git a/src/preparser.cc b/src/preparser.cc index 398f327..8a621b4 100644 --- a/src/preparser.cc +++ b/src/preparser.cc @@ -146,8 +146,8 @@ PreParserExpression PreParserTraits::ParseFunctionLiteral( } -PreParserExpression PreParserTraits::ParsePostfixExpression(bool* ok) { - return pre_parser_->ParsePostfixExpression(ok); +PreParserExpression PreParserTraits::ParseUnaryExpression(bool* ok) { + return pre_parser_->ParseUnaryExpression(ok); } @@ -842,6 +842,37 @@ PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { #undef DUMMY +PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) { + // UnaryExpression :: + // PostfixExpression + // 'delete' UnaryExpression + // 'void' UnaryExpression + // 'typeof' UnaryExpression + // '++' UnaryExpression + // '--' UnaryExpression + // '+' UnaryExpression + // '-' UnaryExpression + // '~' UnaryExpression + // '!' UnaryExpression + + Token::Value op = peek(); + if (Token::IsUnaryOp(op)) { + op = Next(); + ParseUnaryExpression(ok); + return Expression::Default(); + } else if (Token::IsCountOp(op)) { + op = Next(); + Expression expression = ParseUnaryExpression(CHECK_OK); + if (strict_mode() == STRICT) { + CheckStrictModeLValue(expression, CHECK_OK); + } + return Expression::Default(); + } else { + return ParsePostfixExpression(ok); + } +} + + PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { // PostfixExpression :: // LeftHandSideExpression ('++' | '--')? diff --git a/src/preparser.h b/src/preparser.h index 7048c16..a060c03 100644 --- a/src/preparser.h +++ b/src/preparser.h @@ -394,7 +394,6 @@ class ParserBase : public Traits { ExpressionT ParseYieldExpression(bool* ok); ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); - ExpressionT ParseUnaryExpression(bool* ok); // Used to detect duplicates in object literals. Each of the values // kGetterProperty, kSetterProperty and kValueProperty represents @@ -743,13 +742,6 @@ class PreParserFactory { int pos) { return PreParserExpression::Default(); } - - PreParserExpression NewCountOperation(Token::Value op, - bool is_prefix, - PreParserExpression expression, - int pos) { - return PreParserExpression::Default(); - } }; @@ -802,10 +794,6 @@ class PreParserTraits { return expression.IsThisProperty(); } - static bool IsIdentifier(PreParserExpression expression) { - return expression.IsIdentifier(); - } - static bool IsBoilerplateProperty(PreParserExpression property) { // PreParser doesn't count boilerplate properties. return false; @@ -853,12 +841,6 @@ class PreParserTraits { return false; } - PreParserExpression BuildUnaryExpression(PreParserExpression expression, - Token::Value op, int pos, - PreParserFactory* factory) { - return PreParserExpression::Default(); - } - // Reporting errors. void ReportMessageAt(Scanner::Location location, const char* message, @@ -940,7 +922,7 @@ class PreParserTraits { int function_token_position, FunctionLiteral::FunctionType type, bool* ok); - PreParserExpression ParsePostfixExpression(bool* ok); + PreParserExpression ParseUnaryExpression(bool* ok); private: PreParser* pre_parser_; @@ -1104,6 +1086,7 @@ class PreParser : public ParserBase { Statement ParseTryStatement(bool* ok); Statement ParseDebuggerStatement(bool* ok); Expression ParseConditionalExpression(bool accept_IN, bool* ok); + Expression ParseUnaryExpression(bool* ok); Expression ParsePostfixExpression(bool* ok); Expression ParseLeftHandSideExpression(bool* ok); Expression ParseMemberExpression(bool* ok); @@ -1795,64 +1778,6 @@ ParserBase::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { } -template -typename ParserBase::ExpressionT -ParserBase::ParseUnaryExpression(bool* ok) { - // UnaryExpression :: - // PostfixExpression - // 'delete' UnaryExpression - // 'void' UnaryExpression - // 'typeof' UnaryExpression - // '++' UnaryExpression - // '--' UnaryExpression - // '+' UnaryExpression - // '-' UnaryExpression - // '~' UnaryExpression - // '!' UnaryExpression - - Token::Value op = peek(); - if (Token::IsUnaryOp(op)) { - op = Next(); - int pos = position(); - ExpressionT expression = ParseUnaryExpression(CHECK_OK); - - // "delete identifier" is a syntax error in strict mode. - if (op == Token::DELETE && strict_mode() == STRICT && - this->IsIdentifier(expression)) { - ReportMessage("strict_delete", Vector::empty()); - *ok = false; - return this->EmptyExpression(); - } - - // Allow Traits do rewrite the expression. - return BuildUnaryExpression(expression, op, pos, factory()); - } else if (Token::IsCountOp(op)) { - op = Next(); - Scanner::Location lhs_location = scanner()->peek_location(); - ExpressionT expression = ParseUnaryExpression(CHECK_OK); - if (!this->IsValidLeftHandSide(expression)) { - ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true); - *ok = false; - return this->EmptyExpression(); - } - - if (strict_mode() == STRICT) { - // Prefix expression operand in strict mode may not be eval or arguments. - CheckStrictModeLValue(expression, CHECK_OK); - } - MarkExpressionAsLValue(expression); - - return factory()->NewCountOperation(op, - true /* prefix */, - expression, - position()); - - } else { - return this->ParsePostfixExpression(ok); - } -} - - #undef CHECK_OK #undef CHECK_OK_CUSTOM diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index c88b2dc..5a2ee13 100644 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -2472,57 +2472,3 @@ TEST(TooManyArguments) { static const ParserFlag empty_flags[] = {kAllowLazy}; RunParserSyncTest(context_data, statement_data, kError, empty_flags, 1); } - - -TEST(StrictDelete) { - // "delete " is not allowed in strict mode. - const char* strict_context_data[][2] = { - {"\"use strict\"; ", ""}, - { NULL, NULL } - }; - - const char* sloppy_context_data[][2] = { - {"", ""}, - { NULL, NULL } - }; - - // These are errors in the strict mode. - const char* sloppy_statement_data[] = { - "delete foo;", - "delete foo + 1;", - "delete (foo);", - "delete eval;", - "delete interface;", - NULL - }; - - // These are always OK - const char* good_statement_data[] = { - "delete this;", - "delete 1;", - "delete 1 + 2;", - "delete foo();", - "delete foo.bar;", - "delete foo[bar];", - "delete foo--;", - "delete --foo;", - "delete new foo();", - "delete new foo(bar);", - NULL - }; - - // These are always errors - const char* bad_statement_data[] = { - "delete if;", - NULL - }; - - RunParserSyncTest(strict_context_data, sloppy_statement_data, kError); - RunParserSyncTest(sloppy_context_data, sloppy_statement_data, kSuccess); - - RunParserSyncTest(strict_context_data, good_statement_data, kSuccess); - RunParserSyncTest(sloppy_context_data, good_statement_data, kSuccess); - - RunParserSyncTest(strict_context_data, bad_statement_data, kError); - RunParserSyncTest(sloppy_context_data, bad_statement_data, kError); -}