| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
| 6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 } | 110 } |
| 111 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } | 111 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } |
| 112 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } | 112 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } |
| 113 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } | 113 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } |
| 114 bool allow_harmony_computed_property_names() const { | 114 bool allow_harmony_computed_property_names() const { |
| 115 return allow_harmony_computed_property_names_; | 115 return allow_harmony_computed_property_names_; |
| 116 } | 116 } |
| 117 bool allow_harmony_rest_params() const { | 117 bool allow_harmony_rest_params() const { |
| 118 return allow_harmony_rest_params_; | 118 return allow_harmony_rest_params_; |
| 119 } | 119 } |
| 120 | 120 bool allow_harmony_exponentiation() const { |
| 121 return scanner()->HarmonyExponentiation(); |
| 122 } |
| 121 bool allow_strong_mode() const { return allow_strong_mode_; } | 123 bool allow_strong_mode() const { return allow_strong_mode_; } |
| 122 | 124 |
| 123 // Setters that determine whether certain syntactical constructs are | 125 // Setters that determine whether certain syntactical constructs are |
| 124 // allowed to be parsed by this instance of the parser. | 126 // allowed to be parsed by this instance of the parser. |
| 125 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 127 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
| 126 void set_allow_natives(bool allow) { allow_natives_ = allow; } | 128 void set_allow_natives(bool allow) { allow_natives_ = allow; } |
| 127 void set_allow_harmony_arrow_functions(bool allow) { | 129 void set_allow_harmony_arrow_functions(bool allow) { |
| 128 allow_harmony_arrow_functions_ = allow; | 130 allow_harmony_arrow_functions_ = allow; |
| 129 } | 131 } |
| 130 void set_allow_harmony_modules(bool allow) { | 132 void set_allow_harmony_modules(bool allow) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 150 } | 152 } |
| 151 void set_allow_harmony_unicode(bool allow) { | 153 void set_allow_harmony_unicode(bool allow) { |
| 152 scanner()->SetHarmonyUnicode(allow); | 154 scanner()->SetHarmonyUnicode(allow); |
| 153 } | 155 } |
| 154 void set_allow_harmony_computed_property_names(bool allow) { | 156 void set_allow_harmony_computed_property_names(bool allow) { |
| 155 allow_harmony_computed_property_names_ = allow; | 157 allow_harmony_computed_property_names_ = allow; |
| 156 } | 158 } |
| 157 void set_allow_harmony_rest_params(bool allow) { | 159 void set_allow_harmony_rest_params(bool allow) { |
| 158 allow_harmony_rest_params_ = allow; | 160 allow_harmony_rest_params_ = allow; |
| 159 } | 161 } |
| 162 void set_allow_harmony_exponentiation(bool allow) { |
| 163 scanner()->SetHarmonyExponentiation(allow); |
| 164 } |
| 160 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } | 165 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } |
| 161 | 166 |
| 162 protected: | 167 protected: |
| 163 enum AllowEvalOrArgumentsAsIdentifier { | 168 enum AllowEvalOrArgumentsAsIdentifier { |
| 164 kAllowEvalOrArguments, | 169 kAllowEvalOrArguments, |
| 165 kDontAllowEvalOrArguments | 170 kDontAllowEvalOrArguments |
| 166 }; | 171 }; |
| 167 | 172 |
| 168 enum Mode { | 173 enum Mode { |
| 169 PARSE_LAZILY, | 174 PARSE_LAZILY, |
| (...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1165 PreParserExpression NewCall(PreParserExpression expression, | 1170 PreParserExpression NewCall(PreParserExpression expression, |
| 1166 PreParserExpressionList arguments, | 1171 PreParserExpressionList arguments, |
| 1167 int pos) { | 1172 int pos) { |
| 1168 return PreParserExpression::Call(); | 1173 return PreParserExpression::Call(); |
| 1169 } | 1174 } |
| 1170 PreParserExpression NewCallNew(PreParserExpression expression, | 1175 PreParserExpression NewCallNew(PreParserExpression expression, |
| 1171 PreParserExpressionList arguments, | 1176 PreParserExpressionList arguments, |
| 1172 int pos) { | 1177 int pos) { |
| 1173 return PreParserExpression::Default(); | 1178 return PreParserExpression::Default(); |
| 1174 } | 1179 } |
| 1180 PreParserExpression NewCallRuntime(const AstRawString* name, |
| 1181 const Runtime::Function* func, |
| 1182 PreParserExpressionList arguments, |
| 1183 int pos) { |
| 1184 return PreParserExpression::Call(); |
| 1185 } |
| 1175 PreParserStatement NewReturnStatement(PreParserExpression expression, | 1186 PreParserStatement NewReturnStatement(PreParserExpression expression, |
| 1176 int pos) { | 1187 int pos) { |
| 1177 return PreParserStatement::Default(); | 1188 return PreParserStatement::Default(); |
| 1178 } | 1189 } |
| 1179 PreParserExpression NewFunctionLiteral( | 1190 PreParserExpression NewFunctionLiteral( |
| 1180 PreParserIdentifier name, AstValueFactory* ast_value_factory, | 1191 PreParserIdentifier name, AstValueFactory* ast_value_factory, |
| 1181 Scope* scope, PreParserStatementList body, int materialized_literal_count, | 1192 Scope* scope, PreParserStatementList body, int materialized_literal_count, |
| 1182 int expected_property_count, int handler_count, int parameter_count, | 1193 int expected_property_count, int handler_count, int parameter_count, |
| 1183 FunctionLiteral::ParameterFlag has_duplicate_parameters, | 1194 FunctionLiteral::ParameterFlag has_duplicate_parameters, |
| 1184 FunctionLiteral::FunctionType function_type, | 1195 FunctionLiteral::FunctionType function_type, |
| (...skipping 1148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2333 ExpressionT expression = | 2344 ExpressionT expression = |
| 2334 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2345 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
| 2335 | 2346 |
| 2336 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2347 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
| 2337 checkpoint.Restore(); | 2348 checkpoint.Restore(); |
| 2338 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | 2349 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, |
| 2339 expression, CHECK_OK); | 2350 expression, CHECK_OK); |
| 2340 return expression; | 2351 return expression; |
| 2341 } | 2352 } |
| 2342 | 2353 |
| 2354 bool desugar_exponentiation = false; |
| 2343 if (!Token::IsAssignmentOp(peek())) { | 2355 if (!Token::IsAssignmentOp(peek())) { |
| 2344 if (fni_ != NULL) fni_->Leave(); | 2356 if (fni_ != NULL) fni_->Leave(); |
| 2345 // Parsed conditional expression only (no assignment). | 2357 // Parsed conditional expression only (no assignment). |
| 2346 return expression; | 2358 return expression; |
| 2347 } | 2359 } |
| 2348 | 2360 |
| 2349 expression = this->CheckAndRewriteReferenceExpression( | 2361 expression = this->CheckAndRewriteReferenceExpression( |
| 2350 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2362 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
| 2351 expression = this->MarkExpressionAsAssigned(expression); | 2363 expression = this->MarkExpressionAsAssigned(expression); |
| 2352 | 2364 |
| 2353 Token::Value op = Next(); // Get assignment operator. | 2365 Token::Value op = Next(); // Get assignment operator. |
| 2366 if (op == Token::ASSIGN_EXP) { |
| 2367 // TODO(caitp): Desugaring in the parser makes it observable that lhs is |
| 2368 // retrieved twice. Fixed by moving implementation to compiler rather than |
| 2369 // desugaring, or by allocating a temporary variable. |
| 2370 op = Token::ASSIGN; |
| 2371 desugar_exponentiation = true; |
| 2372 } |
| 2373 |
| 2354 int pos = position(); | 2374 int pos = position(); |
| 2355 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 2375 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2356 | 2376 |
| 2357 // TODO(1231235): We try to estimate the set of properties set by | 2377 // TODO(1231235): We try to estimate the set of properties set by |
| 2358 // constructors. We define a new property whenever there is an | 2378 // constructors. We define a new property whenever there is an |
| 2359 // assignment to a property of 'this'. We should probably only add | 2379 // assignment to a property of 'this'. We should probably only add |
| 2360 // properties if we haven't seen them before. Otherwise we'll | 2380 // properties if we haven't seen them before. Otherwise we'll |
| 2361 // probably overestimate the number of properties. | 2381 // probably overestimate the number of properties. |
| 2362 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 2382 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
| 2363 function_state_->AddProperty(); | 2383 function_state_->AddProperty(); |
| 2364 } | 2384 } |
| 2365 | 2385 |
| 2366 this->CheckAssigningFunctionLiteralToProperty(expression, right); | 2386 this->CheckAssigningFunctionLiteralToProperty(expression, right); |
| 2367 | 2387 |
| 2368 if (fni_ != NULL) { | 2388 if (fni_ != NULL) { |
| 2369 // Check if the right hand side is a call to avoid inferring a | 2389 // Check if the right hand side is a call to avoid inferring a |
| 2370 // name if we're dealing with "a = function(){...}();"-like | 2390 // name if we're dealing with "a = function(){...}();"-like |
| 2371 // expression. | 2391 // expression. |
| 2372 if ((op == Token::INIT_VAR | 2392 if ((op == Token::INIT_VAR |
| 2373 || op == Token::INIT_CONST_LEGACY | 2393 || op == Token::INIT_CONST_LEGACY |
| 2374 || op == Token::ASSIGN) | 2394 || op == Token::ASSIGN) |
| 2375 && (!right->IsCall() && !right->IsCallNew())) { | 2395 && (!right->IsCall() && !right->IsCallNew())) { |
| 2376 fni_->Infer(); | 2396 fni_->Infer(); |
| 2377 } else { | 2397 } else { |
| 2378 fni_->RemoveLastFunction(); | 2398 fni_->RemoveLastFunction(); |
| 2379 } | 2399 } |
| 2380 fni_->Leave(); | 2400 fni_->Leave(); |
| 2381 } | 2401 } |
| 2382 | 2402 |
| 2403 if (desugar_exponentiation) { |
| 2404 // Desugar to runtime call |
| 2405 typename Traits::Type::ExpressionList args = |
| 2406 this->NewExpressionList(2, zone_); |
| 2407 args->Add(expression, zone_); |
| 2408 args->Add(right, zone_); |
| 2409 right = factory()->NewCallRuntime( |
| 2410 ast_value_factory()->math_pow_string(), NULL, args, pos); |
| 2411 } |
| 2412 |
| 2383 return factory()->NewAssignment(op, expression, right, pos); | 2413 return factory()->NewAssignment(op, expression, right, pos); |
| 2384 } | 2414 } |
| 2385 | 2415 |
| 2386 template <class Traits> | 2416 template <class Traits> |
| 2387 typename ParserBase<Traits>::ExpressionT | 2417 typename ParserBase<Traits>::ExpressionT |
| 2388 ParserBase<Traits>::ParseYieldExpression(bool* ok) { | 2418 ParserBase<Traits>::ParseYieldExpression(bool* ok) { |
| 2389 // YieldExpression :: | 2419 // YieldExpression :: |
| 2390 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 2420 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
| 2391 int pos = peek_position(); | 2421 int pos = peek_position(); |
| 2392 Expect(Token::YIELD, CHECK_OK); | 2422 Expect(Token::YIELD, CHECK_OK); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2458 typename ParserBase<Traits>::ExpressionT | 2488 typename ParserBase<Traits>::ExpressionT |
| 2459 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 2489 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
| 2460 DCHECK(prec >= 4); | 2490 DCHECK(prec >= 4); |
| 2461 ExpressionT x = this->ParseUnaryExpression(CHECK_OK); | 2491 ExpressionT x = this->ParseUnaryExpression(CHECK_OK); |
| 2462 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2492 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 2463 // prec1 >= 4 | 2493 // prec1 >= 4 |
| 2464 while (Precedence(peek(), accept_IN) == prec1) { | 2494 while (Precedence(peek(), accept_IN) == prec1) { |
| 2465 Token::Value op = Next(); | 2495 Token::Value op = Next(); |
| 2466 Scanner::Location op_location = scanner()->location(); | 2496 Scanner::Location op_location = scanner()->location(); |
| 2467 int pos = position(); | 2497 int pos = position(); |
| 2468 ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 2498 ExpressionT y = Traits::EmptyExpression(); |
| 2499 |
| 2500 if (op != Token::EXP) { |
| 2501 // Left-to-right associativity |
| 2502 y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
| 2503 } else { |
| 2504 // Right-to-left associativity |
| 2505 y = ParseBinaryExpression(prec1, accept_IN, CHECK_OK); |
| 2506 } |
| 2469 | 2507 |
| 2470 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 2508 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
| 2471 factory())) { | 2509 factory())) { |
| 2472 continue; | 2510 continue; |
| 2473 } | 2511 } |
| 2474 | 2512 |
| 2475 // For now we distinguish between comparisons and other binary | 2513 // For now we distinguish between comparisons and other binary |
| 2476 // operations. (We could combine the two and get rid of this | 2514 // operations. (We could combine the two and get rid of this |
| 2477 // code and AST node eventually.) | 2515 // code and AST node eventually.) |
| 2478 if (Token::IsCompareOp(op)) { | 2516 if (Token::IsCompareOp(op)) { |
| (...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3109 *ok = false; | 3147 *ok = false; |
| 3110 return; | 3148 return; |
| 3111 } | 3149 } |
| 3112 has_seen_constructor_ = true; | 3150 has_seen_constructor_ = true; |
| 3113 return; | 3151 return; |
| 3114 } | 3152 } |
| 3115 } | 3153 } |
| 3116 } } // v8::internal | 3154 } } // v8::internal |
| 3117 | 3155 |
| 3118 #endif // V8_PREPARSER_H | 3156 #endif // V8_PREPARSER_H |
| OLD | NEW |