| 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 #include "src/v8.h" | 5 #include "src/v8.h" | 
| 6 | 6 | 
| 7 #include "src/api.h" | 7 #include "src/api.h" | 
| 8 #include "src/ast.h" | 8 #include "src/ast.h" | 
| 9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" | 
| 10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" | 
| (...skipping 2200 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2211 | 2211 | 
| 2212 | 2212 | 
| 2213 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 2213 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 
| 2214                                       ZoneList<const AstRawString*>* names, | 2214                                       ZoneList<const AstRawString*>* names, | 
| 2215                                       bool* ok) { | 2215                                       bool* ok) { | 
| 2216   // VariableStatement :: | 2216   // VariableStatement :: | 
| 2217   //   VariableDeclarations ';' | 2217   //   VariableDeclarations ';' | 
| 2218 | 2218 | 
| 2219   const AstRawString* ignore; | 2219   const AstRawString* ignore; | 
| 2220   Block* result = | 2220   Block* result = | 
| 2221       ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); | 2221       ParseVariableDeclarations(var_context, names, &ignore, nullptr, CHECK_OK); | 
| 2222   ExpectSemicolon(CHECK_OK); | 2222   ExpectSemicolon(CHECK_OK); | 
| 2223   return result; | 2223   return result; | 
| 2224 } | 2224 } | 
| 2225 | 2225 | 
| 2226 | 2226 | 
| 2227 // If the variable declaration declares exactly one non-const | 2227 // If the variable declaration declares exactly one non-const | 
| 2228 // variable, then *out is set to that variable. In all other cases, | 2228 // variable, then *out is set to that variable. In all other cases, | 
| 2229 // *out is untouched; in particular, it is the caller's responsibility | 2229 // *out is untouched; in particular, it is the caller's responsibility | 
| 2230 // to initialize it properly. This mechanism is used for the parsing | 2230 // to initialize it properly. This mechanism is used for the parsing | 
| 2231 // of 'for-in' loops. | 2231 // of 'for-in' loops. | 
| 2232 Block* Parser::ParseVariableDeclarations( | 2232 Block* Parser::ParseVariableDeclarations( | 
| 2233     VariableDeclarationContext var_context, | 2233     VariableDeclarationContext var_context, | 
| 2234     VariableDeclarationProperties* decl_props, | 2234     ZoneList<const AstRawString*>* names, const AstRawString** out, | 
| 2235     ZoneList<const AstRawString*>* names, | 2235     Scanner::Location* first_initializer_loc, bool* ok) { | 
| 2236     const AstRawString** out, |  | 
| 2237     bool* ok) { |  | 
| 2238   // VariableDeclarations :: | 2236   // VariableDeclarations :: | 
| 2239   //   ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] | 2237   //   ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] | 
| 2240   // | 2238   // | 
| 2241   // The ES6 Draft Rev3 specifies the following grammar for const declarations | 2239   // The ES6 Draft Rev3 specifies the following grammar for const declarations | 
| 2242   // | 2240   // | 
| 2243   // ConstDeclaration :: | 2241   // ConstDeclaration :: | 
| 2244   //   const ConstBinding (',' ConstBinding)* ';' | 2242   //   const ConstBinding (',' ConstBinding)* ';' | 
| 2245   // ConstBinding :: | 2243   // ConstBinding :: | 
| 2246   //   Identifier '=' AssignmentExpression | 2244   //   Identifier '=' AssignmentExpression | 
| 2247   // | 2245   // | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2307   Block* block = factory()->NewBlock(NULL, 1, true, pos); | 2305   Block* block = factory()->NewBlock(NULL, 1, true, pos); | 
| 2308   int nvars = 0;  // the number of variables declared | 2306   int nvars = 0;  // the number of variables declared | 
| 2309   const AstRawString* name = NULL; | 2307   const AstRawString* name = NULL; | 
| 2310   bool is_for_iteration_variable; | 2308   bool is_for_iteration_variable; | 
| 2311   do { | 2309   do { | 
| 2312     if (fni_ != NULL) fni_->Enter(); | 2310     if (fni_ != NULL) fni_->Enter(); | 
| 2313 | 2311 | 
| 2314     // Parse variable name. | 2312     // Parse variable name. | 
| 2315     if (nvars > 0) Consume(Token::COMMA); | 2313     if (nvars > 0) Consume(Token::COMMA); | 
| 2316     name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2314     name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 
|  | 2315     Scanner::Location variable_loc = scanner()->location(); | 
| 2317     if (fni_ != NULL) fni_->PushVariableName(name); | 2316     if (fni_ != NULL) fni_->PushVariableName(name); | 
| 2318 | 2317 | 
| 2319     // Declare variable. | 2318     // Declare variable. | 
| 2320     // Note that we *always* must treat the initial value via a separate init | 2319     // Note that we *always* must treat the initial value via a separate init | 
| 2321     // assignment for variables and constants because the value must be assigned | 2320     // assignment for variables and constants because the value must be assigned | 
| 2322     // when the variable is encountered in the source. But the variable/constant | 2321     // when the variable is encountered in the source. But the variable/constant | 
| 2323     // is declared (and set to 'undefined') upon entering the function within | 2322     // is declared (and set to 'undefined') upon entering the function within | 
| 2324     // which the variable or constant is declared. Only function variables have | 2323     // which the variable or constant is declared. Only function variables have | 
| 2325     // an initial value in the declaration (because they are initialized upon | 2324     // an initial value in the declaration (because they are initialized upon | 
| 2326     // entering the function). | 2325     // entering the function). | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2381 | 2380 | 
| 2382     Scope* initialization_scope = is_const ? declaration_scope : scope_; | 2381     Scope* initialization_scope = is_const ? declaration_scope : scope_; | 
| 2383     Expression* value = NULL; | 2382     Expression* value = NULL; | 
| 2384     int pos = -1; | 2383     int pos = -1; | 
| 2385     // Harmony consts have non-optional initializers. | 2384     // Harmony consts have non-optional initializers. | 
| 2386     if (peek() == Token::ASSIGN || | 2385     if (peek() == Token::ASSIGN || | 
| 2387         (mode == CONST && !is_for_iteration_variable)) { | 2386         (mode == CONST && !is_for_iteration_variable)) { | 
| 2388       Expect(Token::ASSIGN, CHECK_OK); | 2387       Expect(Token::ASSIGN, CHECK_OK); | 
| 2389       pos = position(); | 2388       pos = position(); | 
| 2390       value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 2389       value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 
|  | 2390       variable_loc.end_pos = scanner()->location().end_pos; | 
|  | 2391 | 
|  | 2392       if (first_initializer_loc && !first_initializer_loc->IsValid()) { | 
|  | 2393         *first_initializer_loc = variable_loc; | 
|  | 2394       } | 
|  | 2395 | 
| 2391       // Don't infer if it is "a = function(){...}();"-like expression. | 2396       // Don't infer if it is "a = function(){...}();"-like expression. | 
| 2392       if (fni_ != NULL && | 2397       if (fni_ != NULL && | 
| 2393           value->AsCall() == NULL && | 2398           value->AsCall() == NULL && | 
| 2394           value->AsCallNew() == NULL) { | 2399           value->AsCallNew() == NULL) { | 
| 2395         fni_->Infer(); | 2400         fni_->Infer(); | 
| 2396       } else { | 2401       } else { | 
| 2397         fni_->RemoveLastFunction(); | 2402         fni_->RemoveLastFunction(); | 
| 2398       } | 2403       } | 
| 2399       if (decl_props != NULL) *decl_props = kHasInitializers; |  | 
| 2400       // End position of the initializer is after the assignment expression. | 2404       // End position of the initializer is after the assignment expression. | 
| 2401       var->set_initializer_position(scanner()->location().end_pos); | 2405       var->set_initializer_position(scanner()->location().end_pos); | 
| 2402     } else { | 2406     } else { | 
| 2403       // End position of the initializer is after the variable. | 2407       // End position of the initializer is after the variable. | 
| 2404       var->set_initializer_position(position()); | 2408       var->set_initializer_position(position()); | 
| 2405     } | 2409     } | 
| 2406 | 2410 | 
| 2407     // Make sure that 'const x' and 'let x' initialize 'x' to undefined. | 2411     // Make sure that 'const x' and 'let x' initialize 'x' to undefined. | 
| 2408     if (value == NULL && needs_init) { | 2412     if (value == NULL && needs_init) { | 
| 2409       value = GetLiteralUndefined(position()); | 2413       value = GetLiteralUndefined(position()); | 
| (...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3356   scope_ = for_scope; | 3360   scope_ = for_scope; | 
| 3357 | 3361 | 
| 3358   Expect(Token::FOR, CHECK_OK); | 3362   Expect(Token::FOR, CHECK_OK); | 
| 3359   Expect(Token::LPAREN, CHECK_OK); | 3363   Expect(Token::LPAREN, CHECK_OK); | 
| 3360   for_scope->set_start_position(scanner()->location().beg_pos); | 3364   for_scope->set_start_position(scanner()->location().beg_pos); | 
| 3361   bool is_let_identifier_expression = false; | 3365   bool is_let_identifier_expression = false; | 
| 3362   if (peek() != Token::SEMICOLON) { | 3366   if (peek() != Token::SEMICOLON) { | 
| 3363     if (peek() == Token::VAR || | 3367     if (peek() == Token::VAR || | 
| 3364         (peek() == Token::CONST && is_sloppy(language_mode()))) { | 3368         (peek() == Token::CONST && is_sloppy(language_mode()))) { | 
| 3365       const AstRawString* name = NULL; | 3369       const AstRawString* name = NULL; | 
| 3366       VariableDeclarationProperties decl_props = kHasNoInitializers; | 3370       Scanner::Location first_initializer_loc = Scanner::Location::invalid(); | 
| 3367       Block* variable_statement = | 3371       Block* variable_statement = ParseVariableDeclarations( | 
| 3368           ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 3372           kForStatement, nullptr, &name, &first_initializer_loc, CHECK_OK); | 
| 3369                                     CHECK_OK); | 3373       bool accept_OF = true; | 
| 3370       bool accept_OF = decl_props == kHasNoInitializers; |  | 
| 3371       ForEachStatement::VisitMode mode; | 3374       ForEachStatement::VisitMode mode; | 
| 3372       int each_beg_pos = scanner()->location().beg_pos; | 3375       int each_beg_pos = scanner()->location().beg_pos; | 
| 3373       int each_end_pos = scanner()->location().end_pos; | 3376       int each_end_pos = scanner()->location().end_pos; | 
| 3374 | 3377 | 
| 3375       if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { | 3378       if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { | 
| 3376         if (!*ok) return nullptr; | 3379         if (!*ok) return nullptr; | 
|  | 3380         if (first_initializer_loc.IsValid() && | 
|  | 3381             (is_strict(language_mode()) || mode == ForEachStatement::ITERATE)) { | 
|  | 3382           if (mode == ForEachStatement::ITERATE) { | 
|  | 3383             ReportMessageAt(first_initializer_loc, "for_of_loop_initializer"); | 
|  | 3384           } else { | 
|  | 3385             // TODO(caitp): This should be an error in sloppy mode too. | 
|  | 3386             ReportMessageAt(first_initializer_loc, "for_in_loop_initializer"); | 
|  | 3387           } | 
|  | 3388           *ok = false; | 
|  | 3389           return nullptr; | 
|  | 3390         } | 
| 3377         ForEachStatement* loop = | 3391         ForEachStatement* loop = | 
| 3378             factory()->NewForEachStatement(mode, labels, stmt_pos); | 3392             factory()->NewForEachStatement(mode, labels, stmt_pos); | 
| 3379         Target target(&this->target_stack_, loop); | 3393         Target target(&this->target_stack_, loop); | 
| 3380 | 3394 | 
| 3381         Expression* enumerable = ParseExpression(true, CHECK_OK); | 3395         Expression* enumerable = ParseExpression(true, CHECK_OK); | 
| 3382         Expect(Token::RPAREN, CHECK_OK); | 3396         Expect(Token::RPAREN, CHECK_OK); | 
| 3383 | 3397 | 
| 3384         VariableProxy* each = | 3398         VariableProxy* each = | 
| 3385             scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos); | 3399             scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos); | 
| 3386         Statement* body = ParseSubStatement(NULL, CHECK_OK); | 3400         Statement* body = ParseSubStatement(NULL, CHECK_OK); | 
| 3387         InitializeForEachStatement(loop, each, enumerable, body); | 3401         InitializeForEachStatement(loop, each, enumerable, body); | 
| 3388         Block* result = | 3402         Block* result = | 
| 3389             factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 3403             factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 
| 3390         result->AddStatement(variable_statement, zone()); | 3404         result->AddStatement(variable_statement, zone()); | 
| 3391         result->AddStatement(loop, zone()); | 3405         result->AddStatement(loop, zone()); | 
| 3392         scope_ = saved_scope; | 3406         scope_ = saved_scope; | 
| 3393         for_scope->set_end_position(scanner()->location().end_pos); | 3407         for_scope->set_end_position(scanner()->location().end_pos); | 
| 3394         for_scope = for_scope->FinalizeBlockScope(); | 3408         for_scope = for_scope->FinalizeBlockScope(); | 
| 3395         DCHECK(for_scope == NULL); | 3409         DCHECK(for_scope == NULL); | 
| 3396         // Parsed for-in loop w/ variable/const declaration. | 3410         // Parsed for-in loop w/ variable/const declaration. | 
| 3397         return result; | 3411         return result; | 
| 3398       } else { | 3412       } else { | 
| 3399         init = variable_statement; | 3413         init = variable_statement; | 
| 3400       } | 3414       } | 
| 3401     } else if ((peek() == Token::LET || peek() == Token::CONST) && | 3415     } else if ((peek() == Token::LET || peek() == Token::CONST) && | 
| 3402                is_strict(language_mode())) { | 3416                is_strict(language_mode())) { | 
| 3403       is_const = peek() == Token::CONST; | 3417       is_const = peek() == Token::CONST; | 
| 3404       const AstRawString* name = NULL; | 3418       const AstRawString* name = NULL; | 
| 3405       VariableDeclarationProperties decl_props = kHasNoInitializers; | 3419       Scanner::Location first_initializer_loc = Scanner::Location::invalid(); | 
| 3406       Block* variable_statement = | 3420       Block* variable_statement = | 
| 3407           ParseVariableDeclarations(kForStatement, &decl_props, | 3421           ParseVariableDeclarations(kForStatement, &lexical_bindings, &name, | 
| 3408                                     &lexical_bindings, &name, CHECK_OK); | 3422                                     &first_initializer_loc, CHECK_OK); | 
| 3409       bool accept_IN = name != NULL && decl_props != kHasInitializers; | 3423       bool accept_IN = name != NULL; | 
| 3410       bool accept_OF = decl_props == kHasNoInitializers; | 3424       bool accept_OF = true; | 
| 3411       ForEachStatement::VisitMode mode; | 3425       ForEachStatement::VisitMode mode; | 
| 3412       int each_beg_pos = scanner()->location().beg_pos; | 3426       int each_beg_pos = scanner()->location().beg_pos; | 
| 3413       int each_end_pos = scanner()->location().end_pos; | 3427       int each_end_pos = scanner()->location().end_pos; | 
| 3414 | 3428 | 
| 3415       if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { | 3429       if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { | 
| 3416         if (!*ok) return nullptr; | 3430         if (!*ok) return nullptr; | 
| 3417 | 3431         if (first_initializer_loc.IsValid() && | 
|  | 3432             (is_strict(language_mode()) || mode == ForEachStatement::ITERATE)) { | 
|  | 3433           if (mode == ForEachStatement::ITERATE) { | 
|  | 3434             ReportMessageAt(first_initializer_loc, "for_of_loop_initializer"); | 
|  | 3435           } else { | 
|  | 3436             ReportMessageAt(first_initializer_loc, "for_in_loop_initializer"); | 
|  | 3437           } | 
|  | 3438           *ok = false; | 
|  | 3439           return nullptr; | 
|  | 3440         } | 
| 3418         // Rewrite a for-in statement of the form | 3441         // Rewrite a for-in statement of the form | 
| 3419         // | 3442         // | 
| 3420         //   for (let/const x in e) b | 3443         //   for (let/const x in e) b | 
| 3421         // | 3444         // | 
| 3422         // into | 3445         // into | 
| 3423         // | 3446         // | 
| 3424         //   <let x' be a temporary variable> | 3447         //   <let x' be a temporary variable> | 
| 3425         //   for (x' in e) { | 3448         //   for (x' in e) { | 
| 3426         //     let/const x; | 3449         //     let/const x; | 
| 3427         //     x = x'; | 3450         //     x = x'; | 
| (...skipping 2129 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5557     } else { | 5580     } else { | 
| 5558       const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5581       const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 
| 5559       running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5582       running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 
| 5560                                                       raw_string->length()); | 5583                                                       raw_string->length()); | 
| 5561     } | 5584     } | 
| 5562   } | 5585   } | 
| 5563 | 5586 | 
| 5564   return running_hash; | 5587   return running_hash; | 
| 5565 } | 5588 } | 
| 5566 } }  // namespace v8::internal | 5589 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|