Line data Source code
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
3 : // found in the LICENSE file.
4 :
5 : #include "src/parsing/parser.h"
6 :
7 : #include <memory>
8 :
9 : #include "src/api.h"
10 : #include "src/ast/ast-expression-rewriter.h"
11 : #include "src/ast/ast-function-literal-id-reindexer.h"
12 : #include "src/ast/ast-traversal-visitor.h"
13 : #include "src/ast/ast.h"
14 : #include "src/bailout-reason.h"
15 : #include "src/base/platform/platform.h"
16 : #include "src/char-predicates-inl.h"
17 : #include "src/messages.h"
18 : #include "src/objects-inl.h"
19 : #include "src/parsing/duplicate-finder.h"
20 : #include "src/parsing/parameter-initializer-rewriter.h"
21 : #include "src/parsing/parse-info.h"
22 : #include "src/parsing/rewriter.h"
23 : #include "src/parsing/scanner-character-streams.h"
24 : #include "src/runtime/runtime.h"
25 : #include "src/string-stream.h"
26 : #include "src/tracing/trace-event.h"
27 :
28 : namespace v8 {
29 : namespace internal {
30 :
31 1330 : ScriptData::ScriptData(const byte* data, int length)
32 1330 : : owns_data_(false), rejected_(false), data_(data), length_(length) {
33 2660 : if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
34 4 : byte* copy = NewArray<byte>(length);
35 : DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
36 4 : CopyBytes(copy, data, length);
37 4 : data_ = copy;
38 : AcquireDataOwnership();
39 : }
40 1330 : }
41 :
42 276 : FunctionEntry ParseData::GetFunctionEntry(int start) {
43 : // The current pre-data entry must be a FunctionEntry with the given
44 : // start position.
45 414 : if ((function_index_ + FunctionEntry::kSize <= Length()) &&
46 138 : (static_cast<int>(Data()[function_index_]) == start)) {
47 : int index = function_index_;
48 126 : function_index_ += FunctionEntry::kSize;
49 126 : Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
50 126 : return FunctionEntry(subvector);
51 : }
52 12 : return FunctionEntry();
53 : }
54 :
55 :
56 36 : int ParseData::FunctionCount() {
57 : int functions_size = FunctionsSize();
58 36 : if (functions_size < 0) return 0;
59 36 : if (functions_size % FunctionEntry::kSize != 0) return 0;
60 36 : return functions_size / FunctionEntry::kSize;
61 : }
62 :
63 :
64 114 : bool ParseData::IsSane() {
65 228 : if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
66 : // Check that the header data is valid and doesn't specify
67 : // point to positions outside the store.
68 : int data_length = Length();
69 114 : if (data_length < PreparseDataConstants::kHeaderSize) return false;
70 114 : if (Magic() != PreparseDataConstants::kMagicNumber) return false;
71 108 : if (Version() != PreparseDataConstants::kCurrentVersion) return false;
72 : // Check that the space allocated for function entries is sane.
73 : int functions_size = FunctionsSize();
74 108 : if (functions_size < 0) return false;
75 108 : if (functions_size % FunctionEntry::kSize != 0) return false;
76 : // Check that the total size has room for header and function entries.
77 : int minimum_size =
78 108 : PreparseDataConstants::kHeaderSize + functions_size;
79 108 : if (data_length < minimum_size) return false;
80 108 : return true;
81 : }
82 :
83 :
84 72 : void ParseData::Initialize() {
85 : // Prepares state for use.
86 : int data_length = Length();
87 72 : if (data_length >= PreparseDataConstants::kHeaderSize) {
88 72 : function_index_ = PreparseDataConstants::kHeaderSize;
89 : }
90 6 : }
91 :
92 :
93 0 : unsigned ParseData::Magic() {
94 114 : return Data()[PreparseDataConstants::kMagicOffset];
95 : }
96 :
97 :
98 0 : unsigned ParseData::Version() {
99 108 : return Data()[PreparseDataConstants::kVersionOffset];
100 : }
101 :
102 :
103 36 : int ParseData::FunctionsSize() {
104 144 : return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
105 : }
106 :
107 : // Helper for putting parts of the parse results into a temporary zone when
108 : // parsing inner function bodies.
109 : class DiscardableZoneScope {
110 : public:
111 7562020 : DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone)
112 : : ast_node_factory_scope_(parser->factory(), temp_zone, use_temp_zone),
113 : fni_(parser->ast_value_factory_, temp_zone),
114 : parser_(parser),
115 : prev_fni_(parser->fni_),
116 : prev_zone_(parser->zone_),
117 : prev_allow_lazy_(parser->allow_lazy_),
118 15124040 : prev_temp_zoned_(parser->temp_zoned_) {
119 7562028 : if (use_temp_zone) {
120 : DCHECK(!parser_->temp_zoned_);
121 1403478 : parser_->allow_lazy_ = false;
122 1403478 : parser_->temp_zoned_ = true;
123 1403478 : parser_->fni_ = &fni_;
124 1403478 : parser_->zone_ = temp_zone;
125 1403478 : if (parser_->reusable_preparser_ != nullptr) {
126 1011643 : parser_->reusable_preparser_->zone_ = temp_zone;
127 : parser_->reusable_preparser_->factory()->set_zone(temp_zone);
128 : }
129 : }
130 7562028 : }
131 7562065 : void Reset() {
132 7562065 : parser_->fni_ = prev_fni_;
133 7562065 : parser_->zone_ = prev_zone_;
134 7562065 : parser_->allow_lazy_ = prev_allow_lazy_;
135 7562065 : parser_->temp_zoned_ = prev_temp_zoned_;
136 7562065 : if (parser_->reusable_preparser_ != nullptr) {
137 2778811 : parser_->reusable_preparser_->zone_ = prev_zone_;
138 : parser_->reusable_preparser_->factory()->set_zone(prev_zone_);
139 : }
140 : ast_node_factory_scope_.Reset();
141 7562065 : }
142 7562022 : ~DiscardableZoneScope() { Reset(); }
143 :
144 : private:
145 : AstNodeFactory::BodyScope ast_node_factory_scope_;
146 : FuncNameInferrer fni_;
147 : Parser* parser_;
148 : FuncNameInferrer* prev_fni_;
149 : Zone* prev_zone_;
150 : bool prev_allow_lazy_;
151 : bool prev_temp_zoned_;
152 :
153 : DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope);
154 : };
155 :
156 2263423 : void Parser::SetCachedData(ParseInfo* info) {
157 : DCHECK_NULL(cached_parse_data_);
158 2263351 : if (consume_cached_parse_data()) {
159 72 : if (allow_lazy_) {
160 72 : cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
161 2263423 : if (cached_parse_data_ != nullptr) return;
162 : }
163 6 : compile_options_ = ScriptCompiler::kNoCompileOptions;
164 : }
165 : }
166 :
167 87041 : FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
168 : bool call_super, int pos,
169 : int end_pos) {
170 : int expected_property_count = -1;
171 : const int parameter_count = 0;
172 323723 : if (name == nullptr) name = ast_value_factory()->empty_string();
173 :
174 : FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor
175 87041 : : FunctionKind::kDefaultBaseConstructor;
176 87041 : DeclarationScope* function_scope = NewFunctionScope(kind);
177 87041 : SetLanguageMode(function_scope, STRICT);
178 : // Set start and end position to the same value
179 : function_scope->set_start_position(pos);
180 : function_scope->set_end_position(pos);
181 : ZoneList<Statement*>* body = NULL;
182 :
183 : {
184 87041 : FunctionState function_state(&function_state_, &scope_, function_scope);
185 :
186 87041 : body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
187 87041 : if (call_super) {
188 : // Create a SuperCallReference and handle in BytecodeGenerator.
189 15650 : auto constructor_args_name = ast_value_factory()->empty_string();
190 : bool is_duplicate;
191 : bool is_rest = true;
192 : bool is_optional = false;
193 : Variable* constructor_args = function_scope->DeclareParameter(
194 : constructor_args_name, TEMPORARY, is_optional, is_rest, &is_duplicate,
195 15650 : ast_value_factory(), pos);
196 :
197 : ZoneList<Expression*>* args =
198 15650 : new (zone()) ZoneList<Expression*>(1, zone());
199 : Spread* spread_args = factory()->NewSpread(
200 31300 : factory()->NewVariableProxy(constructor_args), pos, pos);
201 :
202 : args->Add(spread_args, zone());
203 15650 : Expression* super_call_ref = NewSuperCallReference(pos);
204 15650 : Expression* call = factory()->NewCall(super_call_ref, args, pos);
205 15650 : body->Add(factory()->NewReturnStatement(call, pos), zone());
206 : }
207 :
208 87041 : expected_property_count = function_state.expected_property_count();
209 : }
210 :
211 : FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
212 : name, function_scope, body, expected_property_count, parameter_count,
213 : parameter_count, FunctionLiteral::kNoDuplicateParameters,
214 : FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
215 87041 : true, GetNextFunctionLiteralId());
216 :
217 87041 : return function_literal;
218 : }
219 :
220 : // ----------------------------------------------------------------------------
221 : // The CHECK_OK macro is a convenient macro to enforce error
222 : // handling for functions that may fail (by returning !*ok).
223 : //
224 : // CAUTION: This macro appends extra statements after a call,
225 : // thus it must never be used where only a single statement
226 : // is correct (e.g. an if statement branch w/o braces)!
227 :
228 : #define CHECK_OK_VALUE(x) ok); \
229 : if (!*ok) return x; \
230 : ((void)0
231 : #define DUMMY ) // to make indentation work
232 : #undef DUMMY
233 :
234 : #define CHECK_OK CHECK_OK_VALUE(nullptr)
235 : #define CHECK_OK_VOID CHECK_OK_VALUE(this->Void())
236 :
237 : #define CHECK_FAILED /**/); \
238 : if (failed_) return nullptr; \
239 : ((void)0
240 : #define DUMMY ) // to make indentation work
241 : #undef DUMMY
242 :
243 : // ----------------------------------------------------------------------------
244 : // Implementation of Parser
245 :
246 12609988 : bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
247 : Expression* y,
248 : Token::Value op, int pos) {
249 31163432 : if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
250 15103570 : y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
251 1447518 : double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
252 1447518 : double y_val = y->AsLiteral()->raw_value()->AsNumber();
253 1447518 : bool x_has_dot = (*x)->AsLiteral()->raw_value()->ContainsDot();
254 723759 : bool y_has_dot = y->AsLiteral()->raw_value()->ContainsDot();
255 723759 : bool has_dot = x_has_dot || y_has_dot;
256 723759 : switch (op) {
257 : case Token::ADD:
258 24837 : *x = factory()->NewNumberLiteral(x_val + y_val, pos, has_dot);
259 24837 : return true;
260 : case Token::SUB:
261 1777 : *x = factory()->NewNumberLiteral(x_val - y_val, pos, has_dot);
262 1777 : return true;
263 : case Token::MUL:
264 356884 : *x = factory()->NewNumberLiteral(x_val * y_val, pos, has_dot);
265 356884 : return true;
266 : case Token::DIV:
267 6219 : *x = factory()->NewNumberLiteral(x_val / y_val, pos, has_dot);
268 6219 : return true;
269 : case Token::BIT_OR: {
270 82369 : int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
271 82369 : *x = factory()->NewNumberLiteral(value, pos, has_dot);
272 82369 : return true;
273 : }
274 : case Token::BIT_AND: {
275 570 : int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
276 570 : *x = factory()->NewNumberLiteral(value, pos, has_dot);
277 570 : return true;
278 : }
279 : case Token::BIT_XOR: {
280 332 : int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
281 332 : *x = factory()->NewNumberLiteral(value, pos, has_dot);
282 332 : return true;
283 : }
284 : case Token::SHL: {
285 225798 : int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
286 225798 : *x = factory()->NewNumberLiteral(value, pos, has_dot);
287 225798 : return true;
288 : }
289 : case Token::SHR: {
290 677 : uint32_t shift = DoubleToInt32(y_val) & 0x1f;
291 677 : uint32_t value = DoubleToUint32(x_val) >> shift;
292 677 : *x = factory()->NewNumberLiteral(value, pos, has_dot);
293 677 : return true;
294 : }
295 : case Token::SAR: {
296 8810 : uint32_t shift = DoubleToInt32(y_val) & 0x1f;
297 8810 : int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
298 8810 : *x = factory()->NewNumberLiteral(value, pos, has_dot);
299 8810 : return true;
300 : }
301 : case Token::EXP: {
302 428 : double value = Pow(x_val, y_val);
303 428 : int int_value = static_cast<int>(value);
304 : *x = factory()->NewNumberLiteral(
305 633 : int_value == value && value != -0.0 ? int_value : value, pos,
306 1284 : has_dot);
307 428 : return true;
308 : }
309 : default:
310 : break;
311 : }
312 : }
313 : return false;
314 : }
315 :
316 3151268 : Expression* Parser::BuildUnaryExpression(Expression* expression,
317 : Token::Value op, int pos) {
318 : DCHECK(expression != NULL);
319 3151268 : if (expression->IsLiteral()) {
320 2520810 : const AstValue* literal = expression->AsLiteral()->raw_value();
321 1260405 : if (op == Token::NOT) {
322 : // Convert the literal to a boolean condition and negate it.
323 411 : bool condition = literal->BooleanValue();
324 411 : return factory()->NewBooleanLiteral(!condition, pos);
325 1259994 : } else if (literal->IsNumber()) {
326 : // Compute some expressions involving only number literals.
327 1258916 : double value = literal->AsNumber();
328 : bool has_dot = literal->ContainsDot();
329 1258916 : switch (op) {
330 : case Token::ADD:
331 : return expression;
332 : case Token::SUB:
333 722832 : return factory()->NewNumberLiteral(-value, pos, has_dot);
334 : case Token::BIT_NOT:
335 828 : return factory()->NewNumberLiteral(~DoubleToInt32(value), pos,
336 1656 : has_dot);
337 : default:
338 : break;
339 : }
340 : }
341 : }
342 : // Desugar '+foo' => 'foo*1'
343 2424918 : if (op == Token::ADD) {
344 : return factory()->NewBinaryOperation(
345 68519 : Token::MUL, expression, factory()->NewNumberLiteral(1, pos, true), pos);
346 : }
347 : // The same idea for '-foo' => 'foo*(-1)'.
348 2356399 : if (op == Token::SUB) {
349 : return factory()->NewBinaryOperation(
350 41410 : Token::MUL, expression, factory()->NewNumberLiteral(-1, pos), pos);
351 : }
352 : // ...and one more time for '~foo' => 'foo^(~0)'.
353 2314989 : if (op == Token::BIT_NOT) {
354 : return factory()->NewBinaryOperation(
355 7474 : Token::BIT_XOR, expression, factory()->NewNumberLiteral(~0, pos), pos);
356 : }
357 4615031 : return factory()->NewUnaryOperation(op, expression, pos);
358 : }
359 :
360 41204 : Expression* Parser::BuildIteratorResult(Expression* value, bool done) {
361 : int pos = kNoSourcePosition;
362 :
363 123612 : if (value == nullptr) value = factory()->NewUndefinedLiteral(pos);
364 :
365 41204 : auto args = new (zone()) ZoneList<Expression*>(2, zone());
366 : args->Add(value, zone());
367 41204 : args->Add(factory()->NewBooleanLiteral(done, pos), zone());
368 :
369 : return factory()->NewCallRuntime(Runtime::kInlineCreateIterResultObject, args,
370 41204 : pos);
371 : }
372 :
373 381382 : Expression* Parser::NewThrowError(Runtime::FunctionId id,
374 : MessageTemplate::Template message,
375 : const AstRawString* arg, int pos) {
376 1144146 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
377 381382 : args->Add(factory()->NewSmiLiteral(message, pos), zone());
378 381382 : args->Add(factory()->NewStringLiteral(arg, pos), zone());
379 381382 : CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
380 762764 : return factory()->NewThrow(call_constructor, pos);
381 : }
382 :
383 6119 : Expression* Parser::NewSuperPropertyReference(int pos) {
384 : // this_function[home_object_symbol]
385 : VariableProxy* this_function_proxy =
386 6119 : NewUnresolved(ast_value_factory()->this_function_string(), pos);
387 : Expression* home_object_symbol_literal = factory()->NewSymbolLiteral(
388 6119 : AstSymbol::kHomeObjectSymbol, kNoSourcePosition);
389 : Expression* home_object = factory()->NewProperty(
390 6119 : this_function_proxy, home_object_symbol_literal, pos);
391 : return factory()->NewSuperPropertyReference(
392 18357 : ThisExpression(pos)->AsVariableProxy(), home_object, pos);
393 : }
394 :
395 21195 : Expression* Parser::NewSuperCallReference(int pos) {
396 : VariableProxy* new_target_proxy =
397 42390 : NewUnresolved(ast_value_factory()->new_target_string(), pos);
398 : VariableProxy* this_function_proxy =
399 21195 : NewUnresolved(ast_value_factory()->this_function_string(), pos);
400 : return factory()->NewSuperCallReference(
401 : ThisExpression(pos)->AsVariableProxy(), new_target_proxy,
402 63585 : this_function_proxy, pos);
403 : }
404 :
405 25292 : Expression* Parser::NewTargetExpression(int pos) {
406 25292 : auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
407 : proxy->set_is_new_target();
408 25292 : return proxy;
409 : }
410 :
411 2641 : Expression* Parser::FunctionSentExpression(int pos) {
412 : // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
413 7923 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
414 : VariableProxy* generator =
415 5282 : factory()->NewVariableProxy(function_state_->generator_object_variable());
416 : args->Add(generator, zone());
417 : return factory()->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
418 2641 : args, pos);
419 : }
420 :
421 31910582 : Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
422 31910582 : switch (token) {
423 : case Token::NULL_LITERAL:
424 32241978 : return factory()->NewNullLiteral(pos);
425 : case Token::TRUE_LITERAL:
426 626092 : return factory()->NewBooleanLiteral(true, pos);
427 : case Token::FALSE_LITERAL:
428 787877 : return factory()->NewBooleanLiteral(false, pos);
429 : case Token::SMI: {
430 28080761 : uint32_t value = scanner()->smi_value();
431 28080761 : return factory()->NewSmiLiteral(value, pos);
432 : }
433 : case Token::NUMBER: {
434 1745359 : bool has_dot = scanner()->ContainsDot();
435 1745359 : double value = scanner()->DoubleValue();
436 1745359 : return factory()->NewNumberLiteral(value, pos, has_dot);
437 : }
438 : default:
439 : DCHECK(false);
440 : }
441 : return NULL;
442 : }
443 :
444 : void Parser::MarkTailPosition(Expression* expression) {
445 10304 : expression->MarkTail();
446 : }
447 :
448 : Expression* Parser::NewV8Intrinsic(const AstRawString* name,
449 : ZoneList<Expression*>* args, int pos,
450 : bool* ok) {
451 2231180 : if (extension_ != nullptr) {
452 : // The extension structures are only accessible while parsing the
453 : // very first time, not when reparsing because of lazy compilation.
454 6 : GetClosureScope()->ForceEagerCompilation();
455 : }
456 :
457 : DCHECK(name->is_one_byte());
458 : const Runtime::Function* function =
459 2231180 : Runtime::FunctionForName(name->raw_data(), name->length());
460 :
461 2231180 : if (function != nullptr) {
462 : // Check for possible name clash.
463 : DCHECK_EQ(Context::kNotFound,
464 : Context::IntrinsicIndexForName(name->raw_data(), name->length()));
465 : // Check for built-in IS_VAR macro.
466 1989254 : if (function->function_id == Runtime::kIS_VAR) {
467 : DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
468 : // %IS_VAR(x) evaluates to x if x is a variable,
469 : // leads to a parse error otherwise. Could be implemented as an
470 : // inline function %_IS_VAR(x) to eliminate this special case.
471 1737612 : if (args->length() == 1 && args->at(0)->AsVariableProxy() != nullptr) {
472 21680 : return args->at(0);
473 : } else {
474 0 : ReportMessage(MessageTemplate::kNotIsvar);
475 0 : *ok = false;
476 : return nullptr;
477 : }
478 : }
479 :
480 : // Check that the expected number of arguments are being passed.
481 3661826 : if (function->nargs != -1 && function->nargs != args->length()) {
482 0 : ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
483 0 : *ok = false;
484 : return nullptr;
485 : }
486 :
487 1967574 : return factory()->NewCallRuntime(function, args, pos);
488 : }
489 :
490 : int context_index =
491 241926 : Context::IntrinsicIndexForName(name->raw_data(), name->length());
492 :
493 : // Check that the function is defined.
494 241926 : if (context_index == Context::kNotFound) {
495 75 : ReportMessage(MessageTemplate::kNotDefined, name);
496 75 : *ok = false;
497 : return nullptr;
498 : }
499 :
500 241851 : return factory()->NewCallRuntime(context_index, args, pos);
501 : }
502 :
503 27711683 : Parser::Parser(ParseInfo* info)
504 : : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
505 : info->extension(), info->ast_value_factory(),
506 : info->runtime_call_stats(),
507 : info->preparsed_scope_data(), true),
508 : scanner_(info->unicode_cache()),
509 : reusable_preparser_(nullptr),
510 : mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
511 : target_stack_(nullptr),
512 : compile_options_(info->compile_options()),
513 : cached_parse_data_(nullptr),
514 : total_preparse_skipped_(0),
515 : temp_zoned_(false),
516 : log_(nullptr),
517 24861392 : parameters_end_pos_(info->parameters_end_pos()) {
518 : // Even though we were passed ParseInfo, we should not store it in
519 : // Parser - this makes sure that Isolate is not accidentally accessed via
520 : // ParseInfo during background parsing.
521 : DCHECK(!info->script().is_null() || info->source_stream() != nullptr ||
522 : info->character_stream() != nullptr);
523 : // Determine if functions can be lazily compiled. This is necessary to
524 : // allow some of our builtin JS files to be lazily compiled. These
525 : // builtins cannot be handled lazily by the parser, since we have to know
526 : // if a function uses the special natives syntax, which is something the
527 : // parser records.
528 : // If the debugger requests compilation for break points, we cannot be
529 : // aggressive about lazy compilation, because it might trigger compilation
530 : // of functions without an outer context when setting a breakpoint through
531 : // Debug::FindSharedFunctionInfoInScript
532 7142918 : bool can_compile_lazily = FLAG_lazy && !info->is_debug();
533 :
534 : // Consider compiling eagerly when targeting the code cache.
535 3571939 : can_compile_lazily &= !(FLAG_serialize_eager && info->will_serialize());
536 :
537 : set_default_eager_compile_hint(can_compile_lazily
538 : ? FunctionLiteral::kShouldLazyCompile
539 3571936 : : FunctionLiteral::kShouldEagerCompile);
540 9684761 : allow_lazy_ = FLAG_lazy && info->allow_lazy_parsing() && !info->is_native() &&
541 6417499 : info->extension() == nullptr && can_compile_lazily;
542 5776605 : set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
543 3590705 : set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() &&
544 : info->is_tail_call_elimination_enabled());
545 3571936 : set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
546 3571936 : set_allow_harmony_function_sent(FLAG_harmony_function_sent);
547 3571936 : set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators);
548 3571936 : set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas);
549 3571936 : set_allow_harmony_class_fields(FLAG_harmony_class_fields);
550 3571936 : set_allow_harmony_object_rest_spread(FLAG_harmony_object_rest_spread);
551 3571936 : set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import);
552 3571936 : set_allow_harmony_async_iteration(FLAG_harmony_async_iteration);
553 3571936 : set_allow_harmony_template_escapes(FLAG_harmony_template_escapes);
554 142877089 : for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
555 : ++feature) {
556 139305153 : use_counts_[feature] = 0;
557 : }
558 3571936 : if (info->ast_value_factory() == NULL) {
559 : // info takes ownership of AstValueFactory.
560 : info->set_ast_value_factory(new AstValueFactory(
561 3429773 : zone(), info->ast_string_constants(), info->hash_seed()));
562 : info->set_ast_value_factory_owned();
563 3429793 : ast_value_factory_ = info->ast_value_factory();
564 : ast_node_factory_.set_ast_value_factory(ast_value_factory_);
565 : }
566 3571956 : }
567 :
568 3567735 : void Parser::DeserializeScopeChain(
569 : ParseInfo* info, MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
570 : // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
571 : // context, which will have the "this" binding for script scopes.
572 6967193 : DeclarationScope* script_scope = NewScriptScope();
573 : info->set_script_scope(script_scope);
574 : Scope* scope = script_scope;
575 : Handle<ScopeInfo> outer_scope_info;
576 3567716 : if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
577 : DCHECK(ThreadId::Current().Equals(
578 : outer_scope_info->GetIsolate()->thread_id()));
579 : scope = Scope::DeserializeScopeChain(
580 : zone(), *outer_scope_info, script_scope, ast_value_factory(),
581 1699729 : Scope::DeserializationMode::kScopesOnly);
582 : DCHECK(!info->is_module() || scope->is_module_scope());
583 : }
584 3567716 : original_scope_ = scope;
585 3567716 : }
586 :
587 9053534 : FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
588 : // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
589 : // see comment for HistogramTimerScope class.
590 :
591 : // It's OK to use the Isolate & counters here, since this function is only
592 : // called in the main thread.
593 : DCHECK(parsing_on_main_thread_);
594 : RuntimeCallTimerScope runtime_timer(
595 : runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval
596 2263349 : : &RuntimeCallStats::ParseProgram);
597 6790060 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
598 : Handle<String> source(String::cast(info->script()->source()));
599 2263352 : isolate->counters()->total_parse_size()->Increment(source->length());
600 : base::ElapsedTimer timer;
601 2263354 : if (FLAG_trace_parse) {
602 : timer.Start();
603 : }
604 4526707 : fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
605 :
606 : // Initialize parser state.
607 2263352 : ParserLogger logger;
608 :
609 2263355 : if (produce_cached_parse_data()) {
610 138 : if (allow_lazy_) {
611 138 : log_ = &logger;
612 : } else {
613 0 : compile_options_ = ScriptCompiler::kNoCompileOptions;
614 : }
615 2263217 : } else if (consume_cached_parse_data()) {
616 66 : cached_parse_data_->Initialize();
617 : }
618 :
619 2263355 : DeserializeScopeChain(info, info->maybe_outer_scope_info());
620 :
621 2263345 : source = String::Flatten(source);
622 : FunctionLiteral* result;
623 :
624 : {
625 2263344 : std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(source));
626 2263354 : if (FLAG_use_parse_tasks) {
627 : // FIXME(wiktorg) make it useful for something
628 : // TODO(wiktorg) make preparser work also with modules
629 0 : if (!info->is_module()) {
630 0 : scanner_.Initialize(stream.get());
631 : // NOTE: Some features will be double counted - once here and one more
632 : // time while being fully parsed by a parse task.
633 : PreParser::PreParseResult result =
634 0 : reusable_preparser()->PreParseProgram(false, use_counts_);
635 0 : if (result == PreParser::kPreParseStackOverflow) {
636 : set_stack_overflow();
637 : return nullptr;
638 : }
639 0 : stream->Seek(0);
640 : }
641 : }
642 2263354 : scanner_.Initialize(stream.get());
643 2263351 : result = DoParseProgram(info);
644 : }
645 : if (result != NULL) {
646 : DCHECK_EQ(scanner_.peek_location().beg_pos, source->length());
647 : }
648 2263353 : HandleSourceURLComments(isolate, info->script());
649 :
650 2263349 : if (FLAG_trace_parse && result != nullptr) {
651 0 : double ms = timer.Elapsed().InMillisecondsF();
652 0 : if (info->is_eval()) {
653 0 : PrintF("[parsing eval");
654 0 : } else if (info->script()->name()->IsString()) {
655 : String* name = String::cast(info->script()->name());
656 0 : std::unique_ptr<char[]> name_chars = name->ToCString();
657 0 : PrintF("[parsing script: %s", name_chars.get());
658 : } else {
659 0 : PrintF("[parsing script");
660 : }
661 0 : PrintF(" - took %0.3f ms]\n", ms);
662 : }
663 2263340 : if (produce_cached_parse_data() && result != nullptr) {
664 138 : *info->cached_data() = logger.GetScriptData();
665 : }
666 2263340 : log_ = nullptr;
667 2263340 : return result;
668 : }
669 :
670 :
671 2281272 : FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
672 : // Note that this function can be called from the main thread or from a
673 : // background thread. We should not access anything Isolate / heap dependent
674 : // via ParseInfo, and also not pass it forward.
675 : DCHECK_NULL(scope_);
676 : DCHECK_NULL(target_stack_);
677 :
678 2263486 : ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
679 11632563 : ResetFunctionLiteralId();
680 : DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel ||
681 : info->function_literal_id() == FunctionLiteral::kIdTypeInvalid);
682 :
683 : FunctionLiteral* result = NULL;
684 : {
685 2263486 : Scope* outer = original_scope_;
686 : DCHECK_NOT_NULL(outer);
687 2263486 : parsing_module_ = info->is_module();
688 2263486 : if (info->is_eval()) {
689 1400404 : outer = NewEvalScope(outer);
690 863082 : } else if (parsing_module_) {
691 : DCHECK_EQ(outer, info->script_scope());
692 17786 : outer = NewModuleScope(info->script_scope());
693 : }
694 :
695 2263486 : DeclarationScope* scope = outer->AsDeclarationScope();
696 :
697 : scope->set_start_position(0);
698 :
699 2263480 : FunctionState function_state(&function_state_, &scope_, scope);
700 :
701 2263485 : ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
702 2263470 : bool ok = true;
703 : int beg_pos = scanner()->location().beg_pos;
704 2263470 : if (parsing_module_) {
705 : // Declare the special module parameter.
706 17786 : auto name = ast_value_factory()->empty_string();
707 : bool is_duplicate;
708 : bool is_rest = false;
709 : bool is_optional = false;
710 : auto var =
711 : scope->DeclareParameter(name, VAR, is_optional, is_rest,
712 17786 : &is_duplicate, ast_value_factory(), beg_pos);
713 : DCHECK(!is_duplicate);
714 : var->AllocateTo(VariableLocation::PARAMETER, 0);
715 :
716 17786 : PrepareGeneratorVariables();
717 : Expression* initial_yield =
718 17786 : BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
719 : body->Add(
720 17786 : factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
721 : zone());
722 :
723 17786 : ParseModuleItemList(body, &ok);
724 25244 : ok = ok &&
725 : module()->Validate(this->scope()->AsModuleScope(),
726 40160 : &pending_error_handler_, zone());
727 : } else {
728 : // Don't count the mode in the use counters--give the program a chance
729 : // to enable script-wide strict mode below.
730 : this->scope()->SetLanguageMode(info->language_mode());
731 2245684 : ParseStatementList(body, Token::EOS, &ok);
732 : }
733 :
734 : // The parser will peek but not consume EOS. Our scope logically goes all
735 : // the way to the EOS, though.
736 : scope->set_end_position(scanner()->peek_location().beg_pos);
737 :
738 4172862 : if (ok && is_strict(language_mode())) {
739 282474 : CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
740 : }
741 4172517 : if (ok && is_sloppy(language_mode())) {
742 : // TODO(littledan): Function bindings on the global object that modify
743 : // pre-existing bindings should be made writable, enumerable and
744 : // nonconfigurable if possible, whereas this code will leave attributes
745 : // unchanged if the property already exists.
746 1626909 : InsertSloppyBlockFunctionVarBindings(scope);
747 : }
748 2263479 : if (ok) {
749 1909038 : CheckConflictingVarDeclarations(scope, &ok);
750 : }
751 :
752 4147331 : if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
753 1371087 : if (body->length() != 1 ||
754 1371072 : !body->at(0)->IsExpressionStatement() ||
755 : !body->at(0)->AsExpressionStatement()->
756 914038 : expression()->IsFunctionLiteral()) {
757 30 : ReportMessage(MessageTemplate::kSingleFunctionLiteral);
758 30 : ok = false;
759 : }
760 : }
761 :
762 2263479 : if (ok) {
763 : RewriteDestructuringAssignments();
764 1883814 : int parameter_count = parsing_module_ ? 1 : 0;
765 : result = factory()->NewScriptOrEvalFunctionLiteral(
766 : scope, body, function_state.expected_property_count(),
767 1883814 : parameter_count);
768 : }
769 : }
770 :
771 : info->set_max_function_literal_id(GetLastFunctionLiteralId());
772 :
773 : // Make sure the target stack is empty.
774 : DCHECK(target_stack_ == NULL);
775 :
776 2263486 : return result;
777 : }
778 :
779 3912656 : FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) {
780 : // It's OK to use the Isolate & counters here, since this function is only
781 : // called in the main thread.
782 : DCHECK(parsing_on_main_thread_);
783 : RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
784 1304219 : &RuntimeCallStats::ParseFunction);
785 3912657 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
786 : Handle<String> source(String::cast(info->script()->source()));
787 1304219 : isolate->counters()->total_parse_size()->Increment(source->length());
788 : base::ElapsedTimer timer;
789 1304219 : if (FLAG_trace_parse) {
790 : timer.Start();
791 : }
792 : Handle<SharedFunctionInfo> shared_info = info->shared_info();
793 1304219 : DeserializeScopeChain(info, info->maybe_outer_scope_info());
794 1304218 : if (info->asm_function_scope()) {
795 11262 : original_scope_ = info->asm_function_scope();
796 1304219 : factory()->set_zone(info->zone());
797 : } else {
798 : DCHECK_EQ(factory()->zone(), info->zone());
799 : }
800 :
801 : // Initialize parser state.
802 1304218 : source = String::Flatten(source);
803 : FunctionLiteral* result;
804 : {
805 : std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
806 1304219 : source, shared_info->start_position(), shared_info->end_position()));
807 : Handle<String> name(String::cast(shared_info->name()));
808 1304219 : scanner_.Initialize(stream.get());
809 1304219 : info->set_function_name(ast_value_factory()->GetString(name));
810 1304218 : result = DoParseFunction(info);
811 1304218 : if (result != nullptr) {
812 1297591 : Handle<String> inferred_name(shared_info->inferred_name());
813 : result->set_inferred_name(inferred_name);
814 : }
815 : }
816 :
817 1304219 : if (FLAG_trace_parse && result != NULL) {
818 0 : double ms = timer.Elapsed().InMillisecondsF();
819 : // We need to make sure that the debug-name is available.
820 0 : ast_value_factory()->Internalize(isolate);
821 0 : std::unique_ptr<char[]> name_chars = result->debug_name()->ToCString();
822 0 : PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
823 : }
824 1304219 : return result;
825 : }
826 :
827 1304247 : static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
828 1304247 : if (info->is_declaration()) {
829 : return FunctionLiteral::kDeclaration;
830 655180 : } else if (info->is_named_expression()) {
831 : return FunctionLiteral::kNamedExpression;
832 1560950 : } else if (IsConciseMethod(info->function_kind()) ||
833 460762 : IsAccessorFunction(info->function_kind())) {
834 : return FunctionLiteral::kAccessorOrMethod;
835 : }
836 453256 : return FunctionLiteral::kAnonymousExpression;
837 : }
838 :
839 2774948 : FunctionLiteral* Parser::DoParseFunction(ParseInfo* info) {
840 : const AstRawString* raw_name = info->function_name();
841 : FunctionNameValidity function_name_validity = kSkipFunctionNameCheck;
842 1304246 : if (!raw_name) {
843 1 : bool ok = true;
844 1409504 : if (peek() == Token::LPAREN) {
845 : const AstRawString* variable_name;
846 : impl()->GetDefaultStrings(&raw_name, &variable_name);
847 : } else {
848 0 : bool is_strict_reserved = true;
849 0 : raw_name = ParseIdentifierOrStrictReservedWord(info->function_kind(),
850 0 : &is_strict_reserved, &ok);
851 0 : if (!ok) return nullptr;
852 : function_name_validity = is_strict_reserved
853 : ? kFunctionNameIsStrictReserved
854 0 : : kFunctionNameValidityUnknown;
855 : }
856 : }
857 :
858 : DCHECK_NOT_NULL(raw_name);
859 : DCHECK_NULL(scope_);
860 : DCHECK_NULL(target_stack_);
861 :
862 : DCHECK(ast_value_factory());
863 1304246 : fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
864 1304247 : fni_->PushEnclosingName(raw_name);
865 :
866 : ResetFunctionLiteralId();
867 : DCHECK_LT(0, info->function_literal_id());
868 1304247 : SkipFunctionLiterals(info->function_literal_id() - 1);
869 :
870 : ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
871 :
872 : // Place holder for the result.
873 : FunctionLiteral* result = nullptr;
874 :
875 : {
876 : // Parse the function literal.
877 1304247 : Scope* outer = original_scope_;
878 1304247 : DeclarationScope* outer_function = outer->GetClosureScope();
879 : DCHECK(outer);
880 1304247 : FunctionState function_state(&function_state_, &scope_, outer_function);
881 : BlockState block_state(&scope_, outer);
882 : DCHECK(is_sloppy(outer->language_mode()) ||
883 : is_strict(info->language_mode()));
884 1304247 : FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
885 1304247 : FunctionKind kind = info->function_kind();
886 1304247 : bool ok = true;
887 :
888 1304247 : if (IsArrowFunction(kind)) {
889 53051 : if (IsAsyncFunction(kind)) {
890 : DCHECK(!scanner()->HasAnyLineTerminatorAfterNext());
891 1137 : if (!Check(Token::ASYNC)) {
892 1 : CHECK(stack_overflow());
893 155 : return nullptr;
894 : }
895 2244 : if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
896 154 : CHECK(stack_overflow());
897 : return nullptr;
898 : }
899 : }
900 :
901 : // TODO(adamk): We should construct this scope from the ScopeInfo.
902 52897 : DeclarationScope* scope = NewFunctionScope(kind);
903 :
904 : // This bit only needs to be explicitly set because we're
905 : // not passing the ScopeInfo to the Scope constructor.
906 52897 : SetLanguageMode(scope, info->language_mode());
907 :
908 : scope->set_start_position(info->start_position());
909 52897 : ExpressionClassifier formals_classifier(this);
910 : ParserFormalParameters formals(scope);
911 : int rewritable_length =
912 52897 : function_state.destructuring_assignments_to_rewrite().length();
913 : {
914 : // Parsing patterns as variable reference expression creates
915 : // NewUnresolved references in current scope. Enter arrow function
916 : // scope for formal parameter parsing.
917 : BlockState block_state(&scope_, scope);
918 52897 : if (Check(Token::LPAREN)) {
919 : // '(' StrictFormalParameters ')'
920 42968 : ParseFormalParameterList(&formals, &ok);
921 42968 : if (ok) ok = Check(Token::RPAREN);
922 : } else {
923 : // BindingIdentifier
924 9929 : ParseFormalParameter(&formals, &ok);
925 9929 : if (ok) DeclareFormalParameters(formals.scope, formals.params);
926 : }
927 : }
928 :
929 52897 : if (ok) {
930 52793 : if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
931 : // If there were FunctionLiterals in the parameters, we need to
932 : // renumber them to shift down so the next function literal id for
933 : // the arrow function is the one requested.
934 : AstFunctionLiteralIdReindexer reindexer(
935 : stack_limit_,
936 299 : (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
937 1000 : for (auto p : formals.params) {
938 402 : if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
939 402 : if (p->initializer != nullptr) reindexer.Reindex(p->initializer);
940 : }
941 : ResetFunctionLiteralId();
942 598 : SkipFunctionLiterals(info->function_literal_id() - 1);
943 : }
944 :
945 : // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
946 : // not be observable, or else the preparser would have failed.
947 : Expression* expression =
948 52793 : ParseArrowFunctionLiteral(true, formals, rewritable_length, &ok);
949 52793 : if (ok) {
950 : // Scanning must end at the same position that was recorded
951 : // previously. If not, parsing has been interrupted due to a stack
952 : // overflow, at which point the partially parsed arrow function
953 : // concise body happens to be a valid expression. This is a problem
954 : // only for arrow functions with single expression bodies, since there
955 : // is no end token such as "}" for normal functions.
956 52309 : if (scanner()->location().end_pos == info->end_position()) {
957 : // The pre-parser saw an arrow function here, so the full parser
958 : // must produce a FunctionLiteral.
959 : DCHECK(expression->IsFunctionLiteral());
960 52309 : result = expression->AsFunctionLiteral();
961 : // Rewrite destructuring assignments in the parameters. (The ones
962 : // inside the function body are rewritten by
963 : // ParseArrowFunctionLiteral.)
964 : RewriteDestructuringAssignments();
965 : } else {
966 0 : ok = false;
967 : }
968 : }
969 : }
970 1251196 : } else if (IsDefaultConstructor(kind)) {
971 : DCHECK_EQ(scope(), outer);
972 : result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
973 8157 : info->start_position(), info->end_position());
974 : } else {
975 : result = ParseFunctionLiteral(
976 : raw_name, Scanner::Location::invalid(), function_name_validity, kind,
977 1243039 : kNoSourcePosition, function_type, info->language_mode(), &ok);
978 : }
979 : // Make sure the results agree.
980 : DCHECK(ok == (result != nullptr));
981 : }
982 :
983 : // Make sure the target stack is empty.
984 : DCHECK_NULL(target_stack_);
985 : DCHECK_IMPLIES(result,
986 : info->function_literal_id() == result->function_literal_id());
987 1304092 : return result;
988 : }
989 :
990 101084 : Statement* Parser::ParseModuleItem(bool* ok) {
991 : // ecma262/#prod-ModuleItem
992 : // ModuleItem :
993 : // ImportDeclaration
994 : // ExportDeclaration
995 : // StatementListItem
996 :
997 2289 : Token::Value next = peek();
998 :
999 101084 : if (next == Token::EXPORT) {
1000 2103 : return ParseExportDeclaration(ok);
1001 : }
1002 :
1003 : // We must be careful not to parse a dynamic import expression as an import
1004 : // declaration.
1005 200251 : if (next == Token::IMPORT &&
1006 690 : (!allow_harmony_dynamic_import() || PeekAhead() != Token::LPAREN)) {
1007 1941 : ParseImportDeclaration(CHECK_OK);
1008 1614 : return factory()->NewEmptyStatement(kNoSourcePosition);
1009 : }
1010 :
1011 97040 : return ParseStatementListItem(ok);
1012 : }
1013 :
1014 :
1015 17786 : void Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
1016 : // ecma262/#prod-Module
1017 : // Module :
1018 : // ModuleBody?
1019 : //
1020 : // ecma262/#prod-ModuleItemList
1021 : // ModuleBody :
1022 : // ModuleItem*
1023 :
1024 : DCHECK(scope()->is_module_scope());
1025 126328 : while (peek() != Token::EOS) {
1026 118870 : Statement* stat = ParseModuleItem(CHECK_OK_VOID);
1027 90756 : if (stat && !stat->IsEmpty()) {
1028 72136 : body->Add(stat, zone());
1029 : }
1030 : }
1031 : }
1032 :
1033 :
1034 1073 : const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
1035 : // ModuleSpecifier :
1036 : // StringLiteral
1037 :
1038 1073 : Expect(Token::STRING, CHECK_OK);
1039 1055 : return GetSymbol();
1040 : }
1041 :
1042 :
1043 575 : void Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
1044 : ZoneList<Scanner::Location>* export_locations,
1045 : ZoneList<const AstRawString*>* local_names,
1046 : Scanner::Location* reserved_loc, bool* ok) {
1047 : // ExportClause :
1048 : // '{' '}'
1049 : // '{' ExportsList '}'
1050 : // '{' ExportsList ',' '}'
1051 : //
1052 : // ExportsList :
1053 : // ExportSpecifier
1054 : // ExportsList ',' ExportSpecifier
1055 : //
1056 : // ExportSpecifier :
1057 : // IdentifierName
1058 : // IdentifierName 'as' IdentifierName
1059 :
1060 3262 : Expect(Token::LBRACE, CHECK_OK_VOID);
1061 :
1062 : Token::Value name_tok;
1063 676 : while ((name_tok = peek()) != Token::RBRACE) {
1064 : // Keep track of the first reserved word encountered in case our
1065 : // caller needs to report an error.
1066 1230 : if (!reserved_loc->IsValid() &&
1067 615 : !Token::IsIdentifier(name_tok, STRICT, false, parsing_module_)) {
1068 81 : *reserved_loc = scanner()->location();
1069 : }
1070 663 : const AstRawString* local_name = ParseIdentifierName(CHECK_OK_VOID);
1071 : const AstRawString* export_name = NULL;
1072 591 : Scanner::Location location = scanner()->location();
1073 591 : if (CheckContextualKeyword(Token::AS)) {
1074 290 : export_name = ParseIdentifierName(CHECK_OK_VOID);
1075 : // Set the location to the whole "a as b" string, so that it makes sense
1076 : // both for errors due to "a" and for errors due to "b".
1077 278 : location.end_pos = scanner()->location().end_pos;
1078 : }
1079 579 : if (export_name == NULL) {
1080 : export_name = local_name;
1081 : }
1082 : export_names->Add(export_name, zone());
1083 : local_names->Add(local_name, zone());
1084 : export_locations->Add(location, zone());
1085 579 : if (peek() == Token::RBRACE) break;
1086 113 : Expect(Token::COMMA, CHECK_OK_VOID);
1087 : }
1088 :
1089 527 : Expect(Token::RBRACE, CHECK_OK_VOID);
1090 : }
1091 :
1092 :
1093 804 : ZoneList<const Parser::NamedImport*>* Parser::ParseNamedImports(
1094 : int pos, bool* ok) {
1095 : // NamedImports :
1096 : // '{' '}'
1097 : // '{' ImportsList '}'
1098 : // '{' ImportsList ',' '}'
1099 : //
1100 : // ImportsList :
1101 : // ImportSpecifier
1102 : // ImportsList ',' ImportSpecifier
1103 : //
1104 : // ImportSpecifier :
1105 : // BindingIdentifier
1106 : // IdentifierName 'as' BindingIdentifier
1107 :
1108 4777 : Expect(Token::LBRACE, CHECK_OK);
1109 :
1110 804 : auto result = new (zone()) ZoneList<const NamedImport*>(1, zone());
1111 1729 : while (peek() != Token::RBRACE) {
1112 893 : const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1113 : const AstRawString* local_name = import_name;
1114 : Scanner::Location location = scanner()->location();
1115 : // In the presence of 'as', the left-side of the 'as' can
1116 : // be any IdentifierName. But without 'as', it must be a valid
1117 : // BindingIdentifier.
1118 827 : if (CheckContextualKeyword(Token::AS)) {
1119 374 : local_name = ParseIdentifierName(CHECK_OK);
1120 : }
1121 827 : if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false,
1122 1654 : parsing_module_)) {
1123 36 : *ok = false;
1124 36 : ReportMessage(MessageTemplate::kUnexpectedReserved);
1125 36 : return nullptr;
1126 791 : } else if (IsEvalOrArguments(local_name)) {
1127 18 : *ok = false;
1128 18 : ReportMessage(MessageTemplate::kStrictEvalArguments);
1129 18 : return nullptr;
1130 : }
1131 :
1132 : DeclareVariable(local_name, CONST, kNeedsInitialization, position(),
1133 773 : CHECK_OK);
1134 :
1135 : NamedImport* import =
1136 : new (zone()) NamedImport(import_name, local_name, location);
1137 : result->Add(import, zone());
1138 :
1139 773 : if (peek() == Token::RBRACE) break;
1140 169 : Expect(Token::COMMA, CHECK_OK);
1141 : }
1142 :
1143 636 : Expect(Token::RBRACE, CHECK_OK);
1144 636 : return result;
1145 : }
1146 :
1147 :
1148 1941 : void Parser::ParseImportDeclaration(bool* ok) {
1149 : // ImportDeclaration :
1150 : // 'import' ImportClause 'from' ModuleSpecifier ';'
1151 : // 'import' ModuleSpecifier ';'
1152 : //
1153 : // ImportClause :
1154 : // ImportedDefaultBinding
1155 : // NameSpaceImport
1156 : // NamedImports
1157 : // ImportedDefaultBinding ',' NameSpaceImport
1158 : // ImportedDefaultBinding ',' NamedImports
1159 : //
1160 : // NameSpaceImport :
1161 : // '*' 'as' ImportedBinding
1162 :
1163 2998 : int pos = peek_position();
1164 3164 : Expect(Token::IMPORT, CHECK_OK_VOID);
1165 :
1166 : Token::Value tok = peek();
1167 :
1168 : // 'import' ModuleSpecifier ';'
1169 1941 : if (tok == Token::STRING) {
1170 89 : const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
1171 89 : ExpectSemicolon(CHECK_OK_VOID);
1172 89 : module()->AddEmptyImport(module_specifier);
1173 89 : return;
1174 : }
1175 :
1176 : // Parse ImportedDefaultBinding if present.
1177 : const AstRawString* import_default_binding = nullptr;
1178 : Scanner::Location import_default_binding_loc;
1179 1852 : if (tok != Token::MUL && tok != Token::LBRACE) {
1180 : import_default_binding =
1181 926 : ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1182 86 : import_default_binding_loc = scanner()->location();
1183 : DeclareVariable(import_default_binding, CONST, kNeedsInitialization, pos,
1184 86 : CHECK_OK_VOID);
1185 : }
1186 :
1187 : // Parse NameSpaceImport or NamedImports if present.
1188 : const AstRawString* module_namespace_binding = nullptr;
1189 : Scanner::Location module_namespace_binding_loc;
1190 : const ZoneList<const NamedImport*>* named_imports = nullptr;
1191 1012 : if (import_default_binding == nullptr || Check(Token::COMMA)) {
1192 950 : switch (peek()) {
1193 : case Token::MUL: {
1194 134 : Consume(Token::MUL);
1195 134 : ExpectContextualKeyword(Token::AS, CHECK_OK_VOID);
1196 : module_namespace_binding =
1197 134 : ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1198 134 : module_namespace_binding_loc = scanner()->location();
1199 : DeclareVariable(module_namespace_binding, CONST, kCreatedInitialized,
1200 134 : pos, CHECK_OK_VOID);
1201 : break;
1202 : }
1203 :
1204 : case Token::LBRACE:
1205 804 : named_imports = ParseNamedImports(pos, CHECK_OK_VOID);
1206 : break;
1207 :
1208 : default:
1209 12 : *ok = false;
1210 12 : ReportUnexpectedToken(scanner()->current_token());
1211 12 : return;
1212 : }
1213 : }
1214 :
1215 832 : ExpectContextualKeyword(Token::FROM, CHECK_OK_VOID);
1216 724 : const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
1217 718 : ExpectSemicolon(CHECK_OK_VOID);
1218 :
1219 : // Now that we have all the information, we can make the appropriate
1220 : // declarations.
1221 :
1222 : // TODO(neis): Would prefer to call DeclareVariable for each case below rather
1223 : // than above and in ParseNamedImports, but then a possible error message
1224 : // would point to the wrong location. Maybe have a DeclareAt version of
1225 : // Declare that takes a location?
1226 :
1227 718 : if (module_namespace_binding != nullptr) {
1228 : module()->AddStarImport(module_namespace_binding, module_specifier,
1229 116 : module_namespace_binding_loc, zone());
1230 : }
1231 :
1232 718 : if (import_default_binding != nullptr) {
1233 : module()->AddImport(ast_value_factory()->default_string(),
1234 : import_default_binding, module_specifier,
1235 112 : import_default_binding_loc, zone());
1236 : }
1237 :
1238 718 : if (named_imports != nullptr) {
1239 1749 : if (named_imports->length() == 0) {
1240 20 : module()->AddEmptyImport(module_specifier);
1241 : } else {
1242 1844 : for (int i = 0; i < named_imports->length(); ++i) {
1243 653 : const NamedImport* import = named_imports->at(i);
1244 : module()->AddImport(import->import_name, import->local_name,
1245 1306 : module_specifier, import->location, zone());
1246 : }
1247 : }
1248 : }
1249 : }
1250 :
1251 :
1252 450 : Statement* Parser::ParseExportDefault(bool* ok) {
1253 : // Supports the following productions, starting after the 'default' token:
1254 : // 'export' 'default' HoistableDeclaration
1255 : // 'export' 'default' ClassDeclaration
1256 : // 'export' 'default' AssignmentExpression[In] ';'
1257 :
1258 2387 : Expect(Token::DEFAULT, CHECK_OK);
1259 450 : Scanner::Location default_loc = scanner()->location();
1260 :
1261 450 : ZoneList<const AstRawString*> local_names(1, zone());
1262 : Statement* result = nullptr;
1263 450 : switch (peek()) {
1264 : case Token::FUNCTION:
1265 79 : result = ParseHoistableDeclaration(&local_names, true, CHECK_OK);
1266 : break;
1267 :
1268 : case Token::CLASS:
1269 52 : Consume(Token::CLASS);
1270 52 : result = ParseClassDeclaration(&local_names, true, CHECK_OK);
1271 : break;
1272 :
1273 : case Token::ASYNC:
1274 144 : if (PeekAhead() == Token::FUNCTION &&
1275 : !scanner()->HasAnyLineTerminatorAfterNext()) {
1276 72 : Consume(Token::ASYNC);
1277 72 : result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK);
1278 : break;
1279 : }
1280 : /* falls through */
1281 :
1282 : default: {
1283 : int pos = position();
1284 247 : ExpressionClassifier classifier(this);
1285 247 : Expression* value = ParseAssignmentExpression(true, CHECK_OK);
1286 199 : RewriteNonPattern(CHECK_OK);
1287 398 : SetFunctionName(value, ast_value_factory()->default_string());
1288 :
1289 : const AstRawString* local_name =
1290 199 : ast_value_factory()->star_default_star_string();
1291 : local_names.Add(local_name, zone());
1292 :
1293 : // It's fine to declare this as CONST because the user has no way of
1294 : // writing to it.
1295 597 : Declaration* decl = DeclareVariable(local_name, CONST, pos, CHECK_OK);
1296 199 : decl->proxy()->var()->set_initializer_position(position());
1297 :
1298 : Assignment* assignment = factory()->NewAssignment(
1299 199 : Token::INIT, decl->proxy(), value, kNoSourcePosition);
1300 : result = IgnoreCompletion(
1301 199 : factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1302 :
1303 199 : ExpectSemicolon(CHECK_OK);
1304 : break;
1305 : }
1306 : }
1307 :
1308 : DCHECK_EQ(local_names.length(), 1);
1309 : module()->AddExport(local_names.first(),
1310 : ast_value_factory()->default_string(), default_loc,
1311 1116 : zone());
1312 :
1313 : DCHECK_NOT_NULL(result);
1314 372 : return result;
1315 : }
1316 :
1317 2103 : Statement* Parser::ParseExportDeclaration(bool* ok) {
1318 : // ExportDeclaration:
1319 : // 'export' '*' 'from' ModuleSpecifier ';'
1320 : // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1321 : // 'export' VariableStatement
1322 : // 'export' Declaration
1323 : // 'export' 'default' ... (handled in ParseExportDefault)
1324 :
1325 8414 : Expect(Token::EXPORT, CHECK_OK);
1326 : int pos = position();
1327 :
1328 : Statement* result = nullptr;
1329 2103 : ZoneList<const AstRawString*> names(1, zone());
1330 2103 : Scanner::Location loc = scanner()->peek_location();
1331 2103 : switch (peek()) {
1332 : case Token::DEFAULT:
1333 450 : return ParseExportDefault(ok);
1334 :
1335 : case Token::MUL: {
1336 134 : Consume(Token::MUL);
1337 134 : loc = scanner()->location();
1338 134 : ExpectContextualKeyword(Token::FROM, CHECK_OK);
1339 128 : const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1340 122 : ExpectSemicolon(CHECK_OK);
1341 122 : module()->AddStarExport(module_specifier, loc, zone());
1342 244 : return factory()->NewEmptyStatement(pos);
1343 : }
1344 :
1345 : case Token::LBRACE: {
1346 : // There are two cases here:
1347 : //
1348 : // 'export' ExportClause ';'
1349 : // and
1350 : // 'export' ExportClause FromClause ';'
1351 : //
1352 : // In the first case, the exported identifiers in ExportClause must
1353 : // not be reserved words, while in the latter they may be. We
1354 : // pass in a location that gets filled with the first reserved word
1355 : // encountered, and then throw a SyntaxError if we are in the
1356 : // non-FromClause case.
1357 575 : Scanner::Location reserved_loc = Scanner::Location::invalid();
1358 575 : ZoneList<const AstRawString*> export_names(1, zone());
1359 575 : ZoneList<Scanner::Location> export_locations(1, zone());
1360 575 : ZoneList<const AstRawString*> original_names(1, zone());
1361 : ParseExportClause(&export_names, &export_locations, &original_names,
1362 575 : &reserved_loc, CHECK_OK);
1363 : const AstRawString* module_specifier = nullptr;
1364 527 : if (CheckContextualKeyword(Token::FROM)) {
1365 132 : module_specifier = ParseModuleSpecifier(CHECK_OK);
1366 395 : } else if (reserved_loc.IsValid()) {
1367 : // No FromClause, so reserved words are invalid in ExportClause.
1368 12 : *ok = false;
1369 : ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1370 : return nullptr;
1371 : }
1372 509 : ExpectSemicolon(CHECK_OK);
1373 509 : const int length = export_names.length();
1374 : DCHECK_EQ(length, original_names.length());
1375 : DCHECK_EQ(length, export_locations.length());
1376 509 : if (module_specifier == nullptr) {
1377 425 : for (int i = 0; i < length; ++i) {
1378 850 : module()->AddExport(original_names[i], export_names[i],
1379 1700 : export_locations[i], zone());
1380 : }
1381 126 : } else if (length == 0) {
1382 35 : module()->AddEmptyImport(module_specifier);
1383 : } else {
1384 112 : for (int i = 0; i < length; ++i) {
1385 224 : module()->AddExport(original_names[i], export_names[i],
1386 448 : module_specifier, export_locations[i], zone());
1387 : }
1388 : }
1389 1018 : return factory()->NewEmptyStatement(pos);
1390 : }
1391 :
1392 : case Token::FUNCTION:
1393 332 : result = ParseHoistableDeclaration(&names, false, CHECK_OK);
1394 : break;
1395 :
1396 : case Token::CLASS:
1397 39 : Consume(Token::CLASS);
1398 39 : result = ParseClassDeclaration(&names, false, CHECK_OK);
1399 : break;
1400 :
1401 : case Token::VAR:
1402 : case Token::LET:
1403 : case Token::CONST:
1404 465 : result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1405 : break;
1406 :
1407 : case Token::ASYNC:
1408 : // TODO(neis): Why don't we have the same check here as in
1409 : // ParseStatementListItem?
1410 102 : Consume(Token::ASYNC);
1411 102 : result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK);
1412 : break;
1413 :
1414 : default:
1415 6 : *ok = false;
1416 6 : ReportUnexpectedToken(scanner()->current_token());
1417 6 : return nullptr;
1418 : }
1419 842 : loc.end_pos = scanner()->location().end_pos;
1420 :
1421 : ModuleDescriptor* descriptor = module();
1422 1684 : for (int i = 0; i < names.length(); ++i) {
1423 1684 : descriptor->AddExport(names[i], names[i], loc, zone());
1424 : }
1425 :
1426 : DCHECK_NOT_NULL(result);
1427 : return result;
1428 : }
1429 :
1430 86686319 : VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos,
1431 : VariableKind kind) {
1432 86760120 : return scope()->NewUnresolved(factory(), name, begin_pos, kind);
1433 : }
1434 :
1435 0 : VariableProxy* Parser::NewUnresolved(const AstRawString* name) {
1436 35407 : return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos);
1437 : }
1438 :
1439 56856 : Declaration* Parser::DeclareVariable(const AstRawString* name,
1440 : VariableMode mode, int pos, bool* ok) {
1441 : return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode),
1442 170455 : pos, ok);
1443 : }
1444 :
1445 171448 : Declaration* Parser::DeclareVariable(const AstRawString* name,
1446 : VariableMode mode, InitializationFlag init,
1447 : int pos, bool* ok) {
1448 : DCHECK_NOT_NULL(name);
1449 : VariableProxy* proxy = factory()->NewVariableProxy(
1450 514344 : name, NORMAL_VARIABLE, scanner()->location().beg_pos);
1451 : Declaration* declaration =
1452 171448 : factory()->NewVariableDeclaration(proxy, this->scope(), pos);
1453 : Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr,
1454 171448 : scanner()->location().end_pos);
1455 171448 : if (!*ok) return nullptr;
1456 165960 : return declaration;
1457 : }
1458 :
1459 16574958 : Variable* Parser::Declare(Declaration* declaration,
1460 : DeclarationDescriptor::Kind declaration_kind,
1461 : VariableMode mode, InitializationFlag init, bool* ok,
1462 : Scope* scope, int var_end_pos) {
1463 16419892 : if (scope == nullptr) {
1464 32838306 : scope = this->scope();
1465 : }
1466 16419892 : bool sloppy_mode_block_scope_function_redefinition = false;
1467 : Variable* variable = scope->DeclareVariable(
1468 : declaration, mode, init, allow_harmony_restrictive_generators(),
1469 16419892 : &sloppy_mode_block_scope_function_redefinition, ok);
1470 16419895 : if (!*ok) {
1471 : // If we only have the start position of a proxy, we can't highlight the
1472 : // whole variable name. Pretend its length is 1 so that we highlight at
1473 : // least the first character.
1474 : Scanner::Location loc(declaration->proxy()->position(),
1475 : var_end_pos != kNoSourcePosition
1476 : ? var_end_pos
1477 235343 : : declaration->proxy()->position() + 1);
1478 80277 : if (declaration_kind == DeclarationDescriptor::NORMAL) {
1479 : ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
1480 : declaration->proxy()->raw_name());
1481 : } else {
1482 : ReportMessageAt(loc, MessageTemplate::kParamDupe);
1483 : }
1484 : return nullptr;
1485 : }
1486 16339618 : if (sloppy_mode_block_scope_function_redefinition) {
1487 238 : ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1488 : }
1489 16339618 : return variable;
1490 : }
1491 :
1492 720937 : Block* Parser::BuildInitializationBlock(
1493 : DeclarationParsingResult* parsing_result,
1494 : ZoneList<const AstRawString*>* names, bool* ok) {
1495 : Block* result = factory()->NewBlock(
1496 720937 : NULL, 1, true, parsing_result->descriptor.declaration_pos);
1497 2189319 : for (auto declaration : parsing_result->declarations) {
1498 : PatternRewriter::DeclareAndInitializeVariables(
1499 : this, result, &(parsing_result->descriptor), &declaration, names,
1500 747473 : CHECK_OK);
1501 : }
1502 720909 : return result;
1503 : }
1504 :
1505 0 : void Parser::DeclareAndInitializeVariables(
1506 : Block* block, const DeclarationDescriptor* declaration_descriptor,
1507 : const DeclarationParsingResult::Declaration* declaration,
1508 : ZoneList<const AstRawString*>* names, bool* ok) {
1509 : DCHECK_NOT_NULL(block);
1510 : PatternRewriter::DeclareAndInitializeVariables(
1511 13356511 : this, block, declaration_descriptor, declaration, names, ok);
1512 0 : }
1513 :
1514 1752082 : Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1515 : FunctionLiteral* function, VariableMode mode,
1516 : int pos, bool is_sloppy_block_function,
1517 : ZoneList<const AstRawString*>* names,
1518 : bool* ok) {
1519 : VariableProxy* proxy =
1520 3515224 : factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE);
1521 :
1522 : Declaration* declaration =
1523 1752082 : factory()->NewFunctionDeclaration(proxy, function, scope(), pos);
1524 : Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
1525 1752082 : CHECK_OK);
1526 1749516 : if (names) names->Add(variable_name, zone());
1527 1749516 : if (is_sloppy_block_function) {
1528 : SloppyBlockFunctionStatement* statement =
1529 10583 : factory()->NewSloppyBlockFunctionStatement();
1530 : GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name, scope(),
1531 10583 : statement);
1532 10583 : return statement;
1533 : }
1534 3477866 : return factory()->NewEmptyStatement(kNoSourcePosition);
1535 : }
1536 :
1537 : Statement* Parser::DeclareClass(const AstRawString* variable_name,
1538 : Expression* value,
1539 : ZoneList<const AstRawString*>* names,
1540 : int class_token_pos, int end_pos, bool* ok) {
1541 96760 : Declaration* decl =
1542 53868 : DeclareVariable(variable_name, LET, class_token_pos, CHECK_OK);
1543 48380 : decl->proxy()->var()->set_initializer_position(end_pos);
1544 48380 : if (names) names->Add(variable_name, zone());
1545 :
1546 48380 : Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(),
1547 48380 : value, class_token_pos);
1548 : return IgnoreCompletion(
1549 48380 : factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1550 : }
1551 :
1552 : Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
1553 : // Make sure that the function containing the native declaration
1554 : // isn't lazily compiled. The extension structures are only
1555 : // accessible while parsing the first time not when reparsing
1556 : // because of lazy compilation.
1557 2988 : GetClosureScope()->ForceEagerCompilation();
1558 :
1559 : // TODO(1240846): It's weird that native function declarations are
1560 : // introduced dynamically when we meet their declarations, whereas
1561 : // other functions are set up when entering the surrounding scope.
1562 5976 : Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
1563 : NativeFunctionLiteral* lit =
1564 2988 : factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1565 : return factory()->NewExpressionStatement(
1566 2988 : factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1567 2988 : kNoSourcePosition),
1568 2988 : pos);
1569 : }
1570 :
1571 25158 : ZoneList<const AstRawString*>* Parser::DeclareLabel(
1572 : ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) {
1573 : DCHECK(IsIdentifier(var));
1574 : const AstRawString* label = var->raw_name();
1575 : // TODO(1240780): We don't check for redeclaration of labels
1576 : // during preparsing since keeping track of the set of active
1577 : // labels requires nontrivial changes to the way scopes are
1578 : // structured. However, these are probably changes we want to
1579 : // make later anyway so we should go back and fix this then.
1580 25158 : if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
1581 75133 : ReportMessage(MessageTemplate::kLabelRedeclaration, label);
1582 0 : *ok = false;
1583 0 : return nullptr;
1584 : }
1585 25158 : if (labels == nullptr) {
1586 24817 : labels = new (zone()) ZoneList<const AstRawString*>(1, zone());
1587 : }
1588 : labels->Add(label, zone());
1589 : // Remove the "ghost" variable that turned out to be a label
1590 : // from the top scope. This way, we don't try to resolve it
1591 : // during the scope processing.
1592 25158 : scope()->RemoveUnresolved(var);
1593 25158 : return labels;
1594 : }
1595 :
1596 0 : bool Parser::ContainsLabel(ZoneList<const AstRawString*>* labels,
1597 : const AstRawString* label) {
1598 : DCHECK_NOT_NULL(label);
1599 142162 : if (labels != nullptr) {
1600 54460 : for (int i = labels->length(); i-- > 0;) {
1601 25337 : if (labels->at(i) == label) return true;
1602 : }
1603 : }
1604 : return false;
1605 : }
1606 :
1607 : Block* Parser::IgnoreCompletion(Statement* statement) {
1608 652628 : Block* block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
1609 652628 : block->statements()->Add(statement, zone());
1610 : return block;
1611 : }
1612 :
1613 5379147 : Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
1614 10758303 : if (IsDerivedConstructor(function_state_->kind())) {
1615 : // For subclass constructors we need to return this in case of undefined;
1616 : // other primitive values trigger an exception in the ConstructStub.
1617 : //
1618 : // return expr;
1619 : //
1620 : // Is rewritten as:
1621 : //
1622 : // return (temp = expr) === undefined ? this : temp;
1623 :
1624 : // temp = expr
1625 874 : Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1626 : Assignment* assign = factory()->NewAssignment(
1627 1748 : Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
1628 :
1629 : // temp === undefined
1630 : Expression* is_undefined = factory()->NewCompareOperation(
1631 : Token::EQ_STRICT, assign,
1632 874 : factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
1633 :
1634 : // is_undefined ? this : temp
1635 : return_value =
1636 : factory()->NewConditional(is_undefined, ThisExpression(pos),
1637 1748 : factory()->NewVariableProxy(temp), pos);
1638 : }
1639 5379156 : return return_value;
1640 : }
1641 :
1642 760 : Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) {
1643 1520 : Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
1644 760 : DoExpression* expr = factory()->NewDoExpression(body, result, pos);
1645 760 : if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) {
1646 0 : *ok = false;
1647 0 : return nullptr;
1648 : }
1649 : return expr;
1650 : }
1651 :
1652 89081 : Statement* Parser::RewriteSwitchStatement(Expression* tag,
1653 : SwitchStatement* switch_statement,
1654 : ZoneList<CaseClause*>* cases,
1655 : Scope* scope) {
1656 : // In order to get the CaseClauses to execute in their own lexical scope,
1657 : // but without requiring downstream code to have special scope handling
1658 : // code for switch statements, desugar into blocks as follows:
1659 : // { // To group the statements--harmless to evaluate Expression in scope
1660 : // .tag_variable = Expression;
1661 : // { // To give CaseClauses a scope
1662 : // switch (.tag_variable) { CaseClause* }
1663 : // }
1664 : // }
1665 :
1666 445405 : Block* switch_block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition);
1667 :
1668 : Variable* tag_variable =
1669 89081 : NewTemporary(ast_value_factory()->dot_switch_tag_string());
1670 : Assignment* tag_assign = factory()->NewAssignment(
1671 89081 : Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
1672 178162 : tag->position());
1673 : Statement* tag_statement =
1674 89081 : factory()->NewExpressionStatement(tag_assign, kNoSourcePosition);
1675 : switch_block->statements()->Add(tag_statement, zone());
1676 :
1677 : // make statement: undefined;
1678 : // This is needed so the tag isn't returned as the value, in case the switch
1679 : // statements don't have a value.
1680 : switch_block->statements()->Add(
1681 : factory()->NewExpressionStatement(
1682 89081 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
1683 : zone());
1684 :
1685 89081 : Expression* tag_read = factory()->NewVariableProxy(tag_variable);
1686 : switch_statement->Initialize(tag_read, cases);
1687 89081 : Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition);
1688 : cases_block->statements()->Add(switch_statement, zone());
1689 : cases_block->set_scope(scope);
1690 : DCHECK_IMPLIES(scope != nullptr,
1691 : switch_statement->position() >= scope->start_position());
1692 : DCHECK_IMPLIES(scope != nullptr,
1693 : switch_statement->position() < scope->end_position());
1694 : switch_block->statements()->Add(cases_block, zone());
1695 89081 : return switch_block;
1696 : }
1697 :
1698 285737 : void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
1699 285737 : if (catch_info->name == nullptr) {
1700 : DCHECK_NOT_NULL(catch_info->pattern);
1701 298715 : catch_info->name = ast_value_factory()->dot_catch_string();
1702 : }
1703 : Variable* catch_variable =
1704 285737 : catch_info->scope->DeclareLocal(catch_info->name, VAR);
1705 285737 : if (catch_info->pattern != nullptr) {
1706 : DeclarationDescriptor descriptor;
1707 4326 : descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
1708 4326 : descriptor.scope = scope();
1709 4326 : descriptor.mode = LET;
1710 4326 : descriptor.declaration_pos = catch_info->pattern->position();
1711 4326 : descriptor.initialization_pos = catch_info->pattern->position();
1712 :
1713 : // Initializer position for variables declared by the pattern.
1714 : const int initializer_position = position();
1715 :
1716 : DeclarationParsingResult::Declaration decl(
1717 : catch_info->pattern, initializer_position,
1718 8652 : factory()->NewVariableProxy(catch_variable));
1719 :
1720 : catch_info->init_block =
1721 4326 : factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
1722 : PatternRewriter::DeclareAndInitializeVariables(
1723 : this, catch_info->init_block, &descriptor, &decl,
1724 4326 : &catch_info->bound_names, ok);
1725 : } else {
1726 281411 : catch_info->bound_names.Add(catch_info->name, zone());
1727 : }
1728 285737 : }
1729 :
1730 285238 : void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {
1731 : // Check for `catch(e) { let e; }` and similar errors.
1732 285238 : Scope* inner_block_scope = catch_info.inner_block->scope();
1733 285238 : if (inner_block_scope != nullptr) {
1734 532 : Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith(
1735 1619 : catch_info.bound_names);
1736 1619 : if (decl != nullptr) {
1737 : const AstRawString* name = decl->proxy()->raw_name();
1738 532 : int position = decl->proxy()->position();
1739 : Scanner::Location location =
1740 : position == kNoSourcePosition
1741 : ? Scanner::Location::invalid()
1742 532 : : Scanner::Location(position, position + 1);
1743 : ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
1744 532 : *ok = false;
1745 : }
1746 : }
1747 285238 : }
1748 :
1749 296564 : Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
1750 : Block* finally_block,
1751 : const CatchInfo& catch_info, int pos) {
1752 : // Simplify the AST nodes by converting:
1753 : // 'try B0 catch B1 finally B2'
1754 : // to:
1755 : // 'try { try B0 catch B1 } finally B2'
1756 :
1757 296564 : if (catch_block != nullptr && finally_block != nullptr) {
1758 : // If we have both, create an inner try/catch.
1759 : DCHECK_NOT_NULL(catch_info.scope);
1760 : TryCatchStatement* statement;
1761 : statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
1762 2106 : catch_block, kNoSourcePosition);
1763 :
1764 1053 : try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
1765 : try_block->statements()->Add(statement, zone());
1766 : catch_block = nullptr; // Clear to indicate it's been handled.
1767 : }
1768 :
1769 296564 : if (catch_block != nullptr) {
1770 : // For a try-catch construct append return expressions from the catch block
1771 : // to the list of return expressions.
1772 283653 : function_state_->tail_call_expressions().Append(
1773 567306 : catch_info.tail_call_expressions);
1774 :
1775 : DCHECK_NULL(finally_block);
1776 : DCHECK_NOT_NULL(catch_info.scope);
1777 : return factory()->NewTryCatchStatement(try_block, catch_info.scope,
1778 567306 : catch_block, pos);
1779 : } else {
1780 : DCHECK_NOT_NULL(finally_block);
1781 25822 : return factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1782 : }
1783 : }
1784 :
1785 47797 : void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind,
1786 : ZoneList<Statement*>* body,
1787 : bool* ok) {
1788 : // For ES6 Generators, we produce:
1789 : //
1790 : // try { InitialYield; ...body...; return {value: undefined, done: true} }
1791 : // finally { %_GeneratorClose(generator) }
1792 : //
1793 : // For ES2017 Async Generators, we produce:
1794 : //
1795 : // try {
1796 : // InitialYield;
1797 : // ...body...;
1798 : // return undefined; // See comment below
1799 : // } catch (.catch) {
1800 : // %AsyncGeneratorReject(generator, .catch);
1801 : // } finally {
1802 : // %_GeneratorClose(generator);
1803 : // }
1804 : //
1805 : // - InitialYield yields the actual generator object.
1806 : // - Any return statement inside the body will have its argument wrapped
1807 : // in an iterator result object with a "done" property set to `true`.
1808 : // - If the generator terminates for whatever reason, we must close it.
1809 : // Hence the finally clause.
1810 : // - BytecodeGenerator performs special handling for ReturnStatements in
1811 : // async generator functions, resolving the appropriate Promise with an
1812 : // "done" iterator result object containing a Promise-unwrapped value.
1813 :
1814 342334 : Block* try_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
1815 47797 : Expression* initial_yield = BuildInitialYield(pos, kind);
1816 : try_block->statements()->Add(
1817 47797 : factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
1818 : zone());
1819 47797 : ParseStatementList(try_block->statements(), Token::RBRACE, ok);
1820 95594 : if (!*ok) return;
1821 :
1822 35067 : if (IsAsyncGeneratorFunction(kind)) {
1823 : // Don't create iterator result for async generators, as the resume methods
1824 : // will create it.
1825 : Statement* final_return = BuildReturnStatement(
1826 14281 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
1827 : try_block->statements()->Add(final_return, zone());
1828 :
1829 : // For AsyncGenerators, a top-level catch block will reject the Promise.
1830 : Scope* catch_scope = NewHiddenCatchScopeWithParent(scope());
1831 :
1832 14281 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
1833 : args->Add(factory()->NewVariableProxy(
1834 28562 : function_state_->generator_object_variable()),
1835 : zone());
1836 14281 : args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
1837 : zone());
1838 :
1839 : Expression* call = factory()->NewCallRuntime(
1840 14281 : Runtime::kInlineAsyncGeneratorReject, args, kNoSourcePosition);
1841 : Block* catch_block = IgnoreCompletion(
1842 14281 : factory()->NewReturnStatement(call, kNoSourcePosition));
1843 :
1844 : TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
1845 14281 : try_block, catch_scope, catch_block, kNoSourcePosition);
1846 :
1847 14281 : try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
1848 : try_block->statements()->Add(try_catch, zone());
1849 : } else {
1850 : Statement* final_return = factory()->NewReturnStatement(
1851 20786 : BuildIteratorResult(nullptr, true), kNoSourcePosition);
1852 : try_block->statements()->Add(final_return, zone());
1853 : }
1854 :
1855 : Block* finally_block =
1856 35067 : factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
1857 35067 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
1858 : VariableProxy* call_proxy =
1859 70134 : factory()->NewVariableProxy(function_state_->generator_object_variable());
1860 : args->Add(call_proxy, zone());
1861 : Expression* call = factory()->NewCallRuntime(Runtime::kInlineGeneratorClose,
1862 35067 : args, kNoSourcePosition);
1863 : finally_block->statements()->Add(
1864 35067 : factory()->NewExpressionStatement(call, kNoSourcePosition), zone());
1865 :
1866 : body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
1867 35067 : kNoSourcePosition),
1868 : zone());
1869 : }
1870 :
1871 6207141 : void Parser::CreateFunctionNameAssignment(
1872 : const AstRawString* function_name, int pos,
1873 : FunctionLiteral::FunctionType function_type,
1874 : DeclarationScope* function_scope, ZoneList<Statement*>* result, int index) {
1875 6207141 : if (function_type == FunctionLiteral::kNamedExpression) {
1876 938869 : StatementT statement = factory()->NewEmptyStatement(kNoSourcePosition);
1877 938871 : if (function_scope->LookupLocal(function_name) == nullptr) {
1878 : // Now that we know the language mode, we can create the const assignment
1879 : // in the previously reserved spot.
1880 : DCHECK_EQ(function_scope, scope());
1881 938707 : Variable* fvar = function_scope->DeclareFunctionVar(function_name);
1882 938711 : VariableProxy* fproxy = factory()->NewVariableProxy(fvar);
1883 : statement = factory()->NewExpressionStatement(
1884 : factory()->NewAssignment(Token::INIT, fproxy,
1885 938695 : factory()->NewThisFunction(pos),
1886 938700 : kNoSourcePosition),
1887 938702 : kNoSourcePosition);
1888 : }
1889 938866 : result->Set(index, statement);
1890 : }
1891 6207138 : }
1892 :
1893 : // [if (IteratorType == kNormal)]
1894 : // !%_IsJSReceiver(result = iterator.next()) &&
1895 : // %ThrowIteratorResultNotAnObject(result)
1896 : // [else if (IteratorType == kAsync)]
1897 : // !%_IsJSReceiver(result = Await(iterator.next())) &&
1898 : // %ThrowIteratorResultNotAnObject(result)
1899 : // [endif]
1900 241558 : Expression* Parser::BuildIteratorNextResult(Expression* iterator,
1901 : Variable* result, IteratorType type,
1902 : int pos) {
1903 : Expression* next_literal = factory()->NewStringLiteral(
1904 1690906 : ast_value_factory()->next_string(), kNoSourcePosition);
1905 : Expression* next_property =
1906 241558 : factory()->NewProperty(iterator, next_literal, kNoSourcePosition);
1907 : ZoneList<Expression*>* next_arguments =
1908 241558 : new (zone()) ZoneList<Expression*>(0, zone());
1909 : Expression* next_call =
1910 241558 : factory()->NewCall(next_property, next_arguments, pos);
1911 241558 : if (type == IteratorType::kAsync) {
1912 : next_call = RewriteAwaitExpression(next_call, pos);
1913 : }
1914 241558 : Expression* result_proxy = factory()->NewVariableProxy(result);
1915 : Expression* left =
1916 241558 : factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
1917 :
1918 : // %_IsJSReceiver(...)
1919 : ZoneList<Expression*>* is_spec_object_args =
1920 241558 : new (zone()) ZoneList<Expression*>(1, zone());
1921 : is_spec_object_args->Add(left, zone());
1922 : Expression* is_spec_object_call = factory()->NewCallRuntime(
1923 241558 : Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
1924 :
1925 : // %ThrowIteratorResultNotAnObject(result)
1926 241558 : Expression* result_proxy_again = factory()->NewVariableProxy(result);
1927 : ZoneList<Expression*>* throw_arguments =
1928 241558 : new (zone()) ZoneList<Expression*>(1, zone());
1929 : throw_arguments->Add(result_proxy_again, zone());
1930 : Expression* throw_call = factory()->NewCallRuntime(
1931 241558 : Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
1932 :
1933 : return factory()->NewBinaryOperation(
1934 : Token::AND,
1935 241558 : factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
1936 241558 : throw_call, pos);
1937 : }
1938 :
1939 168751 : Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
1940 : Expression* each,
1941 : Expression* subject,
1942 : Statement* body,
1943 : int each_keyword_pos) {
1944 168751 : ForOfStatement* for_of = stmt->AsForOfStatement();
1945 168751 : if (for_of != NULL) {
1946 : const bool finalize = true;
1947 : return InitializeForOfStatement(for_of, each, subject, body, finalize,
1948 103480 : IteratorType::kNormal, each_keyword_pos);
1949 : } else {
1950 127566 : if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
1951 26616 : Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1952 6654 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
1953 : Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment(
1954 : this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy,
1955 : kNoSourcePosition),
1956 6654 : scope());
1957 6654 : auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition);
1958 : block->statements()->Add(
1959 6654 : factory()->NewExpressionStatement(assign_each, kNoSourcePosition),
1960 : zone());
1961 : block->statements()->Add(body, zone());
1962 : body = block;
1963 6654 : each = factory()->NewVariableProxy(temp);
1964 : }
1965 : MarkExpressionAsAssigned(each);
1966 : stmt->AsForInStatement()->Initialize(each, subject, body);
1967 : }
1968 65271 : return stmt;
1969 : }
1970 :
1971 : // Special case for legacy for
1972 : //
1973 : // for (var x = initializer in enumerable) body
1974 : //
1975 : // An initialization block of the form
1976 : //
1977 : // {
1978 : // x = initializer;
1979 : // }
1980 : //
1981 : // is returned in this case. It has reserved space for two statements,
1982 : // so that (later on during parsing), the equivalent of
1983 : //
1984 : // for (x in enumerable) body
1985 : //
1986 : // is added as a second statement to it.
1987 112037 : Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
1988 : const DeclarationParsingResult::Declaration& decl =
1989 112037 : for_info.parsing_result.declarations[0];
1990 277679 : if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
1991 163771 : decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
1992 149 : ++use_counts_[v8::Isolate::kForInInitializer];
1993 149 : const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
1994 : VariableProxy* single_var = NewUnresolved(name);
1995 : Block* init_block = factory()->NewBlock(
1996 149 : nullptr, 2, true, for_info.parsing_result.descriptor.declaration_pos);
1997 : init_block->statements()->Add(
1998 : factory()->NewExpressionStatement(
1999 : factory()->NewAssignment(Token::ASSIGN, single_var,
2000 149 : decl.initializer, kNoSourcePosition),
2001 149 : kNoSourcePosition),
2002 : zone());
2003 149 : return init_block;
2004 : }
2005 : return nullptr;
2006 : }
2007 :
2008 : // Rewrite a for-in/of statement of the form
2009 : //
2010 : // for (let/const/var x in/of e) b
2011 : //
2012 : // into
2013 : //
2014 : // {
2015 : // <let x' be a temporary variable>
2016 : // for (x' in/of e) {
2017 : // let/const/var x;
2018 : // x = x';
2019 : // b;
2020 : // }
2021 : // let x; // for TDZ
2022 : // }
2023 128173 : void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
2024 : Block** body_block,
2025 : Expression** each_variable,
2026 : bool* ok) {
2027 : DCHECK(for_info->parsing_result.declarations.length() == 1);
2028 : DeclarationParsingResult::Declaration& decl =
2029 128173 : for_info->parsing_result.declarations[0];
2030 284931 : Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
2031 : auto each_initialization_block =
2032 128173 : factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
2033 : {
2034 128173 : auto descriptor = for_info->parsing_result.descriptor;
2035 128173 : descriptor.declaration_pos = kNoSourcePosition;
2036 128173 : descriptor.initialization_pos = kNoSourcePosition;
2037 256346 : decl.initializer = factory()->NewVariableProxy(temp);
2038 :
2039 : bool is_for_var_of =
2040 220629 : for_info->mode == ForEachStatement::ITERATE &&
2041 92456 : for_info->parsing_result.descriptor.mode == VariableMode::VAR;
2042 : bool collect_names =
2043 256346 : IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
2044 : is_for_var_of;
2045 :
2046 : PatternRewriter::DeclareAndInitializeVariables(
2047 : this, each_initialization_block, &descriptor, &decl,
2048 128355 : collect_names ? &for_info->bound_names : nullptr, CHECK_OK_VOID);
2049 :
2050 : // Annex B.3.5 prohibits the form
2051 : // `try {} catch(e) { for (var e of {}); }`
2052 : // So if we are parsing a statement like `for (var ... of ...)`
2053 : // we need to walk up the scope chain and look for catch scopes
2054 : // which have a simple binding, then compare their binding against
2055 : // all of the names declared in the init of the for-of we're
2056 : // parsing.
2057 128173 : if (is_for_var_of) {
2058 140296 : Scope* catch_scope = scope();
2059 224411 : while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) {
2060 70239 : if (catch_scope->is_catch_scope()) {
2061 668 : auto name = catch_scope->catch_variable()->raw_name();
2062 : // If it's a simple binding and the name is declared in the for loop.
2063 1682 : if (name != ast_value_factory()->dot_catch_string() &&
2064 346 : for_info->bound_names.Contains(name)) {
2065 : ReportMessageAt(for_info->parsing_result.bindings_loc,
2066 : MessageTemplate::kVarRedeclaration, name);
2067 182 : *ok = false;
2068 : return;
2069 : }
2070 : }
2071 : catch_scope = catch_scope->outer_scope();
2072 : }
2073 : }
2074 : }
2075 :
2076 127991 : *body_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
2077 : (*body_block)->statements()->Add(each_initialization_block, zone());
2078 255982 : *each_variable = factory()->NewVariableProxy(temp, for_info->position);
2079 : }
2080 :
2081 : // Create a TDZ for any lexically-bound names in for in/of statements.
2082 127991 : Block* Parser::CreateForEachStatementTDZ(Block* init_block,
2083 : const ForInfo& for_info, bool* ok) {
2084 255982 : if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
2085 : DCHECK_NULL(init_block);
2086 :
2087 151443 : init_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
2088 :
2089 302886 : for (int i = 0; i < for_info.bound_names.length(); ++i) {
2090 : // TODO(adamk): This needs to be some sort of special
2091 : // INTERNAL variable that's invisible to the debugger
2092 : // but visible to everything else.
2093 309813 : Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET,
2094 158370 : kNoSourcePosition, CHECK_OK);
2095 79185 : tdz_decl->proxy()->var()->set_initializer_position(position());
2096 : }
2097 : }
2098 127991 : return init_block;
2099 : }
2100 :
2101 133899 : Statement* Parser::InitializeForOfStatement(
2102 : ForOfStatement* for_of, Expression* each, Expression* iterable,
2103 : Statement* body, bool finalize, IteratorType type, int next_result_pos) {
2104 : // Create the auxiliary expressions needed for iterating over the iterable,
2105 : // and initialize the given ForOfStatement with them.
2106 : // If finalize is true, also instrument the loop with code that performs the
2107 : // proper ES6 iterator finalization. In that case, the result is not
2108 : // immediately a ForOfStatement.
2109 : const int nopos = kNoSourcePosition;
2110 1325369 : auto avfactory = ast_value_factory();
2111 :
2112 : Variable* iterator = NewTemporary(avfactory->dot_iterator_string());
2113 : Variable* result = NewTemporary(avfactory->dot_result_string());
2114 : Variable* completion = NewTemporary(avfactory->empty_string());
2115 :
2116 : // iterator = GetIterator(iterable, type)
2117 : Expression* assign_iterator;
2118 : {
2119 : assign_iterator = factory()->NewAssignment(
2120 133899 : Token::ASSIGN, factory()->NewVariableProxy(iterator),
2121 133899 : factory()->NewGetIterator(iterable, type, iterable->position()),
2122 267798 : iterable->position());
2123 : }
2124 :
2125 : // [if (IteratorType == kNormal)]
2126 : // !%_IsJSReceiver(result = iterator.next()) &&
2127 : // %ThrowIteratorResultNotAnObject(result)
2128 : // [else if (IteratorType == kAsync)]
2129 : // !%_IsJSReceiver(result = Await(iterator.next())) &&
2130 : // %ThrowIteratorResultNotAnObject(result)
2131 : // [endif]
2132 : Expression* next_result;
2133 : {
2134 133899 : Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2135 : next_result =
2136 133899 : BuildIteratorNextResult(iterator_proxy, result, type, next_result_pos);
2137 : }
2138 :
2139 : // result.done
2140 : Expression* result_done;
2141 : {
2142 : Expression* done_literal = factory()->NewStringLiteral(
2143 267798 : ast_value_factory()->done_string(), kNoSourcePosition);
2144 133899 : Expression* result_proxy = factory()->NewVariableProxy(result);
2145 : result_done =
2146 133899 : factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition);
2147 : }
2148 :
2149 : // result.value
2150 : Expression* result_value;
2151 : {
2152 : Expression* value_literal =
2153 133899 : factory()->NewStringLiteral(avfactory->value_string(), nopos);
2154 133899 : Expression* result_proxy = factory()->NewVariableProxy(result);
2155 133899 : result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
2156 : }
2157 :
2158 : // {{completion = kAbruptCompletion;}}
2159 : Statement* set_completion_abrupt;
2160 133899 : if (finalize) {
2161 128502 : Expression* proxy = factory()->NewVariableProxy(completion);
2162 : Expression* assignment = factory()->NewAssignment(
2163 : Token::ASSIGN, proxy,
2164 128502 : factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
2165 :
2166 : set_completion_abrupt =
2167 128502 : IgnoreCompletion(factory()->NewExpressionStatement(assignment, nopos));
2168 : }
2169 :
2170 : // do { let tmp = #result_value; #set_completion_abrupt; tmp }
2171 : // Expression* result_value (gets overwritten)
2172 133899 : if (finalize) {
2173 : Variable* var_tmp = NewTemporary(avfactory->empty_string());
2174 128502 : Expression* tmp = factory()->NewVariableProxy(var_tmp);
2175 : Expression* assignment =
2176 128502 : factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos);
2177 :
2178 128502 : Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
2179 : block->statements()->Add(
2180 128502 : factory()->NewExpressionStatement(assignment, nopos), zone());
2181 : block->statements()->Add(set_completion_abrupt, zone());
2182 :
2183 128502 : result_value = factory()->NewDoExpression(block, var_tmp, nopos);
2184 : }
2185 :
2186 : // each = #result_value;
2187 : Expression* assign_each;
2188 : {
2189 : assign_each =
2190 133899 : factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
2191 263328 : if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
2192 : assign_each = PatternRewriter::RewriteDestructuringAssignment(
2193 26728 : this, assign_each->AsAssignment(), scope());
2194 : }
2195 : }
2196 :
2197 : // {{completion = kNormalCompletion;}}
2198 : Statement* set_completion_normal;
2199 133899 : if (finalize) {
2200 128502 : Expression* proxy = factory()->NewVariableProxy(completion);
2201 : Expression* assignment = factory()->NewAssignment(
2202 : Token::ASSIGN, proxy,
2203 128502 : factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
2204 :
2205 : set_completion_normal =
2206 128502 : IgnoreCompletion(factory()->NewExpressionStatement(assignment, nopos));
2207 : }
2208 :
2209 : // { #loop-body; #set_completion_normal }
2210 : // Statement* body (gets overwritten)
2211 133899 : if (finalize) {
2212 128502 : Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
2213 : block->statements()->Add(body, zone());
2214 : block->statements()->Add(set_completion_normal, zone());
2215 : body = block;
2216 : }
2217 :
2218 : for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
2219 : assign_each);
2220 : return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos)
2221 133899 : : for_of;
2222 : }
2223 :
2224 25291 : Statement* Parser::DesugarLexicalBindingsInForStatement(
2225 : ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2226 : Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) {
2227 : // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
2228 : // copied into a new environment. Moreover, the "next" statement must be
2229 : // evaluated not in the environment of the just completed iteration but in
2230 : // that of the upcoming one. We achieve this with the following desugaring.
2231 : // Extra care is needed to preserve the completion value of the original loop.
2232 : //
2233 : // We are given a for statement of the form
2234 : //
2235 : // labels: for (let/const x = i; cond; next) body
2236 : //
2237 : // and rewrite it as follows. Here we write {{ ... }} for init-blocks, ie.,
2238 : // blocks whose ignore_completion_value_ flag is set.
2239 : //
2240 : // {
2241 : // let/const x = i;
2242 : // temp_x = x;
2243 : // first = 1;
2244 : // undefined;
2245 : // outer: for (;;) {
2246 : // let/const x = temp_x;
2247 : // {{ if (first == 1) {
2248 : // first = 0;
2249 : // } else {
2250 : // next;
2251 : // }
2252 : // flag = 1;
2253 : // if (!cond) break;
2254 : // }}
2255 : // labels: for (; flag == 1; flag = 0, temp_x = x) {
2256 : // body
2257 : // }
2258 : // {{ if (flag == 1) // Body used break.
2259 : // break;
2260 : // }}
2261 : // }
2262 : // }
2263 :
2264 : DCHECK(for_info.bound_names.length() > 0);
2265 736566 : ZoneList<Variable*> temps(for_info.bound_names.length(), zone());
2266 :
2267 : Block* outer_block = factory()->NewBlock(
2268 25291 : nullptr, for_info.bound_names.length() + 4, false, kNoSourcePosition);
2269 :
2270 : // Add statement: let/const x = i.
2271 : outer_block->statements()->Add(init, zone());
2272 :
2273 25291 : const AstRawString* temp_name = ast_value_factory()->dot_for_string();
2274 :
2275 : // For each lexical variable x:
2276 : // make statement: temp_x = x.
2277 119012 : for (int i = 0; i < for_info.bound_names.length(); i++) {
2278 34215 : VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
2279 : Variable* temp = NewTemporary(temp_name);
2280 34215 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2281 : Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
2282 34215 : proxy, kNoSourcePosition);
2283 : Statement* assignment_statement =
2284 34215 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2285 : outer_block->statements()->Add(assignment_statement, zone());
2286 : temps.Add(temp, zone());
2287 : }
2288 :
2289 : Variable* first = NULL;
2290 : // Make statement: first = 1.
2291 25291 : if (next) {
2292 : first = NewTemporary(temp_name);
2293 3806 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2294 3806 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2295 : Assignment* assignment = factory()->NewAssignment(
2296 3806 : Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
2297 : Statement* assignment_statement =
2298 3806 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2299 : outer_block->statements()->Add(assignment_statement, zone());
2300 : }
2301 :
2302 : // make statement: undefined;
2303 : outer_block->statements()->Add(
2304 : factory()->NewExpressionStatement(
2305 25291 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2306 : zone());
2307 :
2308 : // Make statement: outer: for (;;)
2309 : // Note that we don't actually create the label, or set this loop up as an
2310 : // explicit break target, instead handing it directly to those nodes that
2311 : // need to know about it. This should be safe because we don't run any code
2312 : // in this function that looks up break targets.
2313 : ForStatement* outer_loop =
2314 25291 : factory()->NewForStatement(NULL, kNoSourcePosition);
2315 : outer_block->statements()->Add(outer_loop, zone());
2316 : outer_block->set_scope(scope());
2317 :
2318 25291 : Block* inner_block = factory()->NewBlock(NULL, 3, false, kNoSourcePosition);
2319 : {
2320 25291 : BlockState block_state(&scope_, inner_scope);
2321 :
2322 : Block* ignore_completion_block = factory()->NewBlock(
2323 25291 : nullptr, for_info.bound_names.length() + 3, true, kNoSourcePosition);
2324 25291 : ZoneList<Variable*> inner_vars(for_info.bound_names.length(), zone());
2325 : // For each let variable x:
2326 : // make statement: let/const x = temp_x.
2327 119012 : for (int i = 0; i < for_info.bound_names.length(); i++) {
2328 102645 : Declaration* decl = DeclareVariable(
2329 : for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
2330 102645 : kNoSourcePosition, CHECK_OK);
2331 34215 : inner_vars.Add(decl->proxy()->var(), zone());
2332 34215 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2333 : Assignment* assignment = factory()->NewAssignment(
2334 34215 : Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition);
2335 : Statement* assignment_statement =
2336 34215 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2337 : DCHECK(init->position() != kNoSourcePosition);
2338 68430 : decl->proxy()->var()->set_initializer_position(init->position());
2339 : ignore_completion_block->statements()->Add(assignment_statement, zone());
2340 : }
2341 :
2342 : // Make statement: if (first == 1) { first = 0; } else { next; }
2343 25291 : if (next) {
2344 : DCHECK(first);
2345 : Expression* compare = NULL;
2346 : // Make compare expression: first == 1.
2347 : {
2348 3806 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2349 3806 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2350 : compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
2351 3806 : kNoSourcePosition);
2352 : }
2353 : Statement* clear_first = NULL;
2354 : // Make statement: first = 0.
2355 : {
2356 3806 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2357 3806 : Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2358 : Assignment* assignment = factory()->NewAssignment(
2359 3806 : Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
2360 : clear_first =
2361 3806 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2362 : }
2363 : Statement* clear_first_or_next = factory()->NewIfStatement(
2364 3806 : compare, clear_first, next, kNoSourcePosition);
2365 : ignore_completion_block->statements()->Add(clear_first_or_next, zone());
2366 : }
2367 :
2368 : Variable* flag = NewTemporary(temp_name);
2369 : // Make statement: flag = 1.
2370 : {
2371 25291 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2372 25291 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2373 : Assignment* assignment = factory()->NewAssignment(
2374 25291 : Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2375 : Statement* assignment_statement =
2376 25291 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2377 : ignore_completion_block->statements()->Add(assignment_statement, zone());
2378 : }
2379 :
2380 : // Make statement: if (!cond) break.
2381 25291 : if (cond) {
2382 : Statement* stop =
2383 16363 : factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2384 16363 : Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition);
2385 : ignore_completion_block->statements()->Add(
2386 16363 : factory()->NewIfStatement(cond, noop, stop, cond->position()),
2387 : zone());
2388 : }
2389 :
2390 : inner_block->statements()->Add(ignore_completion_block, zone());
2391 : // Make cond expression for main loop: flag == 1.
2392 : Expression* flag_cond = NULL;
2393 : {
2394 25291 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2395 25291 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2396 : flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2397 25291 : kNoSourcePosition);
2398 : }
2399 :
2400 : // Create chain of expressions "flag = 0, temp_x = x, ..."
2401 : Statement* compound_next_statement = NULL;
2402 : {
2403 : Expression* compound_next = NULL;
2404 : // Make expression: flag = 0.
2405 : {
2406 25291 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2407 25291 : Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2408 : compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
2409 25291 : const0, kNoSourcePosition);
2410 : }
2411 :
2412 : // Make the comma-separated list of temp_x = x assignments.
2413 : int inner_var_proxy_pos = scanner()->location().beg_pos;
2414 119012 : for (int i = 0; i < for_info.bound_names.length(); i++) {
2415 34215 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2416 : VariableProxy* proxy =
2417 34215 : factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
2418 : Assignment* assignment = factory()->NewAssignment(
2419 34215 : Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2420 : compound_next = factory()->NewBinaryOperation(
2421 34215 : Token::COMMA, compound_next, assignment, kNoSourcePosition);
2422 : }
2423 :
2424 : compound_next_statement =
2425 25291 : factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2426 : }
2427 :
2428 : // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
2429 : // Note that we re-use the original loop node, which retains its labels
2430 : // and ensures that any break or continue statements in body point to
2431 : // the right place.
2432 : loop->Initialize(NULL, flag_cond, compound_next_statement, body);
2433 : inner_block->statements()->Add(loop, zone());
2434 :
2435 : // Make statement: {{if (flag == 1) break;}}
2436 : {
2437 : Expression* compare = NULL;
2438 : // Make compare expresion: flag == 1.
2439 : {
2440 25291 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2441 25291 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2442 : compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2443 25291 : kNoSourcePosition);
2444 : }
2445 : Statement* stop =
2446 25291 : factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2447 25291 : Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition);
2448 : Statement* if_flag_break =
2449 25291 : factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
2450 : inner_block->statements()->Add(IgnoreCompletion(if_flag_break), zone());
2451 : }
2452 :
2453 : inner_block->set_scope(inner_scope);
2454 : }
2455 :
2456 : outer_loop->Initialize(NULL, NULL, NULL, inner_block);
2457 25291 : return outer_block;
2458 : }
2459 :
2460 322209 : void Parser::AddArrowFunctionFormalParameters(
2461 : ParserFormalParameters* parameters, Expression* expr, int end_pos,
2462 : bool* ok) {
2463 : // ArrowFunctionFormals ::
2464 : // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
2465 : // Tail
2466 : // NonTailArrowFunctionFormals ::
2467 : // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
2468 : // VariableProxy
2469 : // Tail ::
2470 : // VariableProxy
2471 : // Spread(VariableProxy)
2472 : //
2473 : // As we need to visit the parameters in left-to-right order, we recurse on
2474 : // the left-hand side of comma expressions.
2475 : //
2476 322209 : if (expr->IsBinaryOperation()) {
2477 92240 : BinaryOperation* binop = expr->AsBinaryOperation();
2478 : // The classifier has already run, so we know that the expression is a valid
2479 : // arrow function formals production.
2480 : DCHECK_EQ(binop->op(), Token::COMMA);
2481 : Expression* left = binop->left();
2482 : Expression* right = binop->right();
2483 46120 : int comma_pos = binop->position();
2484 : AddArrowFunctionFormalParameters(parameters, left, comma_pos,
2485 368329 : CHECK_OK_VOID);
2486 : // LHS of comma expression should be unparenthesized.
2487 : expr = right;
2488 : }
2489 :
2490 : // Only the right-most expression may be a rest parameter.
2491 : DCHECK(!parameters->has_rest);
2492 :
2493 : bool is_rest = expr->IsSpread();
2494 321921 : if (is_rest) {
2495 4340 : expr = expr->AsSpread()->expression();
2496 2170 : parameters->has_rest = true;
2497 : }
2498 321921 : if (parameters->is_simple) {
2499 593746 : parameters->is_simple = !is_rest && expr->IsVariableProxy();
2500 : }
2501 :
2502 : Expression* initializer = nullptr;
2503 321921 : if (expr->IsAssignment()) {
2504 12940 : Assignment* assignment = expr->AsAssignment();
2505 : DCHECK(!assignment->is_compound());
2506 : initializer = assignment->value();
2507 : expr = assignment->target();
2508 : }
2509 :
2510 : AddFormalParameter(parameters, expr, initializer,
2511 : end_pos, is_rest);
2512 : }
2513 :
2514 602281 : void Parser::DeclareArrowFunctionFormalParameters(
2515 : ParserFormalParameters* parameters, Expression* expr,
2516 : const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
2517 : bool* ok) {
2518 931257 : if (expr->IsEmptyParentheses()) return;
2519 :
2520 : AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
2521 276089 : CHECK_OK_VOID);
2522 :
2523 273305 : if (parameters->arity > Code::kMaxArguments) {
2524 : ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
2525 0 : *ok = false;
2526 0 : return;
2527 : }
2528 :
2529 561487 : ExpressionClassifier classifier(this);
2530 273305 : if (!parameters->is_simple) {
2531 : this->classifier()->RecordNonSimpleParameter();
2532 : }
2533 273305 : DeclareFormalParameters(parameters->scope, parameters->params);
2534 273305 : if (!this->classifier()
2535 : ->is_valid_formal_parameter_list_without_duplicates()) {
2536 : *duplicate_loc =
2537 73 : this->classifier()->duplicate_formal_parameter_error().location;
2538 : }
2539 : DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
2540 : }
2541 :
2542 110847 : void Parser::PrepareGeneratorVariables() {
2543 : // For generators, allocating variables in contexts is currently a win because
2544 : // it minimizes the work needed to suspend and resume an activation. The
2545 : // code produced for generators relies on this forced context allocation (it
2546 : // does not restore the frame's parameters upon resume).
2547 221694 : function_state_->scope()->ForceContextAllocation();
2548 :
2549 : // Calling a generator returns a generator object. That object is stored
2550 : // in a temporary variable, a definition that is used by "yield"
2551 : // expressions.
2552 : function_state_->scope()->DeclareGeneratorObjectVar(
2553 332541 : ast_value_factory()->dot_generator_object_string());
2554 110847 : }
2555 :
2556 7562010 : FunctionLiteral* Parser::ParseFunctionLiteral(
2557 : const AstRawString* function_name, Scanner::Location function_name_location,
2558 : FunctionNameValidity function_name_validity, FunctionKind kind,
2559 : int function_token_pos, FunctionLiteral::FunctionType function_type,
2560 7562024 : LanguageMode language_mode, bool* ok) {
2561 : // Function ::
2562 : // '(' FormalParameterList? ')' '{' FunctionBody '}'
2563 : //
2564 : // Getter ::
2565 : // '(' ')' '{' FunctionBody '}'
2566 : //
2567 : // Setter ::
2568 : // '(' PropertySetParameterList ')' '{' FunctionBody '}'
2569 :
2570 28058464 : int pos = function_token_pos == kNoSourcePosition ? peek_position()
2571 7562010 : : function_token_pos;
2572 :
2573 : // Anonymous functions were passed either the empty symbol or a null
2574 : // handle as the function name. Remember if we were passed a non-empty
2575 : // handle to decide whether to invoke function name inference.
2576 7562010 : bool should_infer_name = function_name == NULL;
2577 :
2578 : // We want a non-null handle as the function name.
2579 7562010 : if (should_infer_name) {
2580 3253824 : function_name = ast_value_factory()->empty_string();
2581 : }
2582 :
2583 : FunctionLiteral::EagerCompileHint eager_compile_hint =
2584 7562010 : function_state_->next_function_is_likely_called()
2585 : ? FunctionLiteral::kShouldEagerCompile
2586 7562010 : : default_eager_compile_hint();
2587 :
2588 : // Determine if the function can be parsed lazily. Lazy parsing is
2589 : // different from lazy compilation; we need to parse more eagerly than we
2590 : // compile.
2591 :
2592 : // We can only parse lazily if we also compile lazily. The heuristics for lazy
2593 : // compilation are:
2594 : // - It must not have been prohibited by the caller to Parse (some callers
2595 : // need a full AST).
2596 : // - The outer scope must allow lazy compilation of inner functions.
2597 : // - The function mustn't be a function expression with an open parenthesis
2598 : // before; we consider that a hint that the function will be called
2599 : // immediately, and it would be a waste of time to make it lazily
2600 : // compiled.
2601 : // These are all things we can know at this point, without looking at the
2602 : // function itself.
2603 :
2604 : // We separate between lazy parsing top level functions and lazy parsing inner
2605 : // functions, because the latter needs to do more work. In particular, we need
2606 : // to track unresolved variables to distinguish between these cases:
2607 : // (function foo() {
2608 : // bar = function() { return 1; }
2609 : // })();
2610 : // and
2611 : // (function foo() {
2612 : // var a = 1;
2613 : // bar = function() { return a; }
2614 : // })();
2615 :
2616 : // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
2617 : // parenthesis before the function means that it will be called
2618 : // immediately). bar can be parsed lazily, but we need to parse it in a mode
2619 : // that tracks unresolved variables.
2620 : DCHECK_IMPLIES(parse_lazily(), FLAG_lazy);
2621 : DCHECK_IMPLIES(parse_lazily(), allow_lazy_);
2622 : DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
2623 :
2624 : const bool is_lazy =
2625 7562010 : eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2626 : const bool is_top_level =
2627 : impl()->AllowsLazyParsingWithoutUnresolvedVariables();
2628 7562010 : const bool is_lazy_top_level_function = is_lazy && is_top_level;
2629 7562010 : const bool is_lazy_inner_function = is_lazy && !is_top_level;
2630 : const bool is_declaration = function_type == FunctionLiteral::kDeclaration;
2631 :
2632 : RuntimeCallTimerScope runtime_timer(
2633 : runtime_call_stats_,
2634 : parsing_on_main_thread_
2635 : ? &RuntimeCallStats::ParseFunctionLiteral
2636 7562010 : : &RuntimeCallStats::ParseBackgroundFunctionLiteral);
2637 :
2638 : // Determine whether we can still lazy parse the inner function.
2639 : // The preconditions are:
2640 : // - Lazy compilation has to be enabled.
2641 : // - Neither V8 natives nor native function declarations can be allowed,
2642 : // since parsing one would retroactively force the function to be
2643 : // eagerly compiled.
2644 : // - The invoker of this parser can't depend on the AST being eagerly
2645 : // built (either because the function is about to be compiled, or
2646 : // because the AST is going to be inspected for some reason).
2647 : // - Because of the above, we can't be attempting to parse a
2648 : // FunctionExpression; even without enclosing parentheses it might be
2649 : // immediately invoked.
2650 : // - The function literal shouldn't be hinted to eagerly compile.
2651 :
2652 : // Inner functions will be parsed using a temporary Zone. After parsing, we
2653 : // will migrate unresolved variable into a Scope in the main Zone.
2654 :
2655 : const bool should_preparse_inner =
2656 7562024 : parse_lazily() && FLAG_lazy_inner_functions && is_lazy_inner_function &&
2657 1416039 : (is_declaration || FLAG_aggressive_lazy_inner_functions);
2658 :
2659 : // This may be modified later to reflect preparsing decision taken
2660 : bool should_preparse =
2661 7562024 : (parse_lazily() && is_lazy_top_level_function) || should_preparse_inner;
2662 :
2663 : ZoneList<Statement*>* body = nullptr;
2664 7562024 : int expected_property_count = -1;
2665 : bool should_be_used_once_hint = false;
2666 7562024 : int num_parameters = -1;
2667 7562024 : int function_length = -1;
2668 7562024 : bool has_duplicate_parameters = false;
2669 : int function_literal_id = GetNextFunctionLiteralId();
2670 :
2671 : Zone* outer_zone = zone();
2672 : DeclarationScope* scope;
2673 :
2674 : {
2675 : // Temporary zones can nest. When we migrate free variables (see below), we
2676 : // need to recreate them in the previous Zone.
2677 : AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
2678 : previous_zone_ast_node_factory.set_zone(zone());
2679 :
2680 : // Open a new zone scope, which sets our AstNodeFactory to allocate in the
2681 : // new temporary zone if the preconditions are satisfied, and ensures that
2682 : // the previous zone is always restored after parsing the body. To be able
2683 : // to do scope analysis correctly after full parsing, we migrate needed
2684 : // information when the function is parsed.
2685 7562024 : Zone temp_zone(zone()->allocator(), ZONE_NAME);
2686 7562025 : DiscardableZoneScope zone_scope(this, &temp_zone, should_preparse);
2687 :
2688 : // This Scope lives in the main zone. We'll migrate data into that zone
2689 : // later.
2690 7562028 : scope = NewFunctionScope(kind, outer_zone);
2691 7562025 : SetLanguageMode(scope, language_mode);
2692 : #ifdef DEBUG
2693 : scope->SetScopeName(function_name);
2694 : if (should_preparse) scope->set_needs_migration();
2695 : #endif
2696 :
2697 7562026 : Expect(Token::LPAREN, CHECK_OK);
2698 4066904 : scope->set_start_position(scanner()->location().beg_pos);
2699 :
2700 : // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
2701 : // lazily. We'll call SkipFunction, which may decide to
2702 : // abort lazy parsing if it suspects that wasn't a good idea. If so (in
2703 : // which case the parser is expected to have backtracked), or if we didn't
2704 : // try to lazy parse in the first place, we'll have to parse eagerly.
2705 7558620 : if (should_preparse) {
2706 : DCHECK(parse_lazily());
2707 : DCHECK(is_lazy_top_level_function || is_lazy_inner_function);
2708 : Scanner::BookmarkScope bookmark(scanner());
2709 1402991 : bookmark.Set();
2710 : LazyParsingResult result =
2711 : SkipFunction(kind, scope, &num_parameters, is_lazy_inner_function,
2712 1402991 : is_lazy_top_level_function, CHECK_OK);
2713 :
2714 1355801 : if (result == kLazyParsingAborted) {
2715 : DCHECK(is_lazy_top_level_function);
2716 44 : bookmark.Apply();
2717 : // This is probably an initialization function. Inform the compiler it
2718 : // should also eager-compile this function, and that we expect it to be
2719 : // used once.
2720 : eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
2721 : should_be_used_once_hint = true;
2722 44 : scope->ResetAfterPreparsing(ast_value_factory(), true);
2723 44 : zone_scope.Reset();
2724 : // Trigger eager (re-)parsing, just below this block.
2725 : should_preparse = false;
2726 : }
2727 : }
2728 :
2729 7511430 : if (should_preparse) {
2730 : scope->AnalyzePartially(&previous_zone_ast_node_factory,
2731 1355757 : preparsed_scope_data_);
2732 : } else {
2733 : body = ParseFunction(function_name, pos, kind, function_type, scope,
2734 : &num_parameters, &function_length,
2735 : &has_duplicate_parameters, &expected_property_count,
2736 6155673 : CHECK_OK);
2737 : }
2738 :
2739 : DCHECK_EQ(should_preparse, temp_zoned_);
2740 7418971 : if (V8_UNLIKELY(FLAG_trace_preparse)) {
2741 : PrintF(" [%s]: %i-%i %.*s\n",
2742 : should_preparse ? (is_top_level ? "Preparse no-resolution"
2743 : : "Preparse resolution")
2744 : : "Full parse",
2745 : scope->start_position(), scope->end_position(),
2746 0 : function_name->byte_length(), function_name->raw_data());
2747 : }
2748 7418971 : if (V8_UNLIKELY(FLAG_runtime_stats)) {
2749 0 : if (should_preparse) {
2750 : RuntimeCallStats::CounterId counter_id =
2751 : parsing_on_main_thread_
2752 : ? &RuntimeCallStats::PreParseWithVariableResolution
2753 0 : : &RuntimeCallStats::PreParseBackgroundWithVariableResolution;
2754 0 : if (is_top_level) {
2755 : counter_id =
2756 : parsing_on_main_thread_
2757 : ? &RuntimeCallStats::PreParseNoVariableResolution
2758 0 : : &RuntimeCallStats::PreParseBackgroundNoVariableResolution;
2759 : }
2760 : RuntimeCallStats::CorrectCurrentCounterId(runtime_call_stats_,
2761 0 : counter_id);
2762 : }
2763 : }
2764 :
2765 : // Validate function name. We can do this only after parsing the function,
2766 : // since the function can declare itself strict.
2767 : language_mode = scope->language_mode();
2768 : CheckFunctionName(language_mode, function_name, function_name_validity,
2769 7418971 : function_name_location, CHECK_OK);
2770 :
2771 7417411 : if (is_strict(language_mode)) {
2772 : CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
2773 4066904 : CHECK_OK);
2774 : }
2775 14822034 : CheckConflictingVarDeclarations(scope, CHECK_OK);
2776 : } // DiscardableZoneScope goes out of scope.
2777 :
2778 : FunctionLiteral::ParameterFlag duplicate_parameters =
2779 : has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2780 7404689 : : FunctionLiteral::kNoDuplicateParameters;
2781 :
2782 : // Note that the FunctionLiteral needs to be created in the main Zone again.
2783 : FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2784 : function_name, scope, body, expected_property_count, num_parameters,
2785 : function_length, duplicate_parameters, function_type, eager_compile_hint,
2786 7404689 : pos, true, function_literal_id);
2787 : function_literal->set_function_token_position(function_token_pos);
2788 7404686 : if (should_be_used_once_hint)
2789 : function_literal->set_should_be_used_once_hint();
2790 :
2791 7404686 : if (should_infer_name) {
2792 : DCHECK_NOT_NULL(fni_);
2793 3197959 : fni_->AddFunction(function_literal);
2794 : }
2795 7404686 : return function_literal;
2796 : }
2797 :
2798 1434202 : Parser::LazyParsingResult Parser::SkipFunction(FunctionKind kind,
2799 : DeclarationScope* function_scope,
2800 : int* num_parameters,
2801 : bool is_inner_function,
2802 2288599 : bool may_abort, bool* ok) {
2803 : DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2804 : DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
2805 1434202 : if (produce_cached_parse_data()) CHECK(log_);
2806 :
2807 : DCHECK_IMPLIES(IsArrowFunction(kind),
2808 : scanner()->current_token() == Token::ARROW);
2809 :
2810 : // Inner functions are not part of the cached data.
2811 1434328 : if (!is_inner_function && consume_cached_parse_data() &&
2812 132 : !cached_parse_data_->rejected()) {
2813 : // If we have cached data, we use it to skip parsing the function. The data
2814 : // contains the information we need to construct the lazy function.
2815 : FunctionEntry entry =
2816 1384742 : cached_parse_data_->GetFunctionEntry(function_scope->start_position());
2817 : // Check that cached data is valid. If not, mark it as invalid (the embedder
2818 : // handles it). Note that end position greater than end of stream is safe,
2819 : // and hard to check.
2820 246 : if (entry.is_valid() &&
2821 : entry.end_pos() > function_scope->start_position()) {
2822 254 : total_preparse_skipped_ += entry.end_pos() - position();
2823 : function_scope->set_end_position(entry.end_pos());
2824 240 : scanner()->SeekForward(entry.end_pos() - 1);
2825 240 : Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2826 120 : *num_parameters = entry.num_parameters();
2827 120 : SetLanguageMode(function_scope, entry.language_mode());
2828 120 : if (entry.uses_super_property())
2829 : function_scope->RecordSuperPropertyUsage();
2830 : SkipFunctionLiterals(entry.num_inner_functions());
2831 120 : return kLazyParsingComplete;
2832 : }
2833 6 : cached_parse_data_->Reject();
2834 : }
2835 :
2836 1434082 : if (FLAG_use_parse_tasks && !is_inner_function &&
2837 0 : reusable_preparser()->preparse_data()) {
2838 : // All top-level functions are already preparsed and parser tasks for eager
2839 : // functions are already created. Use data gathered during the preparse step
2840 : // to skip the function.
2841 : PreParseData::FunctionData data =
2842 : reusable_preparser()->preparse_data()->GetFunctionData(
2843 0 : function_scope->start_position());
2844 0 : if (data.is_valid()) {
2845 0 : if (FLAG_trace_parse_tasks) {
2846 : PrintF("Skipping top level func @ %d : %d using preparse data\n",
2847 0 : function_scope->start_position(), data.end);
2848 : }
2849 : function_scope->set_end_position(data.end);
2850 0 : scanner()->SeekForward(data.end - 1);
2851 0 : Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2852 0 : *num_parameters = data.num_parameters;
2853 0 : SetLanguageMode(function_scope, data.language_mode);
2854 0 : if (data.uses_super_property) {
2855 : function_scope->RecordSuperPropertyUsage();
2856 : }
2857 0 : SkipFunctionLiterals(data.num_inner_functions);
2858 0 : return kLazyParsingComplete;
2859 : }
2860 : }
2861 :
2862 : // FIXME(marja): There are 3 ways to skip functions now. Unify them.
2863 1434082 : if (preparsed_scope_data_->Consuming()) {
2864 : DCHECK(FLAG_experimental_preparser_scope_analysis);
2865 14 : const PreParseData::FunctionData& data =
2866 : preparsed_scope_data_->FindSkippableFunction(
2867 14 : function_scope->start_position());
2868 14 : if (data.is_valid()) {
2869 : function_scope->set_is_skipped_function(true);
2870 : function_scope->outer_scope()->SetMustUsePreParsedScopeData();
2871 :
2872 : function_scope->set_end_position(data.end);
2873 28 : scanner()->SeekForward(data.end - 1);
2874 14 : Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2875 14 : *num_parameters = data.num_parameters;
2876 14 : SetLanguageMode(function_scope, data.language_mode);
2877 14 : if (data.uses_super_property) {
2878 : function_scope->RecordSuperPropertyUsage();
2879 : }
2880 14 : SkipFunctionLiterals(data.num_inner_functions);
2881 14 : return kLazyParsingComplete;
2882 : }
2883 : }
2884 :
2885 : // With no cached data, we partially parse the function, without building an
2886 : // AST. This gathers the data needed to build a lazy function.
2887 2868136 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
2888 :
2889 : // Aborting inner function preparsing would leave scopes in an inconsistent
2890 : // state; we don't parse inner functions in the abortable mode anyway.
2891 : DCHECK(!is_inner_function || !may_abort);
2892 :
2893 : PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
2894 : kind, function_scope, parsing_module_, is_inner_function, may_abort,
2895 1434068 : use_counts_);
2896 :
2897 : // Return immediately if pre-parser decided to abort parsing.
2898 1434068 : if (result == PreParser::kPreParseAbort) return kLazyParsingAborted;
2899 1434016 : if (result == PreParser::kPreParseStackOverflow) {
2900 : // Propagate stack overflow.
2901 : set_stack_overflow();
2902 52 : *ok = false;
2903 52 : return kLazyParsingComplete;
2904 : }
2905 1433964 : if (pending_error_handler_.has_pending_error()) {
2906 49700 : *ok = false;
2907 49700 : return kLazyParsingComplete;
2908 : }
2909 4152996 : PreParserLogger* logger = reusable_preparser()->logger();
2910 : function_scope->set_end_position(logger->end());
2911 1384264 : Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2912 : total_preparse_skipped_ +=
2913 1384264 : function_scope->end_position() - function_scope->start_position();
2914 1384264 : *num_parameters = logger->num_parameters();
2915 : SkipFunctionLiterals(logger->num_inner_functions());
2916 2238661 : if (!is_inner_function && produce_cached_parse_data()) {
2917 : DCHECK(log_);
2918 : log_->LogFunction(function_scope->start_position(),
2919 : function_scope->end_position(), *num_parameters,
2920 : language_mode(), function_scope->uses_super_property(),
2921 612 : logger->num_inner_functions());
2922 : }
2923 1434068 : return kLazyParsingComplete;
2924 : }
2925 :
2926 :
2927 169272 : Statement* Parser::BuildAssertIsCoercible(Variable* var) {
2928 : // if (var === null || var === undefined)
2929 : // throw /* type error kNonCoercible) */;
2930 :
2931 : Expression* condition = factory()->NewBinaryOperation(
2932 : Token::OR,
2933 : factory()->NewCompareOperation(
2934 169272 : Token::EQ_STRICT, factory()->NewVariableProxy(var),
2935 338544 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2936 : factory()->NewCompareOperation(
2937 169272 : Token::EQ_STRICT, factory()->NewVariableProxy(var),
2938 507816 : factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition),
2939 169272 : kNoSourcePosition);
2940 : Expression* throw_type_error =
2941 : NewThrowTypeError(MessageTemplate::kNonCoercible,
2942 169272 : ast_value_factory()->empty_string(), kNoSourcePosition);
2943 : IfStatement* if_statement = factory()->NewIfStatement(
2944 : condition,
2945 169272 : factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition),
2946 338544 : factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
2947 169272 : return if_statement;
2948 : }
2949 :
2950 :
2951 : class InitializerRewriter final
2952 : : public AstTraversalVisitor<InitializerRewriter> {
2953 : public:
2954 : InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser,
2955 : Scope* scope)
2956 : : AstTraversalVisitor(stack_limit, root),
2957 : parser_(parser),
2958 30182 : scope_(scope) {}
2959 :
2960 : private:
2961 : // This is required so that the overriden Visit* methods can be
2962 : // called by the base class (template).
2963 : friend class AstTraversalVisitor<InitializerRewriter>;
2964 :
2965 : // Just rewrite destructuring assignments wrapped in RewritableExpressions.
2966 158 : void VisitRewritableExpression(RewritableExpression* to_rewrite) {
2967 316 : if (to_rewrite->is_rewritten()) return;
2968 : Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
2969 114 : scope_);
2970 : AstTraversalVisitor::VisitRewritableExpression(to_rewrite);
2971 : }
2972 :
2973 : // Code in function literals does not need to be eagerly rewritten, it will be
2974 : // rewritten when scheduled.
2975 : void VisitFunctionLiteral(FunctionLiteral* expr) {}
2976 :
2977 : Parser* parser_;
2978 : Scope* scope_;
2979 : };
2980 :
2981 :
2982 30182 : void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) {
2983 30182 : InitializerRewriter rewriter(stack_limit_, expr, this, scope);
2984 : rewriter.Run();
2985 30182 : }
2986 :
2987 :
2988 49002 : Block* Parser::BuildParameterInitializationBlock(
2989 : const ParserFormalParameters& parameters, bool* ok) {
2990 : DCHECK(!parameters.is_simple);
2991 : DCHECK(scope()->is_function_scope());
2992 : DCHECK_EQ(scope(), parameters.scope);
2993 321037 : Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition);
2994 : int index = 0;
2995 190226 : for (auto parameter : parameters.params) {
2996 : DeclarationDescriptor descriptor;
2997 93522 : descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
2998 93522 : descriptor.scope = scope();
2999 93522 : descriptor.mode = LET;
3000 93522 : descriptor.declaration_pos = parameter->pattern->position();
3001 : // The position that will be used by the AssignmentExpression
3002 : // which copies from the temp parameter to the pattern.
3003 : //
3004 : // TODO(adamk): Should this be kNoSourcePosition, since
3005 : // it's just copying from a temp var to the real param var?
3006 93522 : descriptor.initialization_pos = parameter->pattern->position();
3007 : Expression* initial_value =
3008 187044 : factory()->NewVariableProxy(parameters.scope->parameter(index));
3009 93522 : if (parameter->initializer != nullptr) {
3010 : // IS_UNDEFINED($param) ? initializer : $param
3011 :
3012 : // Ensure initializer is rewritten
3013 30182 : RewriteParameterInitializer(parameter->initializer, scope());
3014 :
3015 : auto condition = factory()->NewCompareOperation(
3016 : Token::EQ_STRICT,
3017 60364 : factory()->NewVariableProxy(parameters.scope->parameter(index)),
3018 60364 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
3019 : initial_value = factory()->NewConditional(
3020 30182 : condition, parameter->initializer, initial_value, kNoSourcePosition);
3021 30182 : descriptor.initialization_pos = parameter->initializer->position();
3022 : }
3023 :
3024 : Scope* param_scope = scope();
3025 : Block* param_block = init_block;
3026 145637 : if (!parameter->is_simple() && scope()->calls_sloppy_eval()) {
3027 1347 : param_scope = NewVarblockScope();
3028 1347 : param_scope->set_start_position(descriptor.initialization_pos);
3029 1347 : param_scope->set_end_position(parameter->initializer_end_position);
3030 : param_scope->RecordEvalCall();
3031 1347 : param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
3032 : param_block->set_scope(param_scope);
3033 : // Pass the appropriate scope in so that PatternRewriter can appropriately
3034 : // rewrite inner initializers of the pattern to param_scope
3035 1347 : descriptor.scope = param_scope;
3036 : // Rewrite the outer initializer to point to param_scope
3037 : ReparentParameterExpressionScope(stack_limit(), initial_value,
3038 1347 : param_scope);
3039 : }
3040 :
3041 93522 : BlockState block_state(&scope_, param_scope);
3042 : DeclarationParsingResult::Declaration decl(
3043 93522 : parameter->pattern, parameter->initializer_end_position, initial_value);
3044 : PatternRewriter::DeclareAndInitializeVariables(
3045 93522 : this, param_block, &descriptor, &decl, nullptr, CHECK_OK);
3046 :
3047 92222 : if (param_block != init_block) {
3048 1347 : param_scope = param_scope->FinalizeBlockScope();
3049 1347 : if (param_scope != nullptr) {
3050 1347 : CheckConflictingVarDeclarations(param_scope, CHECK_OK);
3051 : }
3052 : init_block->statements()->Add(param_block, zone());
3053 : }
3054 92222 : ++index;
3055 : }
3056 : return init_block;
3057 : }
3058 :
3059 : Scope* Parser::NewHiddenCatchScopeWithParent(Scope* parent) {
3060 464250 : Scope* catch_scope = NewScopeWithParent(parent, CATCH_SCOPE);
3061 464250 : catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR);
3062 464250 : catch_scope->set_is_hidden();
3063 : return catch_scope;
3064 : }
3065 :
3066 34035 : Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
3067 : // .promise = %AsyncFunctionPromiseCreate();
3068 : // try {
3069 : // <inner_block>
3070 : // } catch (.catch) {
3071 : // %RejectPromise(.promise, .catch);
3072 : // return .promise;
3073 : // } finally {
3074 : // %AsyncFunctionPromiseRelease(.promise);
3075 : // }
3076 204210 : Block* result = factory()->NewBlock(nullptr, 2, true, kNoSourcePosition);
3077 :
3078 : // .promise = %AsyncFunctionPromiseCreate();
3079 : Statement* set_promise;
3080 : {
3081 : Expression* create_promise = factory()->NewCallRuntime(
3082 : Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX,
3083 34035 : new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition);
3084 : Assignment* assign_promise = factory()->NewAssignment(
3085 34035 : Token::ASSIGN, factory()->NewVariableProxy(PromiseVariable()),
3086 34035 : create_promise, kNoSourcePosition);
3087 : set_promise =
3088 34035 : factory()->NewExpressionStatement(assign_promise, kNoSourcePosition);
3089 : }
3090 : result->statements()->Add(set_promise, zone());
3091 :
3092 : // catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
3093 : Scope* catch_scope = NewHiddenCatchScopeWithParent(scope());
3094 :
3095 : Expression* promise_reject = BuildRejectPromise(
3096 34035 : factory()->NewVariableProxy(catch_scope->catch_variable()),
3097 34035 : kNoSourcePosition);
3098 : Block* catch_block = IgnoreCompletion(
3099 34035 : factory()->NewReturnStatement(promise_reject, kNoSourcePosition));
3100 :
3101 : TryStatement* try_catch_statement =
3102 : factory()->NewTryCatchStatementForAsyncAwait(
3103 34035 : inner_block, catch_scope, catch_block, kNoSourcePosition);
3104 :
3105 : // There is no TryCatchFinally node, so wrap it in an outer try/finally
3106 : Block* outer_try_block = IgnoreCompletion(try_catch_statement);
3107 :
3108 : // finally { %AsyncFunctionPromiseRelease(.promise) }
3109 : Block* finally_block;
3110 : {
3111 34035 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
3112 34035 : args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3113 : Expression* call_promise_release = factory()->NewCallRuntime(
3114 34035 : Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition);
3115 : Statement* promise_release = factory()->NewExpressionStatement(
3116 34035 : call_promise_release, kNoSourcePosition);
3117 : finally_block = IgnoreCompletion(promise_release);
3118 : }
3119 :
3120 : Statement* try_finally_statement = factory()->NewTryFinallyStatement(
3121 34035 : outer_try_block, finally_block, kNoSourcePosition);
3122 :
3123 : result->statements()->Add(try_finally_statement, zone());
3124 34035 : return result;
3125 : }
3126 :
3127 106167 : Assignment* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) {
3128 : // .generator = %CreateJSGeneratorObject(...);
3129 : DCHECK_NOT_NULL(function_state_->generator_object_variable());
3130 318501 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3131 106167 : args->Add(factory()->NewThisFunction(pos), zone());
3132 : args->Add(IsArrowFunction(kind) ? GetLiteralUndefined(pos)
3133 : : ThisExpression(kNoSourcePosition),
3134 106167 : zone());
3135 : Expression* allocation =
3136 106167 : factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args, pos);
3137 : VariableProxy* proxy =
3138 212334 : factory()->NewVariableProxy(function_state_->generator_object_variable());
3139 : return factory()->NewAssignment(Token::INIT, proxy, allocation,
3140 106167 : kNoSourcePosition);
3141 : }
3142 :
3143 32224 : Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
3144 : // %ResolvePromise(.promise, value), .promise
3145 96672 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3146 32224 : args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3147 : args->Add(value, zone());
3148 : Expression* call_runtime =
3149 32224 : factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, pos);
3150 : return factory()->NewBinaryOperation(
3151 : Token::COMMA, call_runtime,
3152 64448 : factory()->NewVariableProxy(PromiseVariable()), pos);
3153 : }
3154 :
3155 34035 : Expression* Parser::BuildRejectPromise(Expression* value, int pos) {
3156 : // %promise_internal_reject(.promise, value, false), .promise
3157 : // Disables the additional debug event for the rejection since a debug event
3158 : // already happened for the exception that got us here.
3159 136140 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(3, zone());
3160 34035 : args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3161 : args->Add(value, zone());
3162 34035 : args->Add(factory()->NewBooleanLiteral(false, pos), zone());
3163 : Expression* call_runtime = factory()->NewCallRuntime(
3164 34035 : Context::PROMISE_INTERNAL_REJECT_INDEX, args, pos);
3165 : return factory()->NewBinaryOperation(
3166 : Token::COMMA, call_runtime,
3167 68070 : factory()->NewVariableProxy(PromiseVariable()), pos);
3168 : }
3169 :
3170 334930 : Variable* Parser::PromiseVariable() {
3171 : // Based on the various compilation paths, there are many different code
3172 : // paths which may be the first to access the Promise temporary. Whichever
3173 : // comes first should create it and stash it in the FunctionState.
3174 367274 : Variable* promise = function_state_->promise_variable();
3175 334930 : if (function_state_->promise_variable() == nullptr) {
3176 : promise = function_state_->scope()->DeclarePromiseVar(
3177 97032 : ast_value_factory()->empty_string());
3178 : }
3179 334930 : return promise;
3180 : }
3181 :
3182 32860 : Variable* Parser::AsyncGeneratorAwaitVariable() {
3183 44246 : Variable* result = function_state_->scope()->async_generator_await_var();
3184 32860 : if (result == nullptr) {
3185 : result = function_state_->scope()->DeclareAsyncGeneratorAwaitVar(
3186 34158 : ast_value_factory()->empty_string());
3187 : }
3188 32860 : return result;
3189 : }
3190 :
3191 65583 : Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
3192 65583 : Assignment* assignment = BuildCreateJSGeneratorObject(pos, kind);
3193 : VariableProxy* generator =
3194 196749 : factory()->NewVariableProxy(function_state_->generator_object_variable());
3195 : // The position of the yield is important for reporting the exception
3196 : // caused by calling the .throw method on a generator suspended at the
3197 : // initial yield (i.e. right after generator instantiation).
3198 : return BuildSuspend(generator, assignment, scope()->start_position(),
3199 65583 : Suspend::kOnExceptionThrow, SuspendFlags::kYield);
3200 : }
3201 :
3202 6155666 : ZoneList<Statement*>* Parser::ParseFunction(
3203 : const AstRawString* function_name, int pos, FunctionKind kind,
3204 : FunctionLiteral::FunctionType function_type,
3205 : DeclarationScope* function_scope, int* num_parameters, int* function_length,
3206 : bool* has_duplicate_parameters, int* expected_property_count, bool* ok) {
3207 6155666 : ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
3208 :
3209 6155666 : FunctionState function_state(&function_state_, &scope_, function_scope);
3210 :
3211 : DuplicateFinder duplicate_finder;
3212 24492469 : ExpressionClassifier formals_classifier(this, &duplicate_finder);
3213 :
3214 6155677 : if (IsResumableFunction(kind)) PrepareGeneratorVariables();
3215 :
3216 6155674 : int expected_parameters_end_pos = parameters_end_pos_;
3217 6155674 : if (expected_parameters_end_pos != kNoSourcePosition) {
3218 : // This is the first function encountered in a CreateDynamicFunction eval.
3219 914 : parameters_end_pos_ = kNoSourcePosition;
3220 : // The function name should have been ignored, giving us the empty string
3221 : // here.
3222 : DCHECK_EQ(function_name, ast_value_factory()->empty_string());
3223 : }
3224 :
3225 : ParserFormalParameters formals(function_scope);
3226 6155674 : ParseFormalParameterList(&formals, CHECK_OK);
3227 6138320 : if (expected_parameters_end_pos != kNoSourcePosition) {
3228 : // Check for '(' or ')' shenanigans in the parameter string for dynamic
3229 : // functions.
3230 : int position = peek_position();
3231 713 : if (position < expected_parameters_end_pos) {
3232 : ReportMessageAt(Scanner::Location(position, position + 1),
3233 15 : MessageTemplate::kArgStringTerminatesParametersEarly);
3234 15 : *ok = false;
3235 15 : return nullptr;
3236 698 : } else if (position > expected_parameters_end_pos) {
3237 : ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
3238 : expected_parameters_end_pos),
3239 0 : MessageTemplate::kUnexpectedEndOfArgString);
3240 0 : *ok = false;
3241 0 : return nullptr;
3242 : }
3243 : }
3244 6138305 : Expect(Token::RPAREN, CHECK_OK);
3245 : int formals_end_position = scanner()->location().end_pos;
3246 12274424 : *num_parameters = formals.num_parameters();
3247 6137212 : *function_length = formals.function_length;
3248 :
3249 : CheckArityRestrictions(formals.arity, kind, formals.has_rest,
3250 : function_scope->start_position(), formals_end_position,
3251 6137212 : CHECK_OK);
3252 6136335 : Expect(Token::LBRACE, CHECK_OK);
3253 :
3254 6135653 : ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(8, zone());
3255 6135649 : ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ok);
3256 :
3257 : // Validate parameter names. We can do this only after parsing the function,
3258 : // since the function can declare itself strict.
3259 : const bool allow_duplicate_parameters =
3260 8424101 : is_sloppy(function_scope->language_mode()) && formals.is_simple &&
3261 : !IsConciseMethod(kind);
3262 : ValidateFormalParameters(function_scope->language_mode(),
3263 12271280 : allow_duplicate_parameters, CHECK_OK);
3264 :
3265 : RewriteDestructuringAssignments();
3266 :
3267 : *has_duplicate_parameters =
3268 6063214 : !classifier()->is_valid_formal_parameter_list_without_duplicates();
3269 :
3270 6063214 : *expected_property_count = function_state.expected_property_count();
3271 6063214 : return body;
3272 : }
3273 :
3274 : void Parser::DeclareClassVariable(const AstRawString* name,
3275 : ClassInfo* class_info, int class_token_pos,
3276 : bool* ok) {
3277 : #ifdef DEBUG
3278 : scope()->SetScopeName(name);
3279 : #endif
3280 :
3281 105813 : if (name != nullptr) {
3282 83888 : class_info->proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3283 : Declaration* declaration = factory()->NewVariableDeclaration(
3284 83888 : class_info->proxy, scope(), class_token_pos);
3285 : Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
3286 83888 : Variable::DefaultInitializationFlag(CONST), ok);
3287 : }
3288 : }
3289 :
3290 : // This method declares a property of the given class. It updates the
3291 : // following fields of class_info, as appropriate:
3292 : // - constructor
3293 : // - properties
3294 : void Parser::DeclareClassProperty(const AstRawString* class_name,
3295 : ClassLiteralProperty* property,
3296 : ClassLiteralProperty::Kind kind,
3297 : bool is_static, bool is_constructor,
3298 : ClassInfo* class_info, bool* ok) {
3299 350663 : if (is_constructor) {
3300 : DCHECK(!class_info->constructor);
3301 28082 : class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral();
3302 : DCHECK_NOT_NULL(class_info->constructor);
3303 : class_info->constructor->set_raw_name(
3304 12908 : class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
3305 26949 : : ast_value_factory()->empty_cons_string());
3306 : return;
3307 : }
3308 :
3309 : if (property->kind() == ClassLiteralProperty::FIELD) {
3310 : DCHECK(allow_harmony_class_fields());
3311 : // TODO(littledan): Implement class fields
3312 : }
3313 336622 : class_info->properties->Add(property, zone());
3314 : }
3315 :
3316 : // This method rewrites a class literal into a do-expression.
3317 : // It uses the following fields of class_info:
3318 : // - constructor (if missing, it updates it with a default constructor)
3319 : // - proxy
3320 : // - extends
3321 : // - properties
3322 : // - has_name_static_property
3323 : // - has_static_computed_names
3324 : Expression* Parser::RewriteClassLiteral(const AstRawString* name,
3325 : ClassInfo* class_info, int pos,
3326 92611 : bool* ok) {
3327 92611 : int end_pos = scanner()->location().end_pos;
3328 92611 : Block* do_block = factory()->NewBlock(nullptr, 1, false, pos);
3329 92611 : Variable* result_var = NewTemporary(ast_value_factory()->empty_string());
3330 92611 : DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos);
3331 :
3332 92611 : bool has_extends = class_info->extends != nullptr;
3333 92611 : bool has_default_constructor = class_info->constructor == nullptr;
3334 92611 : if (has_default_constructor) {
3335 : class_info->constructor =
3336 78884 : DefaultConstructor(name, has_extends, pos, end_pos);
3337 : }
3338 :
3339 92611 : scope()->set_end_position(end_pos);
3340 :
3341 92611 : if (name != nullptr) {
3342 : DCHECK_NOT_NULL(class_info->proxy);
3343 75707 : class_info->proxy->var()->set_initializer_position(end_pos);
3344 : }
3345 :
3346 : ClassLiteral* class_literal = factory()->NewClassLiteral(
3347 : class_info->proxy, class_info->extends, class_info->constructor,
3348 : class_info->properties, pos, end_pos,
3349 : class_info->has_name_static_property,
3350 92611 : class_info->has_static_computed_names);
3351 :
3352 : do_block->statements()->Add(
3353 : factory()->NewExpressionStatement(
3354 : factory()->NewAssignment(Token::ASSIGN,
3355 92611 : factory()->NewVariableProxy(result_var),
3356 92611 : class_literal, kNoSourcePosition),
3357 92611 : pos),
3358 185222 : zone());
3359 92611 : do_block->set_scope(scope()->FinalizeBlockScope());
3360 92611 : do_expr->set_represented_function(class_info->constructor);
3361 92611 : AddFunctionForNameInference(class_info->constructor);
3362 :
3363 : return do_expr;
3364 : }
3365 :
3366 0 : Literal* Parser::GetLiteralUndefined(int position) {
3367 602584 : return factory()->NewUndefinedLiteral(position);
3368 : }
3369 :
3370 :
3371 9987207 : void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
3372 10025203 : Declaration* decl = scope->CheckConflictingVarDeclarations();
3373 9987199 : if (decl != NULL) {
3374 : // In ES6, conflicting variable bindings are early errors.
3375 : const AstRawString* name = decl->proxy()->raw_name();
3376 37996 : int position = decl->proxy()->position();
3377 : Scanner::Location location =
3378 : position == kNoSourcePosition
3379 : ? Scanner::Location::invalid()
3380 37996 : : Scanner::Location(position, position + 1);
3381 : ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
3382 37996 : *ok = false;
3383 : }
3384 9987199 : }
3385 :
3386 :
3387 15474 : void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
3388 : // For each var-binding that shadows a parameter, insert an assignment
3389 : // initializing the variable with the parameter.
3390 15474 : Scope* inner_scope = inner_block->scope();
3391 : DCHECK(inner_scope->is_declaration_scope());
3392 : Scope* function_scope = inner_scope->outer_scope();
3393 : DCHECK(function_scope->is_function_scope());
3394 15474 : BlockState block_state(&scope_, inner_scope);
3395 124577 : for (Declaration* decl : *inner_scope->declarations()) {
3396 94302 : if (decl->proxy()->var()->mode() != VAR || !decl->IsVariableDeclaration()) {
3397 42108 : continue;
3398 : }
3399 : const AstRawString* name = decl->proxy()->raw_name();
3400 7327 : Variable* parameter = function_scope->LookupLocal(name);
3401 7327 : if (parameter == nullptr) continue;
3402 : VariableProxy* to = NewUnresolved(name);
3403 2086 : VariableProxy* from = factory()->NewVariableProxy(parameter);
3404 : Expression* assignment =
3405 1043 : factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
3406 : Statement* statement =
3407 2086 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
3408 : inner_block->statements()->InsertAt(0, statement, zone());
3409 : }
3410 15474 : }
3411 :
3412 3999217 : void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
3413 : // For the outermost eval scope, we cannot hoist during parsing: let
3414 : // declarations in the surrounding scope may prevent hoisting, but the
3415 : // information is unaccessible during parsing. In this case, we hoist later in
3416 : // DeclarationScope::Analyze.
3417 3999217 : if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
3418 3999217 : return;
3419 : }
3420 2925817 : scope->HoistSloppyBlockFunctions(factory());
3421 : }
3422 :
3423 : // ----------------------------------------------------------------------------
3424 : // Parser support
3425 :
3426 25158 : bool Parser::TargetStackContainsLabel(const AstRawString* label) {
3427 50083 : for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
3428 49850 : if (ContainsLabel(t->statement()->labels(), label)) return true;
3429 : }
3430 : return false;
3431 : }
3432 :
3433 :
3434 283602 : BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
3435 : bool* ok) {
3436 283602 : bool anonymous = label == NULL;
3437 515802 : for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
3438 515433 : BreakableStatement* stat = t->statement();
3439 1477297 : if ((anonymous && stat->is_target_for_anonymous()) ||
3440 69002 : (!anonymous && ContainsLabel(stat->labels(), label))) {
3441 : return stat;
3442 : }
3443 : }
3444 : return NULL;
3445 : }
3446 :
3447 :
3448 94230 : IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
3449 : bool* ok) {
3450 : bool anonymous = label == NULL;
3451 294587 : for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
3452 294281 : IterationStatement* stat = t->statement()->AsIterationStatement();
3453 294281 : if (stat == NULL) continue;
3454 :
3455 : DCHECK(stat->is_target_for_anonymous());
3456 100110 : if (anonymous || ContainsLabel(stat->labels(), label)) {
3457 : return stat;
3458 : }
3459 : }
3460 : return NULL;
3461 : }
3462 :
3463 :
3464 2263499 : void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
3465 2263499 : Handle<String> source_url = scanner_.SourceUrl(isolate);
3466 2263503 : if (!source_url.is_null()) {
3467 2306 : script->set_source_url(*source_url);
3468 : }
3469 2263503 : Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
3470 2263500 : if (!source_mapping_url.is_null()) {
3471 133 : script->set_source_mapping_url(*source_mapping_url);
3472 : }
3473 2263500 : }
3474 :
3475 386293 : void Parser::ReportErrors(Isolate* isolate, Handle<Script> script) {
3476 761977 : if (stack_overflow()) {
3477 10609 : isolate->StackOverflow();
3478 : } else {
3479 : DCHECK(pending_error_handler_.has_pending_error());
3480 : // Internalize ast values for throwing the pending error.
3481 375684 : ast_value_factory()->Internalize(isolate);
3482 375684 : pending_error_handler_.ThrowPendingError(isolate, script);
3483 : }
3484 386293 : }
3485 :
3486 7135449 : void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
3487 : // Move statistics to Isolate.
3488 142708904 : for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
3489 : ++feature) {
3490 139141176 : if (use_counts_[feature] > 0) {
3491 3603991 : isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
3492 : }
3493 : }
3494 3567728 : if (scanner_.FoundHtmlComment()) {
3495 15 : isolate->CountUsage(v8::Isolate::kHtmlComment);
3496 30 : if (script->line_offset() == 0 && script->column_offset() == 0) {
3497 15 : isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
3498 : }
3499 : }
3500 : isolate->counters()->total_preparse_skipped()->Increment(
3501 7135456 : total_preparse_skipped_);
3502 3567881 : if (!parsing_on_main_thread_ &&
3503 153 : FLAG_runtime_stats ==
3504 : v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE) {
3505 : // Copy over the counters from the background thread to the main counters on
3506 : // the isolate.
3507 0 : isolate->counters()->runtime_call_stats()->Add(runtime_call_stats_);
3508 : }
3509 3567728 : }
3510 :
3511 778 : void Parser::ParseOnBackground(ParseInfo* info) {
3512 160 : parsing_on_main_thread_ = false;
3513 :
3514 : DCHECK(info->literal() == NULL);
3515 : FunctionLiteral* result = NULL;
3516 :
3517 160 : ParserLogger logger;
3518 160 : if (produce_cached_parse_data()) {
3519 6 : if (allow_lazy_) {
3520 6 : log_ = &logger;
3521 : } else {
3522 0 : compile_options_ = ScriptCompiler::kNoCompileOptions;
3523 : }
3524 : }
3525 160 : if (FLAG_runtime_stats) {
3526 : // Create separate runtime stats for background parsing.
3527 132 : runtime_call_stats_ = new (zone()) RuntimeCallStats();
3528 : }
3529 :
3530 : std::unique_ptr<Utf16CharacterStream> stream;
3531 : Utf16CharacterStream* stream_ptr;
3532 160 : if (info->character_stream()) {
3533 : DCHECK(info->source_stream() == nullptr);
3534 : stream_ptr = info->character_stream();
3535 : } else {
3536 : DCHECK(info->character_stream() == nullptr);
3537 : stream.reset(ScannerStream::For(info->source_stream(),
3538 : info->source_stream_encoding(),
3539 264 : runtime_call_stats_));
3540 : stream_ptr = stream.get();
3541 : }
3542 160 : scanner_.Initialize(stream_ptr);
3543 : DCHECK(info->maybe_outer_scope_info().is_null());
3544 :
3545 : DCHECK(original_scope_);
3546 :
3547 : // When streaming, we don't know the length of the source until we have parsed
3548 : // it. The raw data can be UTF-8, so we wouldn't know the source length until
3549 : // we have decoded it anyway even if we knew the raw data length (which we
3550 : // don't). We work around this by storing all the scopes which need their end
3551 : // position set at the end of the script (the top scope and possible eval
3552 : // scopes) and set their end position after we know the script length.
3553 160 : if (info->is_toplevel()) {
3554 132 : fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
3555 132 : result = DoParseProgram(info);
3556 : } else {
3557 28 : result = DoParseFunction(info);
3558 : }
3559 :
3560 : info->set_literal(result);
3561 :
3562 : // We cannot internalize on a background thread; a foreground task will take
3563 : // care of calling Parser::Internalize just before compilation.
3564 :
3565 160 : if (produce_cached_parse_data()) {
3566 12 : if (result != NULL) *info->cached_data() = logger.GetScriptData();
3567 6 : log_ = NULL;
3568 : }
3569 160 : if (FLAG_runtime_stats &
3570 : v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
3571 0 : auto value = v8::tracing::TracedValue::Create();
3572 0 : runtime_call_stats_->Dump(value.get());
3573 0 : TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("v8.runtime_stats"),
3574 : "V8.RuntimeStats", TRACE_EVENT_SCOPE_THREAD,
3575 : "runtime-call-stats", std::move(value));
3576 : }
3577 160 : }
3578 :
3579 40750 : Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
3580 81500 : return new (zone()) TemplateLiteral(zone(), pos);
3581 : }
3582 :
3583 70792 : void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
3584 : bool tail) {
3585 : DCHECK(should_cook || allow_harmony_template_escapes());
3586 208092 : int pos = scanner()->location().beg_pos;
3587 : int end = scanner()->location().end_pos - (tail ? 1 : 2);
3588 70792 : const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
3589 70792 : Literal* raw = factory()->NewStringLiteral(trv, pos);
3590 70792 : if (should_cook) {
3591 66508 : const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
3592 66508 : Literal* cooked = factory()->NewStringLiteral(tv, pos);
3593 66508 : (*state)->AddTemplateSpan(cooked, raw, end, zone());
3594 : } else {
3595 4284 : (*state)->AddTemplateSpan(GetLiteralUndefined(pos), raw, end, zone());
3596 : }
3597 70792 : }
3598 :
3599 :
3600 0 : void Parser::AddTemplateExpression(TemplateLiteralState* state,
3601 : Expression* expression) {
3602 40118 : (*state)->AddExpression(expression, zone());
3603 0 : }
3604 :
3605 :
3606 28893 : Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
3607 : Expression* tag) {
3608 28893 : TemplateLiteral* lit = *state;
3609 : int pos = lit->position();
3610 28893 : const ZoneList<Expression*>* cooked_strings = lit->cooked();
3611 28893 : const ZoneList<Expression*>* raw_strings = lit->raw();
3612 : const ZoneList<Expression*>* expressions = lit->expressions();
3613 : DCHECK_EQ(cooked_strings->length(), raw_strings->length());
3614 : DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3615 :
3616 28893 : if (!tag) {
3617 : // Build tree of BinaryOps to simplify code-generation
3618 20574 : Expression* expr = cooked_strings->at(0);
3619 : int i = 0;
3620 69870 : while (i < expressions->length()) {
3621 115059 : Expression* sub = expressions->at(i++);
3622 28722 : Expression* cooked_str = cooked_strings->at(i);
3623 :
3624 : // Let middle be ToString(sub).
3625 : ZoneList<Expression*>* args =
3626 115677 : new (zone()) ZoneList<Expression*>(1, zone());
3627 : args->Add(sub, zone());
3628 : Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString,
3629 28722 : args, sub->position());
3630 :
3631 : expr = factory()->NewBinaryOperation(
3632 : Token::ADD, factory()->NewBinaryOperation(
3633 28722 : Token::ADD, expr, middle, expr->position()),
3634 28722 : cooked_str, sub->position());
3635 : }
3636 : return expr;
3637 : } else {
3638 8319 : uint32_t hash = ComputeTemplateLiteralHash(lit);
3639 :
3640 : // $getTemplateCallSite
3641 8319 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
3642 : args->Add(factory()->NewArrayLiteral(
3643 8319 : const_cast<ZoneList<Expression*>*>(cooked_strings), pos),
3644 : zone());
3645 : args->Add(factory()->NewArrayLiteral(
3646 8319 : const_cast<ZoneList<Expression*>*>(raw_strings), pos),
3647 : zone());
3648 :
3649 : // Truncate hash to Smi-range.
3650 8319 : Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
3651 8319 : args->Add(factory()->NewNumberLiteral(hash_obj->value(), pos), zone());
3652 :
3653 : Expression* call_site = factory()->NewCallRuntime(
3654 8319 : Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start);
3655 :
3656 : // Call TagFn
3657 : ZoneList<Expression*>* call_args =
3658 16638 : new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
3659 : call_args->Add(call_site, zone());
3660 : call_args->AddAll(*expressions, zone());
3661 8319 : return factory()->NewCall(tag, call_args, pos);
3662 : }
3663 : }
3664 :
3665 :
3666 8319 : uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
3667 : const ZoneList<Expression*>* raw_strings = lit->raw();
3668 8319 : int total = raw_strings->length();
3669 : DCHECK(total);
3670 :
3671 : uint32_t running_hash = 0;
3672 :
3673 23268 : for (int index = 0; index < total; ++index) {
3674 14949 : if (index) {
3675 : running_hash = StringHasher::ComputeRunningHashOneByte(
3676 : running_hash, "${}", 3);
3677 : }
3678 :
3679 14949 : const AstRawString* raw_string =
3680 29898 : raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
3681 14949 : if (raw_string->is_one_byte()) {
3682 : const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
3683 : running_hash = StringHasher::ComputeRunningHashOneByte(
3684 : running_hash, data, raw_string->length());
3685 : } else {
3686 : const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
3687 : running_hash = StringHasher::ComputeRunningHash(running_hash, data,
3688 : raw_string->length());
3689 : }
3690 : }
3691 :
3692 8319 : return running_hash;
3693 : }
3694 :
3695 : namespace {
3696 :
3697 7180 : bool OnlyLastArgIsSpread(ZoneList<Expression*>* args) {
3698 16296 : for (int i = 0; i < args->length() - 1; i++) {
3699 11488 : if (args->at(i)->IsSpread()) {
3700 : return false;
3701 : }
3702 : }
3703 12956 : return args->at(args->length() - 1)->IsSpread();
3704 : }
3705 :
3706 : } // namespace
3707 :
3708 702 : ZoneList<Expression*>* Parser::PrepareSpreadArguments(
3709 : ZoneList<Expression*>* list) {
3710 10787 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
3711 702 : if (list->length() == 1) {
3712 : // Spread-call with single spread argument produces an InternalArray
3713 : // containing the values from the array.
3714 : //
3715 : // Function is called or constructed with the produced array of arguments
3716 : //
3717 : // EG: Apply(Func, Spread(spread0))
3718 : ZoneList<Expression*>* spread_list =
3719 0 : new (zone()) ZoneList<Expression*>(0, zone());
3720 0 : spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
3721 : args->Add(factory()->NewCallRuntime(Runtime::kSpreadIterablePrepare,
3722 0 : spread_list, kNoSourcePosition),
3723 : zone());
3724 0 : return args;
3725 : } else {
3726 : // Spread-call with multiple arguments produces array literals for each
3727 : // sequences of unspread arguments, and converts each spread iterable to
3728 : // an Internal array. Finally, all of these produced arrays are flattened
3729 : // into a single InternalArray, containing the arguments for the call.
3730 : //
3731 : // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
3732 : // Spread(spread1), [unspread2, unspread3]))
3733 : int i = 0;
3734 : int n = list->length();
3735 1932 : while (i < n) {
3736 3250 : if (!list->at(i)->IsSpread()) {
3737 : ZoneList<Expression*>* unspread =
3738 1145 : new (zone()) ZoneList<Expression*>(1, zone());
3739 :
3740 : // Push array of unspread parameters
3741 9787 : while (i < n && !list->at(i)->IsSpread()) {
3742 3998 : unspread->Add(list->at(i++), zone());
3743 : }
3744 1145 : args->Add(factory()->NewArrayLiteral(unspread, kNoSourcePosition),
3745 : zone());
3746 :
3747 1145 : if (i == n) break;
3748 : }
3749 :
3750 : // Push eagerly spread argument
3751 : ZoneList<Expression*>* spread_list =
3752 1230 : new (zone()) ZoneList<Expression*>(1, zone());
3753 3690 : spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
3754 : args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
3755 1230 : spread_list, kNoSourcePosition),
3756 : zone());
3757 : }
3758 :
3759 702 : list = new (zone()) ZoneList<Expression*>(1, zone());
3760 : list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
3761 702 : kNoSourcePosition),
3762 : zone());
3763 702 : return list;
3764 : }
3765 : UNREACHABLE();
3766 : }
3767 :
3768 6918 : Expression* Parser::SpreadCall(Expression* function,
3769 : ZoneList<Expression*>* args, int pos,
3770 : Call::PossiblyEval is_possibly_eval) {
3771 : // Handle these cases in BytecodeGenerator.
3772 : // [Call,New]WithSpread bytecodes aren't used with tailcalls - see
3773 : // https://crbug.com/v8/5867
3774 8497 : if (!allow_tailcalls() && OnlyLastArgIsSpread(args)) {
3775 12446 : return factory()->NewCall(function, args, pos);
3776 : }
3777 :
3778 1390 : if (function->IsSuperCallReference()) {
3779 : // Super calls
3780 : // $super_constructor = %_GetSuperConstructor(<this-function>)
3781 : // %reflect_construct($super_constructor, args, new.target)
3782 :
3783 42 : args = PrepareSpreadArguments(args);
3784 42 : ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
3785 84 : tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
3786 : Expression* super_constructor = factory()->NewCallRuntime(
3787 42 : Runtime::kInlineGetSuperConstructor, tmp, pos);
3788 : args->InsertAt(0, super_constructor, zone());
3789 84 : args->Add(function->AsSuperCallReference()->new_target_var(), zone());
3790 : return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
3791 42 : pos);
3792 : } else {
3793 653 : args = PrepareSpreadArguments(args);
3794 1306 : if (function->IsProperty()) {
3795 : // Method calls
3796 210 : if (function->AsProperty()->IsSuperAccess()) {
3797 0 : Expression* home = ThisExpression(kNoSourcePosition);
3798 : args->InsertAt(0, function, zone());
3799 : args->InsertAt(1, home, zone());
3800 : } else {
3801 105 : Variable* temp = NewTemporary(ast_value_factory()->empty_string());
3802 105 : VariableProxy* obj = factory()->NewVariableProxy(temp);
3803 : Assignment* assign_obj = factory()->NewAssignment(
3804 : Token::ASSIGN, obj, function->AsProperty()->obj(),
3805 210 : kNoSourcePosition);
3806 : function = factory()->NewProperty(
3807 315 : assign_obj, function->AsProperty()->key(), kNoSourcePosition);
3808 : args->InsertAt(0, function, zone());
3809 105 : obj = factory()->NewVariableProxy(temp);
3810 210 : args->InsertAt(1, obj, zone());
3811 : }
3812 : } else {
3813 : // Non-method calls
3814 : args->InsertAt(0, function, zone());
3815 548 : args->InsertAt(1, factory()->NewUndefinedLiteral(kNoSourcePosition),
3816 1096 : zone());
3817 : }
3818 1306 : return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
3819 : }
3820 : }
3821 :
3822 262 : Expression* Parser::SpreadCallNew(Expression* function,
3823 : ZoneList<Expression*>* args, int pos) {
3824 262 : if (OnlyLastArgIsSpread(args)) {
3825 : // Handle in BytecodeGenerator.
3826 262 : return factory()->NewCallNew(function, args, pos);
3827 : }
3828 7 : args = PrepareSpreadArguments(args);
3829 : args->InsertAt(0, function, zone());
3830 :
3831 14 : return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
3832 : }
3833 :
3834 :
3835 41625207 : void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
3836 : v8::Isolate::UseCounterFeature feature;
3837 41625207 : if (is_sloppy(mode))
3838 : feature = v8::Isolate::kSloppyMode;
3839 17292290 : else if (is_strict(mode))
3840 : feature = v8::Isolate::kStrictMode;
3841 : else
3842 0 : UNREACHABLE();
3843 41625207 : ++use_counts_[feature];
3844 : scope->SetLanguageMode(mode);
3845 41625207 : }
3846 :
3847 11102 : void Parser::SetAsmModule() {
3848 : // Store the usage count; The actual use counter on the isolate is
3849 : // incremented after parsing is done.
3850 11102 : ++use_counts_[v8::Isolate::kUseAsm];
3851 : DCHECK(scope()->is_declaration_scope());
3852 11102 : scope()->AsDeclarationScope()->set_asm_module();
3853 11102 : }
3854 :
3855 : void Parser::MarkCollectedTailCallExpressions() {
3856 : const ZoneList<Expression*>& tail_call_expressions =
3857 6680620 : function_state_->tail_call_expressions().expressions();
3858 6696329 : for (int i = 0; i < tail_call_expressions.length(); ++i) {
3859 6696329 : MarkTailPosition(tail_call_expressions[i]);
3860 : }
3861 : }
3862 :
3863 672 : Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) {
3864 1560 : Expression* expr = args->at(0);
3865 1776 : for (int i = 1; i < args->length(); ++i) {
3866 : expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i),
3867 432 : expr->position());
3868 : }
3869 672 : return expr;
3870 : }
3871 :
3872 : // This method intoduces the line initializing the generator object
3873 : // when desugaring the body of async_function.
3874 : void Parser::PrepareAsyncFunctionBody(ZoneList<Statement*>* body,
3875 : FunctionKind kind, int pos) {
3876 : // When parsing an async arrow function, we get here without having called
3877 : // PrepareGeneratorVariables yet, so do it now.
3878 40584 : if (function_state_->generator_object_variable() == nullptr) {
3879 3363 : PrepareGeneratorVariables();
3880 : }
3881 : body->Add(factory()->NewExpressionStatement(
3882 40584 : BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition),
3883 81168 : zone());
3884 : }
3885 :
3886 : // This method completes the desugaring of the body of async_function.
3887 : void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
3888 : Expression* return_value, bool* ok) {
3889 : // function async_function() {
3890 : // .generator_object = %CreateJSGeneratorObject();
3891 : // BuildRejectPromiseOnException({
3892 : // ... block ...
3893 : // return %ResolvePromise(.promise, expr), .promise;
3894 : // })
3895 : // }
3896 :
3897 64448 : return_value = BuildResolvePromise(return_value, return_value->position());
3898 : block->statements()->Add(
3899 32224 : factory()->NewReturnStatement(return_value, return_value->position()),
3900 64448 : zone());
3901 32224 : block = BuildRejectPromiseOnException(block);
3902 32224 : body->Add(block, zone());
3903 : }
3904 :
3905 : Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
3906 : // In an Async Function:
3907 : // yield do {
3908 : // tmp = <operand>;
3909 : // %AsyncFunctionAwait(.generator_object, tmp, .promise);
3910 : // .promise
3911 : // }
3912 : //
3913 : // In an Async Generator:
3914 : // yield do {
3915 : // tmp = <operand>;
3916 : // %AsyncGeneratorAwait(.generator_object, tmp)
3917 : // .await_result_var
3918 : // }
3919 : //
3920 : // The value of the expression is returned to the caller of the async
3921 : // function for the first yield statement; for this, .promise is the
3922 : // appropriate return value, being a Promise that will be fulfilled or
3923 : // rejected with the appropriate value by the desugaring. Subsequent yield
3924 : // occurrences will return to the AsyncFunctionNext call within the
3925 : // implemementation of the intermediate throwaway Promise's then handler.
3926 : // This handler has nothing useful to do with the value, as the Promise is
3927 : // ignored. If we yielded the value of the throwawayPromise that
3928 : // AsyncFunctionAwait creates as an intermediate, it would create a memory
3929 : // leak; we must return .promise instead;
3930 : // The operand needs to be evaluated on a separate statement in order to get
3931 : // a break location, and the .promise needs to be read earlier so that it
3932 : // doesn't insert a false location.
3933 : // TODO(littledan): investigate why this ordering is needed in more detail.
3934 : //
3935 : // In the case of Async Generators, `.await_result_var` is not actually used
3936 : // for anything, but exists because of the current requirement that
3937 : // Do Expressions have a result variable.
3938 : Variable* generator_object_variable =
3939 100031 : function_state_->generator_object_variable();
3940 : DCHECK_NOT_NULL(generator_object_variable);
3941 :
3942 : const int nopos = kNoSourcePosition;
3943 :
3944 100031 : Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
3945 :
3946 : // Wrap value evaluation to provide a break location.
3947 100031 : Variable* temp_var = NewTemporary(ast_value_factory()->empty_string());
3948 : Expression* value_assignment = factory()->NewAssignment(
3949 100031 : Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos);
3950 : do_block->statements()->Add(
3951 100031 : factory()->NewExpressionStatement(value_assignment, value->position()),
3952 200062 : zone());
3953 :
3954 : Expression* generator_object =
3955 100031 : factory()->NewVariableProxy(generator_object_variable);
3956 :
3957 100031 : if (is_async_generator()) {
3958 : // AsyncGeneratorAwaitCaught will be rewritten to
3959 : // AsyncGeneratorAwaitUncaught by AstNumberingVisitor if there is no local
3960 : // enclosing try/catch block (not counting the one implicitly added in
3961 : // ParseAndRewriteGeneratorFunctionBody)
3962 32860 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3963 32860 : args->Add(generator_object, zone());
3964 32860 : args->Add(factory()->NewVariableProxy(temp_var), zone());
3965 :
3966 : Expression* await = factory()->NewCallRuntime(
3967 32860 : Context::ASYNC_GENERATOR_AWAIT_CAUGHT, args, nopos);
3968 : do_block->statements()->Add(
3969 32860 : factory()->NewExpressionStatement(await, await_pos), zone());
3970 :
3971 : // Wrap await to provide a break location between value evaluation and
3972 : // yield.
3973 : Expression* do_expr = factory()->NewDoExpression(
3974 32860 : do_block, AsyncGeneratorAwaitVariable(), nopos);
3975 : return BuildSuspend(generator_object, do_expr, nopos,
3976 32860 : Suspend::kOnExceptionRethrow, SuspendFlags::kAwait);
3977 : }
3978 :
3979 : // The parser emits calls to AsyncFunctionAwaitCaught or but the
3980 : // AstNumberingVisitor will rewrite this to AsyncFunctionAwaitUncaught or if
3981 : // there is no local enclosing try/catch block.
3982 67171 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(3, zone());
3983 67171 : args->Add(generator_object, zone());
3984 67171 : args->Add(factory()->NewVariableProxy(temp_var), zone());
3985 67171 : args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3986 :
3987 : Expression* await = factory()->NewCallRuntime(
3988 67171 : Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX, args, nopos);
3989 : do_block->statements()->Add(
3990 67171 : factory()->NewExpressionStatement(await, await_pos), zone());
3991 :
3992 : // Wrap await to provide a break location between value evaluation and yield.
3993 : Expression* do_expr =
3994 67171 : factory()->NewDoExpression(do_block, PromiseVariable(), nopos);
3995 :
3996 : return factory()->NewSuspend(generator_object, do_expr, nopos,
3997 : Suspend::kOnExceptionRethrow,
3998 67171 : SuspendFlags::kAwait);
3999 : }
4000 :
4001 : class NonPatternRewriter : public AstExpressionRewriter {
4002 : public:
4003 3276 : NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
4004 3276 : : AstExpressionRewriter(stack_limit), parser_(parser) {}
4005 6552 : ~NonPatternRewriter() override {}
4006 :
4007 : private:
4008 15397 : bool RewriteExpression(Expression* expr) override {
4009 15397 : if (expr->IsRewritableExpression()) return true;
4010 : // Rewrite only what could have been a pattern but is not.
4011 12073 : if (expr->IsArrayLiteral()) {
4012 : // Spread rewriting in array literals.
4013 6648 : ArrayLiteral* lit = expr->AsArrayLiteral();
4014 6648 : VisitExpressions(lit->values());
4015 6648 : replacement_ = parser_->RewriteSpreads(lit);
4016 3324 : return false;
4017 : }
4018 8749 : if (expr->IsObjectLiteral()) {
4019 : return true;
4020 : }
4021 8749 : if (expr->IsBinaryOperation() &&
4022 0 : expr->AsBinaryOperation()->op() == Token::COMMA) {
4023 : return true;
4024 : }
4025 : // Everything else does not need rewriting.
4026 8749 : return false;
4027 : }
4028 :
4029 0 : void VisitLiteralProperty(LiteralProperty* property) override {
4030 0 : if (property == nullptr) return;
4031 : // Do not rewrite (computed) key expressions
4032 0 : AST_REWRITE_PROPERTY(Expression, property, value);
4033 : }
4034 :
4035 : Parser* parser_;
4036 : };
4037 :
4038 : void Parser::RewriteNonPattern(bool* ok) {
4039 305732726 : ValidateExpression(CHECK_OK_VOID);
4040 152863472 : auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite();
4041 152863472 : int begin = classifier()->GetNonPatternBegin();
4042 152863472 : int end = non_patterns_to_rewrite->length();
4043 152863472 : if (begin < end) {
4044 3276 : NonPatternRewriter rewriter(stack_limit_, this);
4045 3324 : for (int i = begin; i < end; i++) {
4046 : DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression());
4047 3324 : rewriter.Rewrite(non_patterns_to_rewrite->at(i));
4048 : }
4049 3276 : non_patterns_to_rewrite->Rewind(begin);
4050 : }
4051 : }
4052 :
4053 :
4054 : void Parser::RewriteDestructuringAssignments() {
4055 : const auto& assignments =
4056 8643200 : function_state_->destructuring_assignments_to_rewrite();
4057 8730595 : for (int i = assignments.length() - 1; i >= 0; --i) {
4058 : // Rewrite list in reverse, so that nested assignment patterns are rewritten
4059 : // correctly.
4060 87397 : const DestructuringAssignment& pair = assignments.at(i);
4061 87397 : RewritableExpression* to_rewrite =
4062 87397 : pair.assignment->AsRewritableExpression();
4063 : DCHECK_NOT_NULL(to_rewrite);
4064 87397 : if (!to_rewrite->is_rewritten()) {
4065 : // Since this function is called at the end of parsing the program,
4066 : // pair.scope may already have been removed by FinalizeBlockScope in the
4067 : // meantime.
4068 73529 : Scope* scope = pair.scope->GetUnremovedScope();
4069 73529 : PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope);
4070 : }
4071 : }
4072 : }
4073 :
4074 : Expression* Parser::RewriteExponentiation(Expression* left, Expression* right,
4075 : int pos) {
4076 2262 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4077 2262 : args->Add(left, zone());
4078 2262 : args->Add(right, zone());
4079 2262 : return factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
4080 : }
4081 :
4082 : Expression* Parser::RewriteAssignExponentiation(Expression* left,
4083 : Expression* right, int pos) {
4084 179 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4085 206 : if (left->IsVariableProxy()) {
4086 : VariableProxy* lhs = left->AsVariableProxy();
4087 :
4088 : Expression* result;
4089 : DCHECK_NOT_NULL(lhs->raw_name());
4090 152 : result = ExpressionFromIdentifier(lhs->raw_name(), lhs->position());
4091 152 : args->Add(left, zone());
4092 152 : args->Add(right, zone());
4093 : Expression* call =
4094 152 : factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
4095 152 : return factory()->NewAssignment(Token::ASSIGN, result, call, pos);
4096 27 : } else if (left->IsProperty()) {
4097 54 : Property* prop = left->AsProperty();
4098 27 : auto temp_obj = NewTemporary(ast_value_factory()->empty_string());
4099 27 : auto temp_key = NewTemporary(ast_value_factory()->empty_string());
4100 : Expression* assign_obj = factory()->NewAssignment(
4101 27 : Token::ASSIGN, factory()->NewVariableProxy(temp_obj), prop->obj(),
4102 54 : kNoSourcePosition);
4103 : Expression* assign_key = factory()->NewAssignment(
4104 27 : Token::ASSIGN, factory()->NewVariableProxy(temp_key), prop->key(),
4105 54 : kNoSourcePosition);
4106 27 : args->Add(factory()->NewProperty(factory()->NewVariableProxy(temp_obj),
4107 27 : factory()->NewVariableProxy(temp_key),
4108 54 : left->position()),
4109 54 : zone());
4110 27 : args->Add(right, zone());
4111 : Expression* call =
4112 27 : factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
4113 : Expression* target = factory()->NewProperty(
4114 27 : factory()->NewVariableProxy(temp_obj),
4115 54 : factory()->NewVariableProxy(temp_key), kNoSourcePosition);
4116 : Expression* assign =
4117 27 : factory()->NewAssignment(Token::ASSIGN, target, call, pos);
4118 : return factory()->NewBinaryOperation(
4119 : Token::COMMA, assign_obj,
4120 27 : factory()->NewBinaryOperation(Token::COMMA, assign_key, assign, pos),
4121 27 : pos);
4122 : }
4123 0 : UNREACHABLE();
4124 : return nullptr;
4125 : }
4126 :
4127 : Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
4128 : // Array literals containing spreads are rewritten using do expressions, e.g.
4129 : // [1, 2, 3, ...x, 4, ...y, 5]
4130 : // is roughly rewritten as:
4131 : // do {
4132 : // $R = [1, 2, 3];
4133 : // for ($i of x) %AppendElement($R, $i);
4134 : // %AppendElement($R, 4);
4135 : // for ($j of y) %AppendElement($R, $j);
4136 : // %AppendElement($R, 5);
4137 : // $R
4138 : // }
4139 : // where $R, $i and $j are fresh temporary variables.
4140 3324 : ZoneList<Expression*>::iterator s = lit->FirstSpread();
4141 3324 : if (s == lit->EndValue()) return nullptr; // no spread, no rewriting...
4142 3324 : Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
4143 : // NOTE: The value assigned to R is the whole original array literal,
4144 : // spreads included. This will be fixed before the rewritten AST is returned.
4145 : // $R = lit
4146 : Expression* init_result = factory()->NewAssignment(
4147 3324 : Token::INIT, factory()->NewVariableProxy(result), lit, kNoSourcePosition);
4148 3324 : Block* do_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition);
4149 : do_block->statements()->Add(
4150 3324 : factory()->NewExpressionStatement(init_result, kNoSourcePosition),
4151 6648 : zone());
4152 : // Traverse the array literal starting from the first spread.
4153 9705 : while (s != lit->EndValue()) {
4154 6381 : Expression* value = *s++;
4155 11778 : Spread* spread = value->AsSpread();
4156 6381 : if (spread == nullptr) {
4157 : // If the element is not a spread, we're adding a single:
4158 : // %AppendElement($R, value)
4159 : // or, in case of a hole,
4160 : // ++($R.length)
4161 2144 : if (!value->IsLiteral() ||
4162 352 : !value->AsLiteral()->raw_value()->IsTheHole()) {
4163 : ZoneList<Expression*>* append_element_args = NewExpressionList(2);
4164 881 : append_element_args->Add(factory()->NewVariableProxy(result), zone());
4165 881 : append_element_args->Add(value, zone());
4166 : do_block->statements()->Add(
4167 : factory()->NewExpressionStatement(
4168 : factory()->NewCallRuntime(Runtime::kAppendElement,
4169 : append_element_args,
4170 881 : kNoSourcePosition),
4171 881 : kNoSourcePosition),
4172 1762 : zone());
4173 : } else {
4174 : Property* length_property = factory()->NewProperty(
4175 103 : factory()->NewVariableProxy(result),
4176 : factory()->NewStringLiteral(ast_value_factory()->length_string(),
4177 103 : kNoSourcePosition),
4178 103 : kNoSourcePosition);
4179 : CountOperation* count_op = factory()->NewCountOperation(
4180 103 : Token::INC, true /* prefix */, length_property, kNoSourcePosition);
4181 : do_block->statements()->Add(
4182 103 : factory()->NewExpressionStatement(count_op, kNoSourcePosition),
4183 206 : zone());
4184 : }
4185 : } else {
4186 : // If it's a spread, we're adding a for/of loop iterating through it.
4187 5397 : Variable* each = NewTemporary(ast_value_factory()->dot_for_string());
4188 5397 : Expression* subject = spread->expression();
4189 : // %AppendElement($R, each)
4190 : Statement* append_body;
4191 : {
4192 : ZoneList<Expression*>* append_element_args = NewExpressionList(2);
4193 5397 : append_element_args->Add(factory()->NewVariableProxy(result), zone());
4194 5397 : append_element_args->Add(factory()->NewVariableProxy(each), zone());
4195 : append_body = factory()->NewExpressionStatement(
4196 : factory()->NewCallRuntime(Runtime::kAppendElement,
4197 5397 : append_element_args, kNoSourcePosition),
4198 5397 : kNoSourcePosition);
4199 : }
4200 : // for (each of spread) %AppendElement($R, each)
4201 : ForOfStatement* loop =
4202 5397 : factory()->NewForOfStatement(nullptr, kNoSourcePosition);
4203 : const bool finalize = false;
4204 5397 : InitializeForOfStatement(loop, factory()->NewVariableProxy(each), subject,
4205 5397 : append_body, finalize, IteratorType::kNormal);
4206 5397 : do_block->statements()->Add(loop, zone());
4207 : }
4208 : }
4209 : // Now, rewind the original array literal to truncate everything from the
4210 : // first spread (included) until the end. This fixes $R's initialization.
4211 3324 : lit->RewindSpreads();
4212 3324 : return factory()->NewDoExpression(do_block, result, lit->position());
4213 : }
4214 :
4215 : void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) {
4216 : DCHECK(expr->IsRewritableExpression());
4217 : function_state_->AddDestructuringAssignment(
4218 92429 : DestructuringAssignment(expr, scope()));
4219 : }
4220 :
4221 : void Parser::QueueNonPatternForRewriting(Expression* expr, bool* ok) {
4222 : DCHECK(expr->IsRewritableExpression());
4223 19210 : function_state_->AddNonPatternForRewriting(expr, ok);
4224 : }
4225 :
4226 30615 : void Parser::AddAccessorPrefixToFunctionName(bool is_get,
4227 : FunctionLiteral* function,
4228 : const AstRawString* name) {
4229 : DCHECK_NOT_NULL(name);
4230 61230 : const AstRawString* prefix = is_get ? ast_value_factory()->get_space_string()
4231 42228 : : ast_value_factory()->set_space_string();
4232 30615 : function->set_raw_name(ast_value_factory()->NewConsString(prefix, name));
4233 30615 : }
4234 :
4235 4681466 : void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
4236 : const AstRawString* name) {
4237 : DCHECK(property->kind() != ObjectLiteralProperty::GETTER);
4238 : DCHECK(property->kind() != ObjectLiteralProperty::SETTER);
4239 :
4240 : // Computed name setting must happen at runtime.
4241 : DCHECK(!property->is_computed_name());
4242 :
4243 : // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
4244 : // of an object literal.
4245 4681466 : if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return;
4246 :
4247 4588801 : Expression* value = property->value();
4248 :
4249 : DCHECK(!value->IsAnonymousFunctionDefinition() ||
4250 : property->kind() == ObjectLiteralProperty::COMPUTED);
4251 4588801 : SetFunctionName(value, name);
4252 : }
4253 :
4254 21314770 : void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
4255 : Expression* identifier) {
4256 42629543 : if (!identifier->IsVariableProxy()) return;
4257 29084062 : SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
4258 : }
4259 :
4260 19131029 : void Parser::SetFunctionName(Expression* value, const AstRawString* name) {
4261 : DCHECK_NOT_NULL(name);
4262 38262058 : if (!value->IsAnonymousFunctionDefinition()) return;
4263 820725 : auto function = value->AsFunctionLiteral();
4264 820725 : if (function != nullptr) {
4265 820725 : function->set_raw_name(ast_value_factory()->NewConsString(name));
4266 : } else {
4267 : DCHECK(value->IsDoExpression());
4268 : value->AsDoExpression()->represented_function()->set_raw_name(
4269 5180 : ast_value_factory()->NewConsString(name));
4270 : }
4271 : }
4272 :
4273 :
4274 : // Desugaring of yield*
4275 : // ====================
4276 : //
4277 : // With the help of do-expressions and function.sent, we desugar yield* into a
4278 : // loop containing a "raw" yield (a yield that doesn't wrap an iterator result
4279 : // object around its argument). Concretely, "yield* iterable" turns into
4280 : // roughly the following code:
4281 : //
4282 : // do {
4283 : // const kNext = 0;
4284 : // const kReturn = 1;
4285 : // const kThrow = 2;
4286 : //
4287 : // let input = undefined;
4288 : // let mode = kNext;
4289 : // let output = undefined;
4290 : //
4291 : // let iterator = GetIterator(iterable);
4292 : //
4293 : // while (true) {
4294 : // // From the generator to the iterator:
4295 : // // Forward input according to resume mode and obtain output.
4296 : // switch (mode) {
4297 : // case kNext:
4298 : // output = iterator.next(input);
4299 : // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4300 : // break;
4301 : // case kReturn:
4302 : // IteratorClose(iterator, input, output); // See below.
4303 : // break;
4304 : // case kThrow:
4305 : // let iteratorThrow = iterator.throw;
4306 : // if (IS_NULL_OR_UNDEFINED(iteratorThrow)) {
4307 : // IteratorClose(iterator); // See below.
4308 : // throw MakeTypeError(kThrowMethodMissing);
4309 : // }
4310 : // output = %_Call(iteratorThrow, iterator, input);
4311 : // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4312 : // break;
4313 : // }
4314 : // if (output.done) break;
4315 : //
4316 : // // From the generator to its user:
4317 : // // Forward output, receive new input, and determine resume mode.
4318 : // mode = kReturn;
4319 : // try {
4320 : // try {
4321 : // RawYield(output); // See explanation above.
4322 : // mode = kNext;
4323 : // } catch (error) {
4324 : // mode = kThrow;
4325 : // }
4326 : // } finally {
4327 : // input = function.sent;
4328 : // continue;
4329 : // }
4330 : // }
4331 : //
4332 : // if (mode === kReturn) {
4333 : // return {value: output.value, done: true};
4334 : // }
4335 : // output.value
4336 : // }
4337 : //
4338 : // IteratorClose(iterator) expands to the following:
4339 : //
4340 : // let iteratorReturn = iterator.return;
4341 : // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
4342 : // let output = %_Call(iteratorReturn, iterator);
4343 : // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4344 : // }
4345 : //
4346 : // IteratorClose(iterator, input, output) expands to the following:
4347 : //
4348 : // let iteratorReturn = iterator.return;
4349 : // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input;
4350 : // output = %_Call(iteratorReturn, iterator, input);
4351 : // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4352 :
4353 2599 : Expression* Parser::RewriteYieldStar(Expression* generator,
4354 : Expression* iterable, int pos) {
4355 : const int nopos = kNoSourcePosition;
4356 : IteratorType type =
4357 176449 : is_async_generator() ? IteratorType::kAsync : IteratorType::kNormal;
4358 :
4359 : // Forward definition for break/continue statements.
4360 2599 : WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos);
4361 :
4362 : // let input = undefined;
4363 2599 : Variable* var_input = NewTemporary(ast_value_factory()->empty_string());
4364 : Statement* initialize_input;
4365 : {
4366 2599 : Expression* input_proxy = factory()->NewVariableProxy(var_input);
4367 : Expression* assignment =
4368 : factory()->NewAssignment(Token::ASSIGN, input_proxy,
4369 2599 : factory()->NewUndefinedLiteral(nopos), nopos);
4370 2599 : initialize_input = factory()->NewExpressionStatement(assignment, nopos);
4371 : }
4372 :
4373 : // let mode = kNext;
4374 2599 : Variable* var_mode = NewTemporary(ast_value_factory()->empty_string());
4375 : Statement* initialize_mode;
4376 : {
4377 2599 : Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4378 : Expression* knext =
4379 2599 : factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
4380 : Expression* assignment =
4381 2599 : factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
4382 2599 : initialize_mode = factory()->NewExpressionStatement(assignment, nopos);
4383 : }
4384 :
4385 : // let output = undefined;
4386 2599 : Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
4387 : Statement* initialize_output;
4388 : {
4389 2599 : Expression* output_proxy = factory()->NewVariableProxy(var_output);
4390 : Expression* assignment =
4391 : factory()->NewAssignment(Token::ASSIGN, output_proxy,
4392 2599 : factory()->NewUndefinedLiteral(nopos), nopos);
4393 2599 : initialize_output = factory()->NewExpressionStatement(assignment, nopos);
4394 : }
4395 :
4396 : // let iterator = GetIterator(iterable);
4397 2599 : Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string());
4398 : Statement* get_iterator;
4399 : {
4400 2599 : Expression* iterator = factory()->NewGetIterator(iterable, type, nopos);
4401 2599 : Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
4402 : Expression* assignment = factory()->NewAssignment(
4403 2599 : Token::ASSIGN, iterator_proxy, iterator, nopos);
4404 2599 : get_iterator = factory()->NewExpressionStatement(assignment, nopos);
4405 : }
4406 :
4407 : // output = iterator.next(input);
4408 : Statement* call_next;
4409 : {
4410 2599 : Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
4411 : Expression* literal =
4412 5198 : factory()->NewStringLiteral(ast_value_factory()->next_string(), nopos);
4413 : Expression* next_property =
4414 2599 : factory()->NewProperty(iterator_proxy, literal, nopos);
4415 2599 : Expression* input_proxy = factory()->NewVariableProxy(var_input);
4416 2599 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4417 : args->Add(input_proxy, zone());
4418 2599 : Expression* call = factory()->NewCall(next_property, args, nopos);
4419 2599 : if (type == IteratorType::kAsync) {
4420 : call = RewriteAwaitExpression(call, nopos);
4421 : }
4422 2599 : Expression* output_proxy = factory()->NewVariableProxy(var_output);
4423 : Expression* assignment =
4424 2599 : factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
4425 2599 : call_next = factory()->NewExpressionStatement(assignment, nopos);
4426 : }
4427 :
4428 : // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4429 : Statement* validate_next_output;
4430 : {
4431 : Expression* is_receiver_call;
4432 : {
4433 2599 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4434 2599 : args->Add(factory()->NewVariableProxy(var_output), zone());
4435 : is_receiver_call =
4436 2599 : factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4437 : }
4438 :
4439 : Statement* throw_call;
4440 : {
4441 2599 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4442 2599 : args->Add(factory()->NewVariableProxy(var_output), zone());
4443 : Expression* call = factory()->NewCallRuntime(
4444 2599 : Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4445 2599 : throw_call = factory()->NewExpressionStatement(call, nopos);
4446 : }
4447 :
4448 : validate_next_output = factory()->NewIfStatement(
4449 2599 : is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4450 2599 : nopos);
4451 : }
4452 :
4453 : // let iteratorThrow = iterator.throw;
4454 2599 : Variable* var_throw = NewTemporary(ast_value_factory()->empty_string());
4455 : Statement* get_throw;
4456 : {
4457 2599 : Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
4458 : Expression* literal =
4459 5198 : factory()->NewStringLiteral(ast_value_factory()->throw_string(), nopos);
4460 : Expression* property =
4461 2599 : factory()->NewProperty(iterator_proxy, literal, nopos);
4462 2599 : Expression* throw_proxy = factory()->NewVariableProxy(var_throw);
4463 : Expression* assignment =
4464 2599 : factory()->NewAssignment(Token::ASSIGN, throw_proxy, property, nopos);
4465 2599 : get_throw = factory()->NewExpressionStatement(assignment, nopos);
4466 : }
4467 :
4468 : // if (IS_NULL_OR_UNDEFINED(iteratorThrow) {
4469 : // IteratorClose(iterator);
4470 : // throw MakeTypeError(kThrowMethodMissing);
4471 : // }
4472 : Statement* check_throw;
4473 : {
4474 : Expression* condition = factory()->NewCompareOperation(
4475 2599 : Token::EQ, factory()->NewVariableProxy(var_throw),
4476 5198 : factory()->NewNullLiteral(nopos), nopos);
4477 : Expression* call =
4478 : NewThrowTypeError(MessageTemplate::kThrowMethodMissing,
4479 2599 : ast_value_factory()->empty_string(), nopos);
4480 2599 : Statement* throw_call = factory()->NewExpressionStatement(call, nopos);
4481 :
4482 2599 : Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos);
4483 : BuildIteratorCloseForCompletion(
4484 : scope(), then->statements(), var_iterator,
4485 5198 : factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), type);
4486 : then->statements()->Add(throw_call, zone());
4487 : check_throw = factory()->NewIfStatement(
4488 5198 : condition, then, factory()->NewEmptyStatement(nopos), nopos);
4489 : }
4490 :
4491 : // output = %_Call(iteratorThrow, iterator, input);
4492 : Statement* call_throw;
4493 : {
4494 2599 : auto args = new (zone()) ZoneList<Expression*>(3, zone());
4495 2599 : args->Add(factory()->NewVariableProxy(var_throw), zone());
4496 2599 : args->Add(factory()->NewVariableProxy(var_iterator), zone());
4497 2599 : args->Add(factory()->NewVariableProxy(var_input), zone());
4498 : Expression* call =
4499 2599 : factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4500 2599 : if (type == IteratorType::kAsync) {
4501 : call = RewriteAwaitExpression(call, nopos);
4502 : }
4503 : Expression* assignment = factory()->NewAssignment(
4504 5198 : Token::ASSIGN, factory()->NewVariableProxy(var_output), call, nopos);
4505 2599 : call_throw = factory()->NewExpressionStatement(assignment, nopos);
4506 : }
4507 :
4508 : // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4509 : Statement* validate_throw_output;
4510 : {
4511 : Expression* is_receiver_call;
4512 : {
4513 2599 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4514 2599 : args->Add(factory()->NewVariableProxy(var_output), zone());
4515 : is_receiver_call =
4516 2599 : factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4517 : }
4518 :
4519 : Statement* throw_call;
4520 : {
4521 2599 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4522 2599 : args->Add(factory()->NewVariableProxy(var_output), zone());
4523 : Expression* call = factory()->NewCallRuntime(
4524 2599 : Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4525 2599 : throw_call = factory()->NewExpressionStatement(call, nopos);
4526 : }
4527 :
4528 : validate_throw_output = factory()->NewIfStatement(
4529 2599 : is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4530 2599 : nopos);
4531 : }
4532 :
4533 : // if (output.done) break;
4534 : Statement* if_done;
4535 : {
4536 2599 : Expression* output_proxy = factory()->NewVariableProxy(var_output);
4537 : Expression* literal =
4538 5198 : factory()->NewStringLiteral(ast_value_factory()->done_string(), nopos);
4539 2599 : Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
4540 2599 : BreakStatement* break_loop = factory()->NewBreakStatement(loop, nopos);
4541 : if_done = factory()->NewIfStatement(
4542 5198 : property, break_loop, factory()->NewEmptyStatement(nopos), nopos);
4543 : }
4544 :
4545 :
4546 : // mode = kReturn;
4547 : Statement* set_mode_return;
4548 : {
4549 2599 : Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4550 : Expression* kreturn =
4551 2599 : factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
4552 : Expression* assignment =
4553 2599 : factory()->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos);
4554 2599 : set_mode_return = factory()->NewExpressionStatement(assignment, nopos);
4555 : }
4556 :
4557 : // Yield(output);
4558 : Statement* yield_output;
4559 : {
4560 2599 : Expression* output_proxy = factory()->NewVariableProxy(var_output);
4561 : Suspend* yield =
4562 : BuildSuspend(generator, output_proxy, nopos, Suspend::kOnExceptionThrow,
4563 2599 : SuspendFlags::kYieldStar);
4564 2599 : yield_output = factory()->NewExpressionStatement(yield, nopos);
4565 : }
4566 :
4567 : // mode = kNext;
4568 : Statement* set_mode_next;
4569 : {
4570 2599 : Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4571 : Expression* knext =
4572 2599 : factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
4573 : Expression* assignment =
4574 2599 : factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
4575 2599 : set_mode_next = factory()->NewExpressionStatement(assignment, nopos);
4576 : }
4577 :
4578 : // mode = kThrow;
4579 : Statement* set_mode_throw;
4580 : {
4581 2599 : Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4582 : Expression* kthrow =
4583 2599 : factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
4584 : Expression* assignment =
4585 2599 : factory()->NewAssignment(Token::ASSIGN, mode_proxy, kthrow, nopos);
4586 2599 : set_mode_throw = factory()->NewExpressionStatement(assignment, nopos);
4587 : }
4588 :
4589 : // input = function.sent;
4590 : Statement* get_input;
4591 : {
4592 2599 : Expression* function_sent = FunctionSentExpression(nopos);
4593 2599 : Expression* input_proxy = factory()->NewVariableProxy(var_input);
4594 : Expression* assignment = factory()->NewAssignment(
4595 2599 : Token::ASSIGN, input_proxy, function_sent, nopos);
4596 2599 : get_input = factory()->NewExpressionStatement(assignment, nopos);
4597 : }
4598 :
4599 : // if (mode === kReturn) {
4600 : // return {value: output.value, done: true};
4601 : // }
4602 : Statement* maybe_return_value;
4603 : {
4604 2599 : Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4605 : Expression* kreturn =
4606 2599 : factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
4607 : Expression* condition = factory()->NewCompareOperation(
4608 2599 : Token::EQ_STRICT, mode_proxy, kreturn, nopos);
4609 :
4610 2599 : Expression* output_proxy = factory()->NewVariableProxy(var_output);
4611 : Expression* literal =
4612 5198 : factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos);
4613 2599 : Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
4614 2599 : Statement* return_value = BuildReturnStatement(property, nopos);
4615 :
4616 : maybe_return_value = factory()->NewIfStatement(
4617 5198 : condition, return_value, factory()->NewEmptyStatement(nopos), nopos);
4618 : }
4619 :
4620 : // output.value
4621 : Statement* get_value;
4622 : {
4623 2599 : Expression* output_proxy = factory()->NewVariableProxy(var_output);
4624 : Expression* literal =
4625 5198 : factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos);
4626 2599 : Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
4627 2599 : get_value = factory()->NewExpressionStatement(property, nopos);
4628 : }
4629 :
4630 : // Now put things together.
4631 :
4632 : // try { ... } catch(e) { ... }
4633 : Statement* try_catch;
4634 : {
4635 2599 : Block* try_block = factory()->NewBlock(nullptr, 2, false, nopos);
4636 : try_block->statements()->Add(yield_output, zone());
4637 : try_block->statements()->Add(set_mode_next, zone());
4638 :
4639 2599 : Block* catch_block = factory()->NewBlock(nullptr, 1, false, nopos);
4640 : catch_block->statements()->Add(set_mode_throw, zone());
4641 :
4642 : Scope* catch_scope = NewHiddenCatchScopeWithParent(scope());
4643 :
4644 : try_catch = factory()->NewTryCatchStatementForDesugaring(
4645 2599 : try_block, catch_scope, catch_block, nopos);
4646 : }
4647 :
4648 : // try { ... } finally { ... }
4649 : Statement* try_finally;
4650 : {
4651 2599 : Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
4652 : try_block->statements()->Add(try_catch, zone());
4653 :
4654 2599 : Block* finally = factory()->NewBlock(nullptr, 2, false, nopos);
4655 : finally->statements()->Add(get_input, zone());
4656 2599 : finally->statements()->Add(factory()->NewContinueStatement(loop, nopos),
4657 : zone());
4658 :
4659 2599 : try_finally = factory()->NewTryFinallyStatement(try_block, finally, nopos);
4660 : }
4661 :
4662 : // switch (mode) { ... }
4663 2599 : SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos);
4664 : {
4665 2599 : auto case_next = new (zone()) ZoneList<Statement*>(3, zone());
4666 : case_next->Add(call_next, zone());
4667 : case_next->Add(validate_next_output, zone());
4668 2599 : case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
4669 :
4670 2599 : auto case_return = new (zone()) ZoneList<Statement*>(5, zone());
4671 2599 : BuildIteratorClose(case_return, var_iterator, var_input, var_output, type);
4672 2599 : case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
4673 :
4674 2599 : auto case_throw = new (zone()) ZoneList<Statement*>(5, zone());
4675 : case_throw->Add(get_throw, zone());
4676 : case_throw->Add(check_throw, zone());
4677 : case_throw->Add(call_throw, zone());
4678 : case_throw->Add(validate_throw_output, zone());
4679 2599 : case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
4680 :
4681 2599 : auto cases = new (zone()) ZoneList<CaseClause*>(3, zone());
4682 : Expression* knext =
4683 2599 : factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
4684 : Expression* kreturn =
4685 2599 : factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
4686 : Expression* kthrow =
4687 2599 : factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
4688 2599 : cases->Add(factory()->NewCaseClause(knext, case_next, nopos), zone());
4689 2599 : cases->Add(factory()->NewCaseClause(kreturn, case_return, nopos), zone());
4690 2599 : cases->Add(factory()->NewCaseClause(kthrow, case_throw, nopos), zone());
4691 :
4692 2599 : switch_mode->Initialize(factory()->NewVariableProxy(var_mode), cases);
4693 : }
4694 :
4695 : // while (true) { ... }
4696 : // Already defined earlier: WhileStatement* loop = ...
4697 : {
4698 2599 : Block* loop_body = factory()->NewBlock(nullptr, 5, false, nopos);
4699 : loop_body->statements()->Add(switch_mode, zone());
4700 : loop_body->statements()->Add(if_done, zone());
4701 : loop_body->statements()->Add(set_mode_return, zone());
4702 :
4703 2599 : if (is_async_generator()) {
4704 : // AsyncGeneratorYield does not yield the original iterator result,
4705 : // unlike sync generators. Do `output = output.value`
4706 1158 : VariableProxy* output_proxy = factory()->NewVariableProxy(var_output);
4707 : Expression* literal = factory()->NewStringLiteral(
4708 2316 : ast_value_factory()->value_string(), nopos);
4709 : Assignment* assign = factory()->NewAssignment(
4710 : Token::ASSIGN, output_proxy,
4711 1158 : factory()->NewProperty(factory()->NewVariableProxy(var_output),
4712 1158 : literal, nopos),
4713 1158 : nopos);
4714 : loop_body->statements()->Add(
4715 1158 : factory()->NewExpressionStatement(assign, nopos), zone());
4716 : }
4717 :
4718 : loop_body->statements()->Add(try_finally, zone());
4719 :
4720 2599 : loop->Initialize(factory()->NewBooleanLiteral(true, nopos), loop_body);
4721 : }
4722 :
4723 : // do { ... }
4724 : DoExpression* yield_star;
4725 : {
4726 : // The rewriter needs to process the get_value statement only, hence we
4727 : // put the preceding statements into an init block.
4728 :
4729 2599 : Block* do_block_ = factory()->NewBlock(nullptr, 6, true, nopos);
4730 : do_block_->statements()->Add(initialize_input, zone());
4731 : do_block_->statements()->Add(initialize_mode, zone());
4732 : do_block_->statements()->Add(initialize_output, zone());
4733 : do_block_->statements()->Add(get_iterator, zone());
4734 : do_block_->statements()->Add(loop, zone());
4735 : do_block_->statements()->Add(maybe_return_value, zone());
4736 :
4737 2599 : Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
4738 : do_block->statements()->Add(do_block_, zone());
4739 : do_block->statements()->Add(get_value, zone());
4740 :
4741 : Variable* dot_result =
4742 2599 : NewTemporary(ast_value_factory()->dot_result_string());
4743 2599 : yield_star = factory()->NewDoExpression(do_block, dot_result, nopos);
4744 2599 : Rewriter::Rewrite(this, GetClosureScope(), yield_star, ast_value_factory());
4745 : }
4746 :
4747 2599 : return yield_star;
4748 : }
4749 :
4750 207967 : Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
4751 : const int nopos = kNoSourcePosition;
4752 : Statement* validate_var;
4753 : {
4754 : Expression* type_of = factory()->NewUnaryOperation(
4755 623901 : Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
4756 : Expression* function_literal = factory()->NewStringLiteral(
4757 415934 : ast_value_factory()->function_string(), nopos);
4758 : Expression* condition = factory()->NewCompareOperation(
4759 207967 : Token::EQ_STRICT, type_of, function_literal, nopos);
4760 :
4761 207967 : Statement* throw_call = factory()->NewExpressionStatement(error, pos);
4762 :
4763 : validate_var = factory()->NewIfStatement(
4764 415934 : condition, factory()->NewEmptyStatement(nopos), throw_call, nopos);
4765 : }
4766 207967 : return validate_var;
4767 : }
4768 :
4769 2599 : void Parser::BuildIteratorClose(ZoneList<Statement*>* statements,
4770 : Variable* iterator, Variable* input,
4771 : Variable* var_output, IteratorType type) {
4772 : //
4773 : // This function adds four statements to [statements], corresponding to the
4774 : // following code:
4775 : //
4776 : // let iteratorReturn = iterator.return;
4777 : // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
4778 : // return {value: input, done: true};
4779 : // }
4780 : // output = %_Call(iteratorReturn, iterator, input);
4781 : // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4782 : //
4783 :
4784 : const int nopos = kNoSourcePosition;
4785 :
4786 : // let iteratorReturn = iterator.return;
4787 : Variable* var_return = var_output; // Reusing the output variable.
4788 : Statement* get_return;
4789 : {
4790 36386 : Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
4791 : Expression* literal = factory()->NewStringLiteral(
4792 5198 : ast_value_factory()->return_string(), nopos);
4793 : Expression* property =
4794 2599 : factory()->NewProperty(iterator_proxy, literal, nopos);
4795 2599 : Expression* return_proxy = factory()->NewVariableProxy(var_return);
4796 : Expression* assignment =
4797 2599 : factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
4798 2599 : get_return = factory()->NewExpressionStatement(assignment, nopos);
4799 : }
4800 :
4801 : // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
4802 : // return {value: input, done: true};
4803 : // }
4804 : Statement* check_return;
4805 : {
4806 : Expression* condition = factory()->NewCompareOperation(
4807 2599 : Token::EQ, factory()->NewVariableProxy(var_return),
4808 5198 : factory()->NewNullLiteral(nopos), nopos);
4809 :
4810 2599 : Expression* value = factory()->NewVariableProxy(input);
4811 :
4812 2599 : Statement* return_input = BuildReturnStatement(value, nopos);
4813 :
4814 : check_return = factory()->NewIfStatement(
4815 5198 : condition, return_input, factory()->NewEmptyStatement(nopos), nopos);
4816 : }
4817 :
4818 : // output = %_Call(iteratorReturn, iterator, input);
4819 : Statement* call_return;
4820 : {
4821 2599 : auto args = new (zone()) ZoneList<Expression*>(3, zone());
4822 2599 : args->Add(factory()->NewVariableProxy(var_return), zone());
4823 2599 : args->Add(factory()->NewVariableProxy(iterator), zone());
4824 2599 : args->Add(factory()->NewVariableProxy(input), zone());
4825 :
4826 : Expression* call =
4827 2599 : factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4828 2599 : if (type == IteratorType::kAsync) {
4829 : call = RewriteAwaitExpression(call, nopos);
4830 : }
4831 2599 : Expression* output_proxy = factory()->NewVariableProxy(var_output);
4832 : Expression* assignment =
4833 2599 : factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
4834 2599 : call_return = factory()->NewExpressionStatement(assignment, nopos);
4835 : }
4836 :
4837 : // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
4838 : Statement* validate_output;
4839 : {
4840 : Expression* is_receiver_call;
4841 : {
4842 2599 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4843 2599 : args->Add(factory()->NewVariableProxy(var_output), zone());
4844 : is_receiver_call =
4845 2599 : factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4846 : }
4847 :
4848 : Statement* throw_call;
4849 : {
4850 2599 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4851 2599 : args->Add(factory()->NewVariableProxy(var_output), zone());
4852 : Expression* call = factory()->NewCallRuntime(
4853 2599 : Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4854 2599 : throw_call = factory()->NewExpressionStatement(call, nopos);
4855 : }
4856 :
4857 : validate_output = factory()->NewIfStatement(
4858 2599 : is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4859 2599 : nopos);
4860 : }
4861 :
4862 : statements->Add(get_return, zone());
4863 : statements->Add(check_return, zone());
4864 : statements->Add(call_return, zone());
4865 : statements->Add(validate_output, zone());
4866 2599 : }
4867 :
4868 205368 : void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion,
4869 : Expression* condition, Variable* iter,
4870 : Block* iterator_use, Block* target,
4871 : IteratorType type) {
4872 : //
4873 : // This function adds two statements to [target], corresponding to the
4874 : // following code:
4875 : //
4876 : // completion = kNormalCompletion;
4877 : // try {
4878 : // try {
4879 : // iterator_use
4880 : // } catch(e) {
4881 : // if (completion === kAbruptCompletion) completion = kThrowCompletion;
4882 : // %ReThrow(e);
4883 : // }
4884 : // } finally {
4885 : // if (condition) {
4886 : // #BuildIteratorCloseForCompletion(iter, completion)
4887 : // }
4888 : // }
4889 : //
4890 :
4891 : const int nopos = kNoSourcePosition;
4892 :
4893 : // completion = kNormalCompletion;
4894 : Statement* initialize_completion;
4895 : {
4896 1642944 : Expression* proxy = factory()->NewVariableProxy(completion);
4897 : Expression* assignment = factory()->NewAssignment(
4898 : Token::ASSIGN, proxy,
4899 205368 : factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
4900 : initialize_completion =
4901 205368 : factory()->NewExpressionStatement(assignment, nopos);
4902 : }
4903 :
4904 : // if (completion === kAbruptCompletion) completion = kThrowCompletion;
4905 : Statement* set_completion_throw;
4906 : {
4907 : Expression* condition = factory()->NewCompareOperation(
4908 205368 : Token::EQ_STRICT, factory()->NewVariableProxy(completion),
4909 410736 : factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
4910 :
4911 205368 : Expression* proxy = factory()->NewVariableProxy(completion);
4912 : Expression* assignment = factory()->NewAssignment(
4913 : Token::ASSIGN, proxy,
4914 205368 : factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
4915 205368 : Statement* statement = factory()->NewExpressionStatement(assignment, nopos);
4916 : set_completion_throw = factory()->NewIfStatement(
4917 410736 : condition, statement, factory()->NewEmptyStatement(nopos), nopos);
4918 : }
4919 :
4920 : // if (condition) {
4921 : // #BuildIteratorCloseForCompletion(iter, completion)
4922 : // }
4923 : Block* maybe_close;
4924 : {
4925 205368 : Block* block = factory()->NewBlock(nullptr, 2, true, nopos);
4926 205368 : Expression* proxy = factory()->NewVariableProxy(completion);
4927 : BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, proxy,
4928 205368 : type);
4929 : DCHECK(block->statements()->length() == 2);
4930 :
4931 : maybe_close = IgnoreCompletion(factory()->NewIfStatement(
4932 410736 : condition, block, factory()->NewEmptyStatement(nopos), nopos));
4933 : }
4934 :
4935 : // try { #try_block }
4936 : // catch(e) {
4937 : // #set_completion_throw;
4938 : // %ReThrow(e);
4939 : // }
4940 : Statement* try_catch;
4941 : {
4942 : Scope* catch_scope = NewHiddenCatchScopeWithParent(use_scope);
4943 :
4944 : Statement* rethrow;
4945 : // We use %ReThrow rather than the ordinary throw because we want to
4946 : // preserve the original exception message. This is also why we create a
4947 : // TryCatchStatementForReThrow below (which does not clear the pending
4948 : // message), rather than a TryCatchStatement.
4949 : {
4950 205368 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4951 205368 : args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
4952 : zone());
4953 : rethrow = factory()->NewExpressionStatement(
4954 205368 : factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
4955 : }
4956 :
4957 205368 : Block* catch_block = factory()->NewBlock(nullptr, 2, false, nopos);
4958 : catch_block->statements()->Add(set_completion_throw, zone());
4959 : catch_block->statements()->Add(rethrow, zone());
4960 :
4961 : try_catch = factory()->NewTryCatchStatementForReThrow(
4962 205368 : iterator_use, catch_scope, catch_block, nopos);
4963 : }
4964 :
4965 : // try { #try_catch } finally { #maybe_close }
4966 : Statement* try_finally;
4967 : {
4968 205368 : Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
4969 : try_block->statements()->Add(try_catch, zone());
4970 :
4971 : try_finally =
4972 205368 : factory()->NewTryFinallyStatement(try_block, maybe_close, nopos);
4973 : }
4974 :
4975 : target->statements()->Add(initialize_completion, zone());
4976 : target->statements()->Add(try_finally, zone());
4977 205368 : }
4978 :
4979 207967 : void Parser::BuildIteratorCloseForCompletion(Scope* scope,
4980 : ZoneList<Statement*>* statements,
4981 : Variable* iterator,
4982 : Expression* completion,
4983 : IteratorType type) {
4984 : //
4985 : // This function adds two statements to [statements], corresponding to the
4986 : // following code:
4987 : //
4988 : // let iteratorReturn = iterator.return;
4989 : // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
4990 : // if (completion === kThrowCompletion) {
4991 : // if (!IS_CALLABLE(iteratorReturn)) {
4992 : // throw MakeTypeError(kReturnMethodNotCallable);
4993 : // }
4994 : // [if (IteratorType == kAsync)]
4995 : // try { Await(%_Call(iteratorReturn, iterator) } catch (_) { }
4996 : // [else]
4997 : // try { %_Call(iteratorReturn, iterator) } catch (_) { }
4998 : // [endif]
4999 : // } else {
5000 : // [if (IteratorType == kAsync)]
5001 : // let output = Await(%_Call(iteratorReturn, iterator));
5002 : // [else]
5003 : // let output = %_Call(iteratorReturn, iterator);
5004 : // [endif]
5005 : // if (!IS_RECEIVER(output)) {
5006 : // %ThrowIterResultNotAnObject(output);
5007 : // }
5008 : // }
5009 : // }
5010 : //
5011 :
5012 : const int nopos = kNoSourcePosition;
5013 : // let iteratorReturn = iterator.return;
5014 4367307 : Variable* var_return = NewTemporary(ast_value_factory()->empty_string());
5015 : Statement* get_return;
5016 : {
5017 207967 : Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
5018 : Expression* literal = factory()->NewStringLiteral(
5019 415934 : ast_value_factory()->return_string(), nopos);
5020 : Expression* property =
5021 207967 : factory()->NewProperty(iterator_proxy, literal, nopos);
5022 207967 : Expression* return_proxy = factory()->NewVariableProxy(var_return);
5023 : Expression* assignment =
5024 207967 : factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
5025 207967 : get_return = factory()->NewExpressionStatement(assignment, nopos);
5026 : }
5027 :
5028 : // if (!IS_CALLABLE(iteratorReturn)) {
5029 : // throw MakeTypeError(kReturnMethodNotCallable);
5030 : // }
5031 : Statement* check_return_callable;
5032 : {
5033 : Expression* throw_expr =
5034 : NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable,
5035 207967 : ast_value_factory()->empty_string(), nopos);
5036 207967 : check_return_callable = CheckCallable(var_return, throw_expr, nopos);
5037 : }
5038 :
5039 : // try { %_Call(iteratorReturn, iterator) } catch (_) { }
5040 : Statement* try_call_return;
5041 : {
5042 207967 : auto args = new (zone()) ZoneList<Expression*>(2, zone());
5043 207967 : args->Add(factory()->NewVariableProxy(var_return), zone());
5044 207967 : args->Add(factory()->NewVariableProxy(iterator), zone());
5045 :
5046 : Expression* call =
5047 207967 : factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
5048 :
5049 207967 : if (type == IteratorType::kAsync) {
5050 : call = RewriteAwaitExpression(call, nopos);
5051 : }
5052 :
5053 207967 : Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
5054 207967 : try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos),
5055 : zone());
5056 :
5057 207967 : Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos);
5058 : Scope* catch_scope = NewHiddenCatchScopeWithParent(scope);
5059 : try_call_return = factory()->NewTryCatchStatement(try_block, catch_scope,
5060 207967 : catch_block, nopos);
5061 : }
5062 :
5063 : // let output = %_Call(iteratorReturn, iterator);
5064 : // if (!IS_RECEIVER(output)) {
5065 : // %ThrowIteratorResultNotAnObject(output);
5066 : // }
5067 : Block* validate_return;
5068 : {
5069 207967 : Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
5070 : Statement* call_return;
5071 : {
5072 207967 : auto args = new (zone()) ZoneList<Expression*>(2, zone());
5073 207967 : args->Add(factory()->NewVariableProxy(var_return), zone());
5074 207967 : args->Add(factory()->NewVariableProxy(iterator), zone());
5075 : Expression* call =
5076 207967 : factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
5077 207967 : if (type == IteratorType::kAsync) {
5078 : call = RewriteAwaitExpression(call, nopos);
5079 : }
5080 :
5081 207967 : Expression* output_proxy = factory()->NewVariableProxy(var_output);
5082 : Expression* assignment =
5083 207967 : factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
5084 207967 : call_return = factory()->NewExpressionStatement(assignment, nopos);
5085 : }
5086 :
5087 : Expression* is_receiver_call;
5088 : {
5089 207967 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
5090 207967 : args->Add(factory()->NewVariableProxy(var_output), zone());
5091 : is_receiver_call =
5092 207967 : factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
5093 : }
5094 :
5095 : Statement* throw_call;
5096 : {
5097 207967 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
5098 207967 : args->Add(factory()->NewVariableProxy(var_output), zone());
5099 : Expression* call = factory()->NewCallRuntime(
5100 207967 : Runtime::kThrowIteratorResultNotAnObject, args, nopos);
5101 207967 : throw_call = factory()->NewExpressionStatement(call, nopos);
5102 : }
5103 :
5104 : Statement* check_return = factory()->NewIfStatement(
5105 207967 : is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
5106 207967 : nopos);
5107 :
5108 207967 : validate_return = factory()->NewBlock(nullptr, 2, false, nopos);
5109 : validate_return->statements()->Add(call_return, zone());
5110 : validate_return->statements()->Add(check_return, zone());
5111 : }
5112 :
5113 : // if (completion === kThrowCompletion) {
5114 : // #check_return_callable;
5115 : // #try_call_return;
5116 : // } else {
5117 : // #validate_return;
5118 : // }
5119 : Statement* call_return_carefully;
5120 : {
5121 : Expression* condition = factory()->NewCompareOperation(
5122 : Token::EQ_STRICT, completion,
5123 207967 : factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
5124 :
5125 207967 : Block* then_block = factory()->NewBlock(nullptr, 2, false, nopos);
5126 : then_block->statements()->Add(check_return_callable, zone());
5127 : then_block->statements()->Add(try_call_return, zone());
5128 :
5129 : call_return_carefully = factory()->NewIfStatement(condition, then_block,
5130 207967 : validate_return, nopos);
5131 : }
5132 :
5133 : // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
5134 : Statement* maybe_call_return;
5135 : {
5136 : Expression* condition = factory()->NewCompareOperation(
5137 207967 : Token::EQ, factory()->NewVariableProxy(var_return),
5138 415934 : factory()->NewNullLiteral(nopos), nopos);
5139 :
5140 : maybe_call_return = factory()->NewIfStatement(
5141 207967 : condition, factory()->NewEmptyStatement(nopos), call_return_carefully,
5142 207967 : nopos);
5143 : }
5144 :
5145 : statements->Add(get_return, zone());
5146 : statements->Add(maybe_call_return, zone());
5147 207967 : }
5148 :
5149 257004 : Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
5150 : Variable* var_completion,
5151 : IteratorType type, int pos) {
5152 : //
5153 : // This function replaces the loop with the following wrapping:
5154 : //
5155 : // completion = kNormalCompletion;
5156 : // try {
5157 : // try {
5158 : // #loop;
5159 : // } catch(e) {
5160 : // if (completion === kAbruptCompletion) completion = kThrowCompletion;
5161 : // %ReThrow(e);
5162 : // }
5163 : // } finally {
5164 : // if (!(completion === kNormalCompletion)) {
5165 : // #BuildIteratorCloseForCompletion(#iterator, completion)
5166 : // }
5167 : // }
5168 : //
5169 : // Note that the loop's body and its assign_each already contain appropriate
5170 : // assignments to completion (see InitializeForOfStatement).
5171 : //
5172 :
5173 : const int nopos = kNoSourcePosition;
5174 :
5175 : // !(completion === kNormalCompletion)
5176 : Expression* closing_condition;
5177 : {
5178 : Expression* cmp = factory()->NewCompareOperation(
5179 128502 : Token::EQ_STRICT, factory()->NewVariableProxy(var_completion),
5180 514008 : factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
5181 128502 : closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos);
5182 : }
5183 :
5184 128502 : Block* final_loop = factory()->NewBlock(nullptr, 2, false, nopos);
5185 : {
5186 128502 : Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
5187 : try_block->statements()->Add(loop, zone());
5188 :
5189 : // The scope in which the parser creates this loop.
5190 128502 : Scope* loop_scope = scope()->outer_scope();
5191 : DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE);
5192 : DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE);
5193 :
5194 : FinalizeIteratorUse(loop_scope, var_completion, closing_condition,
5195 128502 : loop->iterator(), try_block, final_loop, type);
5196 : }
5197 :
5198 128502 : return final_loop;
5199 : }
5200 :
5201 : #undef CHECK_OK
5202 : #undef CHECK_OK_VOID
5203 : #undef CHECK_FAILED
5204 :
5205 : } // namespace internal
5206 : } // namespace v8
|