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