Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(533)

Side by Side Diff: src/parsing/parser.cc

Issue 2351233002: [parser] Refactor of Parse*Statement*, part 8 (Closed)
Patch Set: Change after reviewers' comments Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/ast/ast-expression-rewriter.h" 10 #include "src/ast/ast-expression-rewriter.h"
(...skipping 1977 matching lines...) Expand 10 before | Expand all | Expand 10 after
1988 zone()); 1988 zone());
1989 block->statements()->Add(body, zone()); 1989 block->statements()->Add(body, zone());
1990 body = block; 1990 body = block;
1991 each = factory()->NewVariableProxy(temp); 1991 each = factory()->NewVariableProxy(temp);
1992 } 1992 }
1993 stmt->AsForInStatement()->Initialize(each, subject, body); 1993 stmt->AsForInStatement()->Initialize(each, subject, body);
1994 } 1994 }
1995 return stmt; 1995 return stmt;
1996 } 1996 }
1997 1997
1998 // Special case for legacy for
1999 //
2000 // for (var x = initializer in enumerable) body
2001 //
2002 // An initialization block of the form
2003 //
2004 // {
2005 // x = initializer;
2006 // }
2007 //
2008 // is returned in this case. It has reserved space for two statements,
2009 // so that (later on during parsing), the equivalent of
2010 //
2011 // for (x in enumerable) body
2012 //
2013 // is added as a second statement to it.
2014 Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
2015 const DeclarationParsingResult::Declaration& decl =
2016 for_info.parsing_result.declarations[0];
2017 if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
2018 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
2019 DCHECK(!allow_harmony_for_in());
2020 ++use_counts_[v8::Isolate::kForInInitializer];
2021 const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
2022 VariableProxy* single_var = NewUnresolved(name);
2023 Block* init_block = factory()->NewBlock(
2024 nullptr, 2, true, for_info.parsing_result.descriptor.declaration_pos);
2025 init_block->statements()->Add(
2026 factory()->NewExpressionStatement(
2027 factory()->NewAssignment(Token::ASSIGN, single_var,
2028 decl.initializer, kNoSourcePosition),
2029 kNoSourcePosition),
2030 zone());
2031 return init_block;
2032 }
2033 return nullptr;
2034 }
2035
2036 // Rewrite a for-in/of statement of the form
2037 //
2038 // for (let/const/var x in/of e) b
2039 //
2040 // into
2041 //
2042 // {
2043 // <let x' be a temporary variable>
2044 // for (x' in/of e) {
2045 // let/const/var x;
2046 // x = x';
2047 // b;
2048 // }
2049 // let x; // for TDZ
2050 // }
2051 void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
2052 Block** body_block,
2053 Expression** each_variable,
2054 bool* ok) {
2055 DeclarationParsingResult::Declaration& decl =
2056 for_info->parsing_result.declarations[0];
2057 Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
2058 auto each_initialization_block =
2059 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
2060 {
2061 auto descriptor = for_info->parsing_result.descriptor;
2062 descriptor.declaration_pos = kNoSourcePosition;
2063 descriptor.initialization_pos = kNoSourcePosition;
2064 decl.initializer = factory()->NewVariableProxy(temp);
2065
2066 bool is_for_var_of =
2067 for_info->mode == ForEachStatement::ITERATE &&
2068 for_info->parsing_result.descriptor.mode == VariableMode::VAR;
2069
2070 PatternRewriter::DeclareAndInitializeVariables(
2071 this, each_initialization_block, &descriptor, &decl,
2072 (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
2073 is_for_var_of)
2074 ? &for_info->bound_names
2075 : nullptr,
2076 CHECK_OK_VOID);
2077
2078 // Annex B.3.5 prohibits the form
2079 // `try {} catch(e) { for (var e of {}); }`
2080 // So if we are parsing a statement like `for (var ... of ...)`
2081 // we need to walk up the scope chain and look for catch scopes
2082 // which have a simple binding, then compare their binding against
2083 // all of the names declared in the init of the for-of we're
2084 // parsing.
2085 if (is_for_var_of) {
2086 Scope* catch_scope = scope();
2087 while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) {
2088 if (catch_scope->is_catch_scope()) {
2089 auto name = catch_scope->catch_variable_name();
2090 // If it's a simple binding and the name is declared in the for loop.
2091 if (name != ast_value_factory()->dot_catch_string() &&
2092 for_info->bound_names.Contains(name)) {
2093 ReportMessageAt(for_info->parsing_result.bindings_loc,
2094 MessageTemplate::kVarRedeclaration, name);
2095 *ok = false;
2096 return;
2097 }
2098 }
2099 catch_scope = catch_scope->outer_scope();
2100 }
2101 }
2102 }
2103
2104 *body_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
2105 (*body_block)->statements()->Add(each_initialization_block, zone());
2106 *each_variable = factory()->NewVariableProxy(temp, for_info->each_loc.beg_pos,
2107 for_info->each_loc.end_pos);
2108 }
2109
2110 // Create a TDZ for any lexically-bound names in for in/of statements.
2111 Block* Parser::CreateForEachStatementTDZ(Block* init_block,
2112 const ForInfo& for_info, bool* ok) {
2113 if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
2114 DCHECK_NULL(init_block);
2115
2116 init_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
2117
2118 for (int i = 0; i < for_info.bound_names.length(); ++i) {
2119 // TODO(adamk): This needs to be some sort of special
2120 // INTERNAL variable that's invisible to the debugger
2121 // but visible to everything else.
2122 Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET,
2123 kNoSourcePosition, CHECK_OK);
2124 tdz_decl->proxy()->var()->set_initializer_position(position());
2125 }
2126 }
2127 return init_block;
2128 }
2129
1998 Statement* Parser::InitializeForOfStatement(ForOfStatement* for_of, 2130 Statement* Parser::InitializeForOfStatement(ForOfStatement* for_of,
1999 Expression* each, 2131 Expression* each,
2000 Expression* iterable, 2132 Expression* iterable,
2001 Statement* body, bool finalize, 2133 Statement* body, bool finalize,
2002 int next_result_pos) { 2134 int next_result_pos) {
2003 // Create the auxiliary expressions needed for iterating over the iterable, 2135 // Create the auxiliary expressions needed for iterating over the iterable,
2004 // and initialize the given ForOfStatement with them. 2136 // and initialize the given ForOfStatement with them.
2005 // If finalize is true, also instrument the loop with code that performs the 2137 // If finalize is true, also instrument the loop with code that performs the
2006 // proper ES6 iterator finalization. In that case, the result is not 2138 // proper ES6 iterator finalization. In that case, the result is not
2007 // immediately a ForOfStatement. 2139 // immediately a ForOfStatement.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2112 block->statements()->Add(set_completion_normal, zone()); 2244 block->statements()->Add(set_completion_normal, zone());
2113 body = block; 2245 body = block;
2114 } 2246 }
2115 2247
2116 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, 2248 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
2117 assign_each); 2249 assign_each);
2118 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; 2250 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of;
2119 } 2251 }
2120 2252
2121 Statement* Parser::DesugarLexicalBindingsInForStatement( 2253 Statement* Parser::DesugarLexicalBindingsInForStatement(
2122 Scope* inner_scope, VariableMode mode, ZoneList<const AstRawString*>* names,
2123 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 2254 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2124 Statement* body, bool* ok) { 2255 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) {
2125 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are 2256 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
2126 // copied into a new environment. Moreover, the "next" statement must be 2257 // copied into a new environment. Moreover, the "next" statement must be
2127 // evaluated not in the environment of the just completed iteration but in 2258 // evaluated not in the environment of the just completed iteration but in
2128 // that of the upcoming one. We achieve this with the following desugaring. 2259 // that of the upcoming one. We achieve this with the following desugaring.
2129 // Extra care is needed to preserve the completion value of the original loop. 2260 // Extra care is needed to preserve the completion value of the original loop.
2130 // 2261 //
2131 // We are given a for statement of the form 2262 // We are given a for statement of the form
2132 // 2263 //
2133 // labels: for (let/const x = i; cond; next) body 2264 // labels: for (let/const x = i; cond; next) body
2134 // 2265 //
(...skipping 17 matching lines...) Expand all
2152 // }} 2283 // }}
2153 // labels: for (; flag == 1; flag = 0, temp_x = x) { 2284 // labels: for (; flag == 1; flag = 0, temp_x = x) {
2154 // body 2285 // body
2155 // } 2286 // }
2156 // {{ if (flag == 1) // Body used break. 2287 // {{ if (flag == 1) // Body used break.
2157 // break; 2288 // break;
2158 // }} 2289 // }}
2159 // } 2290 // }
2160 // } 2291 // }
2161 2292
2162 DCHECK(names->length() > 0); 2293 DCHECK(for_info.bound_names.length() > 0);
2163 ZoneList<Variable*> temps(names->length(), zone()); 2294 ZoneList<Variable*> temps(for_info.bound_names.length(), zone());
2164 2295
2165 Block* outer_block = 2296 Block* outer_block = factory()->NewBlock(
2166 factory()->NewBlock(NULL, names->length() + 4, false, kNoSourcePosition); 2297 nullptr, for_info.bound_names.length() + 4, false, kNoSourcePosition);
2167 2298
2168 // Add statement: let/const x = i. 2299 // Add statement: let/const x = i.
2169 outer_block->statements()->Add(init, zone()); 2300 outer_block->statements()->Add(init, zone());
2170 2301
2171 const AstRawString* temp_name = ast_value_factory()->dot_for_string(); 2302 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
2172 2303
2173 // For each lexical variable x: 2304 // For each lexical variable x:
2174 // make statement: temp_x = x. 2305 // make statement: temp_x = x.
2175 for (int i = 0; i < names->length(); i++) { 2306 for (int i = 0; i < for_info.bound_names.length(); i++) {
2176 VariableProxy* proxy = NewUnresolved(names->at(i)); 2307 VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
2177 Variable* temp = NewTemporary(temp_name); 2308 Variable* temp = NewTemporary(temp_name);
2178 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 2309 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2179 Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy, 2310 Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
2180 proxy, kNoSourcePosition); 2311 proxy, kNoSourcePosition);
2181 Statement* assignment_statement = 2312 Statement* assignment_statement =
2182 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 2313 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2183 outer_block->statements()->Add(assignment_statement, zone()); 2314 outer_block->statements()->Add(assignment_statement, zone());
2184 temps.Add(temp, zone()); 2315 temps.Add(temp, zone());
2185 } 2316 }
2186 2317
(...skipping 23 matching lines...) Expand all
2210 // in this function that looks up break targets. 2341 // in this function that looks up break targets.
2211 ForStatement* outer_loop = 2342 ForStatement* outer_loop =
2212 factory()->NewForStatement(NULL, kNoSourcePosition); 2343 factory()->NewForStatement(NULL, kNoSourcePosition);
2213 outer_block->statements()->Add(outer_loop, zone()); 2344 outer_block->statements()->Add(outer_loop, zone());
2214 outer_block->set_scope(scope()); 2345 outer_block->set_scope(scope());
2215 2346
2216 Block* inner_block = factory()->NewBlock(NULL, 3, false, kNoSourcePosition); 2347 Block* inner_block = factory()->NewBlock(NULL, 3, false, kNoSourcePosition);
2217 { 2348 {
2218 BlockState block_state(&scope_state_, inner_scope); 2349 BlockState block_state(&scope_state_, inner_scope);
2219 2350
2220 Block* ignore_completion_block = 2351 Block* ignore_completion_block = factory()->NewBlock(
2221 factory()->NewBlock(NULL, names->length() + 3, true, kNoSourcePosition); 2352 nullptr, for_info.bound_names.length() + 3, true, kNoSourcePosition);
2222 ZoneList<Variable*> inner_vars(names->length(), zone()); 2353 ZoneList<Variable*> inner_vars(for_info.bound_names.length(), zone());
2223 // For each let variable x: 2354 // For each let variable x:
2224 // make statement: let/const x = temp_x. 2355 // make statement: let/const x = temp_x.
2225 for (int i = 0; i < names->length(); i++) { 2356 for (int i = 0; i < for_info.bound_names.length(); i++) {
2226 Declaration* decl = 2357 Declaration* decl = DeclareVariable(
2227 DeclareVariable(names->at(i), mode, kNoSourcePosition, CHECK_OK); 2358 for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
2359 kNoSourcePosition, CHECK_OK);
2228 inner_vars.Add(decl->proxy()->var(), zone()); 2360 inner_vars.Add(decl->proxy()->var(), zone());
2229 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 2361 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2230 Assignment* assignment = factory()->NewAssignment( 2362 Assignment* assignment = factory()->NewAssignment(
2231 Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition); 2363 Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition);
2232 Statement* assignment_statement = 2364 Statement* assignment_statement =
2233 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 2365 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2234 DCHECK(init->position() != kNoSourcePosition); 2366 DCHECK(init->position() != kNoSourcePosition);
2235 decl->proxy()->var()->set_initializer_position(init->position()); 2367 decl->proxy()->var()->set_initializer_position(init->position());
2236 ignore_completion_block->statements()->Add(assignment_statement, zone()); 2368 ignore_completion_block->statements()->Add(assignment_statement, zone());
2237 } 2369 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2301 // Make expression: flag = 0. 2433 // Make expression: flag = 0.
2302 { 2434 {
2303 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 2435 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2304 Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition); 2436 Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2305 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy, 2437 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
2306 const0, kNoSourcePosition); 2438 const0, kNoSourcePosition);
2307 } 2439 }
2308 2440
2309 // Make the comma-separated list of temp_x = x assignments. 2441 // Make the comma-separated list of temp_x = x assignments.
2310 int inner_var_proxy_pos = scanner()->location().beg_pos; 2442 int inner_var_proxy_pos = scanner()->location().beg_pos;
2311 for (int i = 0; i < names->length(); i++) { 2443 for (int i = 0; i < for_info.bound_names.length(); i++) {
2312 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 2444 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2313 VariableProxy* proxy = 2445 VariableProxy* proxy =
2314 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos); 2446 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
2315 Assignment* assignment = factory()->NewAssignment( 2447 Assignment* assignment = factory()->NewAssignment(
2316 Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition); 2448 Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2317 compound_next = factory()->NewBinaryOperation( 2449 compound_next = factory()->NewBinaryOperation(
2318 Token::COMMA, compound_next, assignment, kNoSourcePosition); 2450 Token::COMMA, compound_next, assignment, kNoSourcePosition);
2319 } 2451 }
2320 2452
2321 compound_next_statement = 2453 compound_next_statement =
(...skipping 29 matching lines...) Expand all
2351 } 2483 }
2352 2484
2353 inner_scope->set_end_position(scanner()->location().end_pos); 2485 inner_scope->set_end_position(scanner()->location().end_pos);
2354 inner_block->set_scope(inner_scope); 2486 inner_block->set_scope(inner_scope);
2355 } 2487 }
2356 2488
2357 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 2489 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
2358 return outer_block; 2490 return outer_block;
2359 } 2491 }
2360 2492
2361 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
2362 bool* ok) {
2363 int stmt_pos = peek_position();
2364 Statement* init = NULL;
2365 ZoneList<const AstRawString*> bound_names(1, zone());
2366 bool bound_names_are_lexical = false;
2367
2368 // Create an in-between scope for let-bound iteration variables.
2369 BlockState for_state(&scope_state_);
2370 Expect(Token::FOR, CHECK_OK);
2371 Expect(Token::LPAREN, CHECK_OK);
2372 for_state.set_start_position(scanner()->location().beg_pos);
2373 for_state.set_is_hidden();
2374 DeclarationParsingResult parsing_result;
2375 if (peek() != Token::SEMICOLON) {
2376 if (peek() == Token::VAR || peek() == Token::CONST ||
2377 (peek() == Token::LET && IsNextLetKeyword())) {
2378 ParseVariableDeclarations(kForStatement, &parsing_result, nullptr,
2379 CHECK_OK);
2380
2381 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
2382 int each_beg_pos = scanner()->location().beg_pos;
2383 int each_end_pos = scanner()->location().end_pos;
2384
2385 if (CheckInOrOf(&mode)) {
2386 if (parsing_result.declarations.length() != 1) {
2387 ReportMessageAt(parsing_result.bindings_loc,
2388 MessageTemplate::kForInOfLoopMultiBindings,
2389 ForEachStatement::VisitModeString(mode));
2390 *ok = false;
2391 return nullptr;
2392 }
2393 DeclarationParsingResult::Declaration& decl =
2394 parsing_result.declarations[0];
2395 if (parsing_result.first_initializer_loc.IsValid() &&
2396 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
2397 IsLexicalVariableMode(parsing_result.descriptor.mode) ||
2398 !decl.pattern->IsVariableProxy() || allow_harmony_for_in())) {
2399 // Only increment the use count if we would have let this through
2400 // without the flag.
2401 if (allow_harmony_for_in()) {
2402 ++use_counts_[v8::Isolate::kForInInitializer];
2403 }
2404 ReportMessageAt(parsing_result.first_initializer_loc,
2405 MessageTemplate::kForInOfLoopInitializer,
2406 ForEachStatement::VisitModeString(mode));
2407 *ok = false;
2408 return nullptr;
2409 }
2410
2411 Block* init_block = nullptr;
2412 bound_names_are_lexical =
2413 IsLexicalVariableMode(parsing_result.descriptor.mode);
2414
2415 // special case for legacy for (var ... = ... in ...)
2416 if (!bound_names_are_lexical && decl.pattern->IsVariableProxy() &&
2417 decl.initializer != nullptr) {
2418 DCHECK(!allow_harmony_for_in());
2419 ++use_counts_[v8::Isolate::kForInInitializer];
2420 const AstRawString* name =
2421 decl.pattern->AsVariableProxy()->raw_name();
2422 VariableProxy* single_var = NewUnresolved(name);
2423 init_block = factory()->NewBlock(
2424 nullptr, 2, true, parsing_result.descriptor.declaration_pos);
2425 init_block->statements()->Add(
2426 factory()->NewExpressionStatement(
2427 factory()->NewAssignment(Token::ASSIGN, single_var,
2428 decl.initializer, kNoSourcePosition),
2429 kNoSourcePosition),
2430 zone());
2431 }
2432
2433 // Rewrite a for-in/of statement of the form
2434 //
2435 // for (let/const/var x in/of e) b
2436 //
2437 // into
2438 //
2439 // {
2440 // <let x' be a temporary variable>
2441 // for (x' in/of e) {
2442 // let/const/var x;
2443 // x = x';
2444 // b;
2445 // }
2446 // let x; // for TDZ
2447 // }
2448
2449 Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
2450 ForEachStatement* loop =
2451 factory()->NewForEachStatement(mode, labels, stmt_pos);
2452 ParserTarget target(this, loop);
2453
2454 int each_keyword_position = scanner()->location().beg_pos;
2455
2456 Expression* enumerable;
2457 if (mode == ForEachStatement::ITERATE) {
2458 ExpressionClassifier classifier(this);
2459 enumerable = ParseAssignmentExpression(true, CHECK_OK);
2460 RewriteNonPattern(CHECK_OK);
2461 } else {
2462 enumerable = ParseExpression(true, CHECK_OK);
2463 }
2464
2465 Expect(Token::RPAREN, CHECK_OK);
2466
2467
2468 Block* body_block =
2469 factory()->NewBlock(NULL, 3, false, kNoSourcePosition);
2470
2471 Statement* final_loop;
2472 {
2473 ReturnExprScope no_tail_calls(function_state_,
2474 ReturnExprContext::kInsideForInOfBody);
2475 BlockState block_state(&scope_state_);
2476 block_state.set_start_position(scanner()->location().beg_pos);
2477
2478 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
2479
2480 auto each_initialization_block =
2481 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
2482 {
2483 auto descriptor = parsing_result.descriptor;
2484 descriptor.declaration_pos = kNoSourcePosition;
2485 descriptor.initialization_pos = kNoSourcePosition;
2486 decl.initializer = factory()->NewVariableProxy(temp);
2487
2488 bool is_for_var_of =
2489 mode == ForEachStatement::ITERATE &&
2490 parsing_result.descriptor.mode == VariableMode::VAR;
2491
2492 PatternRewriter::DeclareAndInitializeVariables(
2493 this, each_initialization_block, &descriptor, &decl,
2494 bound_names_are_lexical || is_for_var_of ? &bound_names
2495 : nullptr,
2496 CHECK_OK);
2497
2498 // Annex B.3.5 prohibits the form
2499 // `try {} catch(e) { for (var e of {}); }`
2500 // So if we are parsing a statement like `for (var ... of ...)`
2501 // we need to walk up the scope chain and look for catch scopes
2502 // which have a simple binding, then compare their binding against
2503 // all of the names declared in the init of the for-of we're
2504 // parsing.
2505 if (is_for_var_of) {
2506 Scope* catch_scope = scope();
2507 while (catch_scope != nullptr &&
2508 !catch_scope->is_declaration_scope()) {
2509 if (catch_scope->is_catch_scope()) {
2510 auto name = catch_scope->catch_variable_name();
2511 if (name !=
2512 ast_value_factory()
2513 ->dot_catch_string()) { // i.e. is a simple binding
2514 if (bound_names.Contains(name)) {
2515 ReportMessageAt(parsing_result.bindings_loc,
2516 MessageTemplate::kVarRedeclaration, name);
2517 *ok = false;
2518 return nullptr;
2519 }
2520 }
2521 }
2522 catch_scope = catch_scope->outer_scope();
2523 }
2524 }
2525 }
2526
2527 body_block->statements()->Add(each_initialization_block, zone());
2528 body_block->statements()->Add(body, zone());
2529 VariableProxy* temp_proxy =
2530 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
2531 final_loop = InitializeForEachStatement(
2532 loop, temp_proxy, enumerable, body_block, each_keyword_position);
2533 block_state.set_end_position(scanner()->location().end_pos);
2534 body_block->set_scope(block_state.FinalizedBlockScope());
2535 }
2536
2537 // Create a TDZ for any lexically-bound names.
2538 if (bound_names_are_lexical) {
2539 DCHECK_NULL(init_block);
2540
2541 init_block =
2542 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
2543
2544 for (int i = 0; i < bound_names.length(); ++i) {
2545 // TODO(adamk): This needs to be some sort of special
2546 // INTERNAL variable that's invisible to the debugger
2547 // but visible to everything else.
2548 Declaration* tdz_decl = DeclareVariable(
2549 bound_names[i], LET, kNoSourcePosition, CHECK_OK);
2550 tdz_decl->proxy()->var()->set_initializer_position(position());
2551 }
2552 }
2553
2554 for_state.set_end_position(scanner()->location().end_pos);
2555 Scope* for_scope = for_state.FinalizedBlockScope();
2556 // Parsed for-in loop w/ variable declarations.
2557 if (init_block != nullptr) {
2558 init_block->statements()->Add(final_loop, zone());
2559 init_block->set_scope(for_scope);
2560 return init_block;
2561 } else {
2562 DCHECK_NULL(for_scope);
2563 return final_loop;
2564 }
2565 } else {
2566 bound_names_are_lexical =
2567 IsLexicalVariableMode(parsing_result.descriptor.mode);
2568 init = BuildInitializationBlock(
2569 &parsing_result, bound_names_are_lexical ? &bound_names : nullptr,
2570 CHECK_OK);
2571 }
2572 } else {
2573 int lhs_beg_pos = peek_position();
2574 ExpressionClassifier classifier(this);
2575 Expression* expression = ParseExpressionCoverGrammar(false, CHECK_OK);
2576 int lhs_end_pos = scanner()->location().end_pos;
2577 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
2578
2579 bool is_for_each = CheckInOrOf(&mode);
2580 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
2581 expression->IsObjectLiteral());
2582
2583 if (is_destructuring) {
2584 ValidateAssignmentPattern(CHECK_OK);
2585 } else {
2586 RewriteNonPattern(CHECK_OK);
2587 }
2588
2589 if (is_for_each) {
2590 if (!is_destructuring) {
2591 expression = CheckAndRewriteReferenceExpression(
2592 expression, lhs_beg_pos, lhs_end_pos,
2593 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
2594 }
2595
2596 ForEachStatement* loop =
2597 factory()->NewForEachStatement(mode, labels, stmt_pos);
2598 ParserTarget target(this, loop);
2599
2600 int each_keyword_position = scanner()->location().beg_pos;
2601
2602 Expression* enumerable;
2603 if (mode == ForEachStatement::ITERATE) {
2604 ExpressionClassifier classifier(this);
2605 enumerable = ParseAssignmentExpression(true, CHECK_OK);
2606 RewriteNonPattern(CHECK_OK);
2607 } else {
2608 enumerable = ParseExpression(true, CHECK_OK);
2609 }
2610
2611 Expect(Token::RPAREN, CHECK_OK);
2612
2613 {
2614 ReturnExprScope no_tail_calls(function_state_,
2615 ReturnExprContext::kInsideForInOfBody);
2616 BlockState block_state(&scope_state_);
2617 block_state.set_start_position(scanner()->location().beg_pos);
2618
2619 // For legacy compat reasons, give for loops similar treatment to
2620 // if statements in allowing a function declaration for a body
2621 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
2622 block_state.set_end_position(scanner()->location().end_pos);
2623 Statement* final_loop = InitializeForEachStatement(
2624 loop, expression, enumerable, body, each_keyword_position);
2625
2626 Scope* for_scope = for_state.FinalizedBlockScope();
2627 DCHECK_NULL(for_scope);
2628 USE(for_scope);
2629 Scope* block_scope = block_state.FinalizedBlockScope();
2630 DCHECK_NULL(block_scope);
2631 USE(block_scope);
2632 return final_loop;
2633 }
2634 } else {
2635 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
2636 }
2637 }
2638 }
2639
2640 // Standard 'for' loop
2641 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
2642 ParserTarget target(this, loop);
2643
2644 // Parsed initializer at this point.
2645 Expect(Token::SEMICOLON, CHECK_OK);
2646
2647 Expression* cond = NULL;
2648 Statement* next = NULL;
2649 Statement* body = NULL;
2650
2651 // If there are let bindings, then condition and the next statement of the
2652 // for loop must be parsed in a new scope.
2653 Scope* inner_scope = scope();
2654 // TODO(verwaest): Allocate this through a ScopeState as well.
2655 if (bound_names_are_lexical && bound_names.length() > 0) {
2656 inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE);
2657 inner_scope->set_start_position(scanner()->location().beg_pos);
2658 }
2659 {
2660 BlockState block_state(&scope_state_, inner_scope);
2661
2662 if (peek() != Token::SEMICOLON) {
2663 cond = ParseExpression(true, CHECK_OK);
2664 }
2665 Expect(Token::SEMICOLON, CHECK_OK);
2666
2667 if (peek() != Token::RPAREN) {
2668 Expression* exp = ParseExpression(true, CHECK_OK);
2669 next = factory()->NewExpressionStatement(exp, exp->position());
2670 }
2671 Expect(Token::RPAREN, CHECK_OK);
2672
2673 body = ParseScopedStatement(NULL, true, CHECK_OK);
2674 }
2675
2676 Statement* result = NULL;
2677 if (bound_names_are_lexical && bound_names.length() > 0) {
2678 result = DesugarLexicalBindingsInForStatement(
2679 inner_scope, parsing_result.descriptor.mode, &bound_names, loop, init,
2680 cond, next, body, CHECK_OK);
2681 for_state.set_end_position(scanner()->location().end_pos);
2682 } else {
2683 for_state.set_end_position(scanner()->location().end_pos);
2684 Scope* for_scope = for_state.FinalizedBlockScope();
2685 if (for_scope) {
2686 // Rewrite a for statement of the form
2687 // for (const x = i; c; n) b
2688 //
2689 // into
2690 //
2691 // {
2692 // const x = i;
2693 // for (; c; n) b
2694 // }
2695 //
2696 // or, desugar
2697 // for (; c; n) b
2698 // into
2699 // {
2700 // for (; c; n) b
2701 // }
2702 // just in case b introduces a lexical binding some other way, e.g., if b
2703 // is a FunctionDeclaration.
2704 Block* block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition);
2705 if (init != nullptr) {
2706 block->statements()->Add(init, zone());
2707 }
2708 block->statements()->Add(loop, zone());
2709 block->set_scope(for_scope);
2710 loop->Initialize(NULL, cond, next, body);
2711 result = block;
2712 } else {
2713 loop->Initialize(init, cond, next, body);
2714 result = loop;
2715 }
2716 }
2717 return result;
2718 }
2719
2720 void Parser::ParseArrowFunctionFormalParameters( 2493 void Parser::ParseArrowFunctionFormalParameters(
2721 ParserFormalParameters* parameters, Expression* expr, int end_pos, 2494 ParserFormalParameters* parameters, Expression* expr, int end_pos,
2722 bool* ok) { 2495 bool* ok) {
2723 // ArrowFunctionFormals :: 2496 // ArrowFunctionFormals ::
2724 // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail) 2497 // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
2725 // Tail 2498 // Tail
2726 // NonTailArrowFunctionFormals :: 2499 // NonTailArrowFunctionFormals ::
2727 // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy) 2500 // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
2728 // VariableProxy 2501 // VariableProxy
2729 // Tail :: 2502 // Tail ::
(...skipping 3097 matching lines...) Expand 10 before | Expand all | Expand 10 after
5827 5600
5828 return final_loop; 5601 return final_loop;
5829 } 5602 }
5830 5603
5831 #undef CHECK_OK 5604 #undef CHECK_OK
5832 #undef CHECK_OK_VOID 5605 #undef CHECK_OK_VOID
5833 #undef CHECK_FAILED 5606 #undef CHECK_FAILED
5834 5607
5835 } // namespace internal 5608 } // namespace internal
5836 } // namespace v8 5609 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698