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 <algorithm>
8 : #include <memory>
9 :
10 : #include "src/api.h"
11 : #include "src/ast/ast-expression-rewriter.h"
12 : #include "src/ast/ast-function-literal-id-reindexer.h"
13 : #include "src/ast/ast-traversal-visitor.h"
14 : #include "src/ast/ast.h"
15 : #include "src/bailout-reason.h"
16 : #include "src/base/platform/platform.h"
17 : #include "src/char-predicates-inl.h"
18 : #include "src/compiler-dispatcher/compiler-dispatcher.h"
19 : #include "src/messages.h"
20 : #include "src/objects-inl.h"
21 : #include "src/parsing/duplicate-finder.h"
22 : #include "src/parsing/expression-scope-reparenter.h"
23 : #include "src/parsing/parse-info.h"
24 : #include "src/parsing/rewriter.h"
25 : #include "src/runtime/runtime.h"
26 : #include "src/string-stream.h"
27 : #include "src/tracing/trace-event.h"
28 :
29 : namespace v8 {
30 : namespace internal {
31 :
32 1020 : ScriptData::ScriptData(const byte* data, int length)
33 1020 : : owns_data_(false), rejected_(false), data_(data), length_(length) {
34 2040 : if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
35 4 : byte* copy = NewArray<byte>(length);
36 : DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
37 4 : CopyBytes(copy, data, length);
38 4 : data_ = copy;
39 : AcquireDataOwnership();
40 : }
41 1020 : }
42 :
43 230 : FunctionEntry ParseData::GetFunctionEntry(int start) {
44 : // The current pre-data entry must be a FunctionEntry with the given
45 : // start position.
46 345 : if ((function_index_ + FunctionEntry::kSize <= Length()) &&
47 115 : (static_cast<int>(Data()[function_index_]) == start)) {
48 : int index = function_index_;
49 105 : function_index_ += FunctionEntry::kSize;
50 105 : Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
51 105 : return FunctionEntry(subvector);
52 : }
53 10 : return FunctionEntry();
54 : }
55 :
56 :
57 30 : int ParseData::FunctionCount() {
58 : int functions_size = FunctionsSize();
59 30 : if (functions_size < 0) return 0;
60 30 : if (functions_size % FunctionEntry::kSize != 0) return 0;
61 30 : return functions_size / FunctionEntry::kSize;
62 : }
63 :
64 :
65 95 : bool ParseData::IsSane() {
66 190 : if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
67 : // Check that the header data is valid and doesn't specify
68 : // point to positions outside the store.
69 : int data_length = Length();
70 95 : if (data_length < PreparseDataConstants::kHeaderSize) return false;
71 95 : if (Magic() != PreparseDataConstants::kMagicNumber) return false;
72 90 : if (Version() != PreparseDataConstants::kCurrentVersion) return false;
73 : // Check that the space allocated for function entries is sane.
74 : int functions_size = FunctionsSize();
75 90 : if (functions_size < 0) return false;
76 90 : if (functions_size % FunctionEntry::kSize != 0) return false;
77 : // Check that the total size has room for header and function entries.
78 : int minimum_size =
79 90 : PreparseDataConstants::kHeaderSize + functions_size;
80 90 : if (data_length < minimum_size) return false;
81 90 : return true;
82 : }
83 :
84 :
85 60 : void ParseData::Initialize() {
86 : // Prepares state for use.
87 : int data_length = Length();
88 60 : if (data_length >= PreparseDataConstants::kHeaderSize) {
89 60 : function_index_ = PreparseDataConstants::kHeaderSize;
90 : }
91 5 : }
92 :
93 :
94 0 : unsigned ParseData::Magic() {
95 95 : return Data()[PreparseDataConstants::kMagicOffset];
96 : }
97 :
98 :
99 0 : unsigned ParseData::Version() {
100 90 : return Data()[PreparseDataConstants::kVersionOffset];
101 : }
102 :
103 :
104 30 : int ParseData::FunctionsSize() {
105 120 : return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
106 : }
107 :
108 : // Helper for putting parts of the parse results into a temporary zone when
109 : // parsing inner function bodies.
110 : class DiscardableZoneScope {
111 : public:
112 5234306 : DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool 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 5234306 : prev_temp_zoned_(parser->temp_zoned_) {
119 5234307 : if (use_temp_zone) {
120 : DCHECK(!parser_->temp_zoned_);
121 2247093 : parser_->allow_lazy_ = false;
122 2247093 : parser_->temp_zoned_ = true;
123 2247093 : parser_->fni_ = &fni_;
124 2247093 : parser_->zone_ = temp_zone;
125 2247093 : parser_->factory()->set_zone(temp_zone);
126 2247093 : if (parser_->reusable_preparser_ != nullptr) {
127 1863341 : parser_->reusable_preparser_->zone_ = temp_zone;
128 1863341 : parser_->reusable_preparser_->factory()->set_zone(temp_zone);
129 : }
130 : }
131 5234307 : }
132 5234355 : void Reset() {
133 5234355 : parser_->fni_ = prev_fni_;
134 5234355 : parser_->zone_ = prev_zone_;
135 5234355 : parser_->factory()->set_zone(prev_zone_);
136 5234355 : parser_->allow_lazy_ = prev_allow_lazy_;
137 5234355 : parser_->temp_zoned_ = prev_temp_zoned_;
138 5234355 : if (parser_->reusable_preparser_ != nullptr) {
139 2320796 : parser_->reusable_preparser_->zone_ = prev_zone_;
140 2320796 : parser_->reusable_preparser_->factory()->set_zone(prev_zone_);
141 : }
142 5234355 : }
143 5234302 : ~DiscardableZoneScope() { Reset(); }
144 :
145 : private:
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 1678406 : void Parser::SetCachedData(ParseInfo* info) {
157 : DCHECK_NULL(cached_parse_data_);
158 1678346 : if (consume_cached_parse_data()) {
159 60 : if (allow_lazy_) {
160 60 : cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
161 1678406 : if (cached_parse_data_ != nullptr) return;
162 : }
163 5 : compile_options_ = ScriptCompiler::kNoCompileOptions;
164 : }
165 : }
166 :
167 76903 : 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 :
173 : FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor
174 76903 : : FunctionKind::kDefaultBaseConstructor;
175 287553 : DeclarationScope* function_scope = NewFunctionScope(kind);
176 76903 : SetLanguageMode(function_scope, LanguageMode::kStrict);
177 : // Set start and end position to the same value
178 : function_scope->set_start_position(pos);
179 : function_scope->set_end_position(pos);
180 : ZoneList<Statement*>* body = nullptr;
181 :
182 : {
183 76903 : FunctionState function_state(&function_state_, &scope_, function_scope);
184 :
185 76903 : body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
186 76903 : if (call_super) {
187 : // Create a SuperCallReference and handle in BytecodeGenerator.
188 14211 : auto constructor_args_name = ast_value_factory()->empty_string();
189 : bool is_duplicate;
190 : bool is_rest = true;
191 : bool is_optional = false;
192 : Variable* constructor_args = function_scope->DeclareParameter(
193 : constructor_args_name, TEMPORARY, is_optional, is_rest, &is_duplicate,
194 14211 : ast_value_factory(), pos);
195 :
196 : ZoneList<Expression*>* args =
197 14211 : new (zone()) ZoneList<Expression*>(1, zone());
198 : Spread* spread_args = factory()->NewSpread(
199 28422 : factory()->NewVariableProxy(constructor_args), pos, pos);
200 :
201 14211 : args->Add(spread_args, zone());
202 14211 : Expression* super_call_ref = NewSuperCallReference(pos);
203 14211 : Expression* call = factory()->NewCall(super_call_ref, args, pos);
204 28422 : body->Add(factory()->NewReturnStatement(call, pos), zone());
205 : }
206 :
207 76903 : expected_property_count = function_state.expected_property_count();
208 : }
209 :
210 : FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
211 : name, function_scope, body, expected_property_count, parameter_count,
212 : parameter_count, FunctionLiteral::kNoDuplicateParameters,
213 : FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
214 76903 : true, GetNextFunctionLiteralId());
215 :
216 76903 : return function_literal;
217 : }
218 :
219 : // ----------------------------------------------------------------------------
220 : // The CHECK_OK macro is a convenient macro to enforce error
221 : // handling for functions that may fail (by returning !*ok).
222 : //
223 : // CAUTION: This macro appends extra statements after a call,
224 : // thus it must never be used where only a single statement
225 : // is correct (e.g. an if statement branch w/o braces)!
226 :
227 : #define CHECK_OK_VALUE(x) ok); \
228 : if (!*ok) return x; \
229 : ((void)0
230 : #define DUMMY ) // to make indentation work
231 : #undef DUMMY
232 :
233 : #define CHECK_OK CHECK_OK_VALUE(nullptr)
234 : #define CHECK_OK_VOID CHECK_OK_VALUE(this->Void())
235 :
236 : #define CHECK_FAILED /**/); \
237 : if (failed_) return nullptr; \
238 : ((void)0
239 : #define DUMMY ) // to make indentation work
240 : #undef DUMMY
241 :
242 : // ----------------------------------------------------------------------------
243 : // Implementation of Parser
244 :
245 4742264 : bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
246 : Expression* y,
247 : Token::Value op, int pos) {
248 12890211 : if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
249 6646820 : y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
250 1183626 : double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
251 1183626 : double y_val = y->AsLiteral()->raw_value()->AsNumber();
252 591813 : switch (op) {
253 : case Token::ADD:
254 16314 : *x = factory()->NewNumberLiteral(x_val + y_val, pos);
255 16314 : return true;
256 : case Token::SUB:
257 1288 : *x = factory()->NewNumberLiteral(x_val - y_val, pos);
258 1288 : return true;
259 : case Token::MUL:
260 249908 : *x = factory()->NewNumberLiteral(x_val * y_val, pos);
261 249908 : return true;
262 : case Token::DIV:
263 3383 : *x = factory()->NewNumberLiteral(x_val / y_val, pos);
264 3383 : return true;
265 : case Token::BIT_OR: {
266 18687 : int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
267 18687 : *x = factory()->NewNumberLiteral(value, pos);
268 18687 : return true;
269 : }
270 : case Token::BIT_AND: {
271 435 : int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
272 435 : *x = factory()->NewNumberLiteral(value, pos);
273 435 : return true;
274 : }
275 : case Token::BIT_XOR: {
276 234 : int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
277 234 : *x = factory()->NewNumberLiteral(value, pos);
278 234 : return true;
279 : }
280 : case Token::SHL: {
281 289945 : int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
282 289945 : *x = factory()->NewNumberLiteral(value, pos);
283 289945 : return true;
284 : }
285 : case Token::SHR: {
286 384 : uint32_t shift = DoubleToInt32(y_val) & 0x1f;
287 384 : uint32_t value = DoubleToUint32(x_val) >> shift;
288 384 : *x = factory()->NewNumberLiteral(value, pos);
289 384 : return true;
290 : }
291 : case Token::SAR: {
292 421 : uint32_t shift = DoubleToInt32(y_val) & 0x1f;
293 421 : int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
294 421 : *x = factory()->NewNumberLiteral(value, pos);
295 421 : return true;
296 : }
297 : case Token::EXP: {
298 304 : double value = Pow(x_val, y_val);
299 304 : int int_value = static_cast<int>(value);
300 : *x = factory()->NewNumberLiteral(
301 304 : int_value == value && value != -0.0 ? int_value : value, pos);
302 304 : return true;
303 : }
304 : default:
305 : break;
306 : }
307 : }
308 : return false;
309 : }
310 :
311 1378768 : Expression* Parser::BuildUnaryExpression(Expression* expression,
312 : Token::Value op, int pos) {
313 : DCHECK_NOT_NULL(expression);
314 1378770 : if (expression->IsLiteral()) {
315 1434306 : const AstValue* literal = expression->AsLiteral()->raw_value();
316 717153 : if (op == Token::NOT) {
317 : // Convert the literal to a boolean condition and negate it.
318 274 : bool condition = literal->BooleanValue();
319 274 : return factory()->NewBooleanLiteral(!condition, pos);
320 716879 : } else if (literal->IsNumber()) {
321 : // Compute some expressions involving only number literals.
322 716132 : double value = literal->AsNumber();
323 716132 : switch (op) {
324 : case Token::ADD:
325 : return expression;
326 : case Token::SUB:
327 437945 : return factory()->NewNumberLiteral(-value, pos);
328 : case Token::BIT_NOT:
329 1240 : return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
330 : default:
331 : break;
332 : }
333 : }
334 : }
335 1875679 : return factory()->NewUnaryOperation(op, expression, pos);
336 : }
337 :
338 269010 : Expression* Parser::NewThrowError(Runtime::FunctionId id,
339 : MessageTemplate::Template message,
340 : const AstRawString* arg, int pos) {
341 807030 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
342 269010 : args->Add(factory()->NewSmiLiteral(message, pos), zone());
343 269010 : args->Add(factory()->NewStringLiteral(arg, pos), zone());
344 269010 : CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
345 538020 : return factory()->NewThrow(call_constructor, pos);
346 : }
347 :
348 2814 : Expression* Parser::NewSuperPropertyReference(int pos) {
349 : // this_function[home_object_symbol]
350 : VariableProxy* this_function_proxy =
351 2814 : NewUnresolved(ast_value_factory()->this_function_string(), pos);
352 : Expression* home_object_symbol_literal = factory()->NewSymbolLiteral(
353 2814 : AstSymbol::kHomeObjectSymbol, kNoSourcePosition);
354 : Expression* home_object = factory()->NewProperty(
355 2814 : this_function_proxy, home_object_symbol_literal, pos);
356 : return factory()->NewSuperPropertyReference(
357 8442 : ThisExpression(pos)->AsVariableProxy(), home_object, pos);
358 : }
359 :
360 16531 : Expression* Parser::NewSuperCallReference(int pos) {
361 : VariableProxy* new_target_proxy =
362 33062 : NewUnresolved(ast_value_factory()->new_target_string(), pos);
363 : VariableProxy* this_function_proxy =
364 16531 : NewUnresolved(ast_value_factory()->this_function_string(), pos);
365 : return factory()->NewSuperCallReference(
366 : ThisExpression(pos)->AsVariableProxy(), new_target_proxy,
367 49593 : this_function_proxy, pos);
368 : }
369 :
370 13404 : Expression* Parser::NewTargetExpression(int pos) {
371 13404 : auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
372 : proxy->set_is_new_target();
373 13404 : return proxy;
374 : }
375 :
376 35 : Expression* Parser::FunctionSentExpression(int pos) {
377 : // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
378 105 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
379 : VariableProxy* generator = factory()->NewVariableProxy(
380 70 : function_state_->scope()->generator_object_var());
381 35 : args->Add(generator, zone());
382 : return factory()->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
383 35 : args, pos);
384 : }
385 :
386 3125 : Expression* Parser::ImportMetaExpression(int pos) {
387 : return factory()->NewCallRuntime(
388 : Runtime::kGetImportMetaObject,
389 6250 : new (zone()) ZoneList<Expression*>(0, zone()), pos);
390 : }
391 :
392 20986392 : Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
393 20986392 : switch (token) {
394 : case Token::NULL_LITERAL:
395 20296011 : return factory()->NewNullLiteral(pos);
396 : case Token::TRUE_LITERAL:
397 316932 : return factory()->NewBooleanLiteral(true, pos);
398 : case Token::FALSE_LITERAL:
399 373450 : return factory()->NewBooleanLiteral(false, pos);
400 : case Token::SMI: {
401 19055887 : uint32_t value = scanner()->smi_value();
402 19055887 : return factory()->NewSmiLiteral(value, pos);
403 : }
404 : case Token::NUMBER: {
405 1052157 : double value = scanner()->DoubleValue();
406 1052157 : return factory()->NewNumberLiteral(value, pos);
407 : }
408 : case Token::BIGINT:
409 : return factory()->NewBigIntLiteral(
410 25 : scanner()->CurrentLiteralAsCString(zone()), pos);
411 : default:
412 : DCHECK(false);
413 : }
414 : return nullptr;
415 : }
416 :
417 : Expression* Parser::NewV8Intrinsic(const AstRawString* name,
418 803090 : ZoneList<Expression*>* args, int pos,
419 : bool* ok) {
420 1099279 : if (extension_ != nullptr) {
421 : // The extension structures are only accessible while parsing the
422 : // very first time, not when reparsing because of lazy compilation.
423 5 : GetClosureScope()->ForceEagerCompilation();
424 : }
425 :
426 : DCHECK(name->is_one_byte());
427 : const Runtime::Function* function =
428 1099279 : Runtime::FunctionForName(name->raw_data(), name->length());
429 :
430 1099278 : if (function != nullptr) {
431 : // Check for possible name clash.
432 : DCHECK_EQ(Context::kNotFound,
433 : Context::IntrinsicIndexForName(name->raw_data(), name->length()));
434 : // Check for built-in IS_VAR macro.
435 958532 : if (function->function_id == Runtime::kIS_VAR) {
436 : DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
437 : // %IS_VAR(x) evaluates to x if x is a variable,
438 : // leads to a parse error otherwise. Could be implemented as an
439 : // inline function %_IS_VAR(x) to eliminate this special case.
440 1410 : if (args->length() == 1 && args->at(0)->AsVariableProxy() != nullptr) {
441 705 : return args->at(0);
442 : } else {
443 0 : ReportMessage(MessageTemplate::kNotIsvar);
444 0 : *ok = false;
445 : return nullptr;
446 : }
447 : }
448 :
449 : // Check that the expected number of arguments are being passed.
450 1760212 : if (function->nargs != -1 && function->nargs != args->length()) {
451 10 : ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
452 10 : *ok = false;
453 : return nullptr;
454 : }
455 :
456 957817 : return factory()->NewCallRuntime(function, args, pos);
457 : }
458 :
459 : int context_index =
460 140746 : Context::IntrinsicIndexForName(name->raw_data(), name->length());
461 :
462 : // Check that the function is defined.
463 140746 : if (context_index == Context::kNotFound) {
464 50 : ReportMessage(MessageTemplate::kNotDefined, name);
465 50 : *ok = false;
466 : return nullptr;
467 : }
468 :
469 140696 : return factory()->NewCallRuntime(context_index, args, pos);
470 : }
471 :
472 16069549 : Parser::Parser(ParseInfo* info)
473 : : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
474 : info->extension(), info->GetOrCreateAstValueFactory(),
475 : info->runtime_call_stats(), true),
476 : scanner_(info->unicode_cache(), use_counts_),
477 : reusable_preparser_(nullptr),
478 : mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
479 : source_range_map_(info->source_range_map()),
480 : target_stack_(nullptr),
481 : compile_options_(info->compile_options()),
482 : cached_parse_data_(nullptr),
483 : total_preparse_skipped_(0),
484 : temp_zoned_(false),
485 : log_(nullptr),
486 2348007 : consumed_preparsed_scope_data_(info->consumed_preparsed_scope_data()),
487 21132071 : parameters_end_pos_(info->parameters_end_pos()) {
488 : // Even though we were passed ParseInfo, we should not store it in
489 : // Parser - this makes sure that Isolate is not accidentally accessed via
490 : // ParseInfo during background parsing.
491 : DCHECK_NOT_NULL(info->character_stream());
492 : // Determine if functions can be lazily compiled. This is necessary to
493 : // allow some of our builtin JS files to be lazily compiled. These
494 : // builtins cannot be handled lazily by the parser, since we have to know
495 : // if a function uses the special natives syntax, which is something the
496 : // parser records.
497 : // If the debugger requests compilation for break points, we cannot be
498 : // aggressive about lazy compilation, because it might trigger compilation
499 : // of functions without an outer context when setting a breakpoint through
500 : // Debug::FindSharedFunctionInfoInScript
501 : // We also compile eagerly for kProduceExhaustiveCodeCache.
502 4695666 : bool can_compile_lazily = FLAG_lazy && !info->is_eager();
503 :
504 : set_default_eager_compile_hint(can_compile_lazily
505 : ? FunctionLiteral::kShouldLazyCompile
506 2348007 : : FunctionLiteral::kShouldEagerCompile);
507 6410425 : allow_lazy_ = FLAG_lazy && info->allow_lazy_parsing() && !info->is_native() &&
508 4326376 : info->extension() == nullptr && can_compile_lazily;
509 3992136 : set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
510 2348007 : set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
511 2348007 : set_allow_harmony_function_sent(FLAG_harmony_function_sent);
512 2348007 : set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators);
513 2348007 : set_allow_harmony_class_fields(FLAG_harmony_class_fields);
514 2348007 : set_allow_harmony_object_rest_spread(FLAG_harmony_object_rest_spread);
515 2348007 : set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import);
516 2348007 : set_allow_harmony_import_meta(FLAG_harmony_import_meta);
517 2348007 : set_allow_harmony_async_iteration(FLAG_harmony_async_iteration);
518 2348007 : set_allow_harmony_template_escapes(FLAG_harmony_template_escapes);
519 2348007 : set_allow_harmony_bigint(FLAG_harmony_bigint);
520 100964259 : for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
521 : ++feature) {
522 98616252 : use_counts_[feature] = 0;
523 : }
524 2348007 : }
525 :
526 2348008 : void Parser::DeserializeScopeChain(
527 : ParseInfo* info, MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
528 : // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
529 : // context, which will have the "this" binding for script scopes.
530 4368744 : DeclarationScope* script_scope = NewScriptScope();
531 : info->set_script_scope(script_scope);
532 : Scope* scope = script_scope;
533 : Handle<ScopeInfo> outer_scope_info;
534 2348008 : if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
535 : DCHECK(ThreadId::Current().Equals(
536 : outer_scope_info->GetIsolate()->thread_id()));
537 : scope = Scope::DeserializeScopeChain(
538 : zone(), *outer_scope_info, script_scope, ast_value_factory(),
539 1010368 : Scope::DeserializationMode::kScopesOnly);
540 : DCHECK(!info->is_module() || scope->is_module_scope());
541 : }
542 2348008 : original_scope_ = scope;
543 2348008 : }
544 :
545 : namespace {
546 :
547 4043820 : void MaybeResetCharacterStream(ParseInfo* info, FunctionLiteral* literal) {
548 : // Don't reset the character stream if there is an asm.js module since it will
549 : // be used again by the asm-parser.
550 4696014 : if (!FLAG_stress_validate_asm &&
551 1695813 : (literal == nullptr || !literal->scope()->ContainsAsmModule())) {
552 1955213 : info->ResetCharacterStream();
553 : }
554 2348008 : }
555 :
556 : } // namespace
557 :
558 5035152 : FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
559 : // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
560 : // see comment for HistogramTimerScope class.
561 :
562 : // It's OK to use the Isolate & counters here, since this function is only
563 : // called in the main thread.
564 : DCHECK(parsing_on_main_thread_);
565 : RuntimeCallTimerScope runtime_timer(
566 : runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval
567 1678345 : : &RuntimeCallStats::ParseProgram);
568 5035037 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
569 : base::ElapsedTimer timer;
570 1678346 : if (FLAG_trace_parse) {
571 : timer.Start();
572 : }
573 3356692 : fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
574 :
575 : // Initialize parser state.
576 1678345 : ParserLogger logger;
577 :
578 1678346 : if (produce_cached_parse_data()) {
579 115 : if (allow_lazy_) {
580 115 : log_ = &logger;
581 : } else {
582 0 : compile_options_ = ScriptCompiler::kNoCompileOptions;
583 : }
584 1678231 : } else if (consume_cached_parse_data()) {
585 55 : cached_parse_data_->Initialize();
586 : }
587 :
588 1678346 : DeserializeScopeChain(info, info->maybe_outer_scope_info());
589 :
590 3356690 : scanner_.Initialize(info->character_stream(), info->is_module());
591 1678345 : FunctionLiteral* result = DoParseProgram(info);
592 1678346 : MaybeResetCharacterStream(info, result);
593 :
594 1678346 : HandleSourceURLComments(isolate, info->script());
595 :
596 1678346 : if (FLAG_trace_parse && result != nullptr) {
597 0 : double ms = timer.Elapsed().InMillisecondsF();
598 0 : if (info->is_eval()) {
599 0 : PrintF("[parsing eval");
600 0 : } else if (info->script()->name()->IsString()) {
601 : String* name = String::cast(info->script()->name());
602 0 : std::unique_ptr<char[]> name_chars = name->ToCString();
603 0 : PrintF("[parsing script: %s", name_chars.get());
604 : } else {
605 0 : PrintF("[parsing script");
606 : }
607 0 : PrintF(" - took %0.3f ms]\n", ms);
608 : }
609 1678346 : if (produce_cached_parse_data() && result != nullptr) {
610 115 : *info->cached_data() = logger.GetScriptData();
611 : }
612 1678346 : log_ = nullptr;
613 1678346 : return result;
614 : }
615 :
616 :
617 1704901 : FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
618 : // Note that this function can be called from the main thread or from a
619 : // background thread. We should not access anything Isolate / heap dependent
620 : // via ParseInfo, and also not pass it forward.
621 : DCHECK_NULL(scope_);
622 : DCHECK_NULL(target_stack_);
623 :
624 1678455 : ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
625 8648201 : ResetFunctionLiteralId();
626 : DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel ||
627 : info->function_literal_id() == FunctionLiteral::kIdTypeInvalid);
628 :
629 : FunctionLiteral* result = nullptr;
630 : {
631 1678455 : Scope* outer = original_scope_;
632 : DCHECK_NOT_NULL(outer);
633 1678455 : parsing_module_ = info->is_module();
634 1678455 : if (info->is_eval()) {
635 978149 : outer = NewEvalScope(outer);
636 700306 : } else if (parsing_module_) {
637 : DCHECK_EQ(outer, info->script_scope());
638 26446 : outer = NewModuleScope(info->script_scope());
639 : }
640 :
641 1678455 : DeclarationScope* scope = outer->AsDeclarationScope();
642 :
643 : scope->set_start_position(0);
644 :
645 1678454 : FunctionState function_state(&function_state_, &scope_, scope);
646 :
647 2036471 : ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
648 1678455 : bool ok = true;
649 : int beg_pos = scanner()->location().beg_pos;
650 1678455 : if (parsing_module_) {
651 : // Declare the special module parameter.
652 26446 : auto name = ast_value_factory()->empty_string();
653 26446 : bool is_duplicate = false;
654 : bool is_rest = false;
655 : bool is_optional = false;
656 : auto var =
657 : scope->DeclareParameter(name, VAR, is_optional, is_rest,
658 26446 : &is_duplicate, ast_value_factory(), beg_pos);
659 : DCHECK(!is_duplicate);
660 : var->AllocateTo(VariableLocation::PARAMETER, 0);
661 :
662 26446 : PrepareGeneratorVariables();
663 : scope->ForceContextAllocation();
664 : Expression* initial_yield =
665 26446 : BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
666 : body->Add(
667 26446 : factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
668 26446 : zone());
669 :
670 26446 : ParseModuleItemList(body, &ok);
671 38490 : ok = ok &&
672 : module()->Validate(this->scope()->AsModuleScope(),
673 62578 : &pending_error_handler_, zone());
674 : } else {
675 : // Don't count the mode in the use counters--give the program a chance
676 : // to enable script-wide strict mode below.
677 : this->scope()->SetLanguageMode(info->language_mode());
678 1652009 : ParseStatementList(body, Token::EOS, &ok);
679 : }
680 :
681 : // The parser will peek but not consume EOS. Our scope logically goes all
682 : // the way to the EOS, though.
683 : scope->set_end_position(scanner()->peek_location().beg_pos);
684 :
685 3057646 : if (ok && is_strict(language_mode())) {
686 205392 : CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
687 : }
688 3057124 : if (ok && is_sloppy(language_mode())) {
689 : // TODO(littledan): Function bindings on the global object that modify
690 : // pre-existing bindings should be made writable, enumerable and
691 : // nonconfigurable if possible, whereas this code will leave attributes
692 : // unchanged if the property already exists.
693 1173799 : InsertSloppyBlockFunctionVarBindings(scope);
694 : }
695 1678456 : if (ok) {
696 1378668 : CheckConflictingVarDeclarations(scope, &ok);
697 : }
698 :
699 3040933 : if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
700 716024 : if (body->length() != 1 ||
701 1074031 : !body->at(0)->IsExpressionStatement() ||
702 : !body->at(0)->AsExpressionStatement()->
703 716014 : expression()->IsFunctionLiteral()) {
704 20 : ReportMessage(MessageTemplate::kSingleFunctionLiteral);
705 20 : ok = false;
706 : }
707 : }
708 :
709 1678456 : if (ok) {
710 : RewriteDestructuringAssignments();
711 1362457 : int parameter_count = parsing_module_ ? 1 : 0;
712 : result = factory()->NewScriptOrEvalFunctionLiteral(
713 : scope, body, function_state.expected_property_count(),
714 1362457 : parameter_count);
715 : }
716 : }
717 :
718 : info->set_max_function_literal_id(GetLastFunctionLiteralId());
719 :
720 : // Make sure the target stack is empty.
721 : DCHECK_NULL(target_stack_);
722 :
723 1678456 : return result;
724 : }
725 :
726 1339047 : FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
727 : Handle<SharedFunctionInfo> shared_info) {
728 : // It's OK to use the Isolate & counters here, since this function is only
729 : // called in the main thread.
730 : DCHECK(parsing_on_main_thread_);
731 : RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
732 669523 : &RuntimeCallStats::ParseFunction);
733 2008570 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
734 : base::ElapsedTimer timer;
735 669523 : if (FLAG_trace_parse) {
736 : timer.Start();
737 : }
738 669523 : DeserializeScopeChain(info, info->maybe_outer_scope_info());
739 : DCHECK_EQ(factory()->zone(), info->zone());
740 :
741 : // Initialize parser state.
742 : Handle<String> name(shared_info->name());
743 669524 : info->set_function_name(ast_value_factory()->GetString(name));
744 1339048 : scanner_.Initialize(info->character_stream(), info->is_module());
745 :
746 669524 : FunctionLiteral* result = DoParseFunction(info, info->function_name());
747 669524 : MaybeResetCharacterStream(info, result);
748 669524 : if (result != nullptr) {
749 668141 : Handle<String> inferred_name(shared_info->inferred_name());
750 : result->set_inferred_name(inferred_name);
751 : }
752 :
753 669524 : if (FLAG_trace_parse && result != nullptr) {
754 0 : double ms = timer.Elapsed().InMillisecondsF();
755 : // We need to make sure that the debug-name is available.
756 0 : ast_value_factory()->Internalize(isolate);
757 0 : std::unique_ptr<char[]> name_chars = result->debug_name()->ToCString();
758 0 : PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
759 : }
760 669524 : return result;
761 : }
762 :
763 669551 : static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
764 669551 : if (info->is_declaration()) {
765 : return FunctionLiteral::kDeclaration;
766 365964 : } else if (info->is_named_expression()) {
767 : return FunctionLiteral::kNamedExpression;
768 897974 : } else if (IsConciseMethod(info->function_kind()) ||
769 253726 : IsAccessorFunction(info->function_kind())) {
770 : return FunctionLiteral::kAccessorOrMethod;
771 : }
772 248227 : return FunctionLiteral::kAnonymousExpression;
773 : }
774 :
775 1750703 : FunctionLiteral* Parser::DoParseFunction(ParseInfo* info,
776 : const AstRawString* raw_name) {
777 : DCHECK_NOT_NULL(raw_name);
778 : DCHECK_NULL(scope_);
779 : DCHECK_NULL(target_stack_);
780 :
781 : DCHECK(ast_value_factory());
782 1609163 : fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
783 669550 : fni_->PushEnclosingName(raw_name);
784 :
785 : ResetFunctionLiteralId();
786 : DCHECK_LT(0, info->function_literal_id());
787 669551 : SkipFunctionLiterals(info->function_literal_id() - 1);
788 :
789 : ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
790 :
791 : // Place holder for the result.
792 : FunctionLiteral* result = nullptr;
793 :
794 : {
795 : // Parse the function literal.
796 669551 : Scope* outer = original_scope_;
797 669551 : DeclarationScope* outer_function = outer->GetClosureScope();
798 : DCHECK(outer);
799 669551 : FunctionState function_state(&function_state_, &scope_, outer_function);
800 : BlockState block_state(&scope_, outer);
801 : DCHECK(is_sloppy(outer->language_mode()) ||
802 : is_strict(info->language_mode()));
803 669551 : FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
804 669551 : FunctionKind kind = info->function_kind();
805 669550 : bool ok = true;
806 :
807 669550 : if (IsArrowFunction(kind)) {
808 135204 : if (IsAsyncFunction(kind)) {
809 : DCHECK(!scanner()->HasAnyLineTerminatorAfterNext());
810 925 : if (!Check(Token::ASYNC)) {
811 0 : CHECK(stack_overflow());
812 135 : return nullptr;
813 : }
814 1820 : if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
815 135 : CHECK(stack_overflow());
816 : return nullptr;
817 : }
818 : }
819 :
820 : // TODO(adamk): We should construct this scope from the ScopeInfo.
821 135069 : DeclarationScope* scope = NewFunctionScope(kind);
822 :
823 : // This bit only needs to be explicitly set because we're
824 : // not passing the ScopeInfo to the Scope constructor.
825 135069 : SetLanguageMode(scope, info->language_mode());
826 :
827 : scope->set_start_position(info->start_position());
828 135069 : ExpressionClassifier formals_classifier(this);
829 : ParserFormalParameters formals(scope);
830 : int rewritable_length =
831 135069 : function_state.destructuring_assignments_to_rewrite().length();
832 : {
833 : // Parsing patterns as variable reference expression creates
834 : // NewUnresolved references in current scope. Enter arrow function
835 : // scope for formal parameter parsing.
836 : BlockState block_state(&scope_, scope);
837 135069 : if (Check(Token::LPAREN)) {
838 : // '(' StrictFormalParameters ')'
839 123256 : ParseFormalParameterList(&formals, &ok);
840 123256 : if (ok) ok = Check(Token::RPAREN);
841 : } else {
842 : // BindingIdentifier
843 11813 : ParseFormalParameter(&formals, &ok);
844 11813 : if (ok) {
845 : DeclareFormalParameters(formals.scope, formals.params,
846 11813 : formals.is_simple);
847 : }
848 : }
849 : }
850 :
851 135069 : if (ok) {
852 135069 : if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
853 : // If there were FunctionLiterals in the parameters, we need to
854 : // renumber them to shift down so the next function literal id for
855 : // the arrow function is the one requested.
856 : AstFunctionLiteralIdReindexer reindexer(
857 : stack_limit_,
858 303 : (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
859 1046 : for (auto p : formals.params) {
860 440 : if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
861 440 : if (p->initializer != nullptr) reindexer.Reindex(p->initializer);
862 : }
863 : ResetFunctionLiteralId();
864 606 : SkipFunctionLiterals(info->function_literal_id() - 1);
865 : }
866 :
867 : // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
868 : // not be observable, or else the preparser would have failed.
869 : Expression* expression =
870 135069 : ParseArrowFunctionLiteral(true, formals, rewritable_length, &ok);
871 135069 : if (ok) {
872 : // Scanning must end at the same position that was recorded
873 : // previously. If not, parsing has been interrupted due to a stack
874 : // overflow, at which point the partially parsed arrow function
875 : // concise body happens to be a valid expression. This is a problem
876 : // only for arrow functions with single expression bodies, since there
877 : // is no end token such as "}" for normal functions.
878 134859 : if (scanner()->location().end_pos == info->end_position()) {
879 : // The pre-parser saw an arrow function here, so the full parser
880 : // must produce a FunctionLiteral.
881 : DCHECK(expression->IsFunctionLiteral());
882 134859 : result = expression->AsFunctionLiteral();
883 : // Rewrite destructuring assignments in the parameters. (The ones
884 : // inside the function body are rewritten by
885 : // ParseArrowFunctionLiteral.)
886 : RewriteDestructuringAssignments();
887 : } else {
888 0 : ok = false;
889 : }
890 : }
891 : }
892 534346 : } else if (IsDefaultConstructor(kind)) {
893 : DCHECK_EQ(scope(), outer);
894 : result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
895 6302 : info->start_position(), info->end_position());
896 : } else {
897 : result = ParseFunctionLiteral(
898 : raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
899 528044 : kNoSourcePosition, function_type, info->language_mode(), &ok);
900 : }
901 : // Make sure the results agree.
902 : DCHECK(ok == (result != nullptr));
903 : }
904 :
905 : // Make sure the target stack is empty.
906 : DCHECK_NULL(target_stack_);
907 : DCHECK_IMPLIES(result,
908 : info->function_literal_id() == result->function_literal_id());
909 669416 : return result;
910 : }
911 :
912 107529 : Statement* Parser::ParseModuleItem(bool* ok) {
913 : // ecma262/#prod-ModuleItem
914 : // ModuleItem :
915 : // ImportDeclaration
916 : // ExportDeclaration
917 : // StatementListItem
918 :
919 5372 : Token::Value next = peek();
920 :
921 107529 : if (next == Token::EXPORT) {
922 19003 : return ParseExportDeclaration(ok);
923 : }
924 :
925 88526 : if (next == Token::IMPORT) {
926 : // We must be careful not to parse a dynamic import expression as an import
927 : // declaration. Same for import.meta expressions.
928 : Token::Value peek_ahead = PeekAhead();
929 8203 : if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
930 215 : (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
931 2331 : ParseImportDeclaration(CHECK_OK);
932 2372 : return factory()->NewEmptyStatement(kNoSourcePosition);
933 : }
934 : }
935 :
936 86195 : return ParseStatementListItem(ok);
937 : }
938 :
939 :
940 26446 : void Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
941 : // ecma262/#prod-Module
942 : // Module :
943 : // ModuleBody?
944 : //
945 : // ecma262/#prod-ModuleItemList
946 : // ModuleBody :
947 : // ModuleItem*
948 :
949 : DCHECK(scope()->is_module_scope());
950 146019 : while (peek() != Token::EOS) {
951 133975 : Statement* stat = ParseModuleItem(CHECK_OK_VOID);
952 93127 : if (stat && !stat->IsEmpty()) {
953 78517 : body->Add(stat, zone());
954 : }
955 : }
956 : }
957 :
958 :
959 1418 : const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
960 : // ModuleSpecifier :
961 : // StringLiteral
962 :
963 1418 : Expect(Token::STRING, CHECK_OK);
964 1403 : return GetSymbol();
965 : }
966 :
967 :
968 503 : void Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
969 : ZoneList<Scanner::Location>* export_locations,
970 : ZoneList<const AstRawString*>* local_names,
971 : Scanner::Location* reserved_loc, bool* ok) {
972 : // ExportClause :
973 : // '{' '}'
974 : // '{' ExportsList '}'
975 : // '{' ExportsList ',' '}'
976 : //
977 : // ExportsList :
978 : // ExportSpecifier
979 : // ExportsList ',' ExportSpecifier
980 : //
981 : // ExportSpecifier :
982 : // IdentifierName
983 : // IdentifierName 'as' IdentifierName
984 :
985 2865 : Expect(Token::LBRACE, CHECK_OK_VOID);
986 :
987 : Token::Value name_tok;
988 594 : while ((name_tok = peek()) != Token::RBRACE) {
989 : // Keep track of the first reserved word encountered in case our
990 : // caller needs to report an error.
991 1084 : if (!reserved_loc->IsValid() &&
992 : !Token::IsIdentifier(name_tok, LanguageMode::kStrict, false,
993 542 : parsing_module_)) {
994 68 : *reserved_loc = scanner()->location();
995 : }
996 582 : const AstRawString* local_name = ParseIdentifierName(CHECK_OK_VOID);
997 522 : const AstRawString* export_name = nullptr;
998 522 : Scanner::Location location = scanner()->location();
999 522 : if (CheckContextualKeyword(Token::AS)) {
1000 246 : export_name = ParseIdentifierName(CHECK_OK_VOID);
1001 : // Set the location to the whole "a as b" string, so that it makes sense
1002 : // both for errors due to "a" and for errors due to "b".
1003 236 : location.end_pos = scanner()->location().end_pos;
1004 : }
1005 512 : if (export_name == nullptr) {
1006 276 : export_name = local_name;
1007 : }
1008 512 : export_names->Add(export_name, zone());
1009 512 : local_names->Add(local_name, zone());
1010 512 : export_locations->Add(location, zone());
1011 512 : if (peek() == Token::RBRACE) break;
1012 101 : Expect(Token::COMMA, CHECK_OK_VOID);
1013 : }
1014 :
1015 463 : Expect(Token::RBRACE, CHECK_OK_VOID);
1016 : }
1017 :
1018 :
1019 1152 : ZoneList<const Parser::NamedImport*>* Parser::ParseNamedImports(
1020 : int pos, bool* ok) {
1021 : // NamedImports :
1022 : // '{' '}'
1023 : // '{' ImportsList '}'
1024 : // '{' ImportsList ',' '}'
1025 : //
1026 : // ImportsList :
1027 : // ImportSpecifier
1028 : // ImportsList ',' ImportSpecifier
1029 : //
1030 : // ImportSpecifier :
1031 : // BindingIdentifier
1032 : // IdentifierName 'as' BindingIdentifier
1033 :
1034 6912 : Expect(Token::LBRACE, CHECK_OK);
1035 :
1036 1152 : auto result = new (zone()) ZoneList<const NamedImport*>(1, zone());
1037 2413 : while (peek() != Token::RBRACE) {
1038 1234 : const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1039 : const AstRawString* local_name = import_name;
1040 : Scanner::Location location = scanner()->location();
1041 : // In the presence of 'as', the left-side of the 'as' can
1042 : // be any IdentifierName. But without 'as', it must be a valid
1043 : // BindingIdentifier.
1044 1179 : if (CheckContextualKeyword(Token::AS)) {
1045 619 : local_name = ParseIdentifierName(CHECK_OK);
1046 : }
1047 1179 : if (!Token::IsIdentifier(scanner()->current_token(), LanguageMode::kStrict,
1048 2358 : false, parsing_module_)) {
1049 30 : *ok = false;
1050 30 : ReportMessage(MessageTemplate::kUnexpectedReserved);
1051 30 : return nullptr;
1052 1149 : } else if (IsEvalOrArguments(local_name)) {
1053 15 : *ok = false;
1054 15 : ReportMessage(MessageTemplate::kStrictEvalArguments);
1055 15 : return nullptr;
1056 : }
1057 :
1058 : DeclareVariable(local_name, CONST, kNeedsInitialization, position(),
1059 1134 : CHECK_OK);
1060 :
1061 : NamedImport* import =
1062 : new (zone()) NamedImport(import_name, local_name, location);
1063 1134 : result->Add(import, zone());
1064 :
1065 1134 : if (peek() == Token::RBRACE) break;
1066 149 : Expect(Token::COMMA, CHECK_OK);
1067 : }
1068 :
1069 1012 : Expect(Token::RBRACE, CHECK_OK);
1070 1012 : return result;
1071 : }
1072 :
1073 :
1074 2331 : void Parser::ParseImportDeclaration(bool* ok) {
1075 : // ImportDeclaration :
1076 : // 'import' ImportClause 'from' ModuleSpecifier ';'
1077 : // 'import' ModuleSpecifier ';'
1078 : //
1079 : // ImportClause :
1080 : // ImportedDefaultBinding
1081 : // NameSpaceImport
1082 : // NamedImports
1083 : // ImportedDefaultBinding ',' NameSpaceImport
1084 : // ImportedDefaultBinding ',' NamedImports
1085 : //
1086 : // NameSpaceImport :
1087 : // '*' 'as' ImportedBinding
1088 :
1089 4950 : int pos = peek_position();
1090 3558 : Expect(Token::IMPORT, CHECK_OK_VOID);
1091 :
1092 : Token::Value tok = peek();
1093 :
1094 : // 'import' ModuleSpecifier ';'
1095 2331 : if (tok == Token::STRING) {
1096 82 : Scanner::Location specifier_loc = scanner()->peek_location();
1097 82 : const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
1098 82 : ExpectSemicolon(CHECK_OK_VOID);
1099 82 : module()->AddEmptyImport(module_specifier, specifier_loc);
1100 82 : return;
1101 : }
1102 :
1103 : // Parse ImportedDefaultBinding if present.
1104 : const AstRawString* import_default_binding = nullptr;
1105 : Scanner::Location import_default_binding_loc;
1106 2249 : if (tok != Token::MUL && tok != Token::LBRACE) {
1107 : import_default_binding =
1108 977 : ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1109 77 : import_default_binding_loc = scanner()->location();
1110 : DeclareVariable(import_default_binding, CONST, kNeedsInitialization, pos,
1111 77 : CHECK_OK_VOID);
1112 : }
1113 :
1114 : // Parse NameSpaceImport or NamedImports if present.
1115 : const AstRawString* module_namespace_binding = nullptr;
1116 : Scanner::Location module_namespace_binding_loc;
1117 2911 : const ZoneList<const NamedImport*>* named_imports = nullptr;
1118 1349 : if (import_default_binding == nullptr || Check(Token::COMMA)) {
1119 1297 : switch (peek()) {
1120 : case Token::MUL: {
1121 135 : Consume(Token::MUL);
1122 135 : ExpectContextualKeyword(Token::AS, CHECK_OK_VOID);
1123 : module_namespace_binding =
1124 135 : ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1125 135 : module_namespace_binding_loc = scanner()->location();
1126 : DeclareVariable(module_namespace_binding, CONST, kCreatedInitialized,
1127 135 : pos, CHECK_OK_VOID);
1128 : break;
1129 : }
1130 :
1131 : case Token::LBRACE:
1132 1152 : named_imports = ParseNamedImports(pos, CHECK_OK_VOID);
1133 : break;
1134 :
1135 : default:
1136 10 : *ok = false;
1137 10 : ReportUnexpectedToken(scanner()->current_token());
1138 10 : return;
1139 : }
1140 : }
1141 :
1142 1199 : ExpectContextualKeyword(Token::FROM, CHECK_OK_VOID);
1143 1109 : Scanner::Location specifier_loc = scanner()->peek_location();
1144 1109 : const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
1145 1104 : ExpectSemicolon(CHECK_OK_VOID);
1146 :
1147 : // Now that we have all the information, we can make the appropriate
1148 : // declarations.
1149 :
1150 : // TODO(neis): Would prefer to call DeclareVariable for each case below rather
1151 : // than above and in ParseNamedImports, but then a possible error message
1152 : // would point to the wrong location. Maybe have a DeclareAt version of
1153 : // Declare that takes a location?
1154 :
1155 1104 : if (module_namespace_binding != nullptr) {
1156 : module()->AddStarImport(module_namespace_binding, module_specifier,
1157 : module_namespace_binding_loc, specifier_loc,
1158 120 : zone());
1159 : }
1160 :
1161 1104 : if (import_default_binding != nullptr) {
1162 : module()->AddImport(ast_value_factory()->default_string(),
1163 : import_default_binding, module_specifier,
1164 104 : import_default_binding_loc, specifier_loc, zone());
1165 : }
1166 :
1167 1104 : if (named_imports != nullptr) {
1168 947 : if (named_imports->length() == 0) {
1169 17 : module()->AddEmptyImport(module_specifier, specifier_loc);
1170 : } else {
1171 2998 : for (int i = 0; i < named_imports->length(); ++i) {
1172 1034 : const NamedImport* import = named_imports->at(i);
1173 : module()->AddImport(import->import_name, import->local_name,
1174 : module_specifier, import->location, specifier_loc,
1175 2068 : zone());
1176 : }
1177 : }
1178 : }
1179 : }
1180 :
1181 :
1182 386 : Statement* Parser::ParseExportDefault(bool* ok) {
1183 : // Supports the following productions, starting after the 'default' token:
1184 : // 'export' 'default' HoistableDeclaration
1185 : // 'export' 'default' ClassDeclaration
1186 : // 'export' 'default' AssignmentExpression[In] ';'
1187 :
1188 2068 : Expect(Token::DEFAULT, CHECK_OK);
1189 386 : Scanner::Location default_loc = scanner()->location();
1190 :
1191 386 : ZoneList<const AstRawString*> local_names(1, zone());
1192 : Statement* result = nullptr;
1193 386 : switch (peek()) {
1194 : case Token::FUNCTION:
1195 67 : result = ParseHoistableDeclaration(&local_names, true, CHECK_OK);
1196 : break;
1197 :
1198 : case Token::CLASS:
1199 44 : Consume(Token::CLASS);
1200 44 : result = ParseClassDeclaration(&local_names, true, CHECK_OK);
1201 : break;
1202 :
1203 : case Token::ASYNC:
1204 120 : if (PeekAhead() == Token::FUNCTION &&
1205 : !scanner()->HasAnyLineTerminatorAfterNext()) {
1206 60 : Consume(Token::ASYNC);
1207 60 : result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK);
1208 : break;
1209 : }
1210 : /* falls through */
1211 :
1212 : default: {
1213 : int pos = position();
1214 215 : ExpressionClassifier classifier(this);
1215 215 : Expression* value = ParseAssignmentExpression(true, CHECK_OK);
1216 175 : RewriteNonPattern(CHECK_OK);
1217 350 : SetFunctionName(value, ast_value_factory()->default_string());
1218 :
1219 : const AstRawString* local_name =
1220 350 : ast_value_factory()->star_default_star_string();
1221 175 : local_names.Add(local_name, zone());
1222 :
1223 : // It's fine to declare this as CONST because the user has no way of
1224 : // writing to it.
1225 700 : Declaration* decl = DeclareVariable(local_name, CONST, pos, CHECK_OK);
1226 175 : decl->proxy()->var()->set_initializer_position(position());
1227 :
1228 : Assignment* assignment = factory()->NewAssignment(
1229 175 : Token::INIT, decl->proxy(), value, kNoSourcePosition);
1230 : result = IgnoreCompletion(
1231 175 : factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1232 :
1233 175 : ExpectSemicolon(CHECK_OK);
1234 : break;
1235 : }
1236 : }
1237 :
1238 : DCHECK_EQ(local_names.length(), 1);
1239 : module()->AddExport(local_names.first(),
1240 : ast_value_factory()->default_string(), default_loc,
1241 963 : zone());
1242 :
1243 : DCHECK_NOT_NULL(result);
1244 321 : return result;
1245 : }
1246 :
1247 19003 : Statement* Parser::ParseExportDeclaration(bool* ok) {
1248 : // ExportDeclaration:
1249 : // 'export' '*' 'from' ModuleSpecifier ';'
1250 : // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1251 : // 'export' VariableStatement
1252 : // 'export' Declaration
1253 : // 'export' 'default' ... (handled in ParseExportDefault)
1254 :
1255 76232 : Expect(Token::EXPORT, CHECK_OK);
1256 : int pos = position();
1257 :
1258 : Statement* result = nullptr;
1259 19003 : ZoneList<const AstRawString*> names(1, zone());
1260 19003 : Scanner::Location loc = scanner()->peek_location();
1261 19003 : switch (peek()) {
1262 : case Token::DEFAULT:
1263 386 : return ParseExportDefault(ok);
1264 :
1265 : case Token::MUL: {
1266 114 : Consume(Token::MUL);
1267 114 : loc = scanner()->location();
1268 114 : ExpectContextualKeyword(Token::FROM, CHECK_OK);
1269 109 : Scanner::Location specifier_loc = scanner()->peek_location();
1270 109 : const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1271 104 : ExpectSemicolon(CHECK_OK);
1272 104 : module()->AddStarExport(module_specifier, loc, specifier_loc, zone());
1273 208 : return factory()->NewEmptyStatement(pos);
1274 : }
1275 :
1276 : case Token::LBRACE: {
1277 : // There are two cases here:
1278 : //
1279 : // 'export' ExportClause ';'
1280 : // and
1281 : // 'export' ExportClause FromClause ';'
1282 : //
1283 : // In the first case, the exported identifiers in ExportClause must
1284 : // not be reserved words, while in the latter they may be. We
1285 : // pass in a location that gets filled with the first reserved word
1286 : // encountered, and then throw a SyntaxError if we are in the
1287 : // non-FromClause case.
1288 503 : Scanner::Location reserved_loc = Scanner::Location::invalid();
1289 503 : ZoneList<const AstRawString*> export_names(1, zone());
1290 503 : ZoneList<Scanner::Location> export_locations(1, zone());
1291 503 : ZoneList<const AstRawString*> original_names(1, zone());
1292 : ParseExportClause(&export_names, &export_locations, &original_names,
1293 503 : &reserved_loc, CHECK_OK);
1294 : const AstRawString* module_specifier = nullptr;
1295 : Scanner::Location specifier_loc;
1296 463 : if (CheckContextualKeyword(Token::FROM)) {
1297 118 : specifier_loc = scanner()->peek_location();
1298 118 : module_specifier = ParseModuleSpecifier(CHECK_OK);
1299 345 : } else if (reserved_loc.IsValid()) {
1300 : // No FromClause, so reserved words are invalid in ExportClause.
1301 10 : *ok = false;
1302 : ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1303 : return nullptr;
1304 : }
1305 448 : ExpectSemicolon(CHECK_OK);
1306 448 : const int length = export_names.length();
1307 : DCHECK_EQ(length, original_names.length());
1308 : DCHECK_EQ(length, export_locations.length());
1309 448 : if (module_specifier == nullptr) {
1310 370 : for (int i = 0; i < length; ++i) {
1311 740 : module()->AddExport(original_names[i], export_names[i],
1312 1480 : export_locations[i], zone());
1313 : }
1314 113 : } else if (length == 0) {
1315 30 : module()->AddEmptyImport(module_specifier, specifier_loc);
1316 : } else {
1317 107 : for (int i = 0; i < length; ++i) {
1318 214 : module()->AddExport(original_names[i], export_names[i],
1319 107 : module_specifier, export_locations[i],
1320 321 : specifier_loc, zone());
1321 : }
1322 : }
1323 896 : return factory()->NewEmptyStatement(pos);
1324 : }
1325 :
1326 : case Token::FUNCTION:
1327 303 : result = ParseHoistableDeclaration(&names, false, CHECK_OK);
1328 : break;
1329 :
1330 : case Token::CLASS:
1331 33 : Consume(Token::CLASS);
1332 33 : result = ParseClassDeclaration(&names, false, CHECK_OK);
1333 : break;
1334 :
1335 : case Token::VAR:
1336 : case Token::LET:
1337 : case Token::CONST:
1338 17554 : result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1339 : break;
1340 :
1341 : case Token::ASYNC:
1342 : // TODO(neis): Why don't we have the same check here as in
1343 : // ParseStatementListItem?
1344 105 : Consume(Token::ASYNC);
1345 105 : result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK);
1346 : break;
1347 :
1348 : default:
1349 5 : *ok = false;
1350 5 : ReportUnexpectedToken(scanner()->current_token());
1351 5 : return nullptr;
1352 : }
1353 17895 : loc.end_pos = scanner()->location().end_pos;
1354 :
1355 : ModuleDescriptor* descriptor = module();
1356 35790 : for (int i = 0; i < names.length(); ++i) {
1357 35790 : descriptor->AddExport(names[i], names[i], loc, zone());
1358 : }
1359 :
1360 : DCHECK_NOT_NULL(result);
1361 : return result;
1362 : }
1363 :
1364 44413263 : VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos,
1365 : VariableKind kind) {
1366 88875792 : return scope()->NewUnresolved(factory(), name, begin_pos, kind);
1367 : }
1368 :
1369 24414 : VariableProxy* Parser::NewUnresolved(const AstRawString* name) {
1370 48828 : return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos);
1371 : }
1372 :
1373 79204 : Declaration* Parser::DeclareVariable(const AstRawString* name,
1374 : VariableMode mode, int pos, bool* ok) {
1375 : return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode),
1376 170296 : pos, ok);
1377 : }
1378 :
1379 171642 : Declaration* Parser::DeclareVariable(const AstRawString* name,
1380 : VariableMode mode, InitializationFlag init,
1381 : int pos, bool* ok) {
1382 : DCHECK_NOT_NULL(name);
1383 : VariableProxy* proxy = factory()->NewVariableProxy(
1384 344962 : name, NORMAL_VARIABLE, scanner()->location().beg_pos);
1385 : Declaration* declaration;
1386 173320 : if (mode == VAR && !scope()->is_declaration_scope()) {
1387 : DCHECK(scope()->is_block_scope() || scope()->is_with_scope());
1388 0 : declaration = factory()->NewNestedVariableDeclaration(proxy, scope(), pos);
1389 : } else {
1390 171642 : declaration = factory()->NewVariableDeclaration(proxy, pos);
1391 : }
1392 : Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr,
1393 171642 : scanner()->location().end_pos);
1394 171642 : if (!*ok) return nullptr;
1395 168114 : return declaration;
1396 : }
1397 :
1398 10802496 : Variable* Parser::Declare(Declaration* declaration,
1399 : DeclarationDescriptor::Kind declaration_kind,
1400 : VariableMode mode, InitializationFlag init, bool* ok,
1401 : Scope* scope, int var_end_pos) {
1402 10702300 : if (scope == nullptr) {
1403 21403188 : scope = this->scope();
1404 : }
1405 10702300 : bool sloppy_mode_block_scope_function_redefinition = false;
1406 : Variable* variable = scope->DeclareVariable(
1407 : declaration, mode, init, allow_harmony_restrictive_generators(),
1408 10702300 : &sloppy_mode_block_scope_function_redefinition, ok);
1409 10702299 : if (!*ok) {
1410 : // If we only have the start position of a proxy, we can't highlight the
1411 : // whole variable name. Pretend its length is 1 so that we highlight at
1412 : // least the first character.
1413 : Scanner::Location loc(declaration->proxy()->position(),
1414 : var_end_pos != kNoSourcePosition
1415 : ? var_end_pos
1416 152058 : : declaration->proxy()->position() + 1);
1417 51862 : if (declaration_kind == DeclarationDescriptor::PARAMETER) {
1418 : ReportMessageAt(loc, MessageTemplate::kParamDupe);
1419 : } else {
1420 : ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
1421 : declaration->proxy()->raw_name());
1422 : }
1423 : return nullptr;
1424 : }
1425 10650437 : if (sloppy_mode_block_scope_function_redefinition) {
1426 200 : ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1427 : }
1428 10650437 : return variable;
1429 : }
1430 :
1431 412146 : Block* Parser::BuildInitializationBlock(
1432 : DeclarationParsingResult* parsing_result,
1433 : ZoneList<const AstRawString*>* names, bool* ok) {
1434 412146 : Block* result = factory()->NewBlock(1, true);
1435 1252006 : for (auto declaration : parsing_result->declarations) {
1436 : DeclareAndInitializeVariables(result, &(parsing_result->descriptor),
1437 427732 : &declaration, names, CHECK_OK);
1438 : }
1439 412128 : return result;
1440 : }
1441 :
1442 1219128 : Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1443 : FunctionLiteral* function, VariableMode mode,
1444 : int pos, bool is_sloppy_block_function,
1445 : ZoneList<const AstRawString*>* names,
1446 : bool* ok) {
1447 : VariableProxy* proxy =
1448 1228119 : factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE);
1449 :
1450 : Declaration* declaration =
1451 1219128 : factory()->NewFunctionDeclaration(proxy, function, pos);
1452 : Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
1453 1219128 : CHECK_OK);
1454 1217713 : if (names) names->Add(variable_name, zone());
1455 1217288 : if (is_sloppy_block_function) {
1456 : SloppyBlockFunctionStatement* statement =
1457 8566 : factory()->NewSloppyBlockFunctionStatement();
1458 : GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name, scope(),
1459 17132 : statement);
1460 8566 : return statement;
1461 : }
1462 2417444 : return factory()->NewEmptyStatement(kNoSourcePosition);
1463 : }
1464 :
1465 : Statement* Parser::DeclareClass(const AstRawString* variable_name,
1466 : Expression* value,
1467 : ZoneList<const AstRawString*>* names,
1468 : int class_token_pos, int end_pos, bool* ok) {
1469 147996 : Declaration* decl =
1470 77526 : DeclareVariable(variable_name, LET, class_token_pos, CHECK_OK);
1471 73998 : decl->proxy()->var()->set_initializer_position(end_pos);
1472 73998 : if (names) names->Add(variable_name, zone());
1473 :
1474 73998 : Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(),
1475 73998 : value, class_token_pos);
1476 : return IgnoreCompletion(
1477 73998 : factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1478 : }
1479 :
1480 : Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
1481 : // Make sure that the function containing the native declaration
1482 : // isn't lazily compiled. The extension structures are only
1483 : // accessible while parsing the first time not when reparsing
1484 : // because of lazy compilation.
1485 1678 : GetClosureScope()->ForceEagerCompilation();
1486 :
1487 : // TODO(1240846): It's weird that native function declarations are
1488 : // introduced dynamically when we meet their declarations, whereas
1489 : // other functions are set up when entering the surrounding scope.
1490 3356 : Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
1491 : NativeFunctionLiteral* lit =
1492 1678 : factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1493 : return factory()->NewExpressionStatement(
1494 1678 : factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1495 1678 : kNoSourcePosition),
1496 1678 : pos);
1497 : }
1498 :
1499 18095 : ZoneList<const AstRawString*>* Parser::DeclareLabel(
1500 : ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) {
1501 : DCHECK(IsIdentifier(var));
1502 18095 : const AstRawString* label = var->raw_name();
1503 : // TODO(1240780): We don't check for redeclaration of labels
1504 : // during preparsing since keeping track of the set of active
1505 : // labels requires nontrivial changes to the way scopes are
1506 : // structured. However, these are probably changes we want to
1507 : // make later anyway so we should go back and fix this then.
1508 18095 : if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
1509 53879 : ReportMessage(MessageTemplate::kLabelRedeclaration, label);
1510 0 : *ok = false;
1511 0 : return nullptr;
1512 : }
1513 18095 : if (labels == nullptr) {
1514 17689 : labels = new (zone()) ZoneList<const AstRawString*>(1, zone());
1515 : }
1516 18095 : labels->Add(label, zone());
1517 : // Remove the "ghost" variable that turned out to be a label
1518 : // from the top scope. This way, we don't try to resolve it
1519 : // during the scope processing.
1520 18095 : scope()->RemoveUnresolved(var);
1521 18095 : return labels;
1522 : }
1523 :
1524 12551 : bool Parser::ContainsLabel(ZoneList<const AstRawString*>* labels,
1525 : const AstRawString* label) {
1526 : DCHECK_NOT_NULL(label);
1527 75547 : if (labels != nullptr) {
1528 13770 : for (int i = labels->length(); i-- > 0;) {
1529 12672 : if (labels->at(i) == label) return true;
1530 : }
1531 : }
1532 : return false;
1533 : }
1534 :
1535 : Block* Parser::IgnoreCompletion(Statement* statement) {
1536 461095 : Block* block = factory()->NewBlock(1, true);
1537 461095 : block->statements()->Add(statement, zone());
1538 : return block;
1539 : }
1540 :
1541 2644910 : Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
1542 5289821 : if (IsDerivedConstructor(function_state_->kind())) {
1543 : // For subclass constructors we need to return this in case of undefined;
1544 : // other primitive values trigger an exception in the ConstructStub.
1545 : //
1546 : // return expr;
1547 : //
1548 : // Is rewritten as:
1549 : //
1550 : // return (temp = expr) === undefined ? this : temp;
1551 :
1552 : // temp = expr
1553 407 : Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1554 : Assignment* assign = factory()->NewAssignment(
1555 814 : Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
1556 :
1557 : // temp === undefined
1558 : Expression* is_undefined = factory()->NewCompareOperation(
1559 : Token::EQ_STRICT, assign,
1560 407 : factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
1561 :
1562 : // is_undefined ? this : temp
1563 : return_value =
1564 : factory()->NewConditional(is_undefined, ThisExpression(pos),
1565 814 : factory()->NewVariableProxy(temp), pos);
1566 : }
1567 2644911 : return return_value;
1568 : }
1569 :
1570 612 : Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) {
1571 1224 : Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
1572 612 : DoExpression* expr = factory()->NewDoExpression(body, result, pos);
1573 612 : if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) {
1574 0 : *ok = false;
1575 0 : return nullptr;
1576 : }
1577 : return expr;
1578 : }
1579 :
1580 1840 : Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement,
1581 : Scope* scope) {
1582 : // In order to get the CaseClauses to execute in their own lexical scope,
1583 : // but without requiring downstream code to have special scope handling
1584 : // code for switch statements, desugar into blocks as follows:
1585 : // { // To group the statements--harmless to evaluate Expression in scope
1586 : // .tag_variable = Expression;
1587 : // { // To give CaseClauses a scope
1588 : // switch (.tag_variable) { CaseClause* }
1589 : // }
1590 : // }
1591 : DCHECK_NOT_NULL(scope);
1592 : DCHECK(scope->is_block_scope());
1593 : DCHECK_GE(switch_statement->position(), scope->start_position());
1594 : DCHECK_LT(switch_statement->position(), scope->end_position());
1595 :
1596 4600 : Block* switch_block = factory()->NewBlock(2, false);
1597 :
1598 : Expression* tag = switch_statement->tag();
1599 : Variable* tag_variable =
1600 920 : NewTemporary(ast_value_factory()->dot_switch_tag_string());
1601 : Assignment* tag_assign = factory()->NewAssignment(
1602 920 : Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
1603 1840 : tag->position());
1604 : // Wrap with IgnoreCompletion so the tag isn't returned as the completion
1605 : // value, in case the switch statements don't have a value.
1606 : Statement* tag_statement = IgnoreCompletion(
1607 1840 : factory()->NewExpressionStatement(tag_assign, kNoSourcePosition));
1608 920 : switch_block->statements()->Add(tag_statement, zone());
1609 :
1610 920 : switch_statement->set_tag(factory()->NewVariableProxy(tag_variable));
1611 920 : Block* cases_block = factory()->NewBlock(1, false);
1612 920 : cases_block->statements()->Add(switch_statement, zone());
1613 : cases_block->set_scope(scope);
1614 920 : switch_block->statements()->Add(cases_block, zone());
1615 920 : return switch_block;
1616 : }
1617 :
1618 81707 : void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
1619 81707 : if (catch_info->name == nullptr) {
1620 : DCHECK_NOT_NULL(catch_info->pattern);
1621 92810 : catch_info->name = ast_value_factory()->dot_catch_string();
1622 : }
1623 : Variable* catch_variable =
1624 81707 : catch_info->scope->DeclareLocal(catch_info->name, VAR);
1625 81707 : if (catch_info->pattern != nullptr) {
1626 : DeclarationDescriptor descriptor;
1627 3701 : descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
1628 3701 : descriptor.scope = scope();
1629 3701 : descriptor.mode = LET;
1630 3701 : descriptor.declaration_pos = catch_info->pattern->position();
1631 3701 : descriptor.initialization_pos = catch_info->pattern->position();
1632 :
1633 : // Initializer position for variables declared by the pattern.
1634 : const int initializer_position = position();
1635 :
1636 : DeclarationParsingResult::Declaration decl(
1637 : catch_info->pattern, initializer_position,
1638 7402 : factory()->NewVariableProxy(catch_variable));
1639 :
1640 3701 : catch_info->init_block = factory()->NewBlock(8, true);
1641 : DeclareAndInitializeVariables(catch_info->init_block, &descriptor, &decl,
1642 3701 : &catch_info->bound_names, ok);
1643 : } else {
1644 78006 : catch_info->bound_names.Add(catch_info->name, zone());
1645 : }
1646 81707 : }
1647 :
1648 81424 : void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {
1649 : // Check for `catch(e) { let e; }` and similar errors.
1650 81424 : Scope* inner_block_scope = catch_info.inner_block->scope();
1651 81424 : if (inner_block_scope != nullptr) {
1652 342 : Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith(
1653 1191 : catch_info.bound_names);
1654 1191 : if (decl != nullptr) {
1655 : const AstRawString* name = decl->proxy()->raw_name();
1656 342 : int position = decl->proxy()->position();
1657 : Scanner::Location location =
1658 : position == kNoSourcePosition
1659 : ? Scanner::Location::invalid()
1660 342 : : Scanner::Location(position, position + 1);
1661 : ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
1662 342 : *ok = false;
1663 : }
1664 : }
1665 81424 : }
1666 :
1667 87296 : Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
1668 : const SourceRange& catch_range,
1669 : Block* finally_block,
1670 : const SourceRange& finally_range,
1671 : const CatchInfo& catch_info, int pos) {
1672 : // Simplify the AST nodes by converting:
1673 : // 'try B0 catch B1 finally B2'
1674 : // to:
1675 : // 'try { try B0 catch B1 } finally B2'
1676 :
1677 87296 : if (catch_block != nullptr && finally_block != nullptr) {
1678 : // If we have both, create an inner try/catch.
1679 : DCHECK_NOT_NULL(catch_info.scope);
1680 : TryCatchStatement* statement;
1681 : statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
1682 1408 : catch_block, kNoSourcePosition);
1683 : RecordTryCatchStatementSourceRange(statement, catch_range);
1684 :
1685 704 : try_block = factory()->NewBlock(1, false);
1686 704 : try_block->statements()->Add(statement, zone());
1687 : catch_block = nullptr; // Clear to indicate it's been handled.
1688 : }
1689 :
1690 87296 : if (catch_block != nullptr) {
1691 : DCHECK_NULL(finally_block);
1692 : DCHECK_NOT_NULL(catch_info.scope);
1693 : TryCatchStatement* stmt = factory()->NewTryCatchStatement(
1694 80378 : try_block, catch_info.scope, catch_block, pos);
1695 : RecordTryCatchStatementSourceRange(stmt, catch_range);
1696 80378 : return stmt;
1697 : } else {
1698 : DCHECK_NOT_NULL(finally_block);
1699 : TryFinallyStatement* stmt =
1700 6918 : factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1701 : RecordTryFinallyStatementSourceRange(stmt, finally_range);
1702 6918 : return stmt;
1703 : }
1704 : }
1705 :
1706 21086 : void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind,
1707 : ZoneList<Statement*>* body,
1708 : bool* ok) {
1709 : // For ES6 Generators, we just prepend the initial yield.
1710 21086 : Expression* initial_yield = BuildInitialYield(pos, kind);
1711 21086 : body->Add(factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
1712 42172 : zone());
1713 21086 : ParseStatementList(body, Token::RBRACE, ok);
1714 21086 : }
1715 :
1716 18599 : void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
1717 : int pos, FunctionKind kind, ZoneList<Statement*>* body, bool* ok) {
1718 : // For ES2017 Async Generators, we produce:
1719 : //
1720 : // try {
1721 : // InitialYield;
1722 : // ...body...;
1723 : // return undefined; // See comment below
1724 : // } catch (.catch) {
1725 : // %AsyncGeneratorReject(generator, .catch);
1726 : // } finally {
1727 : // %_GeneratorClose(generator);
1728 : // }
1729 : //
1730 : // - InitialYield yields the actual generator object.
1731 : // - Any return statement inside the body will have its argument wrapped
1732 : // in an iterator result object with a "done" property set to `true`.
1733 : // - If the generator terminates for whatever reason, we must close it.
1734 : // Hence the finally clause.
1735 : // - BytecodeGenerator performs special handling for ReturnStatements in
1736 : // async generator functions, resolving the appropriate Promise with an
1737 : // "done" iterator result object containing a Promise-unwrapped value.
1738 : DCHECK(IsAsyncGeneratorFunction(kind));
1739 :
1740 146269 : Block* try_block = factory()->NewBlock(3, false);
1741 18599 : Expression* initial_yield = BuildInitialYield(pos, kind);
1742 : try_block->statements()->Add(
1743 18599 : factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
1744 18599 : zone());
1745 18599 : ParseStatementList(try_block->statements(), Token::RBRACE, ok);
1746 25079 : if (!*ok) return;
1747 :
1748 : // Don't create iterator result for async generators, as the resume methods
1749 : // will create it.
1750 : Statement* final_return = BuildReturnStatement(
1751 12119 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
1752 12119 : try_block->statements()->Add(final_return, zone());
1753 :
1754 : // For AsyncGenerators, a top-level catch block will reject the Promise.
1755 : Scope* catch_scope = NewHiddenCatchScope();
1756 :
1757 : ZoneList<Expression*>* reject_args =
1758 12119 : new (zone()) ZoneList<Expression*>(2, zone());
1759 : reject_args->Add(factory()->NewVariableProxy(
1760 36357 : function_state_->scope()->generator_object_var()),
1761 12119 : zone());
1762 12119 : reject_args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
1763 12119 : zone());
1764 :
1765 : Expression* reject_call = factory()->NewCallRuntime(
1766 12119 : Runtime::kInlineAsyncGeneratorReject, reject_args, kNoSourcePosition);
1767 : Block* catch_block = IgnoreCompletion(
1768 12119 : factory()->NewReturnStatement(reject_call, kNoSourcePosition));
1769 :
1770 : TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
1771 12119 : try_block, catch_scope, catch_block, kNoSourcePosition);
1772 :
1773 12119 : try_block = factory()->NewBlock(1, false);
1774 12119 : try_block->statements()->Add(try_catch, zone());
1775 :
1776 12119 : Block* finally_block = factory()->NewBlock(1, false);
1777 : ZoneList<Expression*>* close_args =
1778 12119 : new (zone()) ZoneList<Expression*>(1, zone());
1779 : VariableProxy* call_proxy = factory()->NewVariableProxy(
1780 24238 : function_state_->scope()->generator_object_var());
1781 12119 : close_args->Add(call_proxy, zone());
1782 : Expression* close_call = factory()->NewCallRuntime(
1783 12119 : Runtime::kInlineGeneratorClose, close_args, kNoSourcePosition);
1784 : finally_block->statements()->Add(
1785 24238 : factory()->NewExpressionStatement(close_call, kNoSourcePosition), zone());
1786 :
1787 : body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
1788 12119 : kNoSourcePosition),
1789 12119 : zone());
1790 : }
1791 :
1792 3170734 : void Parser::CreateFunctionNameAssignment(
1793 : const AstRawString* function_name, int pos,
1794 : FunctionLiteral::FunctionType function_type,
1795 132133 : DeclarationScope* function_scope, ZoneList<Statement*>* result, int index) {
1796 3170734 : if (function_type == FunctionLiteral::kNamedExpression) {
1797 132132 : StatementT statement = factory()->NewEmptyStatement(kNoSourcePosition);
1798 132133 : if (function_scope->LookupLocal(function_name) == nullptr) {
1799 : // Now that we know the language mode, we can create the const assignment
1800 : // in the previously reserved spot.
1801 : DCHECK_EQ(function_scope, scope());
1802 132045 : Variable* fvar = function_scope->DeclareFunctionVar(function_name);
1803 132045 : VariableProxy* fproxy = factory()->NewVariableProxy(fvar);
1804 : statement = factory()->NewExpressionStatement(
1805 : factory()->NewAssignment(Token::INIT, fproxy,
1806 132044 : factory()->NewThisFunction(pos),
1807 132044 : kNoSourcePosition),
1808 132044 : kNoSourcePosition);
1809 : }
1810 : result->Set(index, statement);
1811 : }
1812 3170735 : }
1813 :
1814 : // [if (IteratorType == kNormal)]
1815 : // !%_IsJSReceiver(result = iterator.next()) &&
1816 : // %ThrowIteratorResultNotAnObject(result)
1817 : // [else if (IteratorType == kAsync)]
1818 : // !%_IsJSReceiver(result = Await(iterator.next())) &&
1819 : // %ThrowIteratorResultNotAnObject(result)
1820 : // [endif]
1821 194967 : Expression* Parser::BuildIteratorNextResult(Expression* iterator,
1822 : Variable* result, IteratorType type,
1823 : int pos) {
1824 : Expression* next_literal = factory()->NewStringLiteral(
1825 1364769 : ast_value_factory()->next_string(), kNoSourcePosition);
1826 : Expression* next_property =
1827 194967 : factory()->NewProperty(iterator, next_literal, kNoSourcePosition);
1828 : ZoneList<Expression*>* next_arguments =
1829 194967 : new (zone()) ZoneList<Expression*>(0, zone());
1830 : Expression* next_call =
1831 194967 : factory()->NewCall(next_property, next_arguments, kNoSourcePosition);
1832 194967 : if (type == IteratorType::kAsync) {
1833 20865 : next_call = factory()->NewAwait(next_call, pos);
1834 : }
1835 194967 : Expression* result_proxy = factory()->NewVariableProxy(result);
1836 : Expression* left =
1837 194967 : factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
1838 :
1839 : // %_IsJSReceiver(...)
1840 : ZoneList<Expression*>* is_spec_object_args =
1841 194967 : new (zone()) ZoneList<Expression*>(1, zone());
1842 194967 : is_spec_object_args->Add(left, zone());
1843 : Expression* is_spec_object_call = factory()->NewCallRuntime(
1844 194967 : Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
1845 :
1846 : // %ThrowIteratorResultNotAnObject(result)
1847 389934 : Expression* result_proxy_again = factory()->NewVariableProxy(result);
1848 : ZoneList<Expression*>* throw_arguments =
1849 194967 : new (zone()) ZoneList<Expression*>(1, zone());
1850 194967 : throw_arguments->Add(result_proxy_again, zone());
1851 : Expression* throw_call = factory()->NewCallRuntime(
1852 194967 : Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
1853 :
1854 : return factory()->NewBinaryOperation(
1855 : Token::AND,
1856 194967 : factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
1857 389934 : throw_call, pos);
1858 : }
1859 :
1860 127315 : Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
1861 : Expression* each,
1862 : Expression* subject,
1863 : Statement* body) {
1864 127315 : ForOfStatement* for_of = stmt->AsForOfStatement();
1865 127315 : if (for_of != nullptr) {
1866 : const bool finalize = true;
1867 : return InitializeForOfStatement(for_of, each, subject, body, finalize,
1868 79573 : IteratorType::kNormal, each->position());
1869 : } else {
1870 93004 : if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
1871 16875 : Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1872 5625 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
1873 : Expression* assign_each =
1874 : RewriteDestructuringAssignment(factory()->NewAssignment(
1875 5625 : Token::ASSIGN, each, temp_proxy, kNoSourcePosition));
1876 5625 : auto block = factory()->NewBlock(2, false);
1877 : block->statements()->Add(
1878 5625 : factory()->NewExpressionStatement(assign_each, kNoSourcePosition),
1879 5625 : zone());
1880 5625 : block->statements()->Add(body, zone());
1881 5625 : body = block;
1882 5625 : each = factory()->NewVariableProxy(temp);
1883 : }
1884 : MarkExpressionAsAssigned(each);
1885 47742 : stmt->AsForInStatement()->Initialize(each, subject, body);
1886 : }
1887 47742 : return stmt;
1888 : }
1889 :
1890 : // Special case for legacy for
1891 : //
1892 : // for (var x = initializer in enumerable) body
1893 : //
1894 : // An initialization block of the form
1895 : //
1896 : // {
1897 : // x = initializer;
1898 : // }
1899 : //
1900 : // is returned in this case. It has reserved space for two statements,
1901 : // so that (later on during parsing), the equivalent of
1902 : //
1903 : // for (x in enumerable) body
1904 : //
1905 : // is added as a second statement to it.
1906 80308 : Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
1907 : const DeclarationParsingResult::Declaration& decl =
1908 80308 : for_info.parsing_result.declarations[0];
1909 191863 : if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
1910 110078 : decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
1911 212 : ++use_counts_[v8::Isolate::kForInInitializer];
1912 212 : const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
1913 212 : VariableProxy* single_var = NewUnresolved(name);
1914 212 : Block* init_block = factory()->NewBlock(2, true);
1915 : init_block->statements()->Add(
1916 : factory()->NewExpressionStatement(
1917 : factory()->NewAssignment(Token::ASSIGN, single_var,
1918 212 : decl.initializer, kNoSourcePosition),
1919 212 : kNoSourcePosition),
1920 212 : zone());
1921 212 : return init_block;
1922 : }
1923 : return nullptr;
1924 : }
1925 :
1926 : // Rewrite a for-in/of statement of the form
1927 : //
1928 : // for (let/const/var x in/of e) b
1929 : //
1930 : // into
1931 : //
1932 : // {
1933 : // var temp;
1934 : // for (temp in/of e) {
1935 : // let/const/var x = temp;
1936 : // b;
1937 : // }
1938 : // let x; // for TDZ
1939 : // }
1940 93749 : void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
1941 : Block** body_block,
1942 : Expression** each_variable,
1943 : bool* ok) {
1944 : DCHECK_EQ(1, for_info->parsing_result.declarations.size());
1945 : DeclarationParsingResult::Declaration& decl =
1946 93749 : for_info->parsing_result.declarations[0];
1947 297553 : Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
1948 93749 : auto each_initialization_block = factory()->NewBlock(1, true);
1949 : {
1950 93749 : auto descriptor = for_info->parsing_result.descriptor;
1951 93749 : descriptor.declaration_pos = kNoSourcePosition;
1952 93749 : descriptor.initialization_pos = kNoSourcePosition;
1953 93749 : descriptor.scope = scope();
1954 187498 : decl.initializer = factory()->NewVariableProxy(temp);
1955 :
1956 : bool is_for_var_of =
1957 164068 : for_info->mode == ForEachStatement::ITERATE &&
1958 70319 : for_info->parsing_result.descriptor.mode == VariableMode::VAR;
1959 : bool collect_names =
1960 93749 : IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
1961 : is_for_var_of;
1962 :
1963 : DeclareAndInitializeVariables(
1964 : each_initialization_block, &descriptor, &decl,
1965 93866 : collect_names ? &for_info->bound_names : nullptr, CHECK_OK_VOID);
1966 :
1967 : // Annex B.3.5 prohibits the form
1968 : // `try {} catch(e) { for (var e of {}); }`
1969 : // So if we are parsing a statement like `for (var ... of ...)`
1970 : // we need to walk up the scope chain and look for catch scopes
1971 : // which have a simple binding, then compare their binding against
1972 : // all of the names declared in the init of the for-of we're
1973 : // parsing.
1974 93749 : if (is_for_var_of) {
1975 19945 : Scope* catch_scope = scope();
1976 67801 : while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) {
1977 10031 : if (catch_scope->is_catch_scope()) {
1978 432 : auto name = catch_scope->catch_variable()->raw_name();
1979 : // If it's a simple binding and the name is declared in the for loop.
1980 1089 : if (name != ast_value_factory()->dot_catch_string() &&
1981 225 : for_info->bound_names.Contains(name)) {
1982 : ReportMessageAt(for_info->parsing_result.bindings_loc,
1983 : MessageTemplate::kVarRedeclaration, name);
1984 117 : *ok = false;
1985 : return;
1986 : }
1987 : }
1988 : catch_scope = catch_scope->outer_scope();
1989 : }
1990 : }
1991 : }
1992 :
1993 93632 : *body_block = factory()->NewBlock(3, false);
1994 93632 : (*body_block)->statements()->Add(each_initialization_block, zone());
1995 187264 : *each_variable = factory()->NewVariableProxy(temp, for_info->position);
1996 : }
1997 :
1998 : // Create a TDZ for any lexically-bound names in for in/of statements.
1999 93632 : Block* Parser::CreateForEachStatementTDZ(Block* init_block,
2000 : const ForInfo& for_info, bool* ok) {
2001 93632 : if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
2002 : DCHECK_NULL(init_block);
2003 :
2004 128071 : init_block = factory()->NewBlock(1, false);
2005 :
2006 256142 : for (int i = 0; i < for_info.bound_names.length(); ++i) {
2007 : // TODO(adamk): This needs to be some sort of special
2008 : // INTERNAL variable that's invisible to the debugger
2009 : // but visible to everything else.
2010 263071 : Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET,
2011 135000 : kNoSourcePosition, CHECK_OK);
2012 67500 : tdz_decl->proxy()->var()->set_initializer_position(position());
2013 : }
2014 : }
2015 93632 : return init_block;
2016 : }
2017 :
2018 103232 : Statement* Parser::InitializeForOfStatement(
2019 : ForOfStatement* for_of, Expression* each, Expression* iterable,
2020 : Statement* body, bool finalize, IteratorType type, int next_result_pos) {
2021 : // Create the auxiliary expressions needed for iterating over the iterable,
2022 : // and initialize the given ForOfStatement with them.
2023 : // If finalize is true, also instrument the loop with code that performs the
2024 : // proper ES6 iterator finalization. In that case, the result is not
2025 : // immediately a ForOfStatement.
2026 : const int nopos = kNoSourcePosition;
2027 817474 : auto avfactory = ast_value_factory();
2028 :
2029 : Variable* iterator = NewTemporary(avfactory->dot_iterator_string());
2030 : Variable* result = NewTemporary(avfactory->dot_result_string());
2031 : Variable* completion = NewTemporary(avfactory->empty_string());
2032 :
2033 : // iterator = GetIterator(iterable, type)
2034 : Expression* assign_iterator;
2035 : {
2036 : assign_iterator = factory()->NewAssignment(
2037 103232 : Token::ASSIGN, factory()->NewVariableProxy(iterator),
2038 103232 : factory()->NewGetIterator(iterable, type, iterable->position()),
2039 206464 : iterable->position());
2040 : }
2041 :
2042 : // [if (IteratorType == kNormal)]
2043 : // !%_IsJSReceiver(result = iterator.next()) &&
2044 : // %ThrowIteratorResultNotAnObject(result)
2045 : // [else if (IteratorType == kAsync)]
2046 : // !%_IsJSReceiver(result = Await(iterator.next())) &&
2047 : // %ThrowIteratorResultNotAnObject(result)
2048 : // [endif]
2049 : Expression* next_result;
2050 : {
2051 103232 : Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2052 : next_result =
2053 103232 : BuildIteratorNextResult(iterator_proxy, result, type, next_result_pos);
2054 : }
2055 :
2056 : // result.done
2057 : Expression* result_done;
2058 : {
2059 : Expression* done_literal = factory()->NewStringLiteral(
2060 206464 : ast_value_factory()->done_string(), kNoSourcePosition);
2061 103232 : Expression* result_proxy = factory()->NewVariableProxy(result);
2062 : result_done =
2063 103232 : factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition);
2064 : }
2065 :
2066 : // result.value
2067 : Expression* result_value;
2068 : {
2069 : Expression* value_literal =
2070 103232 : factory()->NewStringLiteral(avfactory->value_string(), nopos);
2071 103232 : Expression* result_proxy = factory()->NewVariableProxy(result);
2072 103232 : result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
2073 : }
2074 :
2075 : // {{tmp = #result_value, completion = kAbruptCompletion, tmp}}
2076 : // Expression* result_value (gets overwritten)
2077 103232 : if (finalize) {
2078 : Variable* tmp = NewTemporary(avfactory->empty_string());
2079 : Expression* save_result = factory()->NewAssignment(
2080 200876 : Token::ASSIGN, factory()->NewVariableProxy(tmp), result_value, nopos);
2081 :
2082 : Expression* set_completion_abrupt = factory()->NewAssignment(
2083 100438 : Token::ASSIGN, factory()->NewVariableProxy(completion),
2084 200876 : factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
2085 :
2086 : result_value = factory()->NewBinaryOperation(Token::COMMA, save_result,
2087 100438 : set_completion_abrupt, nopos);
2088 : result_value = factory()->NewBinaryOperation(
2089 200876 : Token::COMMA, result_value, factory()->NewVariableProxy(tmp), nopos);
2090 : }
2091 :
2092 : // each = #result_value;
2093 : Expression* assign_each;
2094 : {
2095 : assign_each =
2096 103232 : factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
2097 202716 : if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
2098 22498 : assign_each = RewriteDestructuringAssignment(assign_each->AsAssignment());
2099 : }
2100 : }
2101 :
2102 : // {{completion = kNormalCompletion;}}
2103 : Statement* set_completion_normal;
2104 103232 : if (finalize) {
2105 100438 : Expression* proxy = factory()->NewVariableProxy(completion);
2106 : Expression* assignment = factory()->NewAssignment(
2107 : Token::ASSIGN, proxy,
2108 100438 : factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
2109 :
2110 : set_completion_normal =
2111 200876 : IgnoreCompletion(factory()->NewExpressionStatement(assignment, nopos));
2112 : }
2113 :
2114 : // { #loop-body; #set_completion_normal }
2115 : // Statement* body (gets overwritten)
2116 103232 : if (finalize) {
2117 100438 : Block* block = factory()->NewBlock(2, false);
2118 100438 : block->statements()->Add(body, zone());
2119 100438 : block->statements()->Add(set_completion_normal, zone());
2120 100438 : body = block;
2121 : }
2122 :
2123 : for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
2124 103232 : assign_each);
2125 : return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos)
2126 103232 : : for_of;
2127 : }
2128 :
2129 17391 : Statement* Parser::DesugarLexicalBindingsInForStatement(
2130 : ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2131 : Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) {
2132 : // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
2133 : // copied into a new environment. Moreover, the "next" statement must be
2134 : // evaluated not in the environment of the just completed iteration but in
2135 : // that of the upcoming one. We achieve this with the following desugaring.
2136 : // Extra care is needed to preserve the completion value of the original loop.
2137 : //
2138 : // We are given a for statement of the form
2139 : //
2140 : // labels: for (let/const x = i; cond; next) body
2141 : //
2142 : // and rewrite it as follows. Here we write {{ ... }} for init-blocks, ie.,
2143 : // blocks whose ignore_completion_value_ flag is set.
2144 : //
2145 : // {
2146 : // let/const x = i;
2147 : // temp_x = x;
2148 : // first = 1;
2149 : // undefined;
2150 : // outer: for (;;) {
2151 : // let/const x = temp_x;
2152 : // {{ if (first == 1) {
2153 : // first = 0;
2154 : // } else {
2155 : // next;
2156 : // }
2157 : // flag = 1;
2158 : // if (!cond) break;
2159 : // }}
2160 : // labels: for (; flag == 1; flag = 0, temp_x = x) {
2161 : // body
2162 : // }
2163 : // {{ if (flag == 1) // Body used break.
2164 : // break;
2165 : // }}
2166 : // }
2167 : // }
2168 :
2169 : DCHECK_GT(for_info.bound_names.length(), 0);
2170 505515 : ZoneList<Variable*> temps(for_info.bound_names.length(), zone());
2171 :
2172 : Block* outer_block =
2173 17391 : factory()->NewBlock(for_info.bound_names.length() + 4, false);
2174 :
2175 : // Add statement: let/const x = i.
2176 17391 : outer_block->statements()->Add(init, zone());
2177 :
2178 17391 : const AstRawString* temp_name = ast_value_factory()->dot_for_string();
2179 :
2180 : // For each lexical variable x:
2181 : // make statement: temp_x = x.
2182 81616 : for (int i = 0; i < for_info.bound_names.length(); i++) {
2183 23417 : VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
2184 23417 : Variable* temp = NewTemporary(temp_name);
2185 23417 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2186 : Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
2187 23417 : proxy, kNoSourcePosition);
2188 : Statement* assignment_statement =
2189 46834 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2190 23417 : outer_block->statements()->Add(assignment_statement, zone());
2191 23417 : temps.Add(temp, zone());
2192 : }
2193 :
2194 : Variable* first = nullptr;
2195 : // Make statement: first = 1.
2196 17391 : if (next) {
2197 : first = NewTemporary(temp_name);
2198 2440 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2199 2440 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2200 : Assignment* assignment = factory()->NewAssignment(
2201 2440 : Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
2202 : Statement* assignment_statement =
2203 4880 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2204 2440 : outer_block->statements()->Add(assignment_statement, zone());
2205 : }
2206 :
2207 : // make statement: undefined;
2208 : outer_block->statements()->Add(
2209 : factory()->NewExpressionStatement(
2210 17391 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2211 17391 : zone());
2212 :
2213 : // Make statement: outer: for (;;)
2214 : // Note that we don't actually create the label, or set this loop up as an
2215 : // explicit break target, instead handing it directly to those nodes that
2216 : // need to know about it. This should be safe because we don't run any code
2217 : // in this function that looks up break targets.
2218 : ForStatement* outer_loop =
2219 17391 : factory()->NewForStatement(nullptr, kNoSourcePosition);
2220 17391 : outer_block->statements()->Add(outer_loop, zone());
2221 : outer_block->set_scope(scope());
2222 :
2223 17391 : Block* inner_block = factory()->NewBlock(3, false);
2224 : {
2225 17391 : BlockState block_state(&scope_, inner_scope);
2226 :
2227 : Block* ignore_completion_block =
2228 17391 : factory()->NewBlock(for_info.bound_names.length() + 3, true);
2229 17391 : ZoneList<Variable*> inner_vars(for_info.bound_names.length(), zone());
2230 : // For each let variable x:
2231 : // make statement: let/const x = temp_x.
2232 81616 : for (int i = 0; i < for_info.bound_names.length(); i++) {
2233 70251 : Declaration* decl = DeclareVariable(
2234 : for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
2235 70251 : kNoSourcePosition, CHECK_OK);
2236 23417 : inner_vars.Add(decl->proxy()->var(), zone());
2237 23417 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2238 : Assignment* assignment = factory()->NewAssignment(
2239 23417 : Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition);
2240 : Statement* assignment_statement =
2241 46834 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2242 23417 : int declaration_pos = for_info.parsing_result.descriptor.declaration_pos;
2243 : DCHECK_NE(declaration_pos, kNoSourcePosition);
2244 23417 : decl->proxy()->var()->set_initializer_position(declaration_pos);
2245 23417 : ignore_completion_block->statements()->Add(assignment_statement, zone());
2246 : }
2247 :
2248 : // Make statement: if (first == 1) { first = 0; } else { next; }
2249 17391 : if (next) {
2250 : DCHECK(first);
2251 : Expression* compare = nullptr;
2252 : // Make compare expression: first == 1.
2253 : {
2254 2440 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2255 2440 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2256 : compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
2257 2440 : kNoSourcePosition);
2258 : }
2259 : Statement* clear_first = nullptr;
2260 : // Make statement: first = 0.
2261 : {
2262 2440 : VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2263 2440 : Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2264 : Assignment* assignment = factory()->NewAssignment(
2265 2440 : Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
2266 : clear_first =
2267 2440 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2268 : }
2269 : Statement* clear_first_or_next = factory()->NewIfStatement(
2270 4880 : compare, clear_first, next, kNoSourcePosition);
2271 2440 : ignore_completion_block->statements()->Add(clear_first_or_next, zone());
2272 : }
2273 :
2274 : Variable* flag = NewTemporary(temp_name);
2275 : // Make statement: flag = 1.
2276 : {
2277 17391 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2278 17391 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2279 : Assignment* assignment = factory()->NewAssignment(
2280 17391 : Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2281 : Statement* assignment_statement =
2282 34782 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2283 17391 : ignore_completion_block->statements()->Add(assignment_statement, zone());
2284 : }
2285 :
2286 : // Make statement: if (!cond) break.
2287 17391 : if (cond) {
2288 : Statement* stop =
2289 11626 : factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2290 11626 : Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition);
2291 : ignore_completion_block->statements()->Add(
2292 11626 : factory()->NewIfStatement(cond, noop, stop, cond->position()),
2293 11626 : zone());
2294 : }
2295 :
2296 17391 : inner_block->statements()->Add(ignore_completion_block, zone());
2297 : // Make cond expression for main loop: flag == 1.
2298 : Expression* flag_cond = nullptr;
2299 : {
2300 17391 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2301 17391 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2302 : flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2303 17391 : kNoSourcePosition);
2304 : }
2305 :
2306 : // Create chain of expressions "flag = 0, temp_x = x, ..."
2307 : Statement* compound_next_statement = nullptr;
2308 : {
2309 : Expression* compound_next = nullptr;
2310 : // Make expression: flag = 0.
2311 : {
2312 17391 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2313 17391 : Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2314 : compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
2315 17391 : const0, kNoSourcePosition);
2316 : }
2317 :
2318 : // Make the comma-separated list of temp_x = x assignments.
2319 : int inner_var_proxy_pos = scanner()->location().beg_pos;
2320 81616 : for (int i = 0; i < for_info.bound_names.length(); i++) {
2321 23417 : VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2322 : VariableProxy* proxy =
2323 23417 : factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
2324 : Assignment* assignment = factory()->NewAssignment(
2325 23417 : Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2326 : compound_next = factory()->NewBinaryOperation(
2327 23417 : Token::COMMA, compound_next, assignment, kNoSourcePosition);
2328 : }
2329 :
2330 : compound_next_statement =
2331 17391 : factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2332 : }
2333 :
2334 : // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
2335 : // Note that we re-use the original loop node, which retains its labels
2336 : // and ensures that any break or continue statements in body point to
2337 : // the right place.
2338 : loop->Initialize(nullptr, flag_cond, compound_next_statement, body);
2339 17391 : inner_block->statements()->Add(loop, zone());
2340 :
2341 : // Make statement: {{if (flag == 1) break;}}
2342 : {
2343 : Expression* compare = nullptr;
2344 : // Make compare expresion: flag == 1.
2345 : {
2346 17391 : Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2347 17391 : VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2348 : compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2349 17391 : kNoSourcePosition);
2350 : }
2351 : Statement* stop =
2352 17391 : factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2353 17391 : Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition);
2354 : Statement* if_flag_break =
2355 17391 : factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
2356 17391 : inner_block->statements()->Add(IgnoreCompletion(if_flag_break), zone());
2357 : }
2358 :
2359 : inner_block->set_scope(inner_scope);
2360 : }
2361 :
2362 : outer_loop->Initialize(nullptr, nullptr, nullptr, inner_block);
2363 :
2364 17391 : return outer_block;
2365 : }
2366 :
2367 222641 : void Parser::AddArrowFunctionFormalParameters(
2368 : ParserFormalParameters* parameters, Expression* expr, int end_pos,
2369 : bool* ok) {
2370 : // ArrowFunctionFormals ::
2371 : // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
2372 : // Tail
2373 : // NonTailArrowFunctionFormals ::
2374 : // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
2375 : // VariableProxy
2376 : // Tail ::
2377 : // VariableProxy
2378 : // Spread(VariableProxy)
2379 : //
2380 : // As we need to visit the parameters in left-to-right order, we recurse on
2381 : // the left-hand side of comma expressions.
2382 : //
2383 222641 : if (expr->IsBinaryOperation()) {
2384 54386 : BinaryOperation* binop = expr->AsBinaryOperation();
2385 : // The classifier has already run, so we know that the expression is a valid
2386 : // arrow function formals production.
2387 : DCHECK_EQ(binop->op(), Token::COMMA);
2388 : Expression* left = binop->left();
2389 : Expression* right = binop->right();
2390 27193 : int comma_pos = binop->position();
2391 : AddArrowFunctionFormalParameters(parameters, left, comma_pos,
2392 249834 : CHECK_OK_VOID);
2393 : // LHS of comma expression should be unparenthesized.
2394 : expr = right;
2395 : }
2396 :
2397 : // Only the right-most expression may be a rest parameter.
2398 : DCHECK(!parameters->has_rest);
2399 :
2400 : bool is_rest = expr->IsSpread();
2401 222401 : if (is_rest) {
2402 4370 : expr = expr->AsSpread()->expression();
2403 2185 : parameters->has_rest = true;
2404 : }
2405 : DCHECK_IMPLIES(parameters->is_simple, !is_rest);
2406 : DCHECK_IMPLIES(parameters->is_simple, expr->IsVariableProxy());
2407 :
2408 : Expression* initializer = nullptr;
2409 222401 : if (expr->IsAssignment()) {
2410 5584 : if (expr->IsRewritableExpression()) {
2411 : // This expression was parsed as a possible destructuring assignment.
2412 : // Mark it as already-rewritten to avoid an unnecessary visit later.
2413 1812 : expr->AsRewritableExpression()->set_rewritten();
2414 : }
2415 11168 : Assignment* assignment = expr->AsAssignment();
2416 : DCHECK(!assignment->IsCompoundAssignment());
2417 : initializer = assignment->value();
2418 : expr = assignment->target();
2419 : }
2420 :
2421 : AddFormalParameter(parameters, expr, initializer,
2422 : end_pos, is_rest);
2423 : }
2424 :
2425 465758 : void Parser::DeclareArrowFunctionFormalParameters(
2426 : ParserFormalParameters* parameters, Expression* expr,
2427 : const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
2428 : bool* ok) {
2429 738388 : if (expr->IsEmptyParentheses()) return;
2430 :
2431 : AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
2432 195448 : CHECK_OK_VOID);
2433 :
2434 193128 : if (parameters->arity > Code::kMaxArguments) {
2435 : ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
2436 0 : *ok = false;
2437 0 : return;
2438 : }
2439 :
2440 193128 : bool has_duplicate = false;
2441 : DeclareFormalParameters(parameters->scope, parameters->params,
2442 193128 : parameters->is_simple, &has_duplicate);
2443 193128 : if (has_duplicate) {
2444 48 : *duplicate_loc = scanner()->location();
2445 : }
2446 : DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
2447 : }
2448 :
2449 101636 : void Parser::PrepareGeneratorVariables() {
2450 : // The code produced for generators relies on forced context allocation of
2451 : // parameters (it does not restore the frame's parameters upon resume).
2452 203272 : function_state_->scope()->ForceContextAllocationForParameters();
2453 :
2454 : // Calling a generator returns a generator object. That object is stored
2455 : // in a temporary variable, a definition that is used by "yield"
2456 : // expressions.
2457 : function_state_->scope()->DeclareGeneratorObjectVar(
2458 304908 : ast_value_factory()->dot_generator_object_string());
2459 101636 : }
2460 :
2461 5234302 : FunctionLiteral* Parser::ParseFunctionLiteral(
2462 : const AstRawString* function_name, Scanner::Location function_name_location,
2463 : FunctionNameValidity function_name_validity, FunctionKind kind,
2464 : int function_token_pos, FunctionLiteral::FunctionType function_type,
2465 5234304 : LanguageMode language_mode, bool* ok) {
2466 : // Function ::
2467 : // '(' FormalParameterList? ')' '{' FunctionBody '}'
2468 : //
2469 : // Getter ::
2470 : // '(' ')' '{' FunctionBody '}'
2471 : //
2472 : // Setter ::
2473 : // '(' PropertySetParameterList ')' '{' FunctionBody '}'
2474 :
2475 20586131 : int pos = function_token_pos == kNoSourcePosition ? peek_position()
2476 5234302 : : function_token_pos;
2477 :
2478 : // Anonymous functions were passed either the empty symbol or a null
2479 : // handle as the function name. Remember if we were passed a non-empty
2480 : // handle to decide whether to invoke function name inference.
2481 5234302 : bool should_infer_name = function_name == nullptr;
2482 :
2483 : // We want a non-null handle as the function name by default. We will handle
2484 : // the "function does not have a shared name" case later.
2485 5234302 : if (should_infer_name) {
2486 2224749 : function_name = ast_value_factory()->empty_string();
2487 : }
2488 :
2489 : FunctionLiteral::EagerCompileHint eager_compile_hint =
2490 5234302 : function_state_->next_function_is_likely_called()
2491 : ? FunctionLiteral::kShouldEagerCompile
2492 5234302 : : default_eager_compile_hint();
2493 :
2494 : // Determine if the function can be parsed lazily. Lazy parsing is
2495 : // different from lazy compilation; we need to parse more eagerly than we
2496 : // compile.
2497 :
2498 : // We can only parse lazily if we also compile lazily. The heuristics for lazy
2499 : // compilation are:
2500 : // - It must not have been prohibited by the caller to Parse (some callers
2501 : // need a full AST).
2502 : // - The outer scope must allow lazy compilation of inner functions.
2503 : // - The function mustn't be a function expression with an open parenthesis
2504 : // before; we consider that a hint that the function will be called
2505 : // immediately, and it would be a waste of time to make it lazily
2506 : // compiled.
2507 : // These are all things we can know at this point, without looking at the
2508 : // function itself.
2509 :
2510 : // We separate between lazy parsing top level functions and lazy parsing inner
2511 : // functions, because the latter needs to do more work. In particular, we need
2512 : // to track unresolved variables to distinguish between these cases:
2513 : // (function foo() {
2514 : // bar = function() { return 1; }
2515 : // })();
2516 : // and
2517 : // (function foo() {
2518 : // var a = 1;
2519 : // bar = function() { return a; }
2520 : // })();
2521 :
2522 : // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
2523 : // parenthesis before the function means that it will be called
2524 : // immediately). bar can be parsed lazily, but we need to parse it in a mode
2525 : // that tracks unresolved variables.
2526 : DCHECK_IMPLIES(parse_lazily(), FLAG_lazy);
2527 : DCHECK_IMPLIES(parse_lazily(), allow_lazy_);
2528 : DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
2529 :
2530 : const bool is_lazy =
2531 5234302 : eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2532 : const bool is_top_level =
2533 : impl()->AllowsLazyParsingWithoutUnresolvedVariables();
2534 5234303 : const bool is_lazy_top_level_function = is_lazy && is_top_level;
2535 5234303 : const bool is_lazy_inner_function = is_lazy && !is_top_level;
2536 : const bool is_expression =
2537 : function_type == FunctionLiteral::kAnonymousExpression ||
2538 : function_type == FunctionLiteral::kNamedExpression;
2539 :
2540 : RuntimeCallTimerScope runtime_timer(
2541 : runtime_call_stats_,
2542 : parsing_on_main_thread_
2543 : ? &RuntimeCallStats::ParseFunctionLiteral
2544 5234303 : : &RuntimeCallStats::ParseBackgroundFunctionLiteral);
2545 :
2546 : // Determine whether we can still lazy parse the inner function.
2547 : // The preconditions are:
2548 : // - Lazy compilation has to be enabled.
2549 : // - Neither V8 natives nor native function declarations can be allowed,
2550 : // since parsing one would retroactively force the function to be
2551 : // eagerly compiled.
2552 : // - The invoker of this parser can't depend on the AST being eagerly
2553 : // built (either because the function is about to be compiled, or
2554 : // because the AST is going to be inspected for some reason).
2555 : // - Because of the above, we can't be attempting to parse a
2556 : // FunctionExpression; even without enclosing parentheses it might be
2557 : // immediately invoked.
2558 : // - The function literal shouldn't be hinted to eagerly compile.
2559 :
2560 : // Inner functions will be parsed using a temporary Zone. After parsing, we
2561 : // will migrate unresolved variable into a Scope in the main Zone.
2562 :
2563 : const bool should_preparse_inner =
2564 5234304 : parse_lazily() && FLAG_lazy_inner_functions && is_lazy_inner_function &&
2565 827568 : (!is_expression || FLAG_aggressive_lazy_inner_functions);
2566 :
2567 : // This may be modified later to reflect preparsing decision taken
2568 : bool should_preparse =
2569 5234304 : (parse_lazily() && is_lazy_top_level_function) || should_preparse_inner;
2570 :
2571 : ZoneList<Statement*>* body = nullptr;
2572 5234304 : int expected_property_count = -1;
2573 5234304 : int num_parameters = -1;
2574 5234304 : int function_length = -1;
2575 5234304 : bool has_duplicate_parameters = false;
2576 : int function_literal_id = GetNextFunctionLiteralId();
2577 5234304 : ProducedPreParsedScopeData* produced_preparsed_scope_data = nullptr;
2578 :
2579 : Zone* outer_zone = zone();
2580 : DeclarationScope* scope;
2581 :
2582 : {
2583 : // Temporary zones can nest. When we migrate free variables (see below), we
2584 : // need to recreate them in the previous Zone.
2585 : AstNodeFactory previous_zone_ast_node_factory(ast_value_factory(), zone());
2586 :
2587 : // Open a new zone scope, which sets our AstNodeFactory to allocate in the
2588 : // new temporary zone if the preconditions are satisfied, and ensures that
2589 : // the previous zone is always restored after parsing the body. To be able
2590 : // to do scope analysis correctly after full parsing, we migrate needed
2591 : // information when the function is parsed.
2592 5234304 : Zone temp_zone(zone()->allocator(), ZONE_NAME);
2593 5234306 : DiscardableZoneScope zone_scope(this, &temp_zone, should_preparse);
2594 :
2595 : // This Scope lives in the main zone. We'll migrate data into that zone
2596 : // later.
2597 5234307 : scope = NewFunctionScope(kind, outer_zone);
2598 5234307 : SetLanguageMode(scope, language_mode);
2599 : #ifdef DEBUG
2600 : scope->SetScopeName(function_name);
2601 : if (should_preparse) scope->set_needs_migration();
2602 : #endif
2603 :
2604 5234307 : Expect(Token::LPAREN, CHECK_OK);
2605 2671075 : scope->set_start_position(scanner()->location().beg_pos);
2606 :
2607 : // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
2608 : // lazily. We'll call SkipFunction, which may decide to
2609 : // abort lazy parsing if it suspects that wasn't a good idea. If so (in
2610 : // which case the parser is expected to have backtracked), or if we didn't
2611 : // try to lazy parse in the first place, we'll have to parse eagerly.
2612 5231682 : if (should_preparse) {
2613 : DCHECK(parse_lazily());
2614 : DCHECK(is_lazy_top_level_function || is_lazy_inner_function);
2615 : Scanner::BookmarkScope bookmark(scanner());
2616 2245807 : bookmark.Set();
2617 : LazyParsingResult result = SkipFunction(
2618 : function_name, kind, function_type, scope, &num_parameters,
2619 : &produced_preparsed_scope_data, is_lazy_inner_function,
2620 2245807 : is_lazy_top_level_function, CHECK_OK);
2621 :
2622 2197162 : if (result == kLazyParsingAborted) {
2623 : DCHECK(is_lazy_top_level_function);
2624 49 : bookmark.Apply();
2625 : // This is probably an initialization function. Inform the compiler it
2626 : // should also eager-compile this function.
2627 : eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
2628 49 : scope->ResetAfterPreparsing(ast_value_factory(), true);
2629 49 : zone_scope.Reset();
2630 : // Trigger eager (re-)parsing, just below this block.
2631 : should_preparse = false;
2632 : }
2633 : }
2634 :
2635 5183037 : if (should_preparse) {
2636 2197113 : scope->AnalyzePartially(&previous_zone_ast_node_factory);
2637 : } else {
2638 : body = ParseFunction(function_name, pos, kind, function_type, scope,
2639 : &num_parameters, &function_length,
2640 : &has_duplicate_parameters, &expected_property_count,
2641 2985924 : CHECK_OK);
2642 : }
2643 :
2644 : DCHECK_EQ(should_preparse, temp_zoned_);
2645 5109814 : if (V8_UNLIKELY(FLAG_trace_preparse)) {
2646 : PrintF(" [%s]: %i-%i %.*s\n",
2647 : should_preparse ? (is_top_level ? "Preparse no-resolution"
2648 : : "Preparse resolution")
2649 : : "Full parse",
2650 : scope->start_position(), scope->end_position(),
2651 0 : function_name->byte_length(), function_name->raw_data());
2652 : }
2653 5109814 : if (V8_UNLIKELY(FLAG_runtime_stats)) {
2654 0 : if (should_preparse) {
2655 : RuntimeCallStats::CounterId counter_id =
2656 : parsing_on_main_thread_
2657 : ? &RuntimeCallStats::PreParseWithVariableResolution
2658 0 : : &RuntimeCallStats::PreParseBackgroundWithVariableResolution;
2659 0 : if (is_top_level) {
2660 : counter_id =
2661 : parsing_on_main_thread_
2662 : ? &RuntimeCallStats::PreParseNoVariableResolution
2663 0 : : &RuntimeCallStats::PreParseBackgroundNoVariableResolution;
2664 : }
2665 : RuntimeCallStats::CorrectCurrentCounterId(runtime_call_stats_,
2666 0 : counter_id);
2667 : }
2668 : }
2669 :
2670 : // Validate function name. We can do this only after parsing the function,
2671 : // since the function can declare itself strict.
2672 : language_mode = scope->language_mode();
2673 : CheckFunctionName(language_mode, function_name, function_name_validity,
2674 5109814 : function_name_location, CHECK_OK);
2675 :
2676 5108599 : if (is_strict(language_mode)) {
2677 : CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
2678 2671075 : CHECK_OK);
2679 : }
2680 10208982 : CheckConflictingVarDeclarations(scope, CHECK_OK);
2681 : } // DiscardableZoneScope goes out of scope.
2682 :
2683 : FunctionLiteral::ParameterFlag duplicate_parameters =
2684 : has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2685 5100419 : : FunctionLiteral::kNoDuplicateParameters;
2686 :
2687 : // Note that the FunctionLiteral needs to be created in the main Zone again.
2688 : FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2689 : function_name, scope, body, expected_property_count, num_parameters,
2690 : function_length, duplicate_parameters, function_type, eager_compile_hint,
2691 5100419 : pos, true, function_literal_id, produced_preparsed_scope_data);
2692 : function_literal->set_function_token_position(function_token_pos);
2693 :
2694 5100420 : if (should_infer_name) {
2695 : DCHECK_NOT_NULL(fni_);
2696 2183192 : fni_->AddFunction(function_literal);
2697 : }
2698 5100421 : return function_literal;
2699 : }
2700 :
2701 2269784 : Parser::LazyParsingResult Parser::SkipFunction(
2702 : const AstRawString* function_name, FunctionKind kind,
2703 : FunctionLiteral::FunctionType function_type,
2704 : DeclarationScope* function_scope, int* num_parameters,
2705 : ProducedPreParsedScopeData** produced_preparsed_scope_data,
2706 2879794 : bool is_inner_function, bool may_abort, bool* ok) {
2707 2269784 : FunctionState function_state(&function_state_, &scope_, function_scope);
2708 :
2709 : DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2710 : DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
2711 2269784 : if (produce_cached_parse_data()) CHECK(log_);
2712 :
2713 : DCHECK_IMPLIES(IsArrowFunction(kind),
2714 : scanner()->current_token() == Token::ARROW);
2715 :
2716 : // Inner functions are not part of the cached data.
2717 2269889 : if (!is_inner_function && consume_cached_parse_data() &&
2718 110 : !cached_parse_data_->rejected()) {
2719 : // If we have cached data, we use it to skip parsing the function. The data
2720 : // contains the information we need to construct the lazy function.
2721 : FunctionEntry entry =
2722 2254511 : cached_parse_data_->GetFunctionEntry(function_scope->start_position());
2723 : // Check that cached data is valid. If not, mark it as invalid (the embedder
2724 : // handles it). Note that end position greater than end of stream is safe,
2725 : // and hard to check.
2726 205 : if (entry.is_valid() &&
2727 : entry.end_pos() > function_scope->start_position()) {
2728 35536 : total_preparse_skipped_ += entry.end_pos() - position();
2729 : function_scope->set_end_position(entry.end_pos());
2730 200 : scanner()->SeekForward(entry.end_pos() - 1);
2731 200 : Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2732 100 : *num_parameters = entry.num_parameters();
2733 100 : SetLanguageMode(function_scope, entry.language_mode());
2734 100 : if (entry.uses_super_property())
2735 : function_scope->RecordSuperPropertyUsage();
2736 : SkipFunctionLiterals(entry.num_inner_functions());
2737 100 : return kLazyParsingComplete;
2738 : }
2739 5 : cached_parse_data_->Reject();
2740 : }
2741 :
2742 : // FIXME(marja): There are 3 ways to skip functions now. Unify them.
2743 : DCHECK_NOT_NULL(consumed_preparsed_scope_data_);
2744 4539368 : if (consumed_preparsed_scope_data_->HasData()) {
2745 : DCHECK(FLAG_preparser_scope_analysis);
2746 : int end_position;
2747 : LanguageMode language_mode;
2748 : int num_inner_functions;
2749 : bool uses_super_property;
2750 : *produced_preparsed_scope_data =
2751 : consumed_preparsed_scope_data_->GetDataForSkippableFunction(
2752 : main_zone(), function_scope->start_position(), &end_position,
2753 : num_parameters, &num_inner_functions, &uses_super_property,
2754 35336 : &language_mode);
2755 :
2756 : function_scope->outer_scope()->SetMustUsePreParsedScopeData();
2757 : function_scope->set_is_skipped_function(true);
2758 35336 : function_scope->set_end_position(end_position);
2759 70672 : scanner()->SeekForward(end_position - 1);
2760 35336 : Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2761 35336 : SetLanguageMode(function_scope, language_mode);
2762 35336 : if (uses_super_property) {
2763 : function_scope->RecordSuperPropertyUsage();
2764 : }
2765 35336 : SkipFunctionLiterals(num_inner_functions);
2766 35336 : return kLazyParsingComplete;
2767 : }
2768 :
2769 : // With no cached data, we partially parse the function, without building an
2770 : // AST. This gathers the data needed to build a lazy function.
2771 6703044 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
2772 :
2773 : // Aborting inner function preparsing would leave scopes in an inconsistent
2774 : // state; we don't parse inner functions in the abortable mode anyway.
2775 : DCHECK(!is_inner_function || !may_abort);
2776 :
2777 : PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
2778 : function_name, kind, function_type, function_scope, parsing_module_,
2779 2234348 : is_inner_function, may_abort, use_counts_, produced_preparsed_scope_data);
2780 :
2781 : // Return immediately if pre-parser decided to abort parsing.
2782 2234348 : if (result == PreParser::kPreParseAbort) return kLazyParsingAborted;
2783 2234299 : if (result == PreParser::kPreParseStackOverflow) {
2784 : // Propagate stack overflow.
2785 : set_stack_overflow();
2786 25 : *ok = false;
2787 25 : return kLazyParsingComplete;
2788 : }
2789 2234274 : if (pending_error_handler_.has_pending_error()) {
2790 50810 : *ok = false;
2791 50810 : return kLazyParsingComplete;
2792 : }
2793 6550562 : PreParserLogger* logger = reusable_preparser()->logger();
2794 : function_scope->set_end_position(logger->end());
2795 2183464 : Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2796 : total_preparse_skipped_ +=
2797 2183464 : function_scope->end_position() - function_scope->start_position();
2798 2183464 : *num_parameters = logger->num_parameters();
2799 : SkipFunctionLiterals(logger->num_inner_functions());
2800 2793474 : if (!is_inner_function && produce_cached_parse_data()) {
2801 : DCHECK(log_);
2802 : log_->LogFunction(function_scope->start_position(),
2803 : function_scope->end_position(), *num_parameters,
2804 170 : language_mode(), function_scope->NeedsHomeObject(),
2805 510 : logger->num_inner_functions());
2806 : }
2807 : return kLazyParsingComplete;
2808 : }
2809 :
2810 102057 : Statement* Parser::BuildAssertIsCoercible(Variable* var,
2811 102057 : ObjectLiteral* pattern) {
2812 : // if (var === null || var === undefined)
2813 : // throw /* type error kNonCoercible) */;
2814 102057 : auto source_position = pattern->position();
2815 102057 : const AstRawString* property = ast_value_factory()->empty_string();
2816 : MessageTemplate::Template msg = MessageTemplate::kNonCoercible;
2817 220075 : for (ObjectLiteralProperty* literal_property : *pattern->properties()) {
2818 100830 : Expression* key = literal_property->key();
2819 100830 : if (key->IsPropertyName()) {
2820 169738 : property = key->AsLiteral()->AsRawPropertyName();
2821 : msg = MessageTemplate::kNonCoercibleWithProperty;
2822 : source_position = key->position();
2823 84869 : break;
2824 : }
2825 : }
2826 :
2827 : Expression* condition = factory()->NewBinaryOperation(
2828 : Token::OR,
2829 : factory()->NewCompareOperation(
2830 102057 : Token::EQ_STRICT, factory()->NewVariableProxy(var),
2831 204114 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2832 : factory()->NewCompareOperation(
2833 102057 : Token::EQ_STRICT, factory()->NewVariableProxy(var),
2834 204114 : factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition),
2835 102057 : kNoSourcePosition);
2836 : Expression* throw_type_error =
2837 : NewThrowTypeError(msg, property, source_position);
2838 : IfStatement* if_statement = factory()->NewIfStatement(
2839 : condition,
2840 102057 : factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition),
2841 204114 : factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
2842 102057 : return if_statement;
2843 : }
2844 :
2845 : class InitializerRewriter final
2846 : : public AstTraversalVisitor<InitializerRewriter> {
2847 : public:
2848 : InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser)
2849 16056 : : AstTraversalVisitor(stack_limit, root), parser_(parser) {}
2850 :
2851 : private:
2852 : // This is required so that the overriden Visit* methods can be
2853 : // called by the base class (template).
2854 : friend class AstTraversalVisitor<InitializerRewriter>;
2855 :
2856 : // Just rewrite destructuring assignments wrapped in RewritableExpressions.
2857 186 : void VisitRewritableExpression(RewritableExpression* to_rewrite) {
2858 372 : if (to_rewrite->is_rewritten()) return;
2859 154 : parser_->RewriteDestructuringAssignment(to_rewrite);
2860 : AstTraversalVisitor::VisitRewritableExpression(to_rewrite);
2861 : }
2862 :
2863 : // Code in function literals does not need to be eagerly rewritten, it will be
2864 : // rewritten when scheduled.
2865 : void VisitFunctionLiteral(FunctionLiteral* expr) {}
2866 :
2867 : Parser* parser_;
2868 : };
2869 :
2870 16056 : void Parser::RewriteParameterInitializer(Expression* expr) {
2871 16056 : InitializerRewriter rewriter(stack_limit_, expr, this);
2872 : rewriter.Run();
2873 16056 : }
2874 :
2875 :
2876 30029 : Block* Parser::BuildParameterInitializationBlock(
2877 : const ParserFormalParameters& parameters, bool* ok) {
2878 : DCHECK(!parameters.is_simple);
2879 : DCHECK(scope()->is_function_scope());
2880 : DCHECK_EQ(scope(), parameters.scope);
2881 167022 : Block* init_block = factory()->NewBlock(1, true);
2882 : int index = 0;
2883 110282 : for (auto parameter : parameters.params) {
2884 : DeclarationDescriptor descriptor;
2885 51122 : descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
2886 51122 : descriptor.scope = scope();
2887 51122 : descriptor.mode = LET;
2888 102244 : descriptor.declaration_pos = parameter->pattern->position();
2889 : // The position that will be used by the AssignmentExpression
2890 : // which copies from the temp parameter to the pattern.
2891 : //
2892 : // TODO(adamk): Should this be kNoSourcePosition, since
2893 : // it's just copying from a temp var to the real param var?
2894 102244 : descriptor.initialization_pos = parameter->pattern->position();
2895 : Expression* initial_value =
2896 102244 : factory()->NewVariableProxy(parameters.scope->parameter(index));
2897 51122 : if (parameter->initializer != nullptr) {
2898 : // IS_UNDEFINED($param) ? initializer : $param
2899 :
2900 : // Ensure initializer is rewritten
2901 16056 : RewriteParameterInitializer(parameter->initializer);
2902 :
2903 : auto condition = factory()->NewCompareOperation(
2904 : Token::EQ_STRICT,
2905 32112 : factory()->NewVariableProxy(parameters.scope->parameter(index)),
2906 32112 : factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2907 : initial_value = factory()->NewConditional(
2908 16056 : condition, parameter->initializer, initial_value, kNoSourcePosition);
2909 16056 : descriptor.initialization_pos = parameter->initializer->position();
2910 : }
2911 :
2912 : Scope* param_scope = scope();
2913 : Block* param_block = init_block;
2914 83251 : if (!parameter->is_simple() &&
2915 32129 : scope()->AsDeclarationScope()->calls_sloppy_eval()) {
2916 1310 : param_scope = NewVarblockScope();
2917 1310 : param_scope->set_start_position(descriptor.initialization_pos);
2918 1310 : param_scope->set_end_position(parameter->initializer_end_position);
2919 : param_scope->RecordEvalCall();
2920 1310 : param_block = factory()->NewBlock(8, true);
2921 : param_block->set_scope(param_scope);
2922 : // Pass the appropriate scope in so that PatternRewriter can appropriately
2923 : // rewrite inner initializers of the pattern to param_scope
2924 1310 : descriptor.scope = param_scope;
2925 : // Rewrite the outer initializer to point to param_scope
2926 1310 : ReparentExpressionScope(stack_limit(), initial_value, param_scope);
2927 : }
2928 :
2929 51122 : BlockState block_state(&scope_, param_scope);
2930 : DeclarationParsingResult::Declaration decl(
2931 51122 : parameter->pattern, parameter->initializer_end_position, initial_value);
2932 : DeclareAndInitializeVariables(param_block, &descriptor, &decl, nullptr,
2933 51122 : CHECK_OK);
2934 :
2935 50224 : if (param_block != init_block) {
2936 1310 : param_scope = param_scope->FinalizeBlockScope();
2937 1310 : if (param_scope != nullptr) {
2938 1310 : CheckConflictingVarDeclarations(param_scope, CHECK_OK);
2939 : }
2940 1310 : init_block->statements()->Add(param_block, zone());
2941 : }
2942 50224 : ++index;
2943 : }
2944 : return init_block;
2945 : }
2946 :
2947 : Scope* Parser::NewHiddenCatchScope() {
2948 373667 : Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
2949 373667 : catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR);
2950 373667 : catch_scope->set_is_hidden();
2951 : return catch_scope;
2952 : }
2953 :
2954 30112 : Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
2955 : // .promise = %AsyncFunctionPromiseCreate();
2956 : // try {
2957 : // <inner_block>
2958 : // } catch (.catch) {
2959 : // %RejectPromise(.promise, .catch);
2960 : // return .promise;
2961 : // } finally {
2962 : // %AsyncFunctionPromiseRelease(.promise);
2963 : // }
2964 150560 : Block* result = factory()->NewBlock(2, true);
2965 :
2966 : // .promise = %AsyncFunctionPromiseCreate();
2967 : Statement* set_promise;
2968 : {
2969 : Expression* create_promise = factory()->NewCallRuntime(
2970 : Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX,
2971 30112 : new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition);
2972 : Assignment* assign_promise = factory()->NewAssignment(
2973 30112 : Token::ASSIGN, factory()->NewVariableProxy(PromiseVariable()),
2974 30112 : create_promise, kNoSourcePosition);
2975 : set_promise =
2976 60224 : factory()->NewExpressionStatement(assign_promise, kNoSourcePosition);
2977 : }
2978 30112 : result->statements()->Add(set_promise, zone());
2979 :
2980 : // catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
2981 : Scope* catch_scope = NewHiddenCatchScope();
2982 :
2983 : Expression* promise_reject = BuildRejectPromise(
2984 30112 : factory()->NewVariableProxy(catch_scope->catch_variable()),
2985 30112 : kNoSourcePosition);
2986 : Block* catch_block = IgnoreCompletion(
2987 30112 : factory()->NewReturnStatement(promise_reject, kNoSourcePosition));
2988 :
2989 : TryStatement* try_catch_statement =
2990 : factory()->NewTryCatchStatementForAsyncAwait(
2991 30112 : inner_block, catch_scope, catch_block, kNoSourcePosition);
2992 :
2993 : // There is no TryCatchFinally node, so wrap it in an outer try/finally
2994 : Block* outer_try_block = IgnoreCompletion(try_catch_statement);
2995 :
2996 : // finally { %AsyncFunctionPromiseRelease(.promise) }
2997 : Block* finally_block;
2998 : {
2999 30112 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
3000 60224 : args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3001 : Expression* call_promise_release = factory()->NewCallRuntime(
3002 30112 : Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition);
3003 : Statement* promise_release = factory()->NewExpressionStatement(
3004 30112 : call_promise_release, kNoSourcePosition);
3005 : finally_block = IgnoreCompletion(promise_release);
3006 : }
3007 :
3008 : Statement* try_finally_statement = factory()->NewTryFinallyStatement(
3009 60224 : outer_try_block, finally_block, kNoSourcePosition);
3010 :
3011 30112 : result->statements()->Add(try_finally_statement, zone());
3012 30112 : return result;
3013 : }
3014 :
3015 28512 : Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
3016 : // %ResolvePromise(.promise, value), .promise
3017 85536 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3018 57024 : args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3019 28512 : args->Add(value, zone());
3020 : Expression* call_runtime =
3021 28512 : factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, pos);
3022 : return factory()->NewBinaryOperation(
3023 : Token::COMMA, call_runtime,
3024 85536 : factory()->NewVariableProxy(PromiseVariable()), pos);
3025 : }
3026 :
3027 30112 : Expression* Parser::BuildRejectPromise(Expression* value, int pos) {
3028 : // %promise_internal_reject(.promise, value, false), .promise
3029 : // Disables the additional debug event for the rejection since a debug event
3030 : // already happened for the exception that got us here.
3031 120448 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(3, zone());
3032 60224 : args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3033 30112 : args->Add(value, zone());
3034 30112 : args->Add(factory()->NewBooleanLiteral(false, pos), zone());
3035 : Expression* call_runtime = factory()->NewCallRuntime(
3036 30112 : Context::PROMISE_INTERNAL_REJECT_INDEX, args, pos);
3037 : return factory()->NewBinaryOperation(
3038 : Token::COMMA, call_runtime,
3039 90336 : factory()->NewVariableProxy(PromiseVariable()), pos);
3040 : }
3041 :
3042 177472 : Variable* Parser::PromiseVariable() {
3043 : // Based on the various compilation paths, there are many different code
3044 : // paths which may be the first to access the Promise temporary. Whichever
3045 : // comes first should create it and stash it in the FunctionState.
3046 205984 : Variable* promise = function_state_->scope()->promise_var();
3047 177472 : if (promise == nullptr) {
3048 : promise = function_state_->scope()->DeclarePromiseVar(
3049 85536 : ast_value_factory()->empty_string());
3050 : }
3051 177472 : return promise;
3052 : }
3053 :
3054 66131 : Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
3055 : Expression* yield_result = factory()->NewVariableProxy(
3056 198393 : function_state_->scope()->generator_object_var());
3057 : // The position of the yield is important for reporting the exception
3058 : // caused by calling the .throw method on a generator suspended at the
3059 : // initial yield (i.e. right after generator instantiation).
3060 : return factory()->NewYield(yield_result, scope()->start_position(),
3061 66131 : Suspend::kOnExceptionThrow);
3062 : }
3063 :
3064 2985924 : ZoneList<Statement*>* Parser::ParseFunction(
3065 : const AstRawString* function_name, int pos, FunctionKind kind,
3066 : FunctionLiteral::FunctionType function_type,
3067 : DeclarationScope* function_scope, int* num_parameters, int* function_length,
3068 : bool* has_duplicate_parameters, int* expected_property_count, bool* ok) {
3069 2985924 : ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
3070 :
3071 2985924 : FunctionState function_state(&function_state_, &scope_, function_scope);
3072 :
3073 : DuplicateFinder duplicate_finder;
3074 11844675 : ExpressionClassifier formals_classifier(this, &duplicate_finder);
3075 :
3076 2985924 : int expected_parameters_end_pos = parameters_end_pos_;
3077 2985924 : if (expected_parameters_end_pos != kNoSourcePosition) {
3078 : // This is the first function encountered in a CreateDynamicFunction eval.
3079 2217 : parameters_end_pos_ = kNoSourcePosition;
3080 : // The function name should have been ignored, giving us the empty string
3081 : // here.
3082 : DCHECK_EQ(function_name, ast_value_factory()->empty_string());
3083 : }
3084 :
3085 : ParserFormalParameters formals(function_scope);
3086 2985924 : ParseFormalParameterList(&formals, CHECK_OK);
3087 2973183 : if (expected_parameters_end_pos != kNoSourcePosition) {
3088 : // Check for '(' or ')' shenanigans in the parameter string for dynamic
3089 : // functions.
3090 : int position = peek_position();
3091 2004 : if (position < expected_parameters_end_pos) {
3092 : ReportMessageAt(Scanner::Location(position, position + 1),
3093 10 : MessageTemplate::kArgStringTerminatesParametersEarly);
3094 10 : *ok = false;
3095 10 : return nullptr;
3096 1994 : } else if (position > expected_parameters_end_pos) {
3097 : ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
3098 : expected_parameters_end_pos),
3099 0 : MessageTemplate::kUnexpectedEndOfArgString);
3100 0 : *ok = false;
3101 0 : return nullptr;
3102 : }
3103 : }
3104 2973173 : Expect(Token::RPAREN, CHECK_OK);
3105 : int formals_end_position = scanner()->location().end_pos;
3106 5945004 : *num_parameters = formals.num_parameters();
3107 2972502 : *function_length = formals.function_length;
3108 :
3109 : CheckArityRestrictions(formals.arity, kind, formals.has_rest,
3110 : function_scope->start_position(), formals_end_position,
3111 2972502 : CHECK_OK);
3112 2972041 : Expect(Token::LBRACE, CHECK_OK);
3113 :
3114 2971544 : ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(8, zone());
3115 2971543 : ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ok);
3116 :
3117 : // Validate parameter names. We can do this only after parsing the function,
3118 : // since the function can declare itself strict.
3119 : const bool allow_duplicate_parameters =
3120 3882009 : is_sloppy(function_scope->language_mode()) && formals.is_simple &&
3121 : !IsConciseMethod(kind);
3122 : ValidateFormalParameters(function_scope->language_mode(),
3123 5943088 : allow_duplicate_parameters, CHECK_OK);
3124 :
3125 : RewriteDestructuringAssignments();
3126 :
3127 : *has_duplicate_parameters =
3128 2912701 : !classifier()->is_valid_formal_parameter_list_without_duplicates();
3129 :
3130 2912701 : *expected_property_count = function_state.expected_property_count();
3131 2912701 : return body;
3132 : }
3133 :
3134 : void Parser::DeclareClassVariable(const AstRawString* name,
3135 : ClassInfo* class_info, int class_token_pos,
3136 : bool* ok) {
3137 : #ifdef DEBUG
3138 : scope()->SetScopeName(name);
3139 : #endif
3140 :
3141 125580 : if (name != nullptr) {
3142 102482 : VariableProxy* proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3143 : Declaration* declaration =
3144 102482 : factory()->NewVariableDeclaration(proxy, class_token_pos);
3145 : class_info->variable =
3146 : Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
3147 102482 : Variable::DefaultInitializationFlag(CONST), ok);
3148 : }
3149 : }
3150 :
3151 : // This method declares a property of the given class. It updates the
3152 : // following fields of class_info, as appropriate:
3153 : // - constructor
3154 : // - properties
3155 : void Parser::DeclareClassProperty(const AstRawString* class_name,
3156 : ClassLiteralProperty* property,
3157 : ClassLiteralProperty::Kind kind,
3158 : bool is_static, bool is_constructor,
3159 : ClassInfo* class_info, bool* ok) {
3160 472919 : if (is_constructor) {
3161 : DCHECK(!class_info->constructor);
3162 82786 : class_info->constructor = property->value()->AsFunctionLiteral();
3163 : DCHECK_NOT_NULL(class_info->constructor);
3164 : class_info->constructor->set_raw_name(
3165 38928 : class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
3166 80321 : : nullptr);
3167 : return;
3168 : }
3169 :
3170 : if (property->kind() == ClassLiteralProperty::FIELD) {
3171 : DCHECK(allow_harmony_class_fields());
3172 : // TODO(littledan): Implement class fields
3173 : }
3174 431526 : class_info->properties->Add(property, zone());
3175 : }
3176 :
3177 : // This method generates a ClassLiteral AST node.
3178 : // It uses the following fields of class_info:
3179 : // - constructor (if missing, it updates it with a default constructor)
3180 : // - proxy
3181 : // - extends
3182 : // - properties
3183 : // - has_name_static_property
3184 : // - has_static_computed_names
3185 : Expression* Parser::RewriteClassLiteral(Scope* block_scope,
3186 : const AstRawString* name,
3187 : ClassInfo* class_info, int pos,
3188 111783 : int end_pos, bool* ok) {
3189 : DCHECK_NOT_NULL(block_scope);
3190 : DCHECK_EQ(block_scope->scope_type(), BLOCK_SCOPE);
3191 : DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict);
3192 :
3193 111783 : bool has_extends = class_info->extends != nullptr;
3194 111783 : bool has_default_constructor = class_info->constructor == nullptr;
3195 111783 : if (has_default_constructor) {
3196 : class_info->constructor =
3197 70601 : DefaultConstructor(name, has_extends, pos, end_pos);
3198 : }
3199 :
3200 111783 : if (name != nullptr) {
3201 : DCHECK_NOT_NULL(class_info->variable);
3202 92833 : class_info->variable->set_initializer_position(end_pos);
3203 : }
3204 :
3205 : ClassLiteral* class_literal = factory()->NewClassLiteral(
3206 : block_scope, class_info->variable, class_info->extends,
3207 : class_info->constructor, class_info->properties, pos, end_pos,
3208 : class_info->has_name_static_property,
3209 111783 : class_info->has_static_computed_names, class_info->is_anonymous);
3210 :
3211 111783 : AddFunctionForNameInference(class_info->constructor);
3212 :
3213 : return class_literal;
3214 : }
3215 :
3216 7087646 : void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
3217 7112072 : Declaration* decl = scope->CheckConflictingVarDeclarations();
3218 7087647 : if (decl != nullptr) {
3219 : // In ES6, conflicting variable bindings are early errors.
3220 : const AstRawString* name = decl->proxy()->raw_name();
3221 24426 : int position = decl->proxy()->position();
3222 : Scanner::Location location =
3223 : position == kNoSourcePosition
3224 : ? Scanner::Location::invalid()
3225 24426 : : Scanner::Location(position, position + 1);
3226 : ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
3227 24426 : *ok = false;
3228 : }
3229 7087647 : }
3230 :
3231 :
3232 8199 : void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
3233 : // For each var-binding that shadows a parameter, insert an assignment
3234 : // initializing the variable with the parameter.
3235 8199 : Scope* inner_scope = inner_block->scope();
3236 : DCHECK(inner_scope->is_declaration_scope());
3237 : Scope* function_scope = inner_scope->outer_scope();
3238 : DCHECK(function_scope->is_function_scope());
3239 8199 : BlockState block_state(&scope_, inner_scope);
3240 55202 : for (Declaration* decl : *inner_scope->declarations()) {
3241 41433 : if (decl->proxy()->var()->mode() != VAR || !decl->IsVariableDeclaration()) {
3242 16161 : continue;
3243 : }
3244 : const AstRawString* name = decl->proxy()->raw_name();
3245 4912 : Variable* parameter = function_scope->LookupLocal(name);
3246 4912 : if (parameter == nullptr) continue;
3247 785 : VariableProxy* to = NewUnresolved(name);
3248 1570 : VariableProxy* from = factory()->NewVariableProxy(parameter);
3249 : Expression* assignment =
3250 785 : factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
3251 : Statement* statement =
3252 1570 : factory()->NewExpressionStatement(assignment, kNoSourcePosition);
3253 785 : inner_block->statements()->InsertAt(0, statement, zone());
3254 : }
3255 8199 : }
3256 :
3257 2289990 : void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
3258 : // For the outermost eval scope, we cannot hoist during parsing: let
3259 : // declarations in the surrounding scope may prevent hoisting, but the
3260 : // information is unaccessible during parsing. In this case, we hoist later in
3261 : // DeclarationScope::Analyze.
3262 2289990 : if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
3263 2289989 : return;
3264 : }
3265 1530163 : scope->HoistSloppyBlockFunctions(factory());
3266 : }
3267 :
3268 : // ----------------------------------------------------------------------------
3269 : // Parser support
3270 :
3271 18095 : bool Parser::TargetStackContainsLabel(const AstRawString* label) {
3272 33289 : for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3273 30388 : if (ContainsLabel(t->statement()->labels(), label)) return true;
3274 : }
3275 : return false;
3276 : }
3277 :
3278 :
3279 67671 : BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
3280 : bool* ok) {
3281 67671 : bool anonymous = label == nullptr;
3282 121843 : for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3283 91867 : BreakableStatement* stat = t->statement();
3284 335009 : if ((anonymous && stat->is_target_for_anonymous()) ||
3285 59408 : (!anonymous && ContainsLabel(stat->labels(), label))) {
3286 : return stat;
3287 : }
3288 : }
3289 : return nullptr;
3290 : }
3291 :
3292 :
3293 37165 : IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
3294 : bool* ok) {
3295 : bool anonymous = label == nullptr;
3296 129859 : for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3297 131944 : IterationStatement* stat = t->statement()->AsIterationStatement();
3298 129654 : if (stat == nullptr) continue;
3299 :
3300 : DCHECK(stat->is_target_for_anonymous());
3301 40365 : if (anonymous || ContainsLabel(stat->labels(), label)) {
3302 : return stat;
3303 : }
3304 : }
3305 : return nullptr;
3306 : }
3307 :
3308 :
3309 1678478 : void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
3310 1678478 : Handle<String> source_url = scanner_.SourceUrl(isolate);
3311 1678478 : if (!source_url.is_null()) {
3312 2680 : script->set_source_url(*source_url);
3313 : }
3314 1678478 : Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
3315 1678478 : if (!source_mapping_url.is_null()) {
3316 100 : script->set_source_mapping_url(*source_mapping_url);
3317 : }
3318 1678478 : }
3319 :
3320 317383 : void Parser::ReportErrors(Isolate* isolate, Handle<Script> script) {
3321 629792 : if (stack_overflow()) {
3322 4974 : isolate->StackOverflow();
3323 : } else {
3324 : DCHECK(pending_error_handler_.has_pending_error());
3325 : // Internalize ast values for throwing the pending error.
3326 312409 : ast_value_factory()->Internalize(isolate);
3327 312409 : pending_error_handler_.ThrowPendingError(isolate, script);
3328 : }
3329 317383 : }
3330 :
3331 2348008 : void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
3332 : // Move statistics to Isolate.
3333 100964057 : for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
3334 : ++feature) {
3335 98616055 : if (use_counts_[feature] > 0) {
3336 2399993 : isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
3337 : }
3338 : }
3339 2348002 : if (scanner_.FoundHtmlComment()) {
3340 11 : isolate->CountUsage(v8::Isolate::kHtmlComment);
3341 22 : if (script->line_offset() == 0 && script->column_offset() == 0) {
3342 11 : isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
3343 : }
3344 : }
3345 : isolate->counters()->total_preparse_skipped()->Increment(
3346 4696004 : total_preparse_skipped_);
3347 2348002 : }
3348 :
3349 443 : void Parser::ParseOnBackground(ParseInfo* info) {
3350 137 : parsing_on_main_thread_ = false;
3351 :
3352 : DCHECK_NULL(info->literal());
3353 : FunctionLiteral* result = nullptr;
3354 :
3355 137 : ParserLogger logger;
3356 137 : if (produce_cached_parse_data()) {
3357 5 : if (allow_lazy_) {
3358 5 : log_ = &logger;
3359 : } else {
3360 0 : compile_options_ = ScriptCompiler::kNoCompileOptions;
3361 : }
3362 : }
3363 :
3364 274 : scanner_.Initialize(info->character_stream(), info->is_module());
3365 : DCHECK(info->maybe_outer_scope_info().is_null());
3366 :
3367 : DCHECK(original_scope_);
3368 :
3369 : // When streaming, we don't know the length of the source until we have parsed
3370 : // it. The raw data can be UTF-8, so we wouldn't know the source length until
3371 : // we have decoded it anyway even if we knew the raw data length (which we
3372 : // don't). We work around this by storing all the scopes which need their end
3373 : // position set at the end of the script (the top scope and possible eval
3374 : // scopes) and set their end position after we know the script length.
3375 137 : if (info->is_toplevel()) {
3376 220 : fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
3377 110 : result = DoParseProgram(info);
3378 : } else {
3379 27 : result = DoParseFunction(info, info->function_name());
3380 : }
3381 137 : MaybeResetCharacterStream(info, result);
3382 :
3383 : info->set_literal(result);
3384 :
3385 : // We cannot internalize on a background thread; a foreground task will take
3386 : // care of calling AstValueFactory::Internalize just before compilation.
3387 :
3388 137 : if (produce_cached_parse_data()) {
3389 10 : if (result != nullptr) *info->cached_data() = logger.GetScriptData();
3390 5 : log_ = nullptr;
3391 : }
3392 137 : if (FLAG_runtime_stats &
3393 : v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) {
3394 0 : auto value = v8::tracing::TracedValue::Create();
3395 0 : runtime_call_stats_->Dump(value.get());
3396 0 : TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("v8.runtime_stats"),
3397 : "V8.RuntimeStats", TRACE_EVENT_SCOPE_THREAD,
3398 : "runtime-call-stats", std::move(value));
3399 : }
3400 137 : }
3401 :
3402 34433 : Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
3403 68866 : return new (zone()) TemplateLiteral(zone(), pos);
3404 : }
3405 :
3406 62557 : void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
3407 : bool tail) {
3408 : DCHECK(should_cook || allow_harmony_template_escapes());
3409 184211 : int pos = scanner()->location().beg_pos;
3410 : int end = scanner()->location().end_pos - (tail ? 1 : 2);
3411 62557 : const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
3412 62557 : Literal* raw = factory()->NewStringLiteral(trv, pos);
3413 62557 : if (should_cook) {
3414 59097 : const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
3415 59097 : Literal* cooked = factory()->NewStringLiteral(tv, pos);
3416 59097 : (*state)->AddTemplateSpan(cooked, raw, end, zone());
3417 : } else {
3418 : (*state)->AddTemplateSpan(factory()->NewUndefinedLiteral(pos), raw, end,
3419 3460 : zone());
3420 : }
3421 62557 : }
3422 :
3423 :
3424 0 : void Parser::AddTemplateExpression(TemplateLiteralState* state,
3425 : Expression* expression) {
3426 36586 : (*state)->AddExpression(expression, zone());
3427 0 : }
3428 :
3429 :
3430 24492 : Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
3431 : Expression* tag) {
3432 24492 : TemplateLiteral* lit = *state;
3433 : int pos = lit->position();
3434 24492 : const ZoneList<Literal*>* cooked_strings = lit->cooked();
3435 24492 : const ZoneList<Literal*>* raw_strings = lit->raw();
3436 51753 : const ZoneList<Expression*>* expressions = lit->expressions();
3437 : DCHECK_EQ(cooked_strings->length(), raw_strings->length());
3438 : DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3439 :
3440 24492 : if (!tag) {
3441 : // Build tree of BinaryOps to simplify code-generation
3442 17674 : Expression* expr = cooked_strings->at(0);
3443 : int i = 0;
3444 62609 : while (i < expressions->length()) {
3445 54522 : Expression* sub = expressions->at(i++);
3446 27261 : Expression* cooked_str = cooked_strings->at(i);
3447 :
3448 : // Let middle be ToString(sub).
3449 : ZoneList<Expression*>* args =
3450 74976 : new (zone()) ZoneList<Expression*>(1, zone());
3451 27261 : args->Add(sub, zone());
3452 : Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString,
3453 54522 : args, sub->position());
3454 :
3455 : expr = factory()->NewBinaryOperation(
3456 : Token::ADD, factory()->NewBinaryOperation(
3457 27261 : Token::ADD, expr, middle, expr->position()),
3458 54522 : cooked_str, sub->position());
3459 : }
3460 : return expr;
3461 : } else {
3462 : // GetTemplateObject
3463 6818 : const int32_t hash = ComputeTemplateLiteralHash(lit);
3464 : Expression* template_object = factory()->NewGetTemplateObject(
3465 : const_cast<ZoneList<Literal*>*>(cooked_strings),
3466 13636 : const_cast<ZoneList<Literal*>*>(raw_strings), hash, pos);
3467 :
3468 : // Call TagFn
3469 : ZoneList<Expression*>* call_args =
3470 13636 : new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
3471 6818 : call_args->Add(template_object, zone());
3472 : call_args->AddAll(*expressions, zone());
3473 6818 : return factory()->NewTaggedTemplate(tag, call_args, pos);
3474 : }
3475 : }
3476 :
3477 : namespace {
3478 :
3479 : // http://burtleburtle.net/bob/hash/integer.html
3480 6818 : uint32_t HalfAvalance(uint32_t a) {
3481 6818 : a = (a + 0x479ab41d) + (a << 8);
3482 6818 : a = (a ^ 0xe4aa10ce) ^ (a >> 5);
3483 6818 : a = (a + 0x9942f0a6) - (a << 14);
3484 6818 : a = (a ^ 0x5aedd67d) ^ (a >> 3);
3485 6818 : a = (a + 0x17bea992) + (a << 7);
3486 6818 : return a;
3487 : }
3488 :
3489 : } // namespace
3490 :
3491 6818 : int32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
3492 6818 : const ZoneList<Literal*>* raw_strings = lit->raw();
3493 : int total = raw_strings->length();
3494 : DCHECK_GT(total, 0);
3495 :
3496 : uint32_t running_hash = 0;
3497 :
3498 18992 : for (int index = 0; index < total; ++index) {
3499 12174 : if (index) {
3500 : running_hash = StringHasher::ComputeRunningHashOneByte(
3501 : running_hash, "${}", 3);
3502 : }
3503 :
3504 12174 : const AstRawString* raw_string =
3505 24348 : raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
3506 12174 : if (raw_string->is_one_byte()) {
3507 : const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
3508 : running_hash = StringHasher::ComputeRunningHashOneByte(
3509 : running_hash, data, raw_string->length());
3510 : } else {
3511 : const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
3512 : running_hash = StringHasher::ComputeRunningHash(running_hash, data,
3513 : raw_string->length());
3514 : }
3515 : }
3516 :
3517 : // Pass {running_hash} throught a decent 'half avalance' hash function
3518 : // and take the most significant bits (in Smi range).
3519 6818 : return static_cast<int32_t>(HalfAvalance(running_hash)) >>
3520 6818 : (sizeof(int32_t) * CHAR_BIT - kSmiValueSize);
3521 : }
3522 :
3523 : namespace {
3524 :
3525 9031 : bool OnlyLastArgIsSpread(ZoneList<Expression*>* args) {
3526 9782 : for (int i = 0; i < args->length() - 1; i++) {
3527 2582 : if (args->at(i)->IsSpread()) {
3528 : return false;
3529 : }
3530 : }
3531 7200 : return args->at(args->length() - 1)->IsSpread();
3532 : }
3533 :
3534 : } // namespace
3535 :
3536 540 : ZoneList<Expression*>* Parser::PrepareSpreadArguments(
3537 540 : ZoneList<Expression*>* list) {
3538 8379 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
3539 540 : if (list->length() == 1) {
3540 : // Spread-call with single spread argument produces an InternalArray
3541 : // containing the values from the array.
3542 : //
3543 : // Function is called or constructed with the produced array of arguments
3544 : //
3545 : // EG: Apply(Func, Spread(spread0))
3546 : ZoneList<Expression*>* spread_list =
3547 0 : new (zone()) ZoneList<Expression*>(0, zone());
3548 0 : spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
3549 : args->Add(factory()->NewCallRuntime(Runtime::kSpreadIterablePrepare,
3550 0 : spread_list, kNoSourcePosition),
3551 0 : zone());
3552 0 : return args;
3553 : } else {
3554 : // Spread-call with multiple arguments produces array literals for each
3555 : // sequences of unspread arguments, and converts each spread iterable to
3556 : // an Internal array. Finally, all of these produced arrays are flattened
3557 : // into a single InternalArray, containing the arguments for the call.
3558 : //
3559 : // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
3560 : // Spread(spread1), [unspread2, unspread3]))
3561 : int i = 0;
3562 : int n = list->length();
3563 1500 : while (i < n) {
3564 2510 : if (!list->at(i)->IsSpread()) {
3565 : ZoneList<Expression*>* unspread =
3566 883 : new (zone()) ZoneList<Expression*>(1, zone());
3567 :
3568 : // Push array of unspread parameters
3569 7661 : while (i < n && !list->at(i)->IsSpread()) {
3570 3146 : unspread->Add(list->at(i++), zone());
3571 : }
3572 883 : args->Add(factory()->NewArrayLiteral(unspread, kNoSourcePosition),
3573 883 : zone());
3574 :
3575 883 : if (i == n) break;
3576 : }
3577 :
3578 : // Push eagerly spread argument
3579 : ZoneList<Expression*>* spread_list =
3580 960 : new (zone()) ZoneList<Expression*>(1, zone());
3581 2880 : spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
3582 : args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
3583 960 : spread_list, kNoSourcePosition),
3584 960 : zone());
3585 : }
3586 :
3587 540 : list = new (zone()) ZoneList<Expression*>(1, zone());
3588 : list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
3589 540 : kNoSourcePosition),
3590 540 : zone());
3591 540 : return list;
3592 : }
3593 : UNREACHABLE();
3594 : }
3595 :
3596 3976 : Expression* Parser::SpreadCall(Expression* function,
3597 : ZoneList<Expression*>* args, int pos,
3598 : Call::PossiblyEval is_possibly_eval) {
3599 : // Handle this case in BytecodeGenerator.
3600 3976 : if (OnlyLastArgIsSpread(args)) {
3601 8064 : return factory()->NewCall(function, args, pos);
3602 : }
3603 :
3604 1068 : if (function->IsSuperCallReference()) {
3605 : // Super calls
3606 : // $super_constructor = %_GetSuperConstructor(<this-function>)
3607 : // %reflect_construct($super_constructor, args, new.target)
3608 :
3609 18 : args = PrepareSpreadArguments(args);
3610 18 : ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
3611 36 : tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
3612 : Expression* super_constructor = factory()->NewCallRuntime(
3613 18 : Runtime::kInlineGetSuperConstructor, tmp, pos);
3614 18 : args->InsertAt(0, super_constructor, zone());
3615 36 : args->Add(function->AsSuperCallReference()->new_target_var(), zone());
3616 : return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
3617 18 : pos);
3618 : } else {
3619 516 : args = PrepareSpreadArguments(args);
3620 1032 : if (function->IsProperty()) {
3621 : // Method calls
3622 152 : if (function->AsProperty()->IsSuperAccess()) {
3623 0 : Expression* home = ThisExpression(kNoSourcePosition);
3624 0 : args->InsertAt(0, function, zone());
3625 0 : args->InsertAt(1, home, zone());
3626 : } else {
3627 76 : Variable* temp = NewTemporary(ast_value_factory()->empty_string());
3628 76 : VariableProxy* obj = factory()->NewVariableProxy(temp);
3629 : Assignment* assign_obj = factory()->NewAssignment(
3630 : Token::ASSIGN, obj, function->AsProperty()->obj(),
3631 152 : kNoSourcePosition);
3632 : function = factory()->NewProperty(
3633 228 : assign_obj, function->AsProperty()->key(), kNoSourcePosition);
3634 76 : args->InsertAt(0, function, zone());
3635 76 : obj = factory()->NewVariableProxy(temp);
3636 76 : args->InsertAt(1, obj, zone());
3637 : }
3638 : } else {
3639 : // Non-method calls
3640 440 : args->InsertAt(0, function, zone());
3641 440 : args->InsertAt(1, factory()->NewUndefinedLiteral(kNoSourcePosition),
3642 440 : zone());
3643 : }
3644 1032 : return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
3645 : }
3646 : }
3647 :
3648 164 : Expression* Parser::SpreadCallNew(Expression* function,
3649 : ZoneList<Expression*>* args, int pos) {
3650 164 : if (OnlyLastArgIsSpread(args)) {
3651 : // Handle in BytecodeGenerator.
3652 322 : return factory()->NewCallNew(function, args, pos);
3653 : }
3654 6 : args = PrepareSpreadArguments(args);
3655 6 : args->InsertAt(0, function, zone());
3656 :
3657 12 : return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
3658 : }
3659 :
3660 :
3661 25773048 : void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
3662 : v8::Isolate::UseCounterFeature feature;
3663 25773048 : if (is_sloppy(mode))
3664 : feature = v8::Isolate::kSloppyMode;
3665 10064807 : else if (is_strict(mode))
3666 : feature = v8::Isolate::kStrictMode;
3667 : else
3668 0 : UNREACHABLE();
3669 25773048 : ++use_counts_[feature];
3670 : scope->SetLanguageMode(mode);
3671 25773048 : }
3672 :
3673 5506 : void Parser::SetAsmModule() {
3674 : // Store the usage count; The actual use counter on the isolate is
3675 : // incremented after parsing is done.
3676 5506 : ++use_counts_[v8::Isolate::kUseAsm];
3677 : DCHECK(scope()->is_declaration_scope());
3678 5506 : scope()->AsDeclarationScope()->set_asm_module();
3679 5506 : }
3680 :
3681 3402 : Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) {
3682 1360 : Expression* expr = args->at(0);
3683 4084 : for (int i = 1; i < args->length(); ++i) {
3684 : expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i),
3685 1364 : expr->position());
3686 : }
3687 1360 : return expr;
3688 : }
3689 :
3690 : // This method completes the desugaring of the body of async_function.
3691 : void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
3692 : Expression* return_value, bool* ok) {
3693 : // function async_function() {
3694 : // .generator_object = %CreateJSGeneratorObject();
3695 : // BuildRejectPromiseOnException({
3696 : // ... block ...
3697 : // return %ResolvePromise(.promise, expr), .promise;
3698 : // })
3699 : // }
3700 :
3701 57024 : return_value = BuildResolvePromise(return_value, return_value->position());
3702 : block->statements()->Add(
3703 28512 : factory()->NewReturnStatement(return_value, return_value->position()),
3704 57024 : zone());
3705 28512 : block = BuildRejectPromiseOnException(block);
3706 28512 : body->Add(block, zone());
3707 : }
3708 :
3709 : class NonPatternRewriter : public AstExpressionRewriter {
3710 : public:
3711 2072 : NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
3712 2072 : : AstExpressionRewriter(stack_limit), parser_(parser) {}
3713 4144 : ~NonPatternRewriter() override {}
3714 :
3715 : private:
3716 9050 : bool RewriteExpression(Expression* expr) override {
3717 9050 : if (expr->IsRewritableExpression()) return true;
3718 : // Rewrite only what could have been a pattern but is not.
3719 6938 : if (expr->IsArrayLiteral()) {
3720 : // Spread rewriting in array literals.
3721 4224 : ArrayLiteral* lit = expr->AsArrayLiteral();
3722 4224 : VisitExpressions(lit->values());
3723 4224 : replacement_ = parser_->RewriteSpreads(lit);
3724 2112 : return false;
3725 : }
3726 4826 : if (expr->IsObjectLiteral()) {
3727 : return true;
3728 : }
3729 4826 : if (expr->IsBinaryOperation() &&
3730 0 : expr->AsBinaryOperation()->op() == Token::COMMA) {
3731 : return true;
3732 : }
3733 : // Everything else does not need rewriting.
3734 4826 : return false;
3735 : }
3736 :
3737 0 : void VisitLiteralProperty(LiteralProperty* property) override {
3738 0 : if (property == nullptr) return;
3739 : // Do not rewrite (computed) key expressions
3740 0 : AST_REWRITE_PROPERTY(Expression, property, value);
3741 : }
3742 :
3743 : Parser* parser_;
3744 : };
3745 :
3746 : void Parser::RewriteNonPattern(bool* ok) {
3747 155882495 : ValidateExpression(CHECK_OK_VOID);
3748 155877676 : auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite();
3749 77938839 : int begin = classifier()->GetNonPatternBegin();
3750 : int end = non_patterns_to_rewrite->length();
3751 77938839 : if (begin < end) {
3752 2072 : NonPatternRewriter rewriter(stack_limit_, this);
3753 2112 : for (int i = begin; i < end; i++) {
3754 : DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression());
3755 2112 : rewriter.Rewrite(non_patterns_to_rewrite->at(i));
3756 : }
3757 2072 : non_patterns_to_rewrite->Rewind(begin);
3758 : }
3759 : }
3760 :
3761 :
3762 : void Parser::RewriteDestructuringAssignments() {
3763 5000836 : const auto& assignments =
3764 5000840 : function_state_->destructuring_assignments_to_rewrite();
3765 5073892 : for (int i = assignments.length() - 1; i >= 0; --i) {
3766 : // Rewrite list in reverse, so that nested assignment patterns are rewritten
3767 : // correctly.
3768 73056 : const DestructuringAssignment& pair = assignments.at(i);
3769 73056 : RewritableExpression* to_rewrite =
3770 73056 : pair.assignment->AsRewritableExpression();
3771 : DCHECK_NOT_NULL(to_rewrite);
3772 73056 : if (!to_rewrite->is_rewritten()) {
3773 : // Since this function is called at the end of parsing the program,
3774 : // pair.scope may already have been removed by FinalizeBlockScope in the
3775 : // meantime.
3776 60758 : Scope* scope = pair.scope->GetUnremovedScope();
3777 60758 : BlockState block_state(&scope_, scope);
3778 60758 : RewriteDestructuringAssignment(to_rewrite);
3779 : }
3780 : }
3781 : }
3782 :
3783 : Expression* Parser::RewriteExponentiation(Expression* left, Expression* right,
3784 : int pos) {
3785 1791 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3786 1791 : args->Add(left, zone());
3787 1791 : args->Add(right, zone());
3788 1791 : return factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
3789 : }
3790 :
3791 : Expression* Parser::RewriteAssignExponentiation(Expression* left,
3792 : Expression* right, int pos) {
3793 145 : ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3794 310 : if (left->IsVariableProxy()) {
3795 125 : VariableProxy* lhs = left->AsVariableProxy();
3796 :
3797 : Expression* result;
3798 : DCHECK_NOT_NULL(lhs->raw_name());
3799 125 : result = ExpressionFromIdentifier(lhs->raw_name(), lhs->position());
3800 125 : args->Add(left, zone());
3801 125 : args->Add(right, zone());
3802 : Expression* call =
3803 125 : factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
3804 125 : return factory()->NewAssignment(Token::ASSIGN, result, call, pos);
3805 40 : } else if (left->IsProperty()) {
3806 60 : Property* prop = left->AsProperty();
3807 20 : auto temp_obj = NewTemporary(ast_value_factory()->empty_string());
3808 20 : auto temp_key = NewTemporary(ast_value_factory()->empty_string());
3809 : Expression* assign_obj = factory()->NewAssignment(
3810 20 : Token::ASSIGN, factory()->NewVariableProxy(temp_obj), prop->obj(),
3811 40 : kNoSourcePosition);
3812 : Expression* assign_key = factory()->NewAssignment(
3813 20 : Token::ASSIGN, factory()->NewVariableProxy(temp_key), prop->key(),
3814 40 : kNoSourcePosition);
3815 20 : args->Add(factory()->NewProperty(factory()->NewVariableProxy(temp_obj),
3816 20 : factory()->NewVariableProxy(temp_key),
3817 60 : left->position()),
3818 40 : zone());
3819 20 : args->Add(right, zone());
3820 : Expression* call =
3821 20 : factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
3822 : Expression* target = factory()->NewProperty(
3823 20 : factory()->NewVariableProxy(temp_obj),
3824 40 : factory()->NewVariableProxy(temp_key), kNoSourcePosition);
3825 : Expression* assign =
3826 20 : factory()->NewAssignment(Token::ASSIGN, target, call, pos);
3827 : return factory()->NewBinaryOperation(
3828 : Token::COMMA, assign_obj,
3829 20 : factory()->NewBinaryOperation(Token::COMMA, assign_key, assign, pos),
3830 20 : pos);
3831 : }
3832 0 : UNREACHABLE();
3833 : }
3834 :
3835 : Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
3836 : // Array literals containing spreads are rewritten using do expressions, e.g.
3837 : // [1, 2, 3, ...x, 4, ...y, 5]
3838 : // is roughly rewritten as:
3839 : // do {
3840 : // $R = [1, 2, 3];
3841 : // for ($i of x) %AppendElement($R, $i);
3842 : // %AppendElement($R, 4);
3843 : // for ($j of y) %AppendElement($R, $j);
3844 : // %AppendElement($R, 5);
3845 : // $R
3846 : // }
3847 : // where $R, $i and $j are fresh temporary variables.
3848 2112 : ZoneList<Expression*>::iterator s = lit->FirstSpread();
3849 2112 : if (s == lit->EndValue()) return nullptr; // no spread, no rewriting...
3850 2112 : Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
3851 : // NOTE: The value assigned to R is the whole original array literal,
3852 : // spreads included. This will be fixed before the rewritten AST is returned.
3853 : // $R = lit
3854 : Expression* init_result = factory()->NewAssignment(
3855 2112 : Token::INIT, factory()->NewVariableProxy(result), lit, kNoSourcePosition);
3856 2112 : Block* do_block = factory()->NewBlock(16, false);
3857 : do_block->statements()->Add(
3858 2112 : factory()->NewExpressionStatement(init_result, kNoSourcePosition),
3859 4224 : zone());
3860 : // Traverse the array literal starting from the first spread.
3861 5770 : while (s != lit->EndValue()) {
3862 3658 : Expression* value = *s++;
3863 6452 : Spread* spread = value->AsSpread();
3864 3658 : if (spread == nullptr) {
3865 : // If the element is not a spread, we're adding a single:
3866 : // %AppendElement($R, value)
3867 : // or, in case of a hole,
3868 : // ++($R.length)
3869 1873 : if (!value->IsLiteral() ||
3870 290 : !value->AsLiteral()->raw_value()->IsTheHole()) {
3871 : ZoneList<Expression*>* append_element_args = NewExpressionList(2);
3872 778 : append_element_args->Add(factory()->NewVariableProxy(result), zone());
3873 778 : append_element_args->Add(value, zone());
3874 : do_block->statements()->Add(
3875 : factory()->NewExpressionStatement(
3876 : factory()->NewCallRuntime(Runtime::kAppendElement,
3877 : append_element_args,
3878 778 : kNoSourcePosition),
3879 778 : kNoSourcePosition),
3880 1556 : zone());
3881 : } else {
3882 : Property* length_property = factory()->NewProperty(
3883 86 : factory()->NewVariableProxy(result),
3884 : factory()->NewStringLiteral(ast_value_factory()->length_string(),
3885 86 : kNoSourcePosition),
3886 86 : kNoSourcePosition);
3887 : CountOperation* count_op = factory()->NewCountOperation(
3888 86 : Token::INC, true /* prefix */, length_property, kNoSourcePosition);
3889 : do_block->statements()->Add(
3890 86 : factory()->NewExpressionStatement(count_op, kNoSourcePosition),
3891 172 : zone());
3892 : }
3893 : } else {
3894 : // If it's a spread, we're adding a for/of loop iterating through it.
3895 2794 : Variable* each = NewTemporary(ast_value_factory()->dot_for_string());
3896 2794 : Expression* subject = spread->expression();
3897 : // %AppendElement($R, each)
3898 : Statement* append_body;
3899 : {
3900 : ZoneList<Expression*>* append_element_args = NewExpressionList(2);
3901 2794 : append_element_args->Add(factory()->NewVariableProxy(result), zone());
3902 2794 : append_element_args->Add(factory()->NewVariableProxy(each), zone());
3903 : append_body = factory()->NewExpressionStatement(
3904 : factory()->NewCallRuntime(Runtime::kAppendElement,
3905 2794 : append_element_args, kNoSourcePosition),
3906 2794 : kNoSourcePosition);
3907 : }
3908 : // for (each of spread) %AppendElement($R, each)
3909 : ForOfStatement* loop =
3910 2794 : factory()->NewForOfStatement(nullptr, kNoSourcePosition);
3911 : const bool finalize = false;
3912 2794 : InitializeForOfStatement(loop, factory()->NewVariableProxy(each), subject,
3913 2794 : append_body, finalize, IteratorType::kNormal);
3914 2794 : do_block->statements()->Add(loop, zone());
3915 : }
3916 : }
3917 : // Now, rewind the original array literal to truncate everything from the
3918 : // first spread (included) until the end. This fixes $R's initialization.
3919 2112 : lit->RewindSpreads();
3920 2112 : return factory()->NewDoExpression(do_block, result, lit->position());
3921 : }
3922 :
3923 : void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) {
3924 : DCHECK(expr->IsRewritableExpression());
3925 : function_state_->AddDestructuringAssignment(
3926 77428 : DestructuringAssignment(expr, scope()));
3927 : }
3928 :
3929 : void Parser::QueueNonPatternForRewriting(Expression* expr, bool* ok) {
3930 : DCHECK(expr->IsRewritableExpression());
3931 15205 : function_state_->AddNonPatternForRewriting(expr, ok);
3932 : }
3933 :
3934 8375730 : void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property,
3935 : const AstRawString* name,
3936 : const AstRawString* prefix) {
3937 : // Ensure that the function we are going to create has shared name iff
3938 : // we are not going to set it later.
3939 4187865 : if (property->NeedsSetFunctionName()) {
3940 : name = nullptr;
3941 : prefix = nullptr;
3942 : } else {
3943 : // If the property value is an anonymous function or an anonymous class or
3944 : // a concise method or an accessor function which doesn't require the name
3945 : // to be set then the shared name must be provided.
3946 : DCHECK_IMPLIES(property->value()->IsAnonymousFunctionDefinition() ||
3947 : property->value()->IsConciseMethodDefinition() ||
3948 : property->value()->IsAccessorFunctionDefinition(),
3949 : name != nullptr);
3950 : }
3951 :
3952 : Expression* value = property->value();
3953 4187865 : SetFunctionName(value, name, prefix);
3954 4187863 : }
3955 :
3956 0 : void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
3957 : const AstRawString* name,
3958 : const AstRawString* prefix) {
3959 : // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
3960 : // of an object literal.
3961 : // See ES #sec-__proto__-property-names-in-object-initializers.
3962 3748579 : if (property->IsPrototype()) return;
3963 :
3964 : DCHECK(!property->value()->IsAnonymousFunctionDefinition() ||
3965 : property->kind() == ObjectLiteralProperty::COMPUTED);
3966 :
3967 : SetFunctionNameFromPropertyName(static_cast<LiteralProperty*>(property), name,
3968 3714946 : prefix);
3969 : }
3970 :
3971 12713486 : void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
3972 : Expression* identifier) {
3973 25426973 : if (!identifier->IsVariableProxy()) return;
3974 17406326 : SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
3975 : }
3976 :
3977 12891203 : void Parser::SetFunctionName(Expression* value, const AstRawString* name,
3978 : const AstRawString* prefix) {
3979 38226103 : if (!value->IsAnonymousFunctionDefinition() &&
3980 24901035 : !value->IsConciseMethodDefinition() &&
3981 12009832 : !value->IsAccessorFunctionDefinition()) {
3982 12891199 : return;
3983 : }
3984 909876 : auto function = value->AsFunctionLiteral();
3985 909876 : if (value->IsClassLiteral()) {
3986 2447 : function = value->AsClassLiteral()->constructor();
3987 : }
3988 909876 : if (function != nullptr) {
3989 : AstConsString* cons_name = nullptr;
3990 909876 : if (name != nullptr) {
3991 899416 : if (prefix != nullptr) {
3992 25038 : cons_name = ast_value_factory()->NewConsString(prefix, name);
3993 : } else {
3994 874378 : cons_name = ast_value_factory()->NewConsString(name);
3995 : }
3996 : } else {
3997 : DCHECK_NULL(prefix);
3998 : }
3999 : function->set_raw_name(cons_name);
4000 : }
4001 : }
4002 :
4003 165718 : Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
4004 : const int nopos = kNoSourcePosition;
4005 : Statement* validate_var;
4006 : {
4007 : Expression* type_of = factory()->NewUnaryOperation(
4008 497154 : Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
4009 : Expression* function_literal = factory()->NewStringLiteral(
4010 331436 : ast_value_factory()->function_string(), nopos);
4011 : Expression* condition = factory()->NewCompareOperation(
4012 165718 : Token::EQ_STRICT, type_of, function_literal, nopos);
4013 :
4014 165718 : Statement* throw_call = factory()->NewExpressionStatement(error, pos);
4015 :
4016 : validate_var = factory()->NewIfStatement(
4017 331436 : condition, factory()->NewEmptyStatement(nopos), throw_call, nopos);
4018 : }
4019 165718 : return validate_var;
4020 : }
4021 :
4022 0 : void Parser::BuildIteratorClose(ZoneList<Statement*>* statements,
4023 : Variable* iterator, Variable* input,
4024 : Variable* var_output, IteratorType type) {
4025 : //
4026 : // This function adds four statements to [statements], corresponding to the
4027 : // following code:
4028 : //
4029 : // let iteratorReturn = iterator.return;
4030 : // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
4031 : // return {value: input, done: true};
4032 : // }
4033 : // output = %_Call(iteratorReturn, iterator, input);
4034 : // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4035 : //
4036 :
4037 : const int nopos = kNoSourcePosition;
4038 :
4039 : // let iteratorReturn = iterator.return;
4040 : Variable* var_return = var_output; // Reusing the output variable.
4041 : Statement* get_return;
4042 : {
4043 0 : Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
4044 : Expression* literal = factory()->NewStringLiteral(
4045 0 : ast_value_factory()->return_string(), nopos);
4046 : Expression* property =
4047 0 : factory()->NewProperty(iterator_proxy, literal, nopos);
4048 0 : Expression* return_proxy = factory()->NewVariableProxy(var_return);
4049 : Expression* assignment =
4050 0 : factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
4051 0 : get_return = factory()->NewExpressionStatement(assignment, nopos);
4052 : }
4053 :
4054 : // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
4055 : // return {value: input, done: true};
4056 : // }
4057 : Statement* check_return;
4058 : {
4059 : Expression* condition = factory()->NewCompareOperation(
4060 0 : Token::EQ, factory()->NewVariableProxy(var_return),
4061 0 : factory()->NewNullLiteral(nopos), nopos);
4062 :
4063 0 : Expression* value = factory()->NewVariableProxy(input);
4064 :
4065 0 : Statement* return_input = BuildReturnStatement(value, nopos);
4066 :
4067 : check_return = factory()->NewIfStatement(
4068 0 : condition, return_input, factory()->NewEmptyStatement(nopos), nopos);
4069 : }
4070 :
4071 : // output = %_Call(iteratorReturn, iterator, input);
4072 : Statement* call_return;
4073 : {
4074 0 : auto args = new (zone()) ZoneList<Expression*>(3, zone());
4075 0 : args->Add(factory()->NewVariableProxy(var_return), zone());
4076 0 : args->Add(factory()->NewVariableProxy(iterator), zone());
4077 0 : args->Add(factory()->NewVariableProxy(input), zone());
4078 :
4079 : Expression* call =
4080 0 : factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4081 0 : if (type == IteratorType::kAsync) {
4082 0 : call = factory()->NewAwait(call, nopos);
4083 : }
4084 0 : Expression* output_proxy = factory()->NewVariableProxy(var_output);
4085 : Expression* assignment =
4086 0 : factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
4087 0 : call_return = factory()->NewExpressionStatement(assignment, nopos);
4088 : }
4089 :
4090 : // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
4091 : Statement* validate_output;
4092 : {
4093 : Expression* is_receiver_call;
4094 : {
4095 0 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4096 0 : args->Add(factory()->NewVariableProxy(var_output), zone());
4097 : is_receiver_call =
4098 0 : factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4099 : }
4100 :
4101 : Statement* throw_call;
4102 : {
4103 0 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4104 0 : args->Add(factory()->NewVariableProxy(var_output), zone());
4105 : Expression* call = factory()->NewCallRuntime(
4106 0 : Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4107 0 : throw_call = factory()->NewExpressionStatement(call, nopos);
4108 : }
4109 :
4110 : validate_output = factory()->NewIfStatement(
4111 0 : is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4112 0 : nopos);
4113 : }
4114 :
4115 0 : statements->Add(get_return, zone());
4116 0 : statements->Add(check_return, zone());
4117 0 : statements->Add(call_return, zone());
4118 0 : statements->Add(validate_output, zone());
4119 0 : }
4120 :
4121 165718 : void Parser::FinalizeIteratorUse(Variable* completion, Expression* condition,
4122 : Variable* iter, Block* iterator_use,
4123 : Block* target, IteratorType type) {
4124 : //
4125 : // This function adds two statements to [target], corresponding to the
4126 : // following code:
4127 : //
4128 : // completion = kNormalCompletion;
4129 : // try {
4130 : // try {
4131 : // iterator_use
4132 : // } catch(e) {
4133 : // if (completion === kAbruptCompletion) completion = kThrowCompletion;
4134 : // %ReThrow(e);
4135 : // }
4136 : // } finally {
4137 : // if (condition) {
4138 : // #BuildIteratorCloseForCompletion(iter, completion)
4139 : // }
4140 : // }
4141 : //
4142 :
4143 : const int nopos = kNoSourcePosition;
4144 :
4145 : // completion = kNormalCompletion;
4146 : Statement* initialize_completion;
4147 : {
4148 1325744 : Expression* proxy = factory()->NewVariableProxy(completion);
4149 : Expression* assignment = factory()->NewAssignment(
4150 : Token::ASSIGN, proxy,
4151 165718 : factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
4152 : initialize_completion =
4153 331436 : factory()->NewExpressionStatement(assignment, nopos);
4154 : }
4155 :
4156 : // if (completion === kAbruptCompletion) completion = kThrowCompletion;
4157 : Statement* set_completion_throw;
4158 : {
4159 : Expression* condition = factory()->NewCompareOperation(
4160 165718 : Token::EQ_STRICT, factory()->NewVariableProxy(completion),
4161 331436 : factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
4162 :
4163 165718 : Expression* proxy = factory()->NewVariableProxy(completion);
4164 : Expression* assignment = factory()->NewAssignment(
4165 : Token::ASSIGN, proxy,
4166 165718 : factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
4167 165718 : Statement* statement = factory()->NewExpressionStatement(assignment, nopos);
4168 : set_completion_throw = factory()->NewIfStatement(
4169 497154 : condition, statement, factory()->NewEmptyStatement(nopos), nopos);
4170 : }
4171 :
4172 : // if (condition) {
4173 : // #BuildIteratorCloseForCompletion(iter, completion)
4174 : // }
4175 : Block* maybe_close;
4176 : {
4177 165718 : Block* block = factory()->NewBlock(2, true);
4178 165718 : Expression* proxy = factory()->NewVariableProxy(completion);
4179 165718 : BuildIteratorCloseForCompletion(block->statements(), iter, proxy, type);
4180 : DCHECK_EQ(block->statements()->length(), 2);
4181 :
4182 : maybe_close = IgnoreCompletion(factory()->NewIfStatement(
4183 331436 : condition, block, factory()->NewEmptyStatement(nopos), nopos));
4184 : }
4185 :
4186 : // try { #try_block }
4187 : // catch(e) {
4188 : // #set_completion_throw;
4189 : // %ReThrow(e);
4190 : // }
4191 : Statement* try_catch;
4192 : {
4193 : Scope* catch_scope = NewHiddenCatchScope();
4194 :
4195 : Statement* rethrow;
4196 : // We use %ReThrow rather than the ordinary throw because we want to
4197 : // preserve the original exception message. This is also why we create a
4198 : // TryCatchStatementForReThrow below (which does not clear the pending
4199 : // message), rather than a TryCatchStatement.
4200 : {
4201 165718 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4202 165718 : args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
4203 165718 : zone());
4204 : rethrow = factory()->NewExpressionStatement(
4205 331436 : factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
4206 : }
4207 :
4208 165718 : Block* catch_block = factory()->NewBlock(2, false);
4209 165718 : catch_block->statements()->Add(set_completion_throw, zone());
4210 165718 : catch_block->statements()->Add(rethrow, zone());
4211 :
4212 : try_catch = factory()->NewTryCatchStatementForReThrow(
4213 331436 : iterator_use, catch_scope, catch_block, nopos);
4214 : }
4215 :
4216 : // try { #try_catch } finally { #maybe_close }
4217 : Statement* try_finally;
4218 : {
4219 165718 : Block* try_block = factory()->NewBlock(1, false);
4220 165718 : try_block->statements()->Add(try_catch, zone());
4221 :
4222 : try_finally =
4223 331436 : factory()->NewTryFinallyStatement(try_block, maybe_close, nopos);
4224 : }
4225 :
4226 165718 : target->statements()->Add(initialize_completion, zone());
4227 165718 : target->statements()->Add(try_finally, zone());
4228 165718 : }
4229 :
4230 165718 : void Parser::BuildIteratorCloseForCompletion(ZoneList<Statement*>* statements,
4231 : Variable* iterator,
4232 : Expression* completion,
4233 : IteratorType type) {
4234 : //
4235 : // This function adds two statements to [statements], corresponding to the
4236 : // following code:
4237 : //
4238 : // let iteratorReturn = iterator.return;
4239 : // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
4240 : // if (completion === kThrowCompletion) {
4241 : // if (!IS_CALLABLE(iteratorReturn)) {
4242 : // throw MakeTypeError(kReturnMethodNotCallable);
4243 : // }
4244 : // [if (IteratorType == kAsync)]
4245 : // try { Await(%_Call(iteratorReturn, iterator) } catch (_) { }
4246 : // [else]
4247 : // try { %_Call(iteratorReturn, iterator) } catch (_) { }
4248 : // [endif]
4249 : // } else {
4250 : // [if (IteratorType == kAsync)]
4251 : // let output = Await(%_Call(iteratorReturn, iterator));
4252 : // [else]
4253 : // let output = %_Call(iteratorReturn, iterator);
4254 : // [endif]
4255 : // if (!IS_RECEIVER(output)) {
4256 : // %ThrowIterResultNotAnObject(output);
4257 : // }
4258 : // }
4259 : // }
4260 : //
4261 :
4262 : const int nopos = kNoSourcePosition;
4263 : // let iteratorReturn = iterator.return;
4264 3480078 : Variable* var_return = NewTemporary(ast_value_factory()->empty_string());
4265 : Statement* get_return;
4266 : {
4267 165718 : Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
4268 : Expression* literal = factory()->NewStringLiteral(
4269 331436 : ast_value_factory()->return_string(), nopos);
4270 : Expression* property =
4271 165718 : factory()->NewProperty(iterator_proxy, literal, nopos);
4272 165718 : Expression* return_proxy = factory()->NewVariableProxy(var_return);
4273 : Expression* assignment =
4274 165718 : factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
4275 331436 : get_return = factory()->NewExpressionStatement(assignment, nopos);
4276 : }
4277 :
4278 : // if (!IS_CALLABLE(iteratorReturn)) {
4279 : // throw MakeTypeError(kReturnMethodNotCallable);
4280 : // }
4281 : Statement* check_return_callable;
4282 : {
4283 : Expression* throw_expr =
4284 : NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable,
4285 165718 : ast_value_factory()->empty_string(), nopos);
4286 165718 : check_return_callable = CheckCallable(var_return, throw_expr, nopos);
4287 : }
4288 :
4289 : // try { %_Call(iteratorReturn, iterator) } catch (_) { }
4290 : Statement* try_call_return;
4291 : {
4292 165718 : auto args = new (zone()) ZoneList<Expression*>(2, zone());
4293 331436 : args->Add(factory()->NewVariableProxy(var_return), zone());
4294 331436 : args->Add(factory()->NewVariableProxy(iterator), zone());
4295 :
4296 : Expression* call =
4297 165718 : factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4298 :
4299 165718 : if (type == IteratorType::kAsync) {
4300 20865 : call = factory()->NewAwait(call, nopos);
4301 : }
4302 :
4303 165718 : Block* try_block = factory()->NewBlock(1, false);
4304 165718 : try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos),
4305 165718 : zone());
4306 :
4307 165718 : Block* catch_block = factory()->NewBlock(0, false);
4308 : Scope* catch_scope = NewHiddenCatchScope();
4309 : try_call_return = factory()->NewTryCatchStatement(try_block, catch_scope,
4310 331436 : catch_block, nopos);
4311 : }
4312 :
4313 : // let output = %_Call(iteratorReturn, iterator);
4314 : // if (!IS_RECEIVER(output)) {
4315 : // %ThrowIteratorResultNotAnObject(output);
4316 : // }
4317 : Block* validate_return;
4318 : {
4319 165718 : Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
4320 : Statement* call_return;
4321 : {
4322 165718 : auto args = new (zone()) ZoneList<Expression*>(2, zone());
4323 331436 : args->Add(factory()->NewVariableProxy(var_return), zone());
4324 331436 : args->Add(factory()->NewVariableProxy(iterator), zone());
4325 : Expression* call =
4326 165718 : factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4327 165718 : if (type == IteratorType::kAsync) {
4328 20865 : call = factory()->NewAwait(call, nopos);
4329 : }
4330 :
4331 165718 : Expression* output_proxy = factory()->NewVariableProxy(var_output);
4332 : Expression* assignment =
4333 165718 : factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
4334 331436 : call_return = factory()->NewExpressionStatement(assignment, nopos);
4335 : }
4336 :
4337 : Expression* is_receiver_call;
4338 : {
4339 165718 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4340 331436 : args->Add(factory()->NewVariableProxy(var_output), zone());
4341 : is_receiver_call =
4342 165718 : factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4343 : }
4344 :
4345 : Statement* throw_call;
4346 : {
4347 165718 : auto args = new (zone()) ZoneList<Expression*>(1, zone());
4348 331436 : args->Add(factory()->NewVariableProxy(var_output), zone());
4349 : Expression* call = factory()->NewCallRuntime(
4350 165718 : Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4351 165718 : throw_call = factory()->NewExpressionStatement(call, nopos);
4352 : }
4353 :
4354 : Statement* check_return = factory()->NewIfStatement(
4355 165718 : is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4356 331436 : nopos);
4357 :
4358 165718 : validate_return = factory()->NewBlock(2, false);
4359 165718 : validate_return->statements()->Add(call_return, zone());
4360 165718 : validate_return->statements()->Add(check_return, zone());
4361 : }
4362 :
4363 : // if (completion === kThrowCompletion) {
4364 : // #check_return_callable;
4365 : // #try_call_return;
4366 : // } else {
4367 : // #validate_return;
4368 : // }
4369 : Statement* call_return_carefully;
4370 : {
4371 : Expression* condition = factory()->NewCompareOperation(
4372 : Token::EQ_STRICT, completion,
4373 165718 : factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
4374 :
4375 165718 : Block* then_block = factory()->NewBlock(2, false);
4376 165718 : then_block->statements()->Add(check_return_callable, zone());
4377 165718 : then_block->statements()->Add(try_call_return, zone());
4378 :
4379 : call_return_carefully = factory()->NewIfStatement(condition, then_block,
4380 165718 : validate_return, nopos);
4381 : }
4382 :
4383 : // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
4384 : Statement* maybe_call_return;
4385 : {
4386 : Expression* condition = factory()->NewCompareOperation(
4387 165718 : Token::EQ, factory()->NewVariableProxy(var_return),
4388 331436 : factory()->NewNullLiteral(nopos), nopos);
4389 :
4390 : maybe_call_return = factory()->NewIfStatement(
4391 165718 : condition, factory()->NewEmptyStatement(nopos), call_return_carefully,
4392 331436 : nopos);
4393 : }
4394 :
4395 165718 : statements->Add(get_return, zone());
4396 165718 : statements->Add(maybe_call_return, zone());
4397 165718 : }
4398 :
4399 200876 : Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
4400 : Variable* var_completion,
4401 : IteratorType type, int pos) {
4402 : //
4403 : // This function replaces the loop with the following wrapping:
4404 : //
4405 : // completion = kNormalCompletion;
4406 : // try {
4407 : // try {
4408 : // #loop;
4409 : // } catch(e) {
4410 : // if (completion === kAbruptCompletion) completion = kThrowCompletion;
4411 : // %ReThrow(e);
4412 : // }
4413 : // } finally {
4414 : // if (!(completion === kNormalCompletion)) {
4415 : // #BuildIteratorCloseForCompletion(#iterator, completion)
4416 : // }
4417 : // }
4418 : //
4419 : // Note that the loop's body and its assign_each already contain appropriate
4420 : // assignments to completion (see InitializeForOfStatement).
4421 : //
4422 :
4423 : const int nopos = kNoSourcePosition;
4424 :
4425 : // !(completion === kNormalCompletion)
4426 : Expression* closing_condition;
4427 : {
4428 : Expression* cmp = factory()->NewCompareOperation(
4429 100438 : Token::EQ_STRICT, factory()->NewVariableProxy(var_completion),
4430 301314 : factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
4431 100438 : closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos);
4432 : }
4433 :
4434 100438 : Block* final_loop = factory()->NewBlock(2, false);
4435 : {
4436 100438 : Block* try_block = factory()->NewBlock(1, false);
4437 100438 : try_block->statements()->Add(loop, zone());
4438 :
4439 : FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(),
4440 100438 : try_block, final_loop, type);
4441 : }
4442 :
4443 100438 : return final_loop;
4444 : }
4445 :
4446 : #undef CHECK_OK
4447 : #undef CHECK_OK_VOID
4448 : #undef CHECK_FAILED
4449 :
4450 : } // namespace internal
4451 : } // namespace v8
|