blob: 822c49eb332693a5086b85a3bb53283bd1677d34 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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 "src/api.h"
8#include "src/ast/ast.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +01009#include "src/ast/ast-expression-rewriter.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/ast/ast-expression-visitor.h"
11#include "src/ast/ast-literal-reindexer.h"
12#include "src/ast/scopeinfo.h"
13#include "src/bailout-reason.h"
14#include "src/base/platform/platform.h"
15#include "src/bootstrapper.h"
16#include "src/char-predicates-inl.h"
17#include "src/codegen.h"
18#include "src/compiler.h"
19#include "src/messages.h"
20#include "src/parsing/parameter-initializer-rewriter.h"
21#include "src/parsing/parser-base.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"
Ben Murdoch097c5b22016-05-18 11:27:45 +010026#include "src/tracing/trace-event.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027
28namespace v8 {
29namespace internal {
30
31ScriptData::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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042ParseInfo::ParseInfo(Zone* zone)
43 : zone_(zone),
44 flags_(0),
45 source_stream_(nullptr),
46 source_stream_encoding_(ScriptCompiler::StreamedSource::ONE_BYTE),
47 extension_(nullptr),
48 compile_options_(ScriptCompiler::kNoCompileOptions),
49 script_scope_(nullptr),
50 unicode_cache_(nullptr),
51 stack_limit_(0),
52 hash_seed_(0),
Ben Murdochc5610432016-08-08 18:44:38 +010053 isolate_(nullptr),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000054 cached_data_(nullptr),
55 ast_value_factory_(nullptr),
56 literal_(nullptr),
57 scope_(nullptr) {}
58
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000059ParseInfo::ParseInfo(Zone* zone, Handle<JSFunction> function)
60 : ParseInfo(zone, Handle<SharedFunctionInfo>(function->shared())) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000061 set_context(Handle<Context>(function->context()));
62}
63
64
65ParseInfo::ParseInfo(Zone* zone, Handle<SharedFunctionInfo> shared)
66 : ParseInfo(zone) {
67 isolate_ = shared->GetIsolate();
68
69 set_lazy();
70 set_hash_seed(isolate_->heap()->HashSeed());
71 set_stack_limit(isolate_->stack_guard()->real_climit());
72 set_unicode_cache(isolate_->unicode_cache());
73 set_language_mode(shared->language_mode());
74 set_shared_info(shared);
75
76 Handle<Script> script(Script::cast(shared->script()));
77 set_script(script);
78 if (!script.is_null() && script->type() == Script::TYPE_NATIVE) {
79 set_native();
80 }
81}
82
83
84ParseInfo::ParseInfo(Zone* zone, Handle<Script> script) : ParseInfo(zone) {
85 isolate_ = script->GetIsolate();
86
87 set_hash_seed(isolate_->heap()->HashSeed());
88 set_stack_limit(isolate_->stack_guard()->real_climit());
89 set_unicode_cache(isolate_->unicode_cache());
90 set_script(script);
91
92 if (script->type() == Script::TYPE_NATIVE) {
93 set_native();
94 }
95}
96
97
98FunctionEntry ParseData::GetFunctionEntry(int start) {
99 // The current pre-data entry must be a FunctionEntry with the given
100 // start position.
101 if ((function_index_ + FunctionEntry::kSize <= Length()) &&
102 (static_cast<int>(Data()[function_index_]) == start)) {
103 int index = function_index_;
104 function_index_ += FunctionEntry::kSize;
105 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
106 return FunctionEntry(subvector);
107 }
108 return FunctionEntry();
109}
110
111
112int ParseData::FunctionCount() {
113 int functions_size = FunctionsSize();
114 if (functions_size < 0) return 0;
115 if (functions_size % FunctionEntry::kSize != 0) return 0;
116 return functions_size / FunctionEntry::kSize;
117}
118
119
120bool ParseData::IsSane() {
121 if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
122 // Check that the header data is valid and doesn't specify
123 // point to positions outside the store.
124 int data_length = Length();
125 if (data_length < PreparseDataConstants::kHeaderSize) return false;
126 if (Magic() != PreparseDataConstants::kMagicNumber) return false;
127 if (Version() != PreparseDataConstants::kCurrentVersion) return false;
128 if (HasError()) return false;
129 // Check that the space allocated for function entries is sane.
130 int functions_size = FunctionsSize();
131 if (functions_size < 0) return false;
132 if (functions_size % FunctionEntry::kSize != 0) return false;
133 // Check that the total size has room for header and function entries.
134 int minimum_size =
135 PreparseDataConstants::kHeaderSize + functions_size;
136 if (data_length < minimum_size) return false;
137 return true;
138}
139
140
141void ParseData::Initialize() {
142 // Prepares state for use.
143 int data_length = Length();
144 if (data_length >= PreparseDataConstants::kHeaderSize) {
145 function_index_ = PreparseDataConstants::kHeaderSize;
146 }
147}
148
149
150bool ParseData::HasError() {
151 return Data()[PreparseDataConstants::kHasErrorOffset];
152}
153
154
155unsigned ParseData::Magic() {
156 return Data()[PreparseDataConstants::kMagicOffset];
157}
158
159
160unsigned ParseData::Version() {
161 return Data()[PreparseDataConstants::kVersionOffset];
162}
163
164
165int ParseData::FunctionsSize() {
166 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
167}
168
169
170void Parser::SetCachedData(ParseInfo* info) {
171 if (compile_options_ == ScriptCompiler::kNoCompileOptions) {
172 cached_parse_data_ = NULL;
173 } else {
174 DCHECK(info->cached_data() != NULL);
175 if (compile_options_ == ScriptCompiler::kConsumeParserCache) {
176 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
177 }
178 }
179}
180
Ben Murdoch097c5b22016-05-18 11:27:45 +0100181FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
182 bool call_super, Scope* scope,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000183 int pos, int end_pos,
184 LanguageMode language_mode) {
185 int materialized_literal_count = -1;
186 int expected_property_count = -1;
187 int parameter_count = 0;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100188 if (name == nullptr) name = ast_value_factory()->empty_string();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000189
190 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor
191 : FunctionKind::kDefaultBaseConstructor;
192 Scope* function_scope = NewScope(scope, FUNCTION_SCOPE, kind);
193 SetLanguageMode(function_scope,
194 static_cast<LanguageMode>(language_mode | STRICT));
195 // Set start and end position to the same value
196 function_scope->set_start_position(pos);
197 function_scope->set_end_position(pos);
198 ZoneList<Statement*>* body = NULL;
199
200 {
201 AstNodeFactory function_factory(ast_value_factory());
202 FunctionState function_state(&function_state_, &scope_, function_scope,
203 kind, &function_factory);
204
205 body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
206 if (call_super) {
207 // $super_constructor = %_GetSuperConstructor(<this-function>)
208 // %reflect_construct($super_constructor, arguments, new.target)
209 ZoneList<Expression*>* args =
210 new (zone()) ZoneList<Expression*>(2, zone());
211 VariableProxy* this_function_proxy = scope_->NewUnresolved(
212 factory(), ast_value_factory()->this_function_string(),
213 Variable::NORMAL, pos);
214 ZoneList<Expression*>* tmp =
215 new (zone()) ZoneList<Expression*>(1, zone());
216 tmp->Add(this_function_proxy, zone());
217 Expression* super_constructor = factory()->NewCallRuntime(
218 Runtime::kInlineGetSuperConstructor, tmp, pos);
219 args->Add(super_constructor, zone());
220 VariableProxy* arguments_proxy = scope_->NewUnresolved(
221 factory(), ast_value_factory()->arguments_string(), Variable::NORMAL,
222 pos);
223 args->Add(arguments_proxy, zone());
224 VariableProxy* new_target_proxy = scope_->NewUnresolved(
225 factory(), ast_value_factory()->new_target_string(), Variable::NORMAL,
226 pos);
227 args->Add(new_target_proxy, zone());
228 CallRuntime* call = factory()->NewCallRuntime(
229 Context::REFLECT_CONSTRUCT_INDEX, args, pos);
230 body->Add(factory()->NewReturnStatement(call, pos), zone());
231 }
232
233 materialized_literal_count = function_state.materialized_literal_count();
234 expected_property_count = function_state.expected_property_count();
235 }
236
237 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
238 name, function_scope, body, materialized_literal_count,
239 expected_property_count, parameter_count,
240 FunctionLiteral::kNoDuplicateParameters,
241 FunctionLiteral::kAnonymousExpression,
242 FunctionLiteral::kShouldLazyCompile, kind, pos);
243
244 return function_literal;
245}
246
247
248// ----------------------------------------------------------------------------
249// Target is a support class to facilitate manipulation of the
250// Parser's target_stack_ (the stack of potential 'break' and
251// 'continue' statement targets). Upon construction, a new target is
252// added; it is removed upon destruction.
253
254class Target BASE_EMBEDDED {
255 public:
256 Target(Target** variable, BreakableStatement* statement)
257 : variable_(variable), statement_(statement), previous_(*variable) {
258 *variable = this;
259 }
260
261 ~Target() {
262 *variable_ = previous_;
263 }
264
265 Target* previous() { return previous_; }
266 BreakableStatement* statement() { return statement_; }
267
268 private:
269 Target** variable_;
270 BreakableStatement* statement_;
271 Target* previous_;
272};
273
274
275class TargetScope BASE_EMBEDDED {
276 public:
277 explicit TargetScope(Target** variable)
278 : variable_(variable), previous_(*variable) {
279 *variable = NULL;
280 }
281
282 ~TargetScope() {
283 *variable_ = previous_;
284 }
285
286 private:
287 Target** variable_;
288 Target* previous_;
289};
290
291
292// ----------------------------------------------------------------------------
293// The CHECK_OK macro is a convenient macro to enforce error
294// handling for functions that may fail (by returning !*ok).
295//
296// CAUTION: This macro appends extra statements after a call,
297// thus it must never be used where only a single statement
298// is correct (e.g. an if statement branch w/o braces)!
299
300#define CHECK_OK ok); \
301 if (!*ok) return NULL; \
302 ((void)0
303#define DUMMY ) // to make indentation work
304#undef DUMMY
305
306#define CHECK_FAILED /**/); \
307 if (failed_) return NULL; \
308 ((void)0
309#define DUMMY ) // to make indentation work
310#undef DUMMY
311
312// ----------------------------------------------------------------------------
313// Implementation of Parser
314
315bool ParserTraits::IsEval(const AstRawString* identifier) const {
316 return identifier == parser_->ast_value_factory()->eval_string();
317}
318
319
320bool ParserTraits::IsArguments(const AstRawString* identifier) const {
321 return identifier == parser_->ast_value_factory()->arguments_string();
322}
323
324
325bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
326 return IsEval(identifier) || IsArguments(identifier);
327}
328
329bool ParserTraits::IsUndefined(const AstRawString* identifier) const {
330 return identifier == parser_->ast_value_factory()->undefined_string();
331}
332
Ben Murdochc5610432016-08-08 18:44:38 +0100333bool ParserTraits::IsAwait(const AstRawString* identifier) const {
334 return identifier == parser_->ast_value_factory()->await_string();
335}
336
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000337bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
338 return identifier == parser_->ast_value_factory()->prototype_string();
339}
340
341
342bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
343 return identifier == parser_->ast_value_factory()->constructor_string();
344}
345
346
347bool ParserTraits::IsThisProperty(Expression* expression) {
348 DCHECK(expression != NULL);
349 Property* property = expression->AsProperty();
350 return property != NULL && property->obj()->IsVariableProxy() &&
351 property->obj()->AsVariableProxy()->is_this();
352}
353
354
355bool ParserTraits::IsIdentifier(Expression* expression) {
356 VariableProxy* operand = expression->AsVariableProxy();
357 return operand != NULL && !operand->is_this();
358}
359
360
361void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
362 Expression* expression) {
363 if (expression->IsPropertyName()) {
364 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
365 } else {
366 fni->PushLiteralName(
367 parser_->ast_value_factory()->anonymous_function_string());
368 }
369}
370
371
372void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
373 Expression* right) {
374 DCHECK(left != NULL);
375 if (left->IsProperty() && right->IsFunctionLiteral()) {
376 right->AsFunctionLiteral()->set_pretenure();
377 }
378}
379
380
381Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
382 VariableProxy* proxy =
383 expression != NULL ? expression->AsVariableProxy() : NULL;
384 if (proxy != NULL) proxy->set_is_assigned();
385 return expression;
386}
387
388
389bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
390 Expression** x, Expression* y, Token::Value op, int pos,
391 AstNodeFactory* factory) {
392 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
393 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
394 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
395 double y_val = y->AsLiteral()->raw_value()->AsNumber();
396 bool x_has_dot = (*x)->AsLiteral()->raw_value()->ContainsDot();
397 bool y_has_dot = y->AsLiteral()->raw_value()->ContainsDot();
398 bool has_dot = x_has_dot || y_has_dot;
399 switch (op) {
400 case Token::ADD:
401 *x = factory->NewNumberLiteral(x_val + y_val, pos, has_dot);
402 return true;
403 case Token::SUB:
404 *x = factory->NewNumberLiteral(x_val - y_val, pos, has_dot);
405 return true;
406 case Token::MUL:
407 *x = factory->NewNumberLiteral(x_val * y_val, pos, has_dot);
408 return true;
409 case Token::DIV:
410 *x = factory->NewNumberLiteral(x_val / y_val, pos, has_dot);
411 return true;
412 case Token::BIT_OR: {
413 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
414 *x = factory->NewNumberLiteral(value, pos, has_dot);
415 return true;
416 }
417 case Token::BIT_AND: {
418 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
419 *x = factory->NewNumberLiteral(value, pos, has_dot);
420 return true;
421 }
422 case Token::BIT_XOR: {
423 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
424 *x = factory->NewNumberLiteral(value, pos, has_dot);
425 return true;
426 }
427 case Token::SHL: {
428 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
429 *x = factory->NewNumberLiteral(value, pos, has_dot);
430 return true;
431 }
432 case Token::SHR: {
433 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
434 uint32_t value = DoubleToUint32(x_val) >> shift;
435 *x = factory->NewNumberLiteral(value, pos, has_dot);
436 return true;
437 }
438 case Token::SAR: {
439 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
440 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
441 *x = factory->NewNumberLiteral(value, pos, has_dot);
442 return true;
443 }
Ben Murdochda12d292016-06-02 14:46:10 +0100444 case Token::EXP: {
445 double value = Pow(x_val, y_val);
446 int int_value = static_cast<int>(value);
447 *x = factory->NewNumberLiteral(
448 int_value == value && value != -0.0 ? int_value : value, pos,
449 has_dot);
450 return true;
451 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000452 default:
453 break;
454 }
455 }
456 return false;
457}
458
459
460Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
461 Token::Value op, int pos,
462 AstNodeFactory* factory) {
463 DCHECK(expression != NULL);
464 if (expression->IsLiteral()) {
465 const AstValue* literal = expression->AsLiteral()->raw_value();
466 if (op == Token::NOT) {
467 // Convert the literal to a boolean condition and negate it.
468 bool condition = literal->BooleanValue();
469 return factory->NewBooleanLiteral(!condition, pos);
470 } else if (literal->IsNumber()) {
471 // Compute some expressions involving only number literals.
472 double value = literal->AsNumber();
473 bool has_dot = literal->ContainsDot();
474 switch (op) {
475 case Token::ADD:
476 return expression;
477 case Token::SUB:
478 return factory->NewNumberLiteral(-value, pos, has_dot);
479 case Token::BIT_NOT:
480 return factory->NewNumberLiteral(~DoubleToInt32(value), pos, has_dot);
481 default:
482 break;
483 }
484 }
485 }
486 // Desugar '+foo' => 'foo*1'
487 if (op == Token::ADD) {
488 return factory->NewBinaryOperation(
489 Token::MUL, expression, factory->NewNumberLiteral(1, pos, true), pos);
490 }
491 // The same idea for '-foo' => 'foo*(-1)'.
492 if (op == Token::SUB) {
493 return factory->NewBinaryOperation(
494 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
495 }
496 // ...and one more time for '~foo' => 'foo^(~0)'.
497 if (op == Token::BIT_NOT) {
498 return factory->NewBinaryOperation(
499 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
500 }
501 return factory->NewUnaryOperation(op, expression, pos);
502}
503
Ben Murdochda12d292016-06-02 14:46:10 +0100504Expression* ParserTraits::BuildIteratorResult(Expression* value, bool done) {
505 int pos = RelocInfo::kNoPosition;
506 AstNodeFactory* factory = parser_->factory();
507 Zone* zone = parser_->zone();
508
509 if (value == nullptr) value = factory->NewUndefinedLiteral(pos);
510
511 auto args = new (zone) ZoneList<Expression*>(2, zone);
512 args->Add(value, zone);
513 args->Add(factory->NewBooleanLiteral(done, pos), zone);
514
515 return factory->NewCallRuntime(Runtime::kInlineCreateIterResultObject, args,
516 pos);
517}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000518
519Expression* ParserTraits::NewThrowReferenceError(
520 MessageTemplate::Template message, int pos) {
521 return NewThrowError(Runtime::kNewReferenceError, message,
522 parser_->ast_value_factory()->empty_string(), pos);
523}
524
525
526Expression* ParserTraits::NewThrowSyntaxError(MessageTemplate::Template message,
527 const AstRawString* arg,
528 int pos) {
529 return NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
530}
531
532
533Expression* ParserTraits::NewThrowTypeError(MessageTemplate::Template message,
534 const AstRawString* arg, int pos) {
535 return NewThrowError(Runtime::kNewTypeError, message, arg, pos);
536}
537
538
539Expression* ParserTraits::NewThrowError(Runtime::FunctionId id,
540 MessageTemplate::Template message,
541 const AstRawString* arg, int pos) {
542 Zone* zone = parser_->zone();
543 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
544 args->Add(parser_->factory()->NewSmiLiteral(message, pos), zone);
545 args->Add(parser_->factory()->NewStringLiteral(arg, pos), zone);
546 CallRuntime* call_constructor =
547 parser_->factory()->NewCallRuntime(id, args, pos);
548 return parser_->factory()->NewThrow(call_constructor, pos);
549}
550
551
552void ParserTraits::ReportMessageAt(Scanner::Location source_location,
553 MessageTemplate::Template message,
554 const char* arg, ParseErrorType error_type) {
555 if (parser_->stack_overflow()) {
556 // Suppress the error message (syntax error or such) in the presence of a
557 // stack overflow. The isolate allows only one pending exception at at time
558 // and we want to report the stack overflow later.
559 return;
560 }
561 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
562 source_location.end_pos,
563 message, arg, error_type);
564}
565
566
567void ParserTraits::ReportMessage(MessageTemplate::Template message,
568 const char* arg, ParseErrorType error_type) {
569 Scanner::Location source_location = parser_->scanner()->location();
570 ReportMessageAt(source_location, message, arg, error_type);
571}
572
573
574void ParserTraits::ReportMessage(MessageTemplate::Template message,
575 const AstRawString* arg,
576 ParseErrorType error_type) {
577 Scanner::Location source_location = parser_->scanner()->location();
578 ReportMessageAt(source_location, message, arg, error_type);
579}
580
581
582void ParserTraits::ReportMessageAt(Scanner::Location source_location,
583 MessageTemplate::Template message,
584 const AstRawString* arg,
585 ParseErrorType error_type) {
586 if (parser_->stack_overflow()) {
587 // Suppress the error message (syntax error or such) in the presence of a
588 // stack overflow. The isolate allows only one pending exception at at time
589 // and we want to report the stack overflow later.
590 return;
591 }
592 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos,
593 source_location.end_pos,
594 message, arg, error_type);
595}
596
597
598const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) {
599 const AstRawString* result =
600 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory());
601 DCHECK(result != NULL);
602 return result;
603}
604
605
606const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) {
607 double double_value = parser_->scanner()->DoubleValue();
608 char array[100];
Ben Murdochc5610432016-08-08 18:44:38 +0100609 const char* string = DoubleToCString(double_value, ArrayVector(array));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000610 return parser_->ast_value_factory()->GetOneByteString(string);
611}
612
613
614const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) {
615 return parser_->scanner()->NextSymbol(parser_->ast_value_factory());
616}
617
618
619Expression* ParserTraits::ThisExpression(Scope* scope, AstNodeFactory* factory,
620 int pos) {
621 return scope->NewUnresolved(factory,
622 parser_->ast_value_factory()->this_string(),
623 Variable::THIS, pos, pos + 4);
624}
625
626
627Expression* ParserTraits::SuperPropertyReference(Scope* scope,
628 AstNodeFactory* factory,
629 int pos) {
630 // this_function[home_object_symbol]
631 VariableProxy* this_function_proxy = scope->NewUnresolved(
632 factory, parser_->ast_value_factory()->this_function_string(),
633 Variable::NORMAL, pos);
634 Expression* home_object_symbol_literal =
635 factory->NewSymbolLiteral("home_object_symbol", RelocInfo::kNoPosition);
636 Expression* home_object = factory->NewProperty(
637 this_function_proxy, home_object_symbol_literal, pos);
638 return factory->NewSuperPropertyReference(
639 ThisExpression(scope, factory, pos)->AsVariableProxy(), home_object, pos);
640}
641
642
643Expression* ParserTraits::SuperCallReference(Scope* scope,
644 AstNodeFactory* factory, int pos) {
645 VariableProxy* new_target_proxy = scope->NewUnresolved(
646 factory, parser_->ast_value_factory()->new_target_string(),
647 Variable::NORMAL, pos);
648 VariableProxy* this_function_proxy = scope->NewUnresolved(
649 factory, parser_->ast_value_factory()->this_function_string(),
650 Variable::NORMAL, pos);
651 return factory->NewSuperCallReference(
652 ThisExpression(scope, factory, pos)->AsVariableProxy(), new_target_proxy,
653 this_function_proxy, pos);
654}
655
656
657Expression* ParserTraits::NewTargetExpression(Scope* scope,
658 AstNodeFactory* factory,
659 int pos) {
660 static const int kNewTargetStringLength = 10;
661 auto proxy = scope->NewUnresolved(
662 factory, parser_->ast_value_factory()->new_target_string(),
663 Variable::NORMAL, pos, pos + kNewTargetStringLength);
664 proxy->set_is_new_target();
665 return proxy;
666}
667
668
Ben Murdoch097c5b22016-05-18 11:27:45 +0100669Expression* ParserTraits::FunctionSentExpression(Scope* scope,
670 AstNodeFactory* factory,
671 int pos) {
672 // We desugar function.sent into %GeneratorGetInput(generator).
673 Zone* zone = parser_->zone();
674 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(1, zone);
675 VariableProxy* generator = factory->NewVariableProxy(
676 parser_->function_state_->generator_object_variable());
677 args->Add(generator, zone);
678 return factory->NewCallRuntime(Runtime::kGeneratorGetInput, args, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000679}
680
681
682Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos,
683 Scanner* scanner,
684 AstNodeFactory* factory) {
685 switch (token) {
686 case Token::NULL_LITERAL:
687 return factory->NewNullLiteral(pos);
688 case Token::TRUE_LITERAL:
689 return factory->NewBooleanLiteral(true, pos);
690 case Token::FALSE_LITERAL:
691 return factory->NewBooleanLiteral(false, pos);
692 case Token::SMI: {
693 int value = scanner->smi_value();
694 return factory->NewSmiLiteral(value, pos);
695 }
696 case Token::NUMBER: {
697 bool has_dot = scanner->ContainsDot();
698 double value = scanner->DoubleValue();
699 return factory->NewNumberLiteral(value, pos, has_dot);
700 }
701 default:
702 DCHECK(false);
703 }
704 return NULL;
705}
706
707
708Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name,
709 int start_position,
710 int end_position,
711 Scope* scope,
712 AstNodeFactory* factory) {
713 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
714 return scope->NewUnresolved(factory, name, Variable::NORMAL, start_position,
715 end_position);
716}
717
718
719Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner,
720 AstNodeFactory* factory) {
721 const AstRawString* symbol = GetSymbol(scanner);
722 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
723 return factory->NewStringLiteral(symbol, pos);
724}
725
726
727Expression* ParserTraits::GetIterator(Expression* iterable,
728 AstNodeFactory* factory, int pos) {
729 Expression* iterator_symbol_literal =
730 factory->NewSymbolLiteral("iterator_symbol", RelocInfo::kNoPosition);
731 Expression* prop =
732 factory->NewProperty(iterable, iterator_symbol_literal, pos);
733 Zone* zone = parser_->zone();
734 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone);
735 return factory->NewCall(prop, args, pos);
736}
737
738
739Literal* ParserTraits::GetLiteralTheHole(int position,
740 AstNodeFactory* factory) {
741 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
742}
743
744
745Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
746 return parser_->ParseV8Intrinsic(ok);
747}
748
749
750FunctionLiteral* ParserTraits::ParseFunctionLiteral(
751 const AstRawString* name, Scanner::Location function_name_location,
752 FunctionNameValidity function_name_validity, FunctionKind kind,
753 int function_token_position, FunctionLiteral::FunctionType type,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000754 LanguageMode language_mode, bool* ok) {
755 return parser_->ParseFunctionLiteral(
756 name, function_name_location, function_name_validity, kind,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100757 function_token_position, type, language_mode, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000758}
759
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000760ClassLiteral* ParserTraits::ParseClassLiteral(
Ben Murdochda12d292016-06-02 14:46:10 +0100761 Type::ExpressionClassifier* classifier, const AstRawString* name,
762 Scanner::Location class_name_location, bool name_is_strict_reserved,
763 int pos, bool* ok) {
764 return parser_->ParseClassLiteral(classifier, name, class_name_location,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000765 name_is_strict_reserved, pos, ok);
766}
767
Ben Murdochda12d292016-06-02 14:46:10 +0100768void ParserTraits::MarkTailPosition(Expression* expression) {
769 expression->MarkTail();
770}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000771
Ben Murdochc5610432016-08-08 18:44:38 +0100772void ParserTraits::MarkCollectedTailCallExpressions() {
773 parser_->MarkCollectedTailCallExpressions();
774}
775
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000776Parser::Parser(ParseInfo* info)
777 : ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(),
778 info->extension(), info->ast_value_factory(),
779 NULL, this),
780 scanner_(info->unicode_cache()),
781 reusable_preparser_(NULL),
782 original_scope_(NULL),
783 target_stack_(NULL),
784 compile_options_(info->compile_options()),
785 cached_parse_data_(NULL),
786 total_preparse_skipped_(0),
787 pre_parse_timer_(NULL),
788 parsing_on_main_thread_(true) {
789 // Even though we were passed ParseInfo, we should not store it in
790 // Parser - this makes sure that Isolate is not accidentally accessed via
791 // ParseInfo during background parsing.
792 DCHECK(!info->script().is_null() || info->source_stream() != NULL);
793 set_allow_lazy(info->allow_lazy_parsing());
794 set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
Ben Murdochda12d292016-06-02 14:46:10 +0100795 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() &&
796 info->isolate()->is_tail_call_elimination_enabled());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000797 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
Ben Murdochc5610432016-08-08 18:44:38 +0100798 set_allow_harmony_for_in(FLAG_harmony_for_in);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000799 set_allow_harmony_function_name(FLAG_harmony_function_name);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100800 set_allow_harmony_function_sent(FLAG_harmony_function_sent);
Ben Murdochda12d292016-06-02 14:46:10 +0100801 set_allow_harmony_restrictive_declarations(
802 FLAG_harmony_restrictive_declarations);
803 set_allow_harmony_exponentiation_operator(
804 FLAG_harmony_exponentiation_operator);
Ben Murdochc5610432016-08-08 18:44:38 +0100805 set_allow_harmony_async_await(FLAG_harmony_async_await);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000806 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
807 ++feature) {
808 use_counts_[feature] = 0;
809 }
810 if (info->ast_value_factory() == NULL) {
811 // info takes ownership of AstValueFactory.
812 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
813 info->set_ast_value_factory_owned();
814 ast_value_factory_ = info->ast_value_factory();
815 }
816}
817
818
819FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
820 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
821 // see comment for HistogramTimerScope class.
822
823 // It's OK to use the Isolate & counters here, since this function is only
824 // called in the main thread.
825 DCHECK(parsing_on_main_thread_);
826
827 HistogramTimerScope timer_scope(isolate->counters()->parse(), true);
Ben Murdochc5610432016-08-08 18:44:38 +0100828 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::Parse);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100829 TRACE_EVENT0("v8", "V8.Parse");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000830 Handle<String> source(String::cast(info->script()->source()));
831 isolate->counters()->total_parse_size()->Increment(source->length());
832 base::ElapsedTimer timer;
833 if (FLAG_trace_parse) {
834 timer.Start();
835 }
836 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
837
838 // Initialize parser state.
839 CompleteParserRecorder recorder;
840
841 if (produce_cached_parse_data()) {
842 log_ = &recorder;
843 } else if (consume_cached_parse_data()) {
844 cached_parse_data_->Initialize();
845 }
846
847 source = String::Flatten(source);
848 FunctionLiteral* result;
849
850 if (source->IsExternalTwoByteString()) {
851 // Notice that the stream is destroyed at the end of the branch block.
852 // The last line of the blocks can't be moved outside, even though they're
853 // identical calls.
854 ExternalTwoByteStringUtf16CharacterStream stream(
855 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
856 scanner_.Initialize(&stream);
857 result = DoParseProgram(info);
858 } else {
859 GenericStringUtf16CharacterStream stream(source, 0, source->length());
860 scanner_.Initialize(&stream);
861 result = DoParseProgram(info);
862 }
863 if (result != NULL) {
864 DCHECK_EQ(scanner_.peek_location().beg_pos, source->length());
865 }
866 HandleSourceURLComments(isolate, info->script());
867
868 if (FLAG_trace_parse && result != NULL) {
869 double ms = timer.Elapsed().InMillisecondsF();
870 if (info->is_eval()) {
871 PrintF("[parsing eval");
872 } else if (info->script()->name()->IsString()) {
873 String* name = String::cast(info->script()->name());
874 base::SmartArrayPointer<char> name_chars = name->ToCString();
875 PrintF("[parsing script: %s", name_chars.get());
876 } else {
877 PrintF("[parsing script");
878 }
879 PrintF(" - took %0.3f ms]\n", ms);
880 }
881 if (produce_cached_parse_data()) {
882 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
883 log_ = NULL;
884 }
885 return result;
886}
887
888
889FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
890 // Note that this function can be called from the main thread or from a
891 // background thread. We should not access anything Isolate / heap dependent
892 // via ParseInfo, and also not pass it forward.
893 DCHECK(scope_ == NULL);
894 DCHECK(target_stack_ == NULL);
895
896 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY;
897 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY;
898
899 FunctionLiteral* result = NULL;
900 {
901 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
902 // context, which will have the "this" binding for script scopes.
903 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
904 info->set_script_scope(scope);
905 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
906 scope = Scope::DeserializeScopeChain(info->isolate(), zone(),
907 *info->context(), scope);
908 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
909 // means the Parser cannot operate independent of the V8 heap. Tell the
910 // string table to internalize strings and values right after they're
911 // created. This kind of parsing can only be done in the main thread.
912 DCHECK(parsing_on_main_thread_);
913 ast_value_factory()->Internalize(info->isolate());
914 }
915 original_scope_ = scope;
916 if (info->is_eval()) {
917 if (!scope->is_script_scope() || is_strict(info->language_mode())) {
918 parsing_mode = PARSE_EAGERLY;
919 }
920 scope = NewScope(scope, EVAL_SCOPE);
921 } else if (info->is_module()) {
922 scope = NewScope(scope, MODULE_SCOPE);
923 }
924
925 scope->set_start_position(0);
926
927 // Enter 'scope' with the given parsing mode.
928 ParsingModeScope parsing_mode_scope(this, parsing_mode);
929 AstNodeFactory function_factory(ast_value_factory());
930 FunctionState function_state(&function_state_, &scope_, scope,
931 kNormalFunction, &function_factory);
932
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000933 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
934 bool ok = true;
935 int beg_pos = scanner()->location().beg_pos;
Ben Murdochc5610432016-08-08 18:44:38 +0100936 parsing_module_ = info->is_module();
937 if (parsing_module_) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000938 ParseModuleItemList(body, &ok);
939 } else {
Ben Murdochc5610432016-08-08 18:44:38 +0100940 // Don't count the mode in the use counters--give the program a chance
941 // to enable script-wide strict mode below.
942 scope_->SetLanguageMode(info->language_mode());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000943 ParseStatementList(body, Token::EOS, &ok);
944 }
945
946 // The parser will peek but not consume EOS. Our scope logically goes all
947 // the way to the EOS, though.
948 scope->set_end_position(scanner()->peek_location().beg_pos);
949
950 if (ok && is_strict(language_mode())) {
951 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
Ben Murdochc5610432016-08-08 18:44:38 +0100952 CheckDecimalLiteralWithLeadingZero(use_counts_, beg_pos,
953 scanner()->location().end_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000954 }
Ben Murdochc5610432016-08-08 18:44:38 +0100955 if (ok && is_sloppy(language_mode())) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000956 // TODO(littledan): Function bindings on the global object that modify
957 // pre-existing bindings should be made writable, enumerable and
958 // nonconfigurable if possible, whereas this code will leave attributes
959 // unchanged if the property already exists.
960 InsertSloppyBlockFunctionVarBindings(scope, &ok);
961 }
Ben Murdochda12d292016-06-02 14:46:10 +0100962 if (ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000963 CheckConflictingVarDeclarations(scope_, &ok);
964 }
965
966 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
967 if (body->length() != 1 ||
968 !body->at(0)->IsExpressionStatement() ||
969 !body->at(0)->AsExpressionStatement()->
970 expression()->IsFunctionLiteral()) {
971 ReportMessage(MessageTemplate::kSingleFunctionLiteral);
972 ok = false;
973 }
974 }
975
976 if (ok) {
977 ParserTraits::RewriteDestructuringAssignments();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100978 result = factory()->NewScriptOrEvalFunctionLiteral(
979 scope_, body, function_state.materialized_literal_count(),
980 function_state.expected_property_count());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000981 }
982 }
983
984 // Make sure the target stack is empty.
985 DCHECK(target_stack_ == NULL);
986
987 return result;
988}
989
990
991FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info) {
992 // It's OK to use the Isolate & counters here, since this function is only
993 // called in the main thread.
994 DCHECK(parsing_on_main_thread_);
Ben Murdochc5610432016-08-08 18:44:38 +0100995 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseLazy);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000996 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100997 TRACE_EVENT0("v8", "V8.ParseLazy");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000998 Handle<String> source(String::cast(info->script()->source()));
999 isolate->counters()->total_parse_size()->Increment(source->length());
1000 base::ElapsedTimer timer;
1001 if (FLAG_trace_parse) {
1002 timer.Start();
1003 }
1004 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1005
1006 // Initialize parser state.
1007 source = String::Flatten(source);
1008 FunctionLiteral* result;
1009 if (source->IsExternalTwoByteString()) {
1010 ExternalTwoByteStringUtf16CharacterStream stream(
1011 Handle<ExternalTwoByteString>::cast(source),
1012 shared_info->start_position(),
1013 shared_info->end_position());
1014 result = ParseLazy(isolate, info, &stream);
1015 } else {
1016 GenericStringUtf16CharacterStream stream(source,
1017 shared_info->start_position(),
1018 shared_info->end_position());
1019 result = ParseLazy(isolate, info, &stream);
1020 }
1021
1022 if (FLAG_trace_parse && result != NULL) {
1023 double ms = timer.Elapsed().InMillisecondsF();
1024 base::SmartArrayPointer<char> name_chars =
1025 result->debug_name()->ToCString();
1026 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
1027 }
1028 return result;
1029}
1030
Ben Murdoch097c5b22016-05-18 11:27:45 +01001031static FunctionLiteral::FunctionType ComputeFunctionType(
1032 Handle<SharedFunctionInfo> shared_info) {
1033 if (shared_info->is_declaration()) {
1034 return FunctionLiteral::kDeclaration;
1035 } else if (shared_info->is_named_expression()) {
1036 return FunctionLiteral::kNamedExpression;
1037 } else if (IsConciseMethod(shared_info->kind()) ||
1038 IsAccessorFunction(shared_info->kind())) {
1039 return FunctionLiteral::kAccessorOrMethod;
1040 }
1041 return FunctionLiteral::kAnonymousExpression;
1042}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001043
1044FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
1045 Utf16CharacterStream* source) {
1046 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1047 scanner_.Initialize(source);
1048 DCHECK(scope_ == NULL);
1049 DCHECK(target_stack_ == NULL);
1050
1051 Handle<String> name(String::cast(shared_info->name()));
1052 DCHECK(ast_value_factory());
1053 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
1054 const AstRawString* raw_name = ast_value_factory()->GetString(name);
1055 fni_->PushEnclosingName(raw_name);
1056
1057 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1058
1059 // Place holder for the result.
1060 FunctionLiteral* result = NULL;
1061
1062 {
1063 // Parse the function literal.
1064 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1065 info->set_script_scope(scope);
Ben Murdochc5610432016-08-08 18:44:38 +01001066 if (!info->context().is_null()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001067 // Ok to use Isolate here, since lazy function parsing is only done in the
1068 // main thread.
1069 DCHECK(parsing_on_main_thread_);
Ben Murdochc5610432016-08-08 18:44:38 +01001070 scope = Scope::DeserializeScopeChain(isolate, zone(), *info->context(),
1071 scope);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001072 }
1073 original_scope_ = scope;
1074 AstNodeFactory function_factory(ast_value_factory());
1075 FunctionState function_state(&function_state_, &scope_, scope,
1076 shared_info->kind(), &function_factory);
1077 DCHECK(is_sloppy(scope->language_mode()) ||
1078 is_strict(info->language_mode()));
1079 DCHECK(info->language_mode() == shared_info->language_mode());
1080 FunctionLiteral::FunctionType function_type =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001081 ComputeFunctionType(shared_info);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001082 bool ok = true;
1083
1084 if (shared_info->is_arrow()) {
Ben Murdochc5610432016-08-08 18:44:38 +01001085 bool is_async = allow_harmony_async_await() && shared_info->is_async();
1086 if (is_async) {
1087 DCHECK(!scanner()->HasAnyLineTerminatorAfterNext());
1088 Consume(Token::ASYNC);
1089 DCHECK(peek_any_identifier() || peek() == Token::LPAREN);
1090 }
1091
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001092 // TODO(adamk): We should construct this scope from the ScopeInfo.
1093 Scope* scope =
1094 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
1095
1096 // These two bits only need to be explicitly set because we're
1097 // not passing the ScopeInfo to the Scope constructor.
1098 // TODO(adamk): Remove these calls once the above NewScope call
1099 // passes the ScopeInfo.
1100 if (shared_info->scope_info()->CallsEval()) {
1101 scope->RecordEvalCall();
1102 }
1103 SetLanguageMode(scope, shared_info->language_mode());
1104
1105 scope->set_start_position(shared_info->start_position());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001106 ExpressionClassifier formals_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001107 ParserFormalParameters formals(scope);
1108 Checkpoint checkpoint(this);
1109 {
1110 // Parsing patterns as variable reference expression creates
1111 // NewUnresolved references in current scope. Entrer arrow function
1112 // scope for formal parameter parsing.
1113 BlockState block_state(&scope_, scope);
1114 if (Check(Token::LPAREN)) {
1115 // '(' StrictFormalParameters ')'
1116 ParseFormalParameterList(&formals, &formals_classifier, &ok);
1117 if (ok) ok = Check(Token::RPAREN);
1118 } else {
1119 // BindingIdentifier
1120 ParseFormalParameter(&formals, &formals_classifier, &ok);
1121 if (ok) {
1122 DeclareFormalParameter(formals.scope, formals.at(0),
1123 &formals_classifier);
1124 }
1125 }
1126 }
1127
1128 if (ok) {
1129 checkpoint.Restore(&formals.materialized_literals_count);
1130 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
1131 // not be observable, or else the preparser would have failed.
Ben Murdochc5610432016-08-08 18:44:38 +01001132 Expression* expression = ParseArrowFunctionLiteral(
1133 true, formals, is_async, formals_classifier, &ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001134 if (ok) {
1135 // Scanning must end at the same position that was recorded
1136 // previously. If not, parsing has been interrupted due to a stack
1137 // overflow, at which point the partially parsed arrow function
1138 // concise body happens to be a valid expression. This is a problem
1139 // only for arrow functions with single expression bodies, since there
1140 // is no end token such as "}" for normal functions.
1141 if (scanner()->location().end_pos == shared_info->end_position()) {
1142 // The pre-parser saw an arrow function here, so the full parser
1143 // must produce a FunctionLiteral.
1144 DCHECK(expression->IsFunctionLiteral());
1145 result = expression->AsFunctionLiteral();
1146 } else {
1147 ok = false;
1148 }
1149 }
1150 }
1151 } else if (shared_info->is_default_constructor()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001152 result = DefaultConstructor(
1153 raw_name, IsSubclassConstructor(shared_info->kind()), scope,
1154 shared_info->start_position(), shared_info->end_position(),
1155 shared_info->language_mode());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001156 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001157 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
1158 kSkipFunctionNameCheck, shared_info->kind(),
1159 RelocInfo::kNoPosition, function_type,
1160 shared_info->language_mode(), &ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001161 }
1162 // Make sure the results agree.
1163 DCHECK(ok == (result != NULL));
1164 }
1165
1166 // Make sure the target stack is empty.
1167 DCHECK(target_stack_ == NULL);
1168
1169 if (result != NULL) {
1170 Handle<String> inferred_name(shared_info->inferred_name());
1171 result->set_inferred_name(inferred_name);
1172 }
1173 return result;
1174}
1175
1176
1177void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token,
1178 bool* ok) {
1179 // StatementList ::
1180 // (StatementListItem)* <end_token>
1181
1182 // Allocate a target stack to use for this set of source
1183 // elements. This way, all scripts and functions get their own
1184 // target stack thus avoiding illegal breaks and continues across
1185 // functions.
1186 TargetScope scope(&this->target_stack_);
1187
1188 DCHECK(body != NULL);
1189 bool directive_prologue = true; // Parsing directive prologue.
1190
1191 while (peek() != end_token) {
1192 if (directive_prologue && peek() != Token::STRING) {
1193 directive_prologue = false;
1194 }
1195
1196 Scanner::Location token_loc = scanner()->peek_location();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001197 Statement* stat = ParseStatementListItem(CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001198 if (stat == NULL || stat->IsEmpty()) {
1199 directive_prologue = false; // End of directive prologue.
1200 continue;
1201 }
1202
1203 if (directive_prologue) {
1204 // A shot at a directive.
1205 ExpressionStatement* e_stat;
1206 Literal* literal;
1207 // Still processing directive prologue?
1208 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1209 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1210 literal->raw_value()->IsString()) {
Ben Murdochda12d292016-06-02 14:46:10 +01001211 // Check "use strict" directive (ES5 14.1), "use asm" directive.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001212 bool use_strict_found =
1213 literal->raw_value()->AsString() ==
1214 ast_value_factory()->use_strict_string() &&
1215 token_loc.end_pos - token_loc.beg_pos ==
1216 ast_value_factory()->use_strict_string()->length() + 2;
Ben Murdochda12d292016-06-02 14:46:10 +01001217 if (use_strict_found) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001218 if (is_sloppy(scope_->language_mode())) {
1219 RaiseLanguageMode(STRICT);
1220 }
1221
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001222 if (!scope_->HasSimpleParameters()) {
1223 // TC39 deemed "use strict" directives to be an error when occurring
1224 // in the body of a function with non-simple parameter list, on
1225 // 29/7/2015. https://goo.gl/ueA7Ln
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001226 const AstRawString* string = literal->raw_value()->AsString();
1227 ParserTraits::ReportMessageAt(
1228 token_loc, MessageTemplate::kIllegalLanguageModeDirective,
1229 string);
1230 *ok = false;
1231 return nullptr;
1232 }
1233 // Because declarations in strict eval code don't leak into the scope
1234 // of the eval call, it is likely that functions declared in strict
1235 // eval code will be used within the eval code, so lazy parsing is
1236 // probably not a win.
1237 if (scope_->is_eval_scope()) mode_ = PARSE_EAGERLY;
1238 } else if (literal->raw_value()->AsString() ==
1239 ast_value_factory()->use_asm_string() &&
1240 token_loc.end_pos - token_loc.beg_pos ==
1241 ast_value_factory()->use_asm_string()->length() + 2) {
1242 // Store the usage count; The actual use counter on the isolate is
1243 // incremented after parsing is done.
1244 ++use_counts_[v8::Isolate::kUseAsm];
1245 scope_->SetAsmModule();
1246 } else {
1247 // Should not change mode, but will increment UseCounter
1248 // if appropriate. Ditto usages below.
1249 RaiseLanguageMode(SLOPPY);
1250 }
1251 } else {
1252 // End of the directive prologue.
1253 directive_prologue = false;
1254 RaiseLanguageMode(SLOPPY);
1255 }
1256 } else {
1257 RaiseLanguageMode(SLOPPY);
1258 }
1259
1260 body->Add(stat, zone());
1261 }
1262
1263 return 0;
1264}
1265
1266
1267Statement* Parser::ParseStatementListItem(bool* ok) {
1268 // (Ecma 262 6th Edition, 13.1):
1269 // StatementListItem:
1270 // Statement
1271 // Declaration
Ben Murdochc5610432016-08-08 18:44:38 +01001272 const Token::Value peeked = peek();
1273 switch (peeked) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001274 case Token::FUNCTION:
Ben Murdochc5610432016-08-08 18:44:38 +01001275 return ParseHoistableDeclaration(NULL, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001276 case Token::CLASS:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001277 Consume(Token::CLASS);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001278 return ParseClassDeclaration(NULL, ok);
1279 case Token::CONST:
Ben Murdochc5610432016-08-08 18:44:38 +01001280 return ParseVariableStatement(kStatementListItem, NULL, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001281 case Token::VAR:
1282 return ParseVariableStatement(kStatementListItem, NULL, ok);
1283 case Token::LET:
1284 if (IsNextLetKeyword()) {
1285 return ParseVariableStatement(kStatementListItem, NULL, ok);
1286 }
1287 break;
Ben Murdochc5610432016-08-08 18:44:38 +01001288 case Token::ASYNC:
1289 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
1290 !scanner()->HasAnyLineTerminatorAfterNext()) {
1291 Consume(Token::ASYNC);
1292 return ParseAsyncFunctionDeclaration(NULL, ok);
1293 }
1294 /* falls through */
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001295 default:
1296 break;
1297 }
Ben Murdochda12d292016-06-02 14:46:10 +01001298 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001299}
1300
1301
1302Statement* Parser::ParseModuleItem(bool* ok) {
1303 // (Ecma 262 6th Edition, 15.2):
1304 // ModuleItem :
1305 // ImportDeclaration
1306 // ExportDeclaration
1307 // StatementListItem
1308
1309 switch (peek()) {
1310 case Token::IMPORT:
1311 return ParseImportDeclaration(ok);
1312 case Token::EXPORT:
1313 return ParseExportDeclaration(ok);
1314 default:
1315 return ParseStatementListItem(ok);
1316 }
1317}
1318
1319
1320void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
1321 // (Ecma 262 6th Edition, 15.2):
1322 // Module :
1323 // ModuleBody?
1324 //
1325 // ModuleBody :
1326 // ModuleItem*
1327
1328 DCHECK(scope_->is_module_scope());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001329
1330 while (peek() != Token::EOS) {
1331 Statement* stat = ParseModuleItem(CHECK_OK);
1332 if (stat && !stat->IsEmpty()) {
1333 body->Add(stat, zone());
1334 }
1335 }
1336
1337 // Check that all exports are bound.
1338 ModuleDescriptor* descriptor = scope_->module();
1339 for (ModuleDescriptor::Iterator it = descriptor->iterator(); !it.done();
1340 it.Advance()) {
1341 if (scope_->LookupLocal(it.local_name()) == NULL) {
1342 // TODO(adamk): Pass both local_name and export_name once ParserTraits
1343 // supports multiple arg error messages.
1344 // Also try to report this at a better location.
1345 ParserTraits::ReportMessage(MessageTemplate::kModuleExportUndefined,
1346 it.local_name());
1347 *ok = false;
1348 return NULL;
1349 }
1350 }
1351
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001352 return NULL;
1353}
1354
1355
1356const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
1357 // ModuleSpecifier :
1358 // StringLiteral
1359
1360 Expect(Token::STRING, CHECK_OK);
1361 return GetSymbol(scanner());
1362}
1363
1364
1365void* Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
1366 ZoneList<Scanner::Location>* export_locations,
1367 ZoneList<const AstRawString*>* local_names,
1368 Scanner::Location* reserved_loc, bool* ok) {
1369 // ExportClause :
1370 // '{' '}'
1371 // '{' ExportsList '}'
1372 // '{' ExportsList ',' '}'
1373 //
1374 // ExportsList :
1375 // ExportSpecifier
1376 // ExportsList ',' ExportSpecifier
1377 //
1378 // ExportSpecifier :
1379 // IdentifierName
1380 // IdentifierName 'as' IdentifierName
1381
1382 Expect(Token::LBRACE, CHECK_OK);
1383
1384 Token::Value name_tok;
1385 while ((name_tok = peek()) != Token::RBRACE) {
1386 // Keep track of the first reserved word encountered in case our
1387 // caller needs to report an error.
1388 if (!reserved_loc->IsValid() &&
Ben Murdochc5610432016-08-08 18:44:38 +01001389 !Token::IsIdentifier(name_tok, STRICT, false, parsing_module_)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001390 *reserved_loc = scanner()->location();
1391 }
1392 const AstRawString* local_name = ParseIdentifierName(CHECK_OK);
1393 const AstRawString* export_name = NULL;
1394 if (CheckContextualKeyword(CStrVector("as"))) {
1395 export_name = ParseIdentifierName(CHECK_OK);
1396 }
1397 if (export_name == NULL) {
1398 export_name = local_name;
1399 }
1400 export_names->Add(export_name, zone());
1401 local_names->Add(local_name, zone());
1402 export_locations->Add(scanner()->location(), zone());
1403 if (peek() == Token::RBRACE) break;
1404 Expect(Token::COMMA, CHECK_OK);
1405 }
1406
1407 Expect(Token::RBRACE, CHECK_OK);
1408
1409 return 0;
1410}
1411
1412
1413ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) {
1414 // NamedImports :
1415 // '{' '}'
1416 // '{' ImportsList '}'
1417 // '{' ImportsList ',' '}'
1418 //
1419 // ImportsList :
1420 // ImportSpecifier
1421 // ImportsList ',' ImportSpecifier
1422 //
1423 // ImportSpecifier :
1424 // BindingIdentifier
1425 // IdentifierName 'as' BindingIdentifier
1426
1427 Expect(Token::LBRACE, CHECK_OK);
1428
1429 ZoneList<ImportDeclaration*>* result =
1430 new (zone()) ZoneList<ImportDeclaration*>(1, zone());
1431 while (peek() != Token::RBRACE) {
1432 const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1433 const AstRawString* local_name = import_name;
1434 // In the presence of 'as', the left-side of the 'as' can
1435 // be any IdentifierName. But without 'as', it must be a valid
1436 // BindingIdentifier.
1437 if (CheckContextualKeyword(CStrVector("as"))) {
1438 local_name = ParseIdentifierName(CHECK_OK);
1439 }
Ben Murdochc5610432016-08-08 18:44:38 +01001440 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false,
1441 parsing_module_)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001442 *ok = false;
1443 ReportMessage(MessageTemplate::kUnexpectedReserved);
1444 return NULL;
1445 } else if (IsEvalOrArguments(local_name)) {
1446 *ok = false;
1447 ReportMessage(MessageTemplate::kStrictEvalArguments);
1448 return NULL;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001449 }
Ben Murdochc5610432016-08-08 18:44:38 +01001450 VariableProxy* proxy = NewUnresolved(local_name, CONST);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001451 ImportDeclaration* declaration =
1452 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos);
1453 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
1454 result->Add(declaration, zone());
1455 if (peek() == Token::RBRACE) break;
1456 Expect(Token::COMMA, CHECK_OK);
1457 }
1458
1459 Expect(Token::RBRACE, CHECK_OK);
1460
1461 return result;
1462}
1463
1464
1465Statement* Parser::ParseImportDeclaration(bool* ok) {
1466 // ImportDeclaration :
1467 // 'import' ImportClause 'from' ModuleSpecifier ';'
1468 // 'import' ModuleSpecifier ';'
1469 //
1470 // ImportClause :
1471 // NameSpaceImport
1472 // NamedImports
1473 // ImportedDefaultBinding
1474 // ImportedDefaultBinding ',' NameSpaceImport
1475 // ImportedDefaultBinding ',' NamedImports
1476 //
1477 // NameSpaceImport :
1478 // '*' 'as' ImportedBinding
1479
1480 int pos = peek_position();
1481 Expect(Token::IMPORT, CHECK_OK);
1482
1483 Token::Value tok = peek();
1484
1485 // 'import' ModuleSpecifier ';'
1486 if (tok == Token::STRING) {
1487 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1488 scope_->module()->AddModuleRequest(module_specifier, zone());
1489 ExpectSemicolon(CHECK_OK);
1490 return factory()->NewEmptyStatement(pos);
1491 }
1492
1493 // Parse ImportedDefaultBinding if present.
1494 ImportDeclaration* import_default_declaration = NULL;
1495 if (tok != Token::MUL && tok != Token::LBRACE) {
1496 const AstRawString* local_name =
1497 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01001498 VariableProxy* proxy = NewUnresolved(local_name, CONST);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001499 import_default_declaration = factory()->NewImportDeclaration(
1500 proxy, ast_value_factory()->default_string(), NULL, scope_, pos);
1501 Declare(import_default_declaration, DeclarationDescriptor::NORMAL, true,
1502 CHECK_OK);
1503 }
1504
1505 const AstRawString* module_instance_binding = NULL;
1506 ZoneList<ImportDeclaration*>* named_declarations = NULL;
1507 if (import_default_declaration == NULL || Check(Token::COMMA)) {
1508 switch (peek()) {
1509 case Token::MUL: {
1510 Consume(Token::MUL);
1511 ExpectContextualKeyword(CStrVector("as"), CHECK_OK);
1512 module_instance_binding =
1513 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1514 // TODO(ES6): Add an appropriate declaration.
1515 break;
1516 }
1517
1518 case Token::LBRACE:
1519 named_declarations = ParseNamedImports(pos, CHECK_OK);
1520 break;
1521
1522 default:
1523 *ok = false;
1524 ReportUnexpectedToken(scanner()->current_token());
1525 return NULL;
1526 }
1527 }
1528
1529 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1530 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1531 scope_->module()->AddModuleRequest(module_specifier, zone());
1532
1533 if (module_instance_binding != NULL) {
1534 // TODO(ES6): Set the module specifier for the module namespace binding.
1535 }
1536
1537 if (import_default_declaration != NULL) {
1538 import_default_declaration->set_module_specifier(module_specifier);
1539 }
1540
1541 if (named_declarations != NULL) {
1542 for (int i = 0; i < named_declarations->length(); ++i) {
1543 named_declarations->at(i)->set_module_specifier(module_specifier);
1544 }
1545 }
1546
1547 ExpectSemicolon(CHECK_OK);
1548 return factory()->NewEmptyStatement(pos);
1549}
1550
1551
1552Statement* Parser::ParseExportDefault(bool* ok) {
1553 // Supports the following productions, starting after the 'default' token:
1554 // 'export' 'default' FunctionDeclaration
1555 // 'export' 'default' ClassDeclaration
1556 // 'export' 'default' AssignmentExpression[In] ';'
1557
1558 Expect(Token::DEFAULT, CHECK_OK);
1559 Scanner::Location default_loc = scanner()->location();
1560
Ben Murdoch097c5b22016-05-18 11:27:45 +01001561 const AstRawString* default_string = ast_value_factory()->default_string();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001562 ZoneList<const AstRawString*> names(1, zone());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001563 Statement* result = nullptr;
1564 Expression* default_export = nullptr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001565 switch (peek()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001566 case Token::FUNCTION: {
1567 Consume(Token::FUNCTION);
1568 int pos = position();
1569 bool is_generator = Check(Token::MUL);
1570 if (peek() == Token::LPAREN) {
1571 // FunctionDeclaration[+Default] ::
1572 // 'function' '(' FormalParameters ')' '{' FunctionBody '}'
1573 //
1574 // GeneratorDeclaration[+Default] ::
1575 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
1576 default_export = ParseFunctionLiteral(
1577 default_string, Scanner::Location::invalid(),
1578 kSkipFunctionNameCheck,
1579 is_generator ? FunctionKind::kGeneratorFunction
1580 : FunctionKind::kNormalFunction,
1581 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK);
1582 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1583 } else {
Ben Murdochc5610432016-08-08 18:44:38 +01001584 result = ParseHoistableDeclaration(
1585 pos, is_generator ? ParseFunctionFlags::kIsGenerator
1586 : ParseFunctionFlags::kIsNormal,
1587 &names, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001588 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001589 break;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001590 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001591
1592 case Token::CLASS:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001593 Consume(Token::CLASS);
1594 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) {
1595 // ClassDeclaration[+Default] ::
1596 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
Ben Murdochda12d292016-06-02 14:46:10 +01001597 default_export = ParseClassLiteral(nullptr, default_string,
1598 Scanner::Location::invalid(), false,
1599 position(), CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001600 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1601 } else {
1602 result = ParseClassDeclaration(&names, CHECK_OK);
1603 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001604 break;
1605
Ben Murdochc5610432016-08-08 18:44:38 +01001606 case Token::ASYNC:
1607 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
1608 !scanner()->HasAnyLineTerminatorAfterNext()) {
1609 Consume(Token::ASYNC);
1610 Consume(Token::FUNCTION);
1611 int pos = position();
1612 if (peek() == Token::LPAREN) {
1613 // AsyncFunctionDeclaration[+Default] ::
1614 // async [no LineTerminator here] function ( FormalParameters ) {
1615 // AsyncFunctionBody
1616 // }
1617 default_export = ParseFunctionLiteral(
1618 default_string, Scanner::Location::invalid(),
1619 kSkipFunctionNameCheck, FunctionKind::kAsyncFunction, pos,
1620 FunctionLiteral::kDeclaration, language_mode(), CHECK_OK);
1621 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1622 } else {
1623 result = ParseHoistableDeclaration(pos, ParseFunctionFlags::kIsAsync,
1624 &names, CHECK_OK);
1625 }
1626 break;
1627 }
1628 /* falls through */
1629
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001630 default: {
1631 int pos = peek_position();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001632 ExpressionClassifier classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001633 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001634 RewriteNonPattern(&classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001635
1636 ExpectSemicolon(CHECK_OK);
1637 result = factory()->NewExpressionStatement(expr, pos);
1638 break;
1639 }
1640 }
1641
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001642 DCHECK_LE(names.length(), 1);
1643 if (names.length() == 1) {
1644 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok);
1645 if (!*ok) {
1646 ParserTraits::ReportMessageAt(
1647 default_loc, MessageTemplate::kDuplicateExport, default_string);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001648 return nullptr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001649 }
1650 } else {
1651 // TODO(ES6): Assign result to a const binding with the name "*default*"
1652 // and add an export entry with "*default*" as the local name.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001653 USE(default_export);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001654 }
1655
1656 return result;
1657}
1658
1659
1660Statement* Parser::ParseExportDeclaration(bool* ok) {
1661 // ExportDeclaration:
1662 // 'export' '*' 'from' ModuleSpecifier ';'
1663 // 'export' ExportClause ('from' ModuleSpecifier)? ';'
1664 // 'export' VariableStatement
1665 // 'export' Declaration
1666 // 'export' 'default' ... (handled in ParseExportDefault)
1667
1668 int pos = peek_position();
1669 Expect(Token::EXPORT, CHECK_OK);
1670
1671 Statement* result = NULL;
1672 ZoneList<const AstRawString*> names(1, zone());
1673 switch (peek()) {
1674 case Token::DEFAULT:
1675 return ParseExportDefault(ok);
1676
1677 case Token::MUL: {
1678 Consume(Token::MUL);
1679 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1680 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1681 scope_->module()->AddModuleRequest(module_specifier, zone());
1682 // TODO(ES6): scope_->module()->AddStarExport(...)
1683 ExpectSemicolon(CHECK_OK);
1684 return factory()->NewEmptyStatement(pos);
1685 }
1686
1687 case Token::LBRACE: {
1688 // There are two cases here:
1689 //
1690 // 'export' ExportClause ';'
1691 // and
1692 // 'export' ExportClause FromClause ';'
1693 //
1694 // In the first case, the exported identifiers in ExportClause must
1695 // not be reserved words, while in the latter they may be. We
1696 // pass in a location that gets filled with the first reserved word
1697 // encountered, and then throw a SyntaxError if we are in the
1698 // non-FromClause case.
1699 Scanner::Location reserved_loc = Scanner::Location::invalid();
1700 ZoneList<const AstRawString*> export_names(1, zone());
1701 ZoneList<Scanner::Location> export_locations(1, zone());
1702 ZoneList<const AstRawString*> local_names(1, zone());
1703 ParseExportClause(&export_names, &export_locations, &local_names,
1704 &reserved_loc, CHECK_OK);
1705 const AstRawString* indirect_export_module_specifier = NULL;
1706 if (CheckContextualKeyword(CStrVector("from"))) {
1707 indirect_export_module_specifier = ParseModuleSpecifier(CHECK_OK);
1708 } else if (reserved_loc.IsValid()) {
1709 // No FromClause, so reserved words are invalid in ExportClause.
1710 *ok = false;
1711 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1712 return NULL;
1713 }
1714 ExpectSemicolon(CHECK_OK);
1715 const int length = export_names.length();
1716 DCHECK_EQ(length, local_names.length());
1717 DCHECK_EQ(length, export_locations.length());
1718 if (indirect_export_module_specifier == NULL) {
1719 for (int i = 0; i < length; ++i) {
1720 scope_->module()->AddLocalExport(export_names[i], local_names[i],
1721 zone(), ok);
1722 if (!*ok) {
1723 ParserTraits::ReportMessageAt(export_locations[i],
1724 MessageTemplate::kDuplicateExport,
1725 export_names[i]);
1726 return NULL;
1727 }
1728 }
1729 } else {
1730 scope_->module()->AddModuleRequest(indirect_export_module_specifier,
1731 zone());
1732 for (int i = 0; i < length; ++i) {
1733 // TODO(ES6): scope_->module()->AddIndirectExport(...);(
1734 }
1735 }
1736 return factory()->NewEmptyStatement(pos);
1737 }
1738
1739 case Token::FUNCTION:
Ben Murdochc5610432016-08-08 18:44:38 +01001740 result = ParseHoistableDeclaration(&names, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001741 break;
1742
1743 case Token::CLASS:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001744 Consume(Token::CLASS);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001745 result = ParseClassDeclaration(&names, CHECK_OK);
1746 break;
1747
1748 case Token::VAR:
1749 case Token::LET:
1750 case Token::CONST:
1751 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1752 break;
1753
Ben Murdochc5610432016-08-08 18:44:38 +01001754 case Token::ASYNC:
1755 if (allow_harmony_async_await()) {
1756 Consume(Token::ASYNC);
1757 result = ParseAsyncFunctionDeclaration(&names, CHECK_OK);
1758 break;
1759 }
1760 /* falls through */
1761
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001762 default:
1763 *ok = false;
1764 ReportUnexpectedToken(scanner()->current_token());
1765 return NULL;
1766 }
1767
1768 // Extract declared names into export declarations.
1769 ModuleDescriptor* descriptor = scope_->module();
1770 for (int i = 0; i < names.length(); ++i) {
1771 descriptor->AddLocalExport(names[i], names[i], zone(), ok);
1772 if (!*ok) {
1773 // TODO(adamk): Possibly report this error at the right place.
1774 ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]);
1775 return NULL;
1776 }
1777 }
1778
1779 DCHECK_NOT_NULL(result);
1780 return result;
1781}
1782
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001783Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels,
Ben Murdochda12d292016-06-02 14:46:10 +01001784 AllowLabelledFunctionStatement allow_function,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001785 bool* ok) {
1786 // Statement ::
1787 // EmptyStatement
1788 // ...
1789
1790 if (peek() == Token::SEMICOLON) {
1791 Next();
1792 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1793 }
Ben Murdochda12d292016-06-02 14:46:10 +01001794 return ParseSubStatement(labels, allow_function, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001795}
1796
Ben Murdochda12d292016-06-02 14:46:10 +01001797Statement* Parser::ParseSubStatement(
1798 ZoneList<const AstRawString*>* labels,
1799 AllowLabelledFunctionStatement allow_function, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001800 // Statement ::
1801 // Block
1802 // VariableStatement
1803 // EmptyStatement
1804 // ExpressionStatement
1805 // IfStatement
1806 // IterationStatement
1807 // ContinueStatement
1808 // BreakStatement
1809 // ReturnStatement
1810 // WithStatement
1811 // LabelledStatement
1812 // SwitchStatement
1813 // ThrowStatement
1814 // TryStatement
1815 // DebuggerStatement
1816
1817 // Note: Since labels can only be used by 'break' and 'continue'
1818 // statements, which themselves are only valid within blocks,
1819 // iterations or 'switch' statements (i.e., BreakableStatements),
1820 // labels can be simply ignored in all other cases; except for
1821 // trivial labeled break statements 'label: break label' which is
1822 // parsed into an empty statement.
1823 switch (peek()) {
1824 case Token::LBRACE:
1825 return ParseBlock(labels, ok);
1826
1827 case Token::SEMICOLON:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001828 Next();
1829 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1830
1831 case Token::IF:
1832 return ParseIfStatement(labels, ok);
1833
1834 case Token::DO:
1835 return ParseDoWhileStatement(labels, ok);
1836
1837 case Token::WHILE:
1838 return ParseWhileStatement(labels, ok);
1839
1840 case Token::FOR:
1841 return ParseForStatement(labels, ok);
1842
1843 case Token::CONTINUE:
1844 case Token::BREAK:
1845 case Token::RETURN:
1846 case Token::THROW:
1847 case Token::TRY: {
1848 // These statements must have their labels preserved in an enclosing
1849 // block
1850 if (labels == NULL) {
1851 return ParseStatementAsUnlabelled(labels, ok);
1852 } else {
1853 Block* result =
1854 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1855 Target target(&this->target_stack_, result);
1856 Statement* statement = ParseStatementAsUnlabelled(labels, CHECK_OK);
1857 if (result) result->statements()->Add(statement, zone());
1858 return result;
1859 }
1860 }
1861
1862 case Token::WITH:
1863 return ParseWithStatement(labels, ok);
1864
1865 case Token::SWITCH:
1866 return ParseSwitchStatement(labels, ok);
1867
Ben Murdochda12d292016-06-02 14:46:10 +01001868 case Token::FUNCTION:
1869 // FunctionDeclaration only allowed as a StatementListItem, not in
1870 // an arbitrary Statement position. Exceptions such as
1871 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
1872 // are handled by calling ParseScopedStatement rather than
1873 // ParseSubStatement directly.
1874 ReportMessageAt(scanner()->peek_location(),
1875 is_strict(language_mode())
1876 ? MessageTemplate::kStrictFunction
1877 : MessageTemplate::kSloppyFunction);
1878 *ok = false;
1879 return nullptr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001880
1881 case Token::DEBUGGER:
1882 return ParseDebuggerStatement(ok);
1883
1884 case Token::VAR:
1885 return ParseVariableStatement(kStatement, NULL, ok);
1886
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001887 default:
Ben Murdochda12d292016-06-02 14:46:10 +01001888 return ParseExpressionOrLabelledStatement(labels, allow_function, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001889 }
1890}
1891
1892Statement* Parser::ParseStatementAsUnlabelled(
1893 ZoneList<const AstRawString*>* labels, bool* ok) {
1894 switch (peek()) {
1895 case Token::CONTINUE:
1896 return ParseContinueStatement(ok);
1897
1898 case Token::BREAK:
1899 return ParseBreakStatement(labels, ok);
1900
1901 case Token::RETURN:
1902 return ParseReturnStatement(ok);
1903
1904 case Token::THROW:
1905 return ParseThrowStatement(ok);
1906
1907 case Token::TRY:
1908 return ParseTryStatement(ok);
1909
1910 default:
1911 UNREACHABLE();
1912 return NULL;
1913 }
1914}
1915
1916
1917VariableProxy* Parser::NewUnresolved(const AstRawString* name,
1918 VariableMode mode) {
1919 // If we are inside a function, a declaration of a var/const variable is a
1920 // truly local variable, and the scope of the variable is always the function
1921 // scope.
1922 // Let/const variables in harmony mode are always added to the immediately
1923 // enclosing scope.
1924 Scope* scope =
1925 IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope();
1926 return scope->NewUnresolved(factory(), name, Variable::NORMAL,
1927 scanner()->location().beg_pos,
1928 scanner()->location().end_pos);
1929}
1930
1931
1932Variable* Parser::Declare(Declaration* declaration,
1933 DeclarationDescriptor::Kind declaration_kind,
1934 bool resolve, bool* ok, Scope* scope) {
1935 VariableProxy* proxy = declaration->proxy();
1936 DCHECK(proxy->raw_name() != NULL);
1937 const AstRawString* name = proxy->raw_name();
1938 VariableMode mode = declaration->mode();
Ben Murdochc5610432016-08-08 18:44:38 +01001939 DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001940 bool is_function_declaration = declaration->IsFunctionDeclaration();
1941 if (scope == nullptr) scope = scope_;
1942 Scope* declaration_scope =
1943 IsLexicalVariableMode(mode) ? scope : scope->DeclarationScope();
1944 Variable* var = NULL;
1945
1946 // If a suitable scope exists, then we can statically declare this
1947 // variable and also set its mode. In any case, a Declaration node
1948 // will be added to the scope so that the declaration can be added
1949 // to the corresponding activation frame at runtime if necessary.
1950 // For instance, var declarations inside a sloppy eval scope need
1951 // to be added to the calling function context. Similarly, strict
1952 // mode eval scope and lexical eval bindings do not leak variable
1953 // declarations to the caller's scope so we declare all locals, too.
1954 if (declaration_scope->is_function_scope() ||
1955 declaration_scope->is_block_scope() ||
1956 declaration_scope->is_module_scope() ||
1957 declaration_scope->is_script_scope() ||
1958 (declaration_scope->is_eval_scope() &&
1959 (is_strict(declaration_scope->language_mode()) ||
1960 IsLexicalVariableMode(mode)))) {
1961 // Declare the variable in the declaration scope.
1962 var = declaration_scope->LookupLocal(name);
1963 if (var == NULL) {
1964 // Declare the name.
1965 Variable::Kind kind = Variable::NORMAL;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001966 if (is_function_declaration) {
1967 kind = Variable::FUNCTION;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001968 }
1969 var = declaration_scope->DeclareLocal(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001970 name, mode, declaration->initialization(), kind, kNotAssigned);
Ben Murdochc5610432016-08-08 18:44:38 +01001971 } else if (IsLexicalVariableMode(mode) ||
1972 IsLexicalVariableMode(var->mode())) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001973 // Allow duplicate function decls for web compat, see bug 4693.
1974 if (is_sloppy(language_mode()) && is_function_declaration &&
1975 var->is_function()) {
1976 DCHECK(IsLexicalVariableMode(mode) &&
1977 IsLexicalVariableMode(var->mode()));
1978 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1979 } else {
1980 // The name was declared in this scope before; check for conflicting
1981 // re-declarations. We have a conflict if either of the declarations
1982 // is not a var (in script scope, we also have to ignore legacy const
1983 // for compatibility). There is similar code in runtime.cc in the
1984 // Declare functions. The function CheckConflictingVarDeclarations
1985 // checks for var and let bindings from different scopes whereas this
1986 // is a check for conflicting declarations within the same scope. This
1987 // check also covers the special case
1988 //
1989 // function () { let x; { var x; } }
1990 //
1991 // because the var declaration is hoisted to the function scope where
1992 // 'x' is already bound.
1993 DCHECK(IsDeclaredVariableMode(var->mode()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001994 // In harmony we treat re-declarations as early errors. See
1995 // ES5 16 for a definition of early errors.
1996 if (declaration_kind == DeclarationDescriptor::NORMAL) {
1997 ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name);
1998 } else {
1999 ParserTraits::ReportMessage(MessageTemplate::kParamDupe);
2000 }
2001 *ok = false;
2002 return nullptr;
2003 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002004 } else if (mode == VAR) {
2005 var->set_maybe_assigned();
2006 }
2007 } else if (declaration_scope->is_eval_scope() &&
2008 is_sloppy(declaration_scope->language_mode()) &&
2009 !IsLexicalVariableMode(mode)) {
2010 // In a var binding in a sloppy direct eval, pollute the enclosing scope
2011 // with this new binding by doing the following:
2012 // The proxy is bound to a lookup variable to force a dynamic declaration
2013 // using the DeclareLookupSlot runtime function.
2014 Variable::Kind kind = Variable::NORMAL;
2015 // TODO(sigurds) figure out if kNotAssigned is OK here
2016 var = new (zone()) Variable(declaration_scope, name, mode, kind,
2017 declaration->initialization(), kNotAssigned);
2018 var->AllocateTo(VariableLocation::LOOKUP, -1);
2019 var->SetFromEval();
2020 resolve = true;
2021 }
2022
2023
2024 // We add a declaration node for every declaration. The compiler
2025 // will only generate code if necessary. In particular, declarations
2026 // for inner local variables that do not represent functions won't
2027 // result in any generated code.
2028 //
2029 // Note that we always add an unresolved proxy even if it's not
2030 // used, simply because we don't know in this method (w/o extra
2031 // parameters) if the proxy is needed or not. The proxy will be
2032 // bound during variable resolution time unless it was pre-bound
2033 // below.
2034 //
2035 // WARNING: This will lead to multiple declaration nodes for the
2036 // same variable if it is declared several times. This is not a
2037 // semantic issue as long as we keep the source order, but it may be
2038 // a performance issue since it may lead to repeated
2039 // RuntimeHidden_DeclareLookupSlot calls.
2040 declaration_scope->AddDeclaration(declaration);
2041
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002042 // If requested and we have a local variable, bind the proxy to the variable
2043 // at parse-time. This is used for functions (and consts) declared inside
2044 // statements: the corresponding function (or const) variable must be in the
2045 // function scope and not a statement-local scope, e.g. as provided with a
2046 // 'with' statement:
2047 //
2048 // with (obj) {
2049 // function f() {}
2050 // }
2051 //
2052 // which is translated into:
2053 //
2054 // with (obj) {
2055 // // in this case this is not: 'var f; f = function () {};'
2056 // var f = function () {};
2057 // }
2058 //
2059 // Note that if 'f' is accessed from inside the 'with' statement, it
2060 // will be allocated in the context (because we must be able to look
2061 // it up dynamically) but it will also be accessed statically, i.e.,
2062 // with a context slot index and a context chain length for this
2063 // initialization code. Thus, inside the 'with' statement, we need
2064 // both access to the static and the dynamic context chain; the
2065 // runtime needs to provide both.
2066 if (resolve && var != NULL) {
2067 proxy->BindTo(var);
2068 }
2069 return var;
2070}
2071
2072
2073// Language extension which is only enabled for source files loaded
2074// through the API's extension mechanism. A native function
2075// declaration is resolved by looking up the function through a
2076// callback provided by the extension.
2077Statement* Parser::ParseNativeDeclaration(bool* ok) {
2078 int pos = peek_position();
2079 Expect(Token::FUNCTION, CHECK_OK);
2080 // Allow "eval" or "arguments" for backward compatibility.
2081 const AstRawString* name =
2082 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2083 Expect(Token::LPAREN, CHECK_OK);
2084 bool done = (peek() == Token::RPAREN);
2085 while (!done) {
2086 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2087 done = (peek() == Token::RPAREN);
2088 if (!done) {
2089 Expect(Token::COMMA, CHECK_OK);
2090 }
2091 }
2092 Expect(Token::RPAREN, CHECK_OK);
2093 Expect(Token::SEMICOLON, CHECK_OK);
2094
2095 // Make sure that the function containing the native declaration
2096 // isn't lazily compiled. The extension structures are only
2097 // accessible while parsing the first time not when reparsing
2098 // because of lazy compilation.
2099 // TODO(adamk): Should this be ClosureScope()?
2100 scope_->DeclarationScope()->ForceEagerCompilation();
2101
2102 // TODO(1240846): It's weird that native function declarations are
2103 // introduced dynamically when we meet their declarations, whereas
2104 // other functions are set up when entering the surrounding scope.
2105 VariableProxy* proxy = NewUnresolved(name, VAR);
2106 Declaration* declaration =
2107 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
2108 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2109 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
2110 name, extension_, RelocInfo::kNoPosition);
2111 return factory()->NewExpressionStatement(
2112 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition),
2113 pos);
2114}
2115
2116
Ben Murdochc5610432016-08-08 18:44:38 +01002117Statement* Parser::ParseHoistableDeclaration(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002118 ZoneList<const AstRawString*>* names, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002119 Expect(Token::FUNCTION, CHECK_OK);
2120 int pos = position();
Ben Murdochc5610432016-08-08 18:44:38 +01002121 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
2122 if (Check(Token::MUL)) {
2123 flags |= ParseFunctionFlags::kIsGenerator;
2124 }
2125 return ParseHoistableDeclaration(pos, flags, names, ok);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002126}
2127
Ben Murdochc5610432016-08-08 18:44:38 +01002128Statement* Parser::ParseAsyncFunctionDeclaration(
2129 ZoneList<const AstRawString*>* names, bool* ok) {
2130 DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
2131 int pos = position();
2132 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
2133 *ok = false;
2134 ReportUnexpectedToken(scanner()->current_token());
2135 return nullptr;
2136 }
2137 Expect(Token::FUNCTION, CHECK_OK);
2138 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
2139 return ParseHoistableDeclaration(pos, flags, names, ok);
2140}
Ben Murdoch097c5b22016-05-18 11:27:45 +01002141
Ben Murdochc5610432016-08-08 18:44:38 +01002142Statement* Parser::ParseHoistableDeclaration(
2143 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002144 bool* ok) {
2145 // FunctionDeclaration ::
2146 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
2147 // GeneratorDeclaration ::
2148 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
2149 //
2150 // 'function' and '*' (if present) have been consumed by the caller.
Ben Murdochc5610432016-08-08 18:44:38 +01002151 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
2152 const bool is_async = flags & ParseFunctionFlags::kIsAsync;
2153 DCHECK(!is_generator || !is_async);
2154
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002155 bool is_strict_reserved = false;
2156 const AstRawString* name = ParseIdentifierOrStrictReservedWord(
2157 &is_strict_reserved, CHECK_OK);
2158
Ben Murdochc5610432016-08-08 18:44:38 +01002159 if (V8_UNLIKELY(is_async_function() && this->IsAwait(name))) {
2160 ReportMessageAt(scanner()->location(),
2161 MessageTemplate::kAwaitBindingIdentifier);
2162 *ok = false;
2163 return nullptr;
2164 }
2165
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002166 FuncNameInferrer::State fni_state(fni_);
2167 if (fni_ != NULL) fni_->PushEnclosingName(name);
2168 FunctionLiteral* fun = ParseFunctionLiteral(
2169 name, scanner()->location(),
2170 is_strict_reserved ? kFunctionNameIsStrictReserved
2171 : kFunctionNameValidityUnknown,
2172 is_generator ? FunctionKind::kGeneratorFunction
Ben Murdochc5610432016-08-08 18:44:38 +01002173 : is_async ? FunctionKind::kAsyncFunction
2174 : FunctionKind::kNormalFunction,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002175 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002176
2177 // Even if we're not at the top-level of the global or a function
2178 // scope, we treat it as such and introduce the function with its
2179 // initial value upon entering the corresponding scope.
2180 // In ES6, a function behaves as a lexical binding, except in
2181 // a script scope, or the initial scope of eval or another function.
2182 VariableMode mode =
Ben Murdochc5610432016-08-08 18:44:38 +01002183 (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET
2184 : VAR;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002185 VariableProxy* proxy = NewUnresolved(name, mode);
2186 Declaration* declaration =
2187 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
2188 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2189 if (names) names->Add(name, zone());
2190 EmptyStatement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
Ben Murdochc5610432016-08-08 18:44:38 +01002191 if (is_sloppy(language_mode()) && !scope_->is_declaration_scope()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002192 SloppyBlockFunctionStatement* delegate =
2193 factory()->NewSloppyBlockFunctionStatement(empty, scope_);
2194 scope_->DeclarationScope()->sloppy_block_function_map()->Declare(name,
2195 delegate);
2196 return delegate;
2197 }
2198 return empty;
2199}
2200
2201
2202Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
2203 bool* ok) {
2204 // ClassDeclaration ::
2205 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
2206 //
Ben Murdoch097c5b22016-05-18 11:27:45 +01002207 // 'class' is expected to be consumed by the caller.
2208 //
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002209 // A ClassDeclaration
2210 //
2211 // class C { ... }
2212 //
2213 // has the same semantics as:
2214 //
2215 // let C = class C { ... };
2216 //
2217 // so rewrite it as such.
2218
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002219 int pos = position();
2220 bool is_strict_reserved = false;
2221 const AstRawString* name =
2222 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
Ben Murdochda12d292016-06-02 14:46:10 +01002223 ClassLiteral* value = ParseClassLiteral(nullptr, name, scanner()->location(),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002224 is_strict_reserved, pos, CHECK_OK);
2225
Ben Murdochda12d292016-06-02 14:46:10 +01002226 VariableProxy* proxy = NewUnresolved(name, LET);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002227 Declaration* declaration =
Ben Murdochda12d292016-06-02 14:46:10 +01002228 factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002229 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002230 proxy->var()->set_initializer_position(position());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002231 Assignment* assignment =
2232 factory()->NewAssignment(Token::INIT, proxy, value, pos);
2233 Statement* assignment_statement =
2234 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
2235 if (names) names->Add(name, zone());
2236 return assignment_statement;
2237}
2238
2239
2240Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels,
2241 bool finalize_block_scope, bool* ok) {
2242 // The harmony mode uses block elements instead of statements.
2243 //
2244 // Block ::
2245 // '{' StatementList '}'
2246
2247 // Construct block expecting 16 statements.
2248 Block* body =
2249 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2250 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2251
2252 // Parse the statements and collect escaping labels.
2253 Expect(Token::LBRACE, CHECK_OK);
2254 block_scope->set_start_position(scanner()->location().beg_pos);
2255 { BlockState block_state(&scope_, block_scope);
2256 Target target(&this->target_stack_, body);
2257
2258 while (peek() != Token::RBRACE) {
2259 Statement* stat = ParseStatementListItem(CHECK_OK);
2260 if (stat && !stat->IsEmpty()) {
2261 body->statements()->Add(stat, zone());
2262 }
2263 }
2264 }
2265 Expect(Token::RBRACE, CHECK_OK);
2266 block_scope->set_end_position(scanner()->location().end_pos);
2267 if (finalize_block_scope) {
2268 block_scope = block_scope->FinalizeBlockScope();
2269 }
2270 body->set_scope(block_scope);
2271 return body;
2272}
2273
2274
2275Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
2276 return ParseBlock(labels, true, ok);
2277}
2278
2279
2280Block* Parser::DeclarationParsingResult::BuildInitializationBlock(
2281 ZoneList<const AstRawString*>* names, bool* ok) {
2282 Block* result = descriptor.parser->factory()->NewBlock(
2283 NULL, 1, true, descriptor.declaration_pos);
2284 for (auto declaration : declarations) {
2285 PatternRewriter::DeclareAndInitializeVariables(
2286 result, &descriptor, &declaration, names, CHECK_OK);
2287 }
2288 return result;
2289}
2290
2291
2292Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
2293 ZoneList<const AstRawString*>* names,
2294 bool* ok) {
2295 // VariableStatement ::
2296 // VariableDeclarations ';'
2297
2298 // The scope of a var/const declared variable anywhere inside a function
2299 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2300 // transform a source-level var/const declaration into a (Function)
2301 // Scope declaration, and rewrite the source-level initialization into an
2302 // assignment statement. We use a block to collect multiple assignments.
2303 //
2304 // We mark the block as initializer block because we don't want the
2305 // rewriter to add a '.result' assignment to such a block (to get compliant
2306 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2307 // reasons when pretty-printing. Also, unless an assignment (initialization)
2308 // is inside an initializer block, it is ignored.
2309
2310 DeclarationParsingResult parsing_result;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002311 Block* result =
2312 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002313 ExpectSemicolon(CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002314 return result;
2315}
2316
Ben Murdoch097c5b22016-05-18 11:27:45 +01002317Block* Parser::ParseVariableDeclarations(
2318 VariableDeclarationContext var_context,
2319 DeclarationParsingResult* parsing_result,
2320 ZoneList<const AstRawString*>* names, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002321 // VariableDeclarations ::
2322 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2323 //
2324 // The ES6 Draft Rev3 specifies the following grammar for const declarations
2325 //
2326 // ConstDeclaration ::
2327 // const ConstBinding (',' ConstBinding)* ';'
2328 // ConstBinding ::
2329 // Identifier '=' AssignmentExpression
2330 //
2331 // TODO(ES6):
2332 // ConstBinding ::
2333 // BindingPattern '=' AssignmentExpression
2334
2335 parsing_result->descriptor.parser = this;
2336 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
2337 parsing_result->descriptor.declaration_pos = peek_position();
2338 parsing_result->descriptor.initialization_pos = peek_position();
2339 parsing_result->descriptor.mode = VAR;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002340
2341 Block* init_block = nullptr;
2342 if (var_context != kForStatement) {
2343 init_block = factory()->NewBlock(
2344 NULL, 1, true, parsing_result->descriptor.declaration_pos);
2345 }
2346
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002347 if (peek() == Token::VAR) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002348 Consume(Token::VAR);
Ben Murdochc5610432016-08-08 18:44:38 +01002349 } else if (peek() == Token::CONST) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002350 Consume(Token::CONST);
Ben Murdochda12d292016-06-02 14:46:10 +01002351 DCHECK(var_context != kStatement);
2352 parsing_result->descriptor.mode = CONST;
Ben Murdochc5610432016-08-08 18:44:38 +01002353 } else if (peek() == Token::LET) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002354 Consume(Token::LET);
2355 DCHECK(var_context != kStatement);
2356 parsing_result->descriptor.mode = LET;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002357 } else {
2358 UNREACHABLE(); // by current callers
2359 }
2360
2361 parsing_result->descriptor.scope = scope_;
2362 parsing_result->descriptor.hoist_scope = nullptr;
2363
2364
2365 bool first_declaration = true;
2366 int bindings_start = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002367 do {
2368 FuncNameInferrer::State fni_state(fni_);
2369
2370 // Parse name.
2371 if (!first_declaration) Consume(Token::COMMA);
2372
2373 Expression* pattern;
2374 int decl_pos = peek_position();
2375 {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002376 ExpressionClassifier pattern_classifier(this);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002377 pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
2378 ValidateBindingPattern(&pattern_classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002379 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002380 ValidateLetPattern(&pattern_classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002381 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002382 }
2383
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002384 Scanner::Location variable_loc = scanner()->location();
2385 const AstRawString* single_name =
2386 pattern->IsVariableProxy() ? pattern->AsVariableProxy()->raw_name()
2387 : nullptr;
2388 if (single_name != nullptr) {
2389 if (fni_ != NULL) fni_->PushVariableName(single_name);
2390 }
2391
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002392 Expression* value = NULL;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002393 int initializer_position = RelocInfo::kNoPosition;
2394 if (Check(Token::ASSIGN)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002395 ExpressionClassifier classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002396 value = ParseAssignmentExpression(var_context != kForStatement,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002397 &classifier, CHECK_OK);
2398 RewriteNonPattern(&classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002399 variable_loc.end_pos = scanner()->location().end_pos;
2400
2401 if (!parsing_result->first_initializer_loc.IsValid()) {
2402 parsing_result->first_initializer_loc = variable_loc;
2403 }
2404
2405 // Don't infer if it is "a = function(){...}();"-like expression.
2406 if (single_name) {
2407 if (fni_ != NULL && value->AsCall() == NULL &&
2408 value->AsCallNew() == NULL) {
2409 fni_->Infer();
2410 } else {
2411 fni_->RemoveLastFunction();
2412 }
2413 }
2414
Ben Murdoch097c5b22016-05-18 11:27:45 +01002415 if (allow_harmony_function_name()) {
2416 ParserTraits::SetFunctionNameFromIdentifierRef(value, pattern);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002417 }
2418
2419 // End position of the initializer is after the assignment expression.
2420 initializer_position = scanner()->location().end_pos;
2421 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002422 // Initializers may be either required or implied unless this is a
2423 // for-in/of iteration variable.
2424 if (var_context != kForStatement || !PeekInOrOf()) {
2425 // ES6 'const' and binding patterns require initializers.
2426 if (parsing_result->descriptor.mode == CONST ||
2427 !pattern->IsVariableProxy()) {
2428 ParserTraits::ReportMessageAt(
2429 Scanner::Location(decl_pos, scanner()->location().end_pos),
2430 MessageTemplate::kDeclarationMissingInitializer,
2431 !pattern->IsVariableProxy() ? "destructuring" : "const");
2432 *ok = false;
2433 return nullptr;
2434 }
2435
Ben Murdochc5610432016-08-08 18:44:38 +01002436 // 'let x' initializes 'x' to undefined.
2437 if (parsing_result->descriptor.mode == LET) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002438 value = GetLiteralUndefined(position());
2439 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002440 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002441
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002442 // End position of the initializer is after the variable.
2443 initializer_position = position();
2444 }
2445
Ben Murdoch097c5b22016-05-18 11:27:45 +01002446 DeclarationParsingResult::Declaration decl(pattern, initializer_position,
2447 value);
2448 if (var_context == kForStatement) {
2449 // Save the declaration for further handling in ParseForStatement.
2450 parsing_result->declarations.Add(decl);
2451 } else {
2452 // Immediately declare the variable otherwise. This avoids O(N^2)
2453 // behavior (where N is the number of variables in a single
2454 // declaration) in the PatternRewriter having to do with removing
2455 // and adding VariableProxies to the Scope (see bug 4699).
2456 DCHECK_NOT_NULL(init_block);
2457 PatternRewriter::DeclareAndInitializeVariables(
2458 init_block, &parsing_result->descriptor, &decl, names, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002459 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002460 first_declaration = false;
2461 } while (peek() == Token::COMMA);
2462
2463 parsing_result->bindings_loc =
2464 Scanner::Location(bindings_start, scanner()->location().end_pos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002465
2466 DCHECK(*ok);
2467 return init_block;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002468}
2469
2470
2471static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2472 const AstRawString* label) {
2473 DCHECK(label != NULL);
2474 if (labels != NULL) {
2475 for (int i = labels->length(); i-- > 0; ) {
2476 if (labels->at(i) == label) {
2477 return true;
2478 }
2479 }
2480 }
2481 return false;
2482}
2483
Ben Murdochc5610432016-08-08 18:44:38 +01002484Statement* Parser::ParseFunctionDeclaration(bool* ok) {
2485 Consume(Token::FUNCTION);
2486 int pos = position();
2487 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
2488 if (Check(Token::MUL)) {
2489 flags |= ParseFunctionFlags::kIsGenerator;
2490 if (allow_harmony_restrictive_declarations()) {
2491 ParserTraits::ReportMessageAt(scanner()->location(),
2492 MessageTemplate::kGeneratorInLegacyContext);
2493 *ok = false;
2494 return nullptr;
2495 }
2496 }
2497
2498 return ParseHoistableDeclaration(pos, flags, nullptr, CHECK_OK);
2499}
2500
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002501Statement* Parser::ParseExpressionOrLabelledStatement(
Ben Murdochda12d292016-06-02 14:46:10 +01002502 ZoneList<const AstRawString*>* labels,
2503 AllowLabelledFunctionStatement allow_function, bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002504 // ExpressionStatement | LabelledStatement ::
2505 // Expression ';'
2506 // Identifier ':' Statement
2507 //
2508 // ExpressionStatement[Yield] :
2509 // [lookahead ∉ {{, function, class, let [}] Expression[In, ?Yield] ;
2510
2511 int pos = peek_position();
2512
2513 switch (peek()) {
2514 case Token::FUNCTION:
2515 case Token::LBRACE:
2516 UNREACHABLE(); // Always handled by the callers.
2517 case Token::CLASS:
2518 ReportUnexpectedToken(Next());
2519 *ok = false;
2520 return nullptr;
2521
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002522 default:
2523 break;
2524 }
2525
2526 bool starts_with_idenfifier = peek_any_identifier();
2527 Expression* expr = ParseExpression(true, CHECK_OK);
2528 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2529 expr->AsVariableProxy() != NULL &&
2530 !expr->AsVariableProxy()->is_this()) {
2531 // Expression is a single identifier, and not, e.g., a parenthesized
2532 // identifier.
2533 VariableProxy* var = expr->AsVariableProxy();
2534 const AstRawString* label = var->raw_name();
2535 // TODO(1240780): We don't check for redeclaration of labels
2536 // during preparsing since keeping track of the set of active
2537 // labels requires nontrivial changes to the way scopes are
2538 // structured. However, these are probably changes we want to
2539 // make later anyway so we should go back and fix this then.
2540 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2541 ParserTraits::ReportMessage(MessageTemplate::kLabelRedeclaration, label);
2542 *ok = false;
2543 return NULL;
2544 }
2545 if (labels == NULL) {
2546 labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2547 }
2548 labels->Add(label, zone());
2549 // Remove the "ghost" variable that turned out to be a label
2550 // from the top scope. This way, we don't try to resolve it
2551 // during the scope processing.
2552 scope_->RemoveUnresolved(var);
2553 Expect(Token::COLON, CHECK_OK);
Ben Murdochda12d292016-06-02 14:46:10 +01002554 // ES#sec-labelled-function-declarations Labelled Function Declarations
2555 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
2556 if (allow_function == kAllowLabelledFunctionStatement) {
Ben Murdochc5610432016-08-08 18:44:38 +01002557 return ParseFunctionDeclaration(ok);
Ben Murdochda12d292016-06-02 14:46:10 +01002558 } else {
2559 return ParseScopedStatement(labels, true, ok);
2560 }
2561 }
2562 return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002563 }
2564
2565 // If we have an extension, we allow a native function declaration.
2566 // A native function declaration starts with "native function" with
2567 // no line-terminator between the two words.
2568 if (extension_ != NULL && peek() == Token::FUNCTION &&
2569 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2570 expr->AsVariableProxy() != NULL &&
2571 expr->AsVariableProxy()->raw_name() ==
2572 ast_value_factory()->native_string() &&
2573 !scanner()->literal_contains_escapes()) {
2574 return ParseNativeDeclaration(ok);
2575 }
2576
2577 // Parsed expression statement, followed by semicolon.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002578 ExpectSemicolon(CHECK_OK);
2579 return factory()->NewExpressionStatement(expr, pos);
2580}
2581
2582
2583IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2584 bool* ok) {
2585 // IfStatement ::
2586 // 'if' '(' Expression ')' Statement ('else' Statement)?
2587
2588 int pos = peek_position();
2589 Expect(Token::IF, CHECK_OK);
2590 Expect(Token::LPAREN, CHECK_OK);
2591 Expression* condition = ParseExpression(true, CHECK_OK);
2592 Expect(Token::RPAREN, CHECK_OK);
Ben Murdochda12d292016-06-02 14:46:10 +01002593 Statement* then_statement = ParseScopedStatement(labels, false, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002594 Statement* else_statement = NULL;
2595 if (peek() == Token::ELSE) {
2596 Next();
Ben Murdochda12d292016-06-02 14:46:10 +01002597 else_statement = ParseScopedStatement(labels, false, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002598 } else {
2599 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2600 }
2601 return factory()->NewIfStatement(
2602 condition, then_statement, else_statement, pos);
2603}
2604
2605
2606Statement* Parser::ParseContinueStatement(bool* ok) {
2607 // ContinueStatement ::
2608 // 'continue' Identifier? ';'
2609
2610 int pos = peek_position();
2611 Expect(Token::CONTINUE, CHECK_OK);
2612 const AstRawString* label = NULL;
2613 Token::Value tok = peek();
2614 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2615 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2616 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2617 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2618 }
2619 IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
2620 if (target == NULL) {
2621 // Illegal continue statement.
2622 MessageTemplate::Template message = MessageTemplate::kIllegalContinue;
2623 if (label != NULL) {
2624 message = MessageTemplate::kUnknownLabel;
2625 }
2626 ParserTraits::ReportMessage(message, label);
2627 *ok = false;
2628 return NULL;
2629 }
2630 ExpectSemicolon(CHECK_OK);
2631 return factory()->NewContinueStatement(target, pos);
2632}
2633
2634
2635Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2636 bool* ok) {
2637 // BreakStatement ::
2638 // 'break' Identifier? ';'
2639
2640 int pos = peek_position();
2641 Expect(Token::BREAK, CHECK_OK);
2642 const AstRawString* label = NULL;
2643 Token::Value tok = peek();
2644 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2645 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2646 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2647 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2648 }
2649 // Parse labeled break statements that target themselves into
2650 // empty statements, e.g. 'l1: l2: l3: break l2;'
2651 if (label != NULL && ContainsLabel(labels, label)) {
2652 ExpectSemicolon(CHECK_OK);
2653 return factory()->NewEmptyStatement(pos);
2654 }
2655 BreakableStatement* target = NULL;
2656 target = LookupBreakTarget(label, CHECK_OK);
2657 if (target == NULL) {
2658 // Illegal break statement.
2659 MessageTemplate::Template message = MessageTemplate::kIllegalBreak;
2660 if (label != NULL) {
2661 message = MessageTemplate::kUnknownLabel;
2662 }
2663 ParserTraits::ReportMessage(message, label);
2664 *ok = false;
2665 return NULL;
2666 }
2667 ExpectSemicolon(CHECK_OK);
2668 return factory()->NewBreakStatement(target, pos);
2669}
2670
2671
2672Statement* Parser::ParseReturnStatement(bool* ok) {
2673 // ReturnStatement ::
2674 // 'return' Expression? ';'
2675
2676 // Consume the return token. It is necessary to do that before
2677 // reporting any errors on it, because of the way errors are
2678 // reported (underlining).
2679 Expect(Token::RETURN, CHECK_OK);
2680 Scanner::Location loc = scanner()->location();
2681 function_state_->set_return_location(loc);
2682
2683 Token::Value tok = peek();
2684 Statement* result;
2685 Expression* return_value;
2686 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
2687 tok == Token::SEMICOLON ||
2688 tok == Token::RBRACE ||
2689 tok == Token::EOS) {
2690 if (IsSubclassConstructor(function_state_->kind())) {
2691 return_value = ThisExpression(scope_, factory(), loc.beg_pos);
2692 } else {
2693 return_value = GetLiteralUndefined(position());
2694 }
2695 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002696 int pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002697
2698 if (IsSubclassConstructor(function_state_->kind())) {
Ben Murdochc5610432016-08-08 18:44:38 +01002699 // Because of the return code rewriting that happens in case of a subclass
2700 // constructor we don't want to accept tail calls, therefore we don't set
2701 // ReturnExprScope to kInsideValidReturnStatement here.
2702 return_value = ParseExpression(true, CHECK_OK);
2703
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002704 // For subclass constructors we need to return this in case of undefined
Ben Murdoch097c5b22016-05-18 11:27:45 +01002705 // return a Smi (transformed into an exception in the ConstructStub)
2706 // for a non object.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002707 //
2708 // return expr;
2709 //
2710 // Is rewritten as:
2711 //
2712 // return (temp = expr) === undefined ? this :
Ben Murdoch097c5b22016-05-18 11:27:45 +01002713 // %_IsJSReceiver(temp) ? temp : 1;
2714
2715 // temp = expr
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002716 Variable* temp = scope_->NewTemporary(
2717 ast_value_factory()->empty_string());
2718 Assignment* assign = factory()->NewAssignment(
2719 Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
2720
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002721 // %_IsJSReceiver(temp)
2722 ZoneList<Expression*>* is_spec_object_args =
2723 new (zone()) ZoneList<Expression*>(1, zone());
2724 is_spec_object_args->Add(factory()->NewVariableProxy(temp), zone());
2725 Expression* is_spec_object_call = factory()->NewCallRuntime(
2726 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
2727
2728 // %_IsJSReceiver(temp) ? temp : throw_expression
2729 Expression* is_object_conditional = factory()->NewConditional(
2730 is_spec_object_call, factory()->NewVariableProxy(temp),
Ben Murdoch097c5b22016-05-18 11:27:45 +01002731 factory()->NewSmiLiteral(1, pos), pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002732
2733 // temp === undefined
2734 Expression* is_undefined = factory()->NewCompareOperation(
2735 Token::EQ_STRICT, assign,
2736 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), pos);
2737
2738 // is_undefined ? this : is_object_conditional
2739 return_value = factory()->NewConditional(
2740 is_undefined, ThisExpression(scope_, factory(), pos),
2741 is_object_conditional, pos);
Ben Murdochc5610432016-08-08 18:44:38 +01002742 } else {
2743 ReturnExprScope maybe_allow_tail_calls(
2744 function_state_, ReturnExprContext::kInsideValidReturnStatement);
2745 return_value = ParseExpression(true, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002746
Ben Murdochc5610432016-08-08 18:44:38 +01002747 if (allow_tailcalls() && !is_sloppy(language_mode())) {
2748 // ES6 14.6.1 Static Semantics: IsInTailPosition
2749 function_state_->AddImplicitTailCallExpression(return_value);
2750 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002751 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002752 }
2753 ExpectSemicolon(CHECK_OK);
2754
2755 if (is_generator()) {
Ben Murdochda12d292016-06-02 14:46:10 +01002756 return_value = BuildIteratorResult(return_value, true);
Ben Murdochc5610432016-08-08 18:44:38 +01002757 } else if (is_async_function()) {
2758 return_value = BuildPromiseResolve(return_value, return_value->position());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002759 }
2760
Ben Murdochda12d292016-06-02 14:46:10 +01002761 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2762
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002763 Scope* decl_scope = scope_->DeclarationScope();
2764 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
2765 ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
2766 *ok = false;
2767 return NULL;
2768 }
2769 return result;
2770}
2771
2772
2773Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
2774 bool* ok) {
2775 // WithStatement ::
2776 // 'with' '(' Expression ')' Statement
2777
2778 Expect(Token::WITH, CHECK_OK);
2779 int pos = position();
2780
2781 if (is_strict(language_mode())) {
2782 ReportMessage(MessageTemplate::kStrictWith);
2783 *ok = false;
2784 return NULL;
2785 }
2786
2787 Expect(Token::LPAREN, CHECK_OK);
2788 Expression* expr = ParseExpression(true, CHECK_OK);
2789 Expect(Token::RPAREN, CHECK_OK);
2790
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002791 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
Ben Murdochda12d292016-06-02 14:46:10 +01002792 Statement* body;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002793 { BlockState block_state(&scope_, with_scope);
2794 with_scope->set_start_position(scanner()->peek_location().beg_pos);
Ben Murdochda12d292016-06-02 14:46:10 +01002795 body = ParseScopedStatement(labels, true, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002796 with_scope->set_end_position(scanner()->location().end_pos);
2797 }
2798 return factory()->NewWithStatement(with_scope, expr, body, pos);
2799}
2800
2801
2802CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2803 // CaseClause ::
2804 // 'case' Expression ':' StatementList
2805 // 'default' ':' StatementList
2806
2807 Expression* label = NULL; // NULL expression indicates default case
2808 if (peek() == Token::CASE) {
2809 Expect(Token::CASE, CHECK_OK);
2810 label = ParseExpression(true, CHECK_OK);
2811 } else {
2812 Expect(Token::DEFAULT, CHECK_OK);
2813 if (*default_seen_ptr) {
2814 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
2815 *ok = false;
2816 return NULL;
2817 }
2818 *default_seen_ptr = true;
2819 }
2820 Expect(Token::COLON, CHECK_OK);
2821 int pos = position();
2822 ZoneList<Statement*>* statements =
2823 new(zone()) ZoneList<Statement*>(5, zone());
2824 Statement* stat = NULL;
2825 while (peek() != Token::CASE &&
2826 peek() != Token::DEFAULT &&
2827 peek() != Token::RBRACE) {
2828 stat = ParseStatementListItem(CHECK_OK);
2829 statements->Add(stat, zone());
2830 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002831 return factory()->NewCaseClause(label, statements, pos);
2832}
2833
2834
2835Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
2836 bool* ok) {
2837 // SwitchStatement ::
2838 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2839 // In order to get the CaseClauses to execute in their own lexical scope,
2840 // but without requiring downstream code to have special scope handling
2841 // code for switch statements, desugar into blocks as follows:
2842 // { // To group the statements--harmless to evaluate Expression in scope
2843 // .tag_variable = Expression;
2844 // { // To give CaseClauses a scope
2845 // switch (.tag_variable) { CaseClause* }
2846 // }
2847 // }
2848
2849 Block* switch_block =
2850 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
2851 int switch_pos = peek_position();
2852
2853 Expect(Token::SWITCH, CHECK_OK);
2854 Expect(Token::LPAREN, CHECK_OK);
2855 Expression* tag = ParseExpression(true, CHECK_OK);
2856 Expect(Token::RPAREN, CHECK_OK);
2857
2858 Variable* tag_variable =
2859 scope_->NewTemporary(ast_value_factory()->dot_switch_tag_string());
2860 Assignment* tag_assign = factory()->NewAssignment(
2861 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
2862 tag->position());
2863 Statement* tag_statement =
2864 factory()->NewExpressionStatement(tag_assign, RelocInfo::kNoPosition);
2865 switch_block->statements()->Add(tag_statement, zone());
2866
2867 // make statement: undefined;
2868 // This is needed so the tag isn't returned as the value, in case the switch
2869 // statements don't have a value.
2870 switch_block->statements()->Add(
2871 factory()->NewExpressionStatement(
2872 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
2873 RelocInfo::kNoPosition),
2874 zone());
2875
2876 Block* cases_block =
2877 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
2878 Scope* cases_scope = NewScope(scope_, BLOCK_SCOPE);
2879 cases_scope->SetNonlinear();
2880
2881 SwitchStatement* switch_statement =
2882 factory()->NewSwitchStatement(labels, switch_pos);
2883
2884 cases_scope->set_start_position(scanner()->location().beg_pos);
2885 {
2886 BlockState cases_block_state(&scope_, cases_scope);
2887 Target target(&this->target_stack_, switch_statement);
2888
2889 Expression* tag_read = factory()->NewVariableProxy(tag_variable);
2890
2891 bool default_seen = false;
2892 ZoneList<CaseClause*>* cases =
2893 new (zone()) ZoneList<CaseClause*>(4, zone());
2894 Expect(Token::LBRACE, CHECK_OK);
2895 while (peek() != Token::RBRACE) {
2896 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
2897 cases->Add(clause, zone());
2898 }
2899 switch_statement->Initialize(tag_read, cases);
2900 cases_block->statements()->Add(switch_statement, zone());
2901 }
2902 Expect(Token::RBRACE, CHECK_OK);
2903
2904 cases_scope->set_end_position(scanner()->location().end_pos);
2905 cases_scope = cases_scope->FinalizeBlockScope();
2906 cases_block->set_scope(cases_scope);
2907
2908 switch_block->statements()->Add(cases_block, zone());
2909
2910 return switch_block;
2911}
2912
2913
2914Statement* Parser::ParseThrowStatement(bool* ok) {
2915 // ThrowStatement ::
2916 // 'throw' Expression ';'
2917
2918 Expect(Token::THROW, CHECK_OK);
2919 int pos = position();
2920 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
2921 ReportMessage(MessageTemplate::kNewlineAfterThrow);
2922 *ok = false;
2923 return NULL;
2924 }
2925 Expression* exception = ParseExpression(true, CHECK_OK);
2926 ExpectSemicolon(CHECK_OK);
2927
2928 return factory()->NewExpressionStatement(
2929 factory()->NewThrow(exception, pos), pos);
2930}
2931
2932
2933TryStatement* Parser::ParseTryStatement(bool* ok) {
2934 // TryStatement ::
2935 // 'try' Block Catch
2936 // 'try' Block Finally
2937 // 'try' Block Catch Finally
2938 //
2939 // Catch ::
2940 // 'catch' '(' Identifier ')' Block
2941 //
2942 // Finally ::
2943 // 'finally' Block
2944
2945 Expect(Token::TRY, CHECK_OK);
2946 int pos = position();
2947
Ben Murdoch097c5b22016-05-18 11:27:45 +01002948 Block* try_block;
2949 {
Ben Murdochc5610432016-08-08 18:44:38 +01002950 ReturnExprScope no_tail_calls(function_state_,
2951 ReturnExprContext::kInsideTryBlock);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002952 try_block = ParseBlock(NULL, CHECK_OK);
2953 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002954
2955 Token::Value tok = peek();
2956 if (tok != Token::CATCH && tok != Token::FINALLY) {
2957 ReportMessage(MessageTemplate::kNoCatchOrFinally);
2958 *ok = false;
2959 return NULL;
2960 }
2961
2962 Scope* catch_scope = NULL;
2963 Variable* catch_variable = NULL;
2964 Block* catch_block = NULL;
Ben Murdochc5610432016-08-08 18:44:38 +01002965 TailCallExpressionList tail_call_expressions_in_catch_block(zone());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002966 if (tok == Token::CATCH) {
2967 Consume(Token::CATCH);
2968
2969 Expect(Token::LPAREN, CHECK_OK);
2970 catch_scope = NewScope(scope_, CATCH_SCOPE);
2971 catch_scope->set_start_position(scanner()->location().beg_pos);
2972
Ben Murdoch097c5b22016-05-18 11:27:45 +01002973 ExpressionClassifier pattern_classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002974 Expression* pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
2975 ValidateBindingPattern(&pattern_classifier, CHECK_OK);
2976
2977 const AstRawString* name = ast_value_factory()->dot_catch_string();
2978 bool is_simple = pattern->IsVariableProxy();
2979 if (is_simple) {
2980 auto proxy = pattern->AsVariableProxy();
2981 scope_->RemoveUnresolved(proxy);
2982 name = proxy->raw_name();
2983 }
2984
2985 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
2986 Variable::NORMAL);
2987
2988 Expect(Token::RPAREN, CHECK_OK);
2989
2990 {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002991 CollectExpressionsInTailPositionToListScope
Ben Murdochc5610432016-08-08 18:44:38 +01002992 collect_tail_call_expressions_scope(
2993 function_state_, &tail_call_expressions_in_catch_block);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002994 BlockState block_state(&scope_, catch_scope);
2995
2996 // TODO(adamk): Make a version of ParseBlock that takes a scope and
2997 // a block.
2998 catch_block =
2999 factory()->NewBlock(nullptr, 16, false, RelocInfo::kNoPosition);
3000 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
3001
3002 block_scope->set_start_position(scanner()->location().beg_pos);
3003 {
3004 BlockState block_state(&scope_, block_scope);
3005 Target target(&this->target_stack_, catch_block);
3006
3007 if (!is_simple) {
3008 DeclarationDescriptor descriptor;
3009 descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
3010 descriptor.parser = this;
3011 descriptor.scope = scope_;
3012 descriptor.hoist_scope = nullptr;
3013 descriptor.mode = LET;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003014 descriptor.declaration_pos = pattern->position();
3015 descriptor.initialization_pos = pattern->position();
3016
Ben Murdochc5610432016-08-08 18:44:38 +01003017 // Initializer position for variables declared by the pattern.
3018 const int initializer_position = position();
3019
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003020 DeclarationParsingResult::Declaration decl(
Ben Murdochc5610432016-08-08 18:44:38 +01003021 pattern, initializer_position,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003022 factory()->NewVariableProxy(catch_variable));
3023
Ben Murdochda12d292016-06-02 14:46:10 +01003024 Block* init_block =
3025 factory()->NewBlock(nullptr, 8, true, RelocInfo::kNoPosition);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003026 PatternRewriter::DeclareAndInitializeVariables(
Ben Murdochda12d292016-06-02 14:46:10 +01003027 init_block, &descriptor, &decl, nullptr, CHECK_OK);
3028 catch_block->statements()->Add(init_block, zone());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003029 }
3030
3031 Expect(Token::LBRACE, CHECK_OK);
3032 while (peek() != Token::RBRACE) {
3033 Statement* stat = ParseStatementListItem(CHECK_OK);
3034 if (stat && !stat->IsEmpty()) {
3035 catch_block->statements()->Add(stat, zone());
3036 }
3037 }
3038 Consume(Token::RBRACE);
3039 }
3040 block_scope->set_end_position(scanner()->location().end_pos);
3041 block_scope = block_scope->FinalizeBlockScope();
3042 catch_block->set_scope(block_scope);
3043 }
3044
3045 catch_scope->set_end_position(scanner()->location().end_pos);
3046 tok = peek();
3047 }
3048
3049 Block* finally_block = NULL;
3050 DCHECK(tok == Token::FINALLY || catch_block != NULL);
3051 if (tok == Token::FINALLY) {
3052 Consume(Token::FINALLY);
3053 finally_block = ParseBlock(NULL, CHECK_OK);
3054 }
3055
3056 // Simplify the AST nodes by converting:
3057 // 'try B0 catch B1 finally B2'
3058 // to:
3059 // 'try { try B0 catch B1 } finally B2'
3060
3061 if (catch_block != NULL && finally_block != NULL) {
3062 // If we have both, create an inner try/catch.
3063 DCHECK(catch_scope != NULL && catch_variable != NULL);
3064 TryCatchStatement* statement =
3065 factory()->NewTryCatchStatement(try_block, catch_scope, catch_variable,
3066 catch_block, RelocInfo::kNoPosition);
3067 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3068 try_block->statements()->Add(statement, zone());
3069 catch_block = NULL; // Clear to indicate it's been handled.
3070 }
3071
3072 TryStatement* result = NULL;
3073 if (catch_block != NULL) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003074 // For a try-catch construct append return expressions from the catch block
3075 // to the list of return expressions.
Ben Murdochc5610432016-08-08 18:44:38 +01003076 function_state_->tail_call_expressions().Append(
3077 tail_call_expressions_in_catch_block);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003078
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003079 DCHECK(finally_block == NULL);
3080 DCHECK(catch_scope != NULL && catch_variable != NULL);
3081 result = factory()->NewTryCatchStatement(try_block, catch_scope,
3082 catch_variable, catch_block, pos);
3083 } else {
Ben Murdochc5610432016-08-08 18:44:38 +01003084 if (FLAG_harmony_explicit_tailcalls &&
3085 tail_call_expressions_in_catch_block.has_explicit_tail_calls()) {
3086 // TODO(ishell): update chapter number.
3087 // ES8 XX.YY.ZZ
3088 ReportMessageAt(tail_call_expressions_in_catch_block.location(),
3089 MessageTemplate::kUnexpectedTailCallInCatchBlock);
3090 *ok = false;
3091 return NULL;
3092 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003093 DCHECK(finally_block != NULL);
3094 result = factory()->NewTryFinallyStatement(try_block, finally_block, pos);
3095 }
3096
3097 return result;
3098}
3099
3100
3101DoWhileStatement* Parser::ParseDoWhileStatement(
3102 ZoneList<const AstRawString*>* labels, bool* ok) {
3103 // DoStatement ::
3104 // 'do' Statement 'while' '(' Expression ')' ';'
3105
3106 DoWhileStatement* loop =
3107 factory()->NewDoWhileStatement(labels, peek_position());
3108 Target target(&this->target_stack_, loop);
3109
3110 Expect(Token::DO, CHECK_OK);
Ben Murdochda12d292016-06-02 14:46:10 +01003111 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003112 Expect(Token::WHILE, CHECK_OK);
3113 Expect(Token::LPAREN, CHECK_OK);
3114
3115 Expression* cond = ParseExpression(true, CHECK_OK);
3116 Expect(Token::RPAREN, CHECK_OK);
3117
3118 // Allow do-statements to be terminated with and without
3119 // semi-colons. This allows code such as 'do;while(0)return' to
3120 // parse, which would not be the case if we had used the
3121 // ExpectSemicolon() functionality here.
3122 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
3123
3124 if (loop != NULL) loop->Initialize(cond, body);
3125 return loop;
3126}
3127
3128
3129WhileStatement* Parser::ParseWhileStatement(
3130 ZoneList<const AstRawString*>* labels, bool* ok) {
3131 // WhileStatement ::
3132 // 'while' '(' Expression ')' Statement
3133
3134 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
3135 Target target(&this->target_stack_, loop);
3136
3137 Expect(Token::WHILE, CHECK_OK);
3138 Expect(Token::LPAREN, CHECK_OK);
3139 Expression* cond = ParseExpression(true, CHECK_OK);
3140 Expect(Token::RPAREN, CHECK_OK);
Ben Murdochda12d292016-06-02 14:46:10 +01003141 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003142
3143 if (loop != NULL) loop->Initialize(cond, body);
3144 return loop;
3145}
3146
3147
3148// !%_IsJSReceiver(result = iterator.next()) &&
3149// %ThrowIteratorResultNotAnObject(result)
3150Expression* Parser::BuildIteratorNextResult(Expression* iterator,
3151 Variable* result, int pos) {
3152 Expression* next_literal = factory()->NewStringLiteral(
3153 ast_value_factory()->next_string(), RelocInfo::kNoPosition);
3154 Expression* next_property =
3155 factory()->NewProperty(iterator, next_literal, RelocInfo::kNoPosition);
3156 ZoneList<Expression*>* next_arguments =
3157 new (zone()) ZoneList<Expression*>(0, zone());
3158 Expression* next_call =
3159 factory()->NewCall(next_property, next_arguments, pos);
3160 Expression* result_proxy = factory()->NewVariableProxy(result);
3161 Expression* left =
3162 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
3163
3164 // %_IsJSReceiver(...)
3165 ZoneList<Expression*>* is_spec_object_args =
3166 new (zone()) ZoneList<Expression*>(1, zone());
3167 is_spec_object_args->Add(left, zone());
3168 Expression* is_spec_object_call = factory()->NewCallRuntime(
3169 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
3170
3171 // %ThrowIteratorResultNotAnObject(result)
3172 Expression* result_proxy_again = factory()->NewVariableProxy(result);
3173 ZoneList<Expression*>* throw_arguments =
3174 new (zone()) ZoneList<Expression*>(1, zone());
3175 throw_arguments->Add(result_proxy_again, zone());
3176 Expression* throw_call = factory()->NewCallRuntime(
3177 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
3178
3179 return factory()->NewBinaryOperation(
3180 Token::AND,
3181 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
3182 throw_call, pos);
3183}
3184
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003185void Parser::InitializeForEachStatement(ForEachStatement* stmt,
3186 Expression* each, Expression* subject,
Ben Murdochc5610432016-08-08 18:44:38 +01003187 Statement* body, int each_keyword_pos) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003188 ForOfStatement* for_of = stmt->AsForOfStatement();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003189 if (for_of != NULL) {
Ben Murdochc5610432016-08-08 18:44:38 +01003190 InitializeForOfStatement(for_of, each, subject, body, each_keyword_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003191 } else {
Ben Murdochda12d292016-06-02 14:46:10 +01003192 if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003193 Variable* temp =
3194 scope_->NewTemporary(ast_value_factory()->empty_string());
3195 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3196 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment(
3197 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy,
3198 RelocInfo::kNoPosition),
3199 scope_);
3200 auto block =
3201 factory()->NewBlock(nullptr, 2, false, RelocInfo::kNoPosition);
3202 block->statements()->Add(factory()->NewExpressionStatement(
3203 assign_each, RelocInfo::kNoPosition),
3204 zone());
3205 block->statements()->Add(body, zone());
3206 body = block;
3207 each = factory()->NewVariableProxy(temp);
3208 }
Ben Murdochc5610432016-08-08 18:44:38 +01003209 stmt->AsForInStatement()->Initialize(each, subject, body);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003210 }
3211}
3212
Ben Murdochda12d292016-06-02 14:46:10 +01003213void Parser::InitializeForOfStatement(ForOfStatement* for_of, Expression* each,
3214 Expression* iterable, Statement* body,
Ben Murdochc5610432016-08-08 18:44:38 +01003215 int next_result_pos) {
Ben Murdochda12d292016-06-02 14:46:10 +01003216 Variable* iterator =
3217 scope_->NewTemporary(ast_value_factory()->dot_iterator_string());
3218 Variable* result =
3219 scope_->NewTemporary(ast_value_factory()->dot_result_string());
3220
3221 Expression* assign_iterator;
3222 Expression* next_result;
3223 Expression* result_done;
3224 Expression* assign_each;
3225
Ben Murdochc5610432016-08-08 18:44:38 +01003226 int get_iterator_pos = iterable->position();
Ben Murdochda12d292016-06-02 14:46:10 +01003227
3228 // iterator = iterable[Symbol.iterator]()
3229 assign_iterator = factory()->NewAssignment(
3230 Token::ASSIGN, factory()->NewVariableProxy(iterator),
3231 GetIterator(iterable, factory(), get_iterator_pos), iterable->position());
3232
3233 // !%_IsJSReceiver(result = iterator.next()) &&
3234 // %ThrowIteratorResultNotAnObject(result)
3235 {
3236 // result = iterator.next()
3237 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
3238 next_result =
3239 BuildIteratorNextResult(iterator_proxy, result, next_result_pos);
3240 }
3241
3242 // result.done
3243 {
3244 Expression* done_literal = factory()->NewStringLiteral(
3245 ast_value_factory()->done_string(), RelocInfo::kNoPosition);
3246 Expression* result_proxy = factory()->NewVariableProxy(result);
3247 result_done = factory()->NewProperty(result_proxy, done_literal,
3248 RelocInfo::kNoPosition);
3249 }
3250
3251 // each = result.value
3252 {
3253 Expression* value_literal = factory()->NewStringLiteral(
3254 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
3255 Expression* result_proxy = factory()->NewVariableProxy(result);
3256 Expression* result_value = factory()->NewProperty(
3257 result_proxy, value_literal, RelocInfo::kNoPosition);
3258 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
3259 RelocInfo::kNoPosition);
3260 if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
3261 assign_each = PatternRewriter::RewriteDestructuringAssignment(
3262 this, assign_each->AsAssignment(), scope_);
3263 }
3264 }
3265
Ben Murdochc5610432016-08-08 18:44:38 +01003266 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
3267 assign_each);
Ben Murdochda12d292016-06-02 14:46:10 +01003268}
3269
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003270Statement* Parser::DesugarLexicalBindingsInForStatement(
Ben Murdoch097c5b22016-05-18 11:27:45 +01003271 Scope* inner_scope, VariableMode mode, ZoneList<const AstRawString*>* names,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003272 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3273 Statement* body, bool* ok) {
3274 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
3275 // copied into a new environment. Moreover, the "next" statement must be
3276 // evaluated not in the environment of the just completed iteration but in
3277 // that of the upcoming one. We achieve this with the following desugaring.
3278 // Extra care is needed to preserve the completion value of the original loop.
3279 //
3280 // We are given a for statement of the form
3281 //
3282 // labels: for (let/const x = i; cond; next) body
3283 //
3284 // and rewrite it as follows. Here we write {{ ... }} for init-blocks, ie.,
3285 // blocks whose ignore_completion_value_ flag is set.
3286 //
3287 // {
3288 // let/const x = i;
3289 // temp_x = x;
3290 // first = 1;
3291 // undefined;
3292 // outer: for (;;) {
3293 // let/const x = temp_x;
3294 // {{ if (first == 1) {
3295 // first = 0;
3296 // } else {
3297 // next;
3298 // }
3299 // flag = 1;
3300 // if (!cond) break;
3301 // }}
3302 // labels: for (; flag == 1; flag = 0, temp_x = x) {
3303 // body
3304 // }
3305 // {{ if (flag == 1) // Body used break.
3306 // break;
3307 // }}
3308 // }
3309 // }
3310
3311 DCHECK(names->length() > 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003312 ZoneList<Variable*> temps(names->length(), zone());
3313
3314 Block* outer_block = factory()->NewBlock(NULL, names->length() + 4, false,
3315 RelocInfo::kNoPosition);
3316
3317 // Add statement: let/const x = i.
3318 outer_block->statements()->Add(init, zone());
3319
3320 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
3321
3322 // For each lexical variable x:
3323 // make statement: temp_x = x.
3324 for (int i = 0; i < names->length(); i++) {
3325 VariableProxy* proxy = NewUnresolved(names->at(i), LET);
3326 Variable* temp = scope_->NewTemporary(temp_name);
3327 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3328 Assignment* assignment = factory()->NewAssignment(
3329 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3330 Statement* assignment_statement = factory()->NewExpressionStatement(
3331 assignment, RelocInfo::kNoPosition);
3332 outer_block->statements()->Add(assignment_statement, zone());
3333 temps.Add(temp, zone());
3334 }
3335
3336 Variable* first = NULL;
3337 // Make statement: first = 1.
3338 if (next) {
3339 first = scope_->NewTemporary(temp_name);
3340 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3341 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3342 Assignment* assignment = factory()->NewAssignment(
3343 Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition);
3344 Statement* assignment_statement =
3345 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3346 outer_block->statements()->Add(assignment_statement, zone());
3347 }
3348
3349 // make statement: undefined;
3350 outer_block->statements()->Add(
3351 factory()->NewExpressionStatement(
3352 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3353 RelocInfo::kNoPosition),
3354 zone());
3355
3356 // Make statement: outer: for (;;)
3357 // Note that we don't actually create the label, or set this loop up as an
3358 // explicit break target, instead handing it directly to those nodes that
3359 // need to know about it. This should be safe because we don't run any code
3360 // in this function that looks up break targets.
3361 ForStatement* outer_loop =
3362 factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3363 outer_block->statements()->Add(outer_loop, zone());
Ben Murdoch097c5b22016-05-18 11:27:45 +01003364 outer_block->set_scope(scope_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003365
3366 Block* inner_block =
3367 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003368 {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003369 BlockState block_state(&scope_, inner_scope);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003370
Ben Murdoch097c5b22016-05-18 11:27:45 +01003371 Block* ignore_completion_block = factory()->NewBlock(
3372 NULL, names->length() + 3, true, RelocInfo::kNoPosition);
3373 ZoneList<Variable*> inner_vars(names->length(), zone());
3374 // For each let variable x:
3375 // make statement: let/const x = temp_x.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003376 for (int i = 0; i < names->length(); i++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003377 VariableProxy* proxy = NewUnresolved(names->at(i), mode);
3378 Declaration* declaration = factory()->NewVariableDeclaration(
3379 proxy, mode, scope_, RelocInfo::kNoPosition);
3380 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3381 inner_vars.Add(declaration->proxy()->var(), zone());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003382 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003383 Assignment* assignment = factory()->NewAssignment(
Ben Murdoch097c5b22016-05-18 11:27:45 +01003384 Token::INIT, proxy, temp_proxy, RelocInfo::kNoPosition);
3385 Statement* assignment_statement =
3386 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3387 DCHECK(init->position() != RelocInfo::kNoPosition);
3388 proxy->var()->set_initializer_position(init->position());
3389 ignore_completion_block->statements()->Add(assignment_statement, zone());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003390 }
3391
Ben Murdoch097c5b22016-05-18 11:27:45 +01003392 // Make statement: if (first == 1) { first = 0; } else { next; }
3393 if (next) {
3394 DCHECK(first);
3395 Expression* compare = NULL;
3396 // Make compare expression: first == 1.
3397 {
3398 Expression* const1 =
3399 factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3400 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3401 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
3402 RelocInfo::kNoPosition);
3403 }
3404 Statement* clear_first = NULL;
3405 // Make statement: first = 0.
3406 {
3407 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3408 Expression* const0 =
3409 factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3410 Assignment* assignment = factory()->NewAssignment(
3411 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition);
3412 clear_first = factory()->NewExpressionStatement(assignment,
3413 RelocInfo::kNoPosition);
3414 }
3415 Statement* clear_first_or_next = factory()->NewIfStatement(
3416 compare, clear_first, next, RelocInfo::kNoPosition);
3417 ignore_completion_block->statements()->Add(clear_first_or_next, zone());
3418 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003419
Ben Murdoch097c5b22016-05-18 11:27:45 +01003420 Variable* flag = scope_->NewTemporary(temp_name);
3421 // Make statement: flag = 1.
3422 {
3423 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3424 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3425 Assignment* assignment = factory()->NewAssignment(
3426 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3427 Statement* assignment_statement =
3428 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3429 ignore_completion_block->statements()->Add(assignment_statement, zone());
3430 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003431
Ben Murdoch097c5b22016-05-18 11:27:45 +01003432 // Make statement: if (!cond) break.
3433 if (cond) {
3434 Statement* stop =
3435 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3436 Statement* noop = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3437 ignore_completion_block->statements()->Add(
3438 factory()->NewIfStatement(cond, noop, stop, cond->position()),
3439 zone());
3440 }
3441
3442 inner_block->statements()->Add(ignore_completion_block, zone());
3443 // Make cond expression for main loop: flag == 1.
3444 Expression* flag_cond = NULL;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003445 {
3446 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3447 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003448 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3449 RelocInfo::kNoPosition);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003450 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003451
Ben Murdoch097c5b22016-05-18 11:27:45 +01003452 // Create chain of expressions "flag = 0, temp_x = x, ..."
3453 Statement* compound_next_statement = NULL;
3454 {
3455 Expression* compound_next = NULL;
3456 // Make expression: flag = 0.
3457 {
3458 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3459 Expression* const0 =
3460 factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3461 compound_next = factory()->NewAssignment(
3462 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition);
3463 }
3464
3465 // Make the comma-separated list of temp_x = x assignments.
3466 int inner_var_proxy_pos = scanner()->location().beg_pos;
3467 for (int i = 0; i < names->length(); i++) {
3468 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3469 VariableProxy* proxy =
3470 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
3471 Assignment* assignment = factory()->NewAssignment(
3472 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3473 compound_next = factory()->NewBinaryOperation(
3474 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
3475 }
3476
3477 compound_next_statement = factory()->NewExpressionStatement(
3478 compound_next, RelocInfo::kNoPosition);
3479 }
3480
3481 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3482 // Note that we re-use the original loop node, which retains its labels
3483 // and ensures that any break or continue statements in body point to
3484 // the right place.
3485 loop->Initialize(NULL, flag_cond, compound_next_statement, body);
3486 inner_block->statements()->Add(loop, zone());
3487
3488 // Make statement: {{if (flag == 1) break;}}
3489 {
3490 Expression* compare = NULL;
3491 // Make compare expresion: flag == 1.
3492 {
3493 Expression* const1 =
3494 factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3495 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3496 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3497 RelocInfo::kNoPosition);
3498 }
3499 Statement* stop =
3500 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3501 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3502 Statement* if_flag_break = factory()->NewIfStatement(
3503 compare, stop, empty, RelocInfo::kNoPosition);
3504 Block* ignore_completion_block =
3505 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
3506 ignore_completion_block->statements()->Add(if_flag_break, zone());
3507 inner_block->statements()->Add(ignore_completion_block, zone());
3508 }
3509
3510 inner_scope->set_end_position(scanner()->location().end_pos);
3511 inner_block->set_scope(inner_scope);
3512 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003513
3514 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3515 return outer_block;
3516}
3517
Ben Murdochda12d292016-06-02 14:46:10 +01003518Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels,
3519 bool legacy, bool* ok) {
3520 if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
3521 (legacy && allow_harmony_restrictive_declarations())) {
3522 return ParseSubStatement(labels, kDisallowLabelledFunctionStatement, ok);
3523 } else {
3524 if (legacy) {
3525 ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration];
3526 }
3527 // Make a block around the statement for a lexical binding
3528 // is introduced by a FunctionDeclaration.
3529 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
Ben Murdochc5610432016-08-08 18:44:38 +01003530 body_scope->set_start_position(scanner()->location().beg_pos);
Ben Murdochda12d292016-06-02 14:46:10 +01003531 BlockState block_state(&scope_, body_scope);
3532 Block* block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
Ben Murdochc5610432016-08-08 18:44:38 +01003533 Statement* body = ParseFunctionDeclaration(CHECK_OK);
Ben Murdochda12d292016-06-02 14:46:10 +01003534 block->statements()->Add(body, zone());
3535 body_scope->set_end_position(scanner()->location().end_pos);
3536 body_scope = body_scope->FinalizeBlockScope();
3537 block->set_scope(body_scope);
3538 return block;
3539 }
3540}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003541
3542Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3543 bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003544 int stmt_pos = peek_position();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003545 Statement* init = NULL;
3546 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3547
3548 // Create an in-between scope for let-bound iteration variables.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003549 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003550
3551 BlockState block_state(&scope_, for_scope);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003552 Expect(Token::FOR, CHECK_OK);
3553 Expect(Token::LPAREN, CHECK_OK);
3554 for_scope->set_start_position(scanner()->location().beg_pos);
Ben Murdochc5610432016-08-08 18:44:38 +01003555 for_scope->set_is_hidden();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003556 DeclarationParsingResult parsing_result;
3557 if (peek() != Token::SEMICOLON) {
Ben Murdochc5610432016-08-08 18:44:38 +01003558 if (peek() == Token::VAR || peek() == Token::CONST ||
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003559 (peek() == Token::LET && IsNextLetKeyword())) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003560 ParseVariableDeclarations(kForStatement, &parsing_result, nullptr,
3561 CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003562
Ben Murdochda12d292016-06-02 14:46:10 +01003563 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003564 int each_beg_pos = scanner()->location().beg_pos;
3565 int each_end_pos = scanner()->location().end_pos;
3566
Ben Murdoch097c5b22016-05-18 11:27:45 +01003567 if (CheckInOrOf(&mode, ok)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003568 if (!*ok) return nullptr;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003569 if (parsing_result.declarations.length() != 1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003570 ParserTraits::ReportMessageAt(
3571 parsing_result.bindings_loc,
Ben Murdoch097c5b22016-05-18 11:27:45 +01003572 MessageTemplate::kForInOfLoopMultiBindings,
3573 ForEachStatement::VisitModeString(mode));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003574 *ok = false;
3575 return nullptr;
3576 }
3577 DeclarationParsingResult::Declaration& decl =
3578 parsing_result.declarations[0];
3579 if (parsing_result.first_initializer_loc.IsValid() &&
3580 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE ||
3581 IsLexicalVariableMode(parsing_result.descriptor.mode) ||
Ben Murdochc5610432016-08-08 18:44:38 +01003582 !decl.pattern->IsVariableProxy() || allow_harmony_for_in())) {
3583 // Only increment the use count if we would have let this through
3584 // without the flag.
3585 if (allow_harmony_for_in()) {
3586 ++use_counts_[v8::Isolate::kForInInitializer];
3587 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01003588 ParserTraits::ReportMessageAt(
3589 parsing_result.first_initializer_loc,
3590 MessageTemplate::kForInOfLoopInitializer,
3591 ForEachStatement::VisitModeString(mode));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003592 *ok = false;
3593 return nullptr;
3594 }
3595
3596 Block* init_block = nullptr;
3597
3598 // special case for legacy for (var/const x =.... in)
3599 if (!IsLexicalVariableMode(parsing_result.descriptor.mode) &&
3600 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
Ben Murdochc5610432016-08-08 18:44:38 +01003601 DCHECK(!allow_harmony_for_in());
Ben Murdoch097c5b22016-05-18 11:27:45 +01003602 ++use_counts_[v8::Isolate::kForInInitializer];
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003603 const AstRawString* name =
3604 decl.pattern->AsVariableProxy()->raw_name();
3605 VariableProxy* single_var = scope_->NewUnresolved(
3606 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos);
3607 init_block = factory()->NewBlock(
3608 nullptr, 2, true, parsing_result.descriptor.declaration_pos);
3609 init_block->statements()->Add(
3610 factory()->NewExpressionStatement(
3611 factory()->NewAssignment(Token::ASSIGN, single_var,
3612 decl.initializer,
3613 RelocInfo::kNoPosition),
3614 RelocInfo::kNoPosition),
3615 zone());
3616 }
3617
3618 // Rewrite a for-in/of statement of the form
3619 //
3620 // for (let/const/var x in/of e) b
3621 //
3622 // into
3623 //
3624 // {
3625 // <let x' be a temporary variable>
3626 // for (x' in/of e) {
3627 // let/const/var x;
3628 // x = x';
3629 // b;
3630 // }
3631 // let x; // for TDZ
3632 // }
3633
Ben Murdoch097c5b22016-05-18 11:27:45 +01003634 Variable* temp =
3635 scope_->NewTemporary(ast_value_factory()->dot_for_string());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003636 ForEachStatement* loop =
3637 factory()->NewForEachStatement(mode, labels, stmt_pos);
3638 Target target(&this->target_stack_, loop);
3639
Ben Murdochc5610432016-08-08 18:44:38 +01003640 int each_keyword_position = scanner()->location().beg_pos;
3641
Ben Murdoch097c5b22016-05-18 11:27:45 +01003642 Expression* enumerable;
3643 if (mode == ForEachStatement::ITERATE) {
3644 ExpressionClassifier classifier(this);
3645 enumerable = ParseAssignmentExpression(true, &classifier, CHECK_OK);
3646 RewriteNonPattern(&classifier, CHECK_OK);
3647 } else {
3648 enumerable = ParseExpression(true, CHECK_OK);
3649 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003650
3651 Expect(Token::RPAREN, CHECK_OK);
3652
3653 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3654 body_scope->set_start_position(scanner()->location().beg_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003655
3656 Block* body_block =
3657 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3658
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003659 {
Ben Murdochc5610432016-08-08 18:44:38 +01003660 ReturnExprScope no_tail_calls(function_state_,
3661 ReturnExprContext::kInsideForInOfBody);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003662 BlockState block_state(&scope_, body_scope);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003663
Ben Murdochda12d292016-06-02 14:46:10 +01003664 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003665
3666 auto each_initialization_block =
3667 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
3668 {
3669 auto descriptor = parsing_result.descriptor;
3670 descriptor.declaration_pos = RelocInfo::kNoPosition;
3671 descriptor.initialization_pos = RelocInfo::kNoPosition;
3672 decl.initializer = factory()->NewVariableProxy(temp);
3673
3674 PatternRewriter::DeclareAndInitializeVariables(
3675 each_initialization_block, &descriptor, &decl,
3676 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings
3677 : nullptr,
3678 CHECK_OK);
3679 }
3680
3681 body_block->statements()->Add(each_initialization_block, zone());
3682 body_block->statements()->Add(body, zone());
3683 VariableProxy* temp_proxy =
3684 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
Ben Murdochc5610432016-08-08 18:44:38 +01003685 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block,
3686 each_keyword_position);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003687 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003688 body_scope->set_end_position(scanner()->location().end_pos);
3689 body_scope = body_scope->FinalizeBlockScope();
Ben Murdoch097c5b22016-05-18 11:27:45 +01003690 body_block->set_scope(body_scope);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003691
3692 // Create a TDZ for any lexically-bound names.
3693 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) {
3694 DCHECK_NULL(init_block);
3695
3696 init_block =
3697 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
3698
3699 for (int i = 0; i < lexical_bindings.length(); ++i) {
3700 // TODO(adamk): This needs to be some sort of special
3701 // INTERNAL variable that's invisible to the debugger
3702 // but visible to everything else.
Ben Murdoch097c5b22016-05-18 11:27:45 +01003703 VariableProxy* tdz_proxy =
3704 NewUnresolved(lexical_bindings[i], LET);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003705 Declaration* tdz_decl = factory()->NewVariableDeclaration(
3706 tdz_proxy, LET, scope_, RelocInfo::kNoPosition);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003707 Variable* tdz_var = Declare(
3708 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003709 tdz_var->set_initializer_position(position());
3710 }
3711 }
3712
Ben Murdoch097c5b22016-05-18 11:27:45 +01003713 Statement* final_loop = loop->IsForOfStatement()
3714 ? FinalizeForOfStatement(
3715 loop->AsForOfStatement(), RelocInfo::kNoPosition)
3716 : loop;
3717
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003718 for_scope->set_end_position(scanner()->location().end_pos);
3719 for_scope = for_scope->FinalizeBlockScope();
3720 // Parsed for-in loop w/ variable declarations.
3721 if (init_block != nullptr) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003722 init_block->statements()->Add(final_loop, zone());
3723 init_block->set_scope(for_scope);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003724 return init_block;
3725 } else {
3726 DCHECK_NULL(for_scope);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003727 return final_loop;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003728 }
3729 } else {
3730 init = parsing_result.BuildInitializationBlock(
3731 IsLexicalVariableMode(parsing_result.descriptor.mode)
3732 ? &lexical_bindings
3733 : nullptr,
3734 CHECK_OK);
3735 }
3736 } else {
3737 int lhs_beg_pos = peek_position();
Ben Murdoch097c5b22016-05-18 11:27:45 +01003738 ExpressionClassifier classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003739 Expression* expression = ParseExpression(false, &classifier, CHECK_OK);
3740 int lhs_end_pos = scanner()->location().end_pos;
Ben Murdochda12d292016-06-02 14:46:10 +01003741 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003742
3743 bool is_for_each = CheckInOrOf(&mode, ok);
3744 if (!*ok) return nullptr;
Ben Murdochda12d292016-06-02 14:46:10 +01003745 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
3746 expression->IsObjectLiteral());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003747
3748 if (is_destructuring) {
3749 ValidateAssignmentPattern(&classifier, CHECK_OK);
3750 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003751 RewriteNonPattern(&classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003752 }
3753
3754 if (is_for_each) {
3755 if (!is_destructuring) {
3756 expression = this->CheckAndRewriteReferenceExpression(
3757 expression, lhs_beg_pos, lhs_end_pos,
3758 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
3759 }
3760
3761 ForEachStatement* loop =
3762 factory()->NewForEachStatement(mode, labels, stmt_pos);
3763 Target target(&this->target_stack_, loop);
3764
Ben Murdochc5610432016-08-08 18:44:38 +01003765 int each_keyword_position = scanner()->location().beg_pos;
3766
Ben Murdoch097c5b22016-05-18 11:27:45 +01003767 Expression* enumerable;
3768 if (mode == ForEachStatement::ITERATE) {
3769 ExpressionClassifier classifier(this);
3770 enumerable = ParseAssignmentExpression(true, &classifier, CHECK_OK);
3771 RewriteNonPattern(&classifier, CHECK_OK);
3772 } else {
3773 enumerable = ParseExpression(true, CHECK_OK);
3774 }
3775
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003776 Expect(Token::RPAREN, CHECK_OK);
3777
Ben Murdochda12d292016-06-02 14:46:10 +01003778 // For legacy compat reasons, give for loops similar treatment to
3779 // if statements in allowing a function declaration for a body
3780 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01003781 InitializeForEachStatement(loop, expression, enumerable, body,
3782 each_keyword_position);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003783
3784 Statement* final_loop = loop->IsForOfStatement()
3785 ? FinalizeForOfStatement(
3786 loop->AsForOfStatement(), RelocInfo::kNoPosition)
3787 : loop;
3788
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003789 for_scope->set_end_position(scanner()->location().end_pos);
3790 for_scope = for_scope->FinalizeBlockScope();
3791 DCHECK(for_scope == nullptr);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003792 return final_loop;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003793
3794 } else {
3795 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
3796 }
3797 }
3798 }
3799
3800 // Standard 'for' loop
3801 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
3802 Target target(&this->target_stack_, loop);
3803
3804 // Parsed initializer at this point.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003805 Expect(Token::SEMICOLON, CHECK_OK);
3806
Ben Murdoch097c5b22016-05-18 11:27:45 +01003807 Expression* cond = NULL;
3808 Statement* next = NULL;
3809 Statement* body = NULL;
3810
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003811 // If there are let bindings, then condition and the next statement of the
3812 // for loop must be parsed in a new scope.
Ben Murdoch097c5b22016-05-18 11:27:45 +01003813 Scope* inner_scope = scope_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003814 if (lexical_bindings.length() > 0) {
3815 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3816 inner_scope->set_start_position(scanner()->location().beg_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003817 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01003818 {
3819 BlockState block_state(&scope_, inner_scope);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003820
Ben Murdoch097c5b22016-05-18 11:27:45 +01003821 if (peek() != Token::SEMICOLON) {
3822 cond = ParseExpression(true, CHECK_OK);
3823 }
3824 Expect(Token::SEMICOLON, CHECK_OK);
3825
3826 if (peek() != Token::RPAREN) {
3827 Expression* exp = ParseExpression(true, CHECK_OK);
3828 next = factory()->NewExpressionStatement(exp, exp->position());
3829 }
3830 Expect(Token::RPAREN, CHECK_OK);
3831
Ben Murdochda12d292016-06-02 14:46:10 +01003832 body = ParseScopedStatement(NULL, true, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003833 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003834
3835 Statement* result = NULL;
3836 if (lexical_bindings.length() > 0) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003837 BlockState block_state(&scope_, for_scope);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003838 result = DesugarLexicalBindingsInForStatement(
Ben Murdoch097c5b22016-05-18 11:27:45 +01003839 inner_scope, parsing_result.descriptor.mode, &lexical_bindings, loop,
3840 init, cond, next, body, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003841 for_scope->set_end_position(scanner()->location().end_pos);
3842 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003843 for_scope->set_end_position(scanner()->location().end_pos);
3844 for_scope = for_scope->FinalizeBlockScope();
3845 if (for_scope) {
3846 // Rewrite a for statement of the form
3847 // for (const x = i; c; n) b
3848 //
3849 // into
3850 //
3851 // {
3852 // const x = i;
3853 // for (; c; n) b
3854 // }
3855 //
3856 // or, desugar
3857 // for (; c; n) b
3858 // into
3859 // {
3860 // for (; c; n) b
3861 // }
3862 // just in case b introduces a lexical binding some other way, e.g., if b
3863 // is a FunctionDeclaration.
3864 Block* block =
3865 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3866 if (init != nullptr) {
3867 block->statements()->Add(init, zone());
3868 }
3869 block->statements()->Add(loop, zone());
3870 block->set_scope(for_scope);
3871 loop->Initialize(NULL, cond, next, body);
3872 result = block;
3873 } else {
3874 loop->Initialize(init, cond, next, body);
3875 result = loop;
3876 }
3877 }
3878 return result;
3879}
3880
3881
3882DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3883 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3884 // contexts this is used as a statement which invokes the debugger as i a
3885 // break point is present.
3886 // DebuggerStatement ::
3887 // 'debugger' ';'
3888
3889 int pos = peek_position();
3890 Expect(Token::DEBUGGER, CHECK_OK);
3891 ExpectSemicolon(CHECK_OK);
3892 return factory()->NewDebuggerStatement(pos);
3893}
3894
3895
3896bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3897 if (expression->IsLiteral()) return true;
3898 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3899 return lit != NULL && lit->is_simple();
3900}
3901
3902
3903Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3904 Expression* expression) {
3905 Factory* factory = isolate->factory();
3906 DCHECK(IsCompileTimeValue(expression));
3907 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
3908 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3909 if (object_literal != NULL) {
3910 DCHECK(object_literal->is_simple());
3911 if (object_literal->fast_elements()) {
3912 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3913 } else {
3914 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3915 }
3916 result->set(kElementsSlot, *object_literal->constant_properties());
3917 } else {
3918 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3919 DCHECK(array_literal != NULL && array_literal->is_simple());
3920 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3921 result->set(kElementsSlot, *array_literal->constant_elements());
3922 }
3923 return result;
3924}
3925
3926
3927CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3928 Handle<FixedArray> value) {
3929 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3930 return static_cast<LiteralType>(literal_type->value());
3931}
3932
3933
3934Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3935 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3936}
3937
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003938void ParserTraits::ParseArrowFunctionFormalParameters(
Ben Murdochc5610432016-08-08 18:44:38 +01003939 ParserFormalParameters* parameters, Expression* expr, int end_pos,
3940 bool* ok) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003941 // ArrowFunctionFormals ::
3942 // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
3943 // Tail
3944 // NonTailArrowFunctionFormals ::
3945 // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
3946 // VariableProxy
3947 // Tail ::
3948 // VariableProxy
3949 // Spread(VariableProxy)
3950 //
3951 // As we need to visit the parameters in left-to-right order, we recurse on
3952 // the left-hand side of comma expressions.
3953 //
3954 if (expr->IsBinaryOperation()) {
3955 BinaryOperation* binop = expr->AsBinaryOperation();
3956 // The classifier has already run, so we know that the expression is a valid
3957 // arrow function formals production.
3958 DCHECK_EQ(binop->op(), Token::COMMA);
3959 Expression* left = binop->left();
3960 Expression* right = binop->right();
Ben Murdochc5610432016-08-08 18:44:38 +01003961 int comma_pos = binop->position();
3962 ParseArrowFunctionFormalParameters(parameters, left, comma_pos, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003963 if (!*ok) return;
3964 // LHS of comma expression should be unparenthesized.
3965 expr = right;
3966 }
3967
3968 // Only the right-most expression may be a rest parameter.
3969 DCHECK(!parameters->has_rest);
3970
3971 bool is_rest = expr->IsSpread();
3972 if (is_rest) {
3973 expr = expr->AsSpread()->expression();
3974 parameters->has_rest = true;
3975 }
3976 if (parameters->is_simple) {
3977 parameters->is_simple = !is_rest && expr->IsVariableProxy();
3978 }
3979
3980 Expression* initializer = nullptr;
3981 if (expr->IsVariableProxy()) {
3982 // When the formal parameter was originally seen, it was parsed as a
3983 // VariableProxy and recorded as unresolved in the scope. Here we undo that
3984 // parse-time side-effect for parameters that are single-names (not
3985 // patterns; for patterns that happens uniformly in
3986 // PatternRewriter::VisitVariableProxy).
3987 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
3988 } else if (expr->IsAssignment()) {
3989 Assignment* assignment = expr->AsAssignment();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003990 DCHECK(!assignment->is_compound());
3991 initializer = assignment->value();
3992 expr = assignment->target();
3993
3994 // TODO(adamk): Only call this if necessary.
3995 RewriteParameterInitializerScope(parser_->stack_limit(), initializer,
3996 parser_->scope_, parameters->scope);
3997 }
3998
Ben Murdochc5610432016-08-08 18:44:38 +01003999 AddFormalParameter(parameters, expr, initializer, end_pos, is_rest);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004000}
4001
Ben Murdochc5610432016-08-08 18:44:38 +01004002void ParserTraits::ParseAsyncArrowSingleExpressionBody(
4003 ZoneList<Statement*>* body, bool accept_IN,
4004 Type::ExpressionClassifier* classifier, int pos, bool* ok) {
4005 parser_->DesugarAsyncFunctionBody(
4006 parser_->ast_value_factory()->empty_string(), parser_->scope_, body,
4007 classifier, kAsyncArrowFunction, FunctionBody::SingleExpression,
4008 accept_IN, pos, ok);
4009}
4010
4011void Parser::DesugarAsyncFunctionBody(const AstRawString* function_name,
4012 Scope* scope, ZoneList<Statement*>* body,
4013 ExpressionClassifier* classifier,
4014 FunctionKind kind, FunctionBody body_type,
4015 bool accept_IN, int pos, bool* ok) {
4016 // function async_function() {
4017 // try {
4018 // .generator_object = %CreateGeneratorObject();
4019 // ... function body ...
4020 // } catch (e) {
4021 // return Promise.reject(e);
4022 // }
4023 // }
4024 scope->ForceContextAllocation();
4025 Variable* temp =
4026 scope_->NewTemporary(ast_value_factory()->dot_generator_object_string());
4027 function_state_->set_generator_object_variable(temp);
4028
4029 Expression* init_generator_variable = factory()->NewAssignment(
4030 Token::INIT, factory()->NewVariableProxy(temp),
4031 BuildCreateJSGeneratorObject(pos, kind), RelocInfo::kNoPosition);
4032 body->Add(factory()->NewExpressionStatement(init_generator_variable,
4033 RelocInfo::kNoPosition),
4034 zone());
4035
4036 Block* try_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4037
4038 ZoneList<Statement*>* inner_body = try_block->statements();
4039
4040 Expression* return_value = nullptr;
4041 if (body_type == FunctionBody::Normal) {
4042 ParseStatementList(inner_body, Token::RBRACE, ok);
4043 if (!*ok) return;
4044 return_value = factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
4045 } else {
4046 return_value = ParseAssignmentExpression(accept_IN, classifier, ok);
4047 if (!*ok) return;
4048 ParserTraits::RewriteNonPattern(classifier, ok);
4049 if (!*ok) return;
4050 }
4051
4052 return_value = BuildPromiseResolve(return_value, return_value->position());
4053 inner_body->Add(
4054 factory()->NewReturnStatement(return_value, return_value->position()),
4055 zone());
4056 body->Add(BuildRejectPromiseOnException(try_block), zone());
4057 scope->set_end_position(scanner()->location().end_pos);
4058}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004059
4060DoExpression* Parser::ParseDoExpression(bool* ok) {
4061 // AssignmentExpression ::
4062 // do '{' StatementList '}'
4063 int pos = peek_position();
4064
4065 Expect(Token::DO, CHECK_OK);
4066 Variable* result =
4067 scope_->NewTemporary(ast_value_factory()->dot_result_string());
4068 Block* block = ParseBlock(nullptr, false, CHECK_OK);
4069 DoExpression* expr = factory()->NewDoExpression(block, result, pos);
4070 if (!Rewriter::Rewrite(this, expr, ast_value_factory())) {
4071 *ok = false;
4072 return nullptr;
4073 }
4074 block->set_scope(block->scope()->FinalizeBlockScope());
4075 return expr;
4076}
4077
4078
4079void ParserTraits::ParseArrowFunctionFormalParameterList(
4080 ParserFormalParameters* parameters, Expression* expr,
4081 const Scanner::Location& params_loc,
4082 Scanner::Location* duplicate_loc, bool* ok) {
4083 if (expr->IsEmptyParentheses()) return;
4084
Ben Murdochc5610432016-08-08 18:44:38 +01004085 ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004086 if (!*ok) return;
4087
Ben Murdochc5610432016-08-08 18:44:38 +01004088 if (parameters->Arity() > Code::kMaxArguments) {
4089 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
4090 *ok = false;
4091 return;
4092 }
4093
Ben Murdoch097c5b22016-05-18 11:27:45 +01004094 Type::ExpressionClassifier classifier(parser_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004095 if (!parameters->is_simple) {
4096 classifier.RecordNonSimpleParameter();
4097 }
4098 for (int i = 0; i < parameters->Arity(); ++i) {
4099 auto parameter = parameters->at(i);
4100 DeclareFormalParameter(parameters->scope, parameter, &classifier);
4101 if (!duplicate_loc->IsValid()) {
4102 *duplicate_loc = classifier.duplicate_formal_parameter_error().location;
4103 }
4104 }
4105 DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
4106}
4107
4108
4109void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) {
4110 if (parser_->function_state_->materialized_literal_count() > 0) {
4111 AstLiteralReindexer reindexer;
4112
4113 for (const auto p : parameters.params) {
4114 if (p.pattern != nullptr) reindexer.Reindex(p.pattern);
4115 if (p.initializer != nullptr) reindexer.Reindex(p.initializer);
4116 }
4117
4118 DCHECK(reindexer.count() <=
4119 parser_->function_state_->materialized_literal_count());
4120 }
4121}
4122
4123
4124FunctionLiteral* Parser::ParseFunctionLiteral(
4125 const AstRawString* function_name, Scanner::Location function_name_location,
4126 FunctionNameValidity function_name_validity, FunctionKind kind,
4127 int function_token_pos, FunctionLiteral::FunctionType function_type,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004128 LanguageMode language_mode, bool* ok) {
4129 // Function ::
4130 // '(' FormalParameterList? ')' '{' FunctionBody '}'
4131 //
4132 // Getter ::
4133 // '(' ')' '{' FunctionBody '}'
4134 //
4135 // Setter ::
4136 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
4137
4138 int pos = function_token_pos == RelocInfo::kNoPosition
4139 ? peek_position() : function_token_pos;
4140
4141 bool is_generator = IsGeneratorFunction(kind);
4142
4143 // Anonymous functions were passed either the empty symbol or a null
4144 // handle as the function name. Remember if we were passed a non-empty
4145 // handle to decide whether to invoke function name inference.
4146 bool should_infer_name = function_name == NULL;
4147
4148 // We want a non-null handle as the function name.
4149 if (should_infer_name) {
4150 function_name = ast_value_factory()->empty_string();
4151 }
4152
Ben Murdochc5610432016-08-08 18:44:38 +01004153 Scope* scope = NewScope(scope_, FUNCTION_SCOPE, kind);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004154 SetLanguageMode(scope, language_mode);
4155 ZoneList<Statement*>* body = NULL;
4156 int arity = -1;
4157 int materialized_literal_count = -1;
4158 int expected_property_count = -1;
4159 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004160 bool should_be_used_once_hint = false;
Ben Murdoch097c5b22016-05-18 11:27:45 +01004161 bool has_duplicate_parameters;
Ben Murdochc5610432016-08-08 18:44:38 +01004162 FunctionLiteral::EagerCompileHint eager_compile_hint;
4163
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004164 // Parse function.
4165 {
4166 AstNodeFactory function_factory(ast_value_factory());
4167 FunctionState function_state(&function_state_, &scope_, scope, kind,
4168 &function_factory);
4169 scope_->SetScopeName(function_name);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004170 ExpressionClassifier formals_classifier(this, &duplicate_finder);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004171
Ben Murdochc5610432016-08-08 18:44:38 +01004172 eager_compile_hint = function_state_->this_function_is_parenthesized()
4173 ? FunctionLiteral::kShouldEagerCompile
4174 : FunctionLiteral::kShouldLazyCompile;
4175
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004176 if (is_generator) {
4177 // For generators, allocating variables in contexts is currently a win
4178 // because it minimizes the work needed to suspend and resume an
Ben Murdochda12d292016-06-02 14:46:10 +01004179 // activation. The machine code produced for generators (by full-codegen)
4180 // relies on this forced context allocation, but not in an essential way.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004181 scope_->ForceContextAllocation();
4182
4183 // Calling a generator returns a generator object. That object is stored
4184 // in a temporary variable, a definition that is used by "yield"
4185 // expressions. This also marks the FunctionState as a generator.
4186 Variable* temp = scope_->NewTemporary(
4187 ast_value_factory()->dot_generator_object_string());
4188 function_state.set_generator_object_variable(temp);
4189 }
4190
4191 Expect(Token::LPAREN, CHECK_OK);
4192 int start_position = scanner()->location().beg_pos;
4193 scope_->set_start_position(start_position);
4194 ParserFormalParameters formals(scope);
4195 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
4196 arity = formals.Arity();
4197 Expect(Token::RPAREN, CHECK_OK);
4198 int formals_end_position = scanner()->location().end_pos;
4199
Ben Murdoch097c5b22016-05-18 11:27:45 +01004200 CheckArityRestrictions(arity, kind, formals.has_rest, start_position,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004201 formals_end_position, CHECK_OK);
4202 Expect(Token::LBRACE, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004203 // Don't include the rest parameter into the function's formal parameter
4204 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
4205 // which says whether we need to create an arguments adaptor frame).
4206 if (formals.has_rest) arity--;
4207
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004208 // Determine if the function can be parsed lazily. Lazy parsing is different
4209 // from lazy compilation; we need to parse more eagerly than we compile.
4210
4211 // We can only parse lazily if we also compile lazily. The heuristics for
4212 // lazy compilation are:
4213 // - It must not have been prohibited by the caller to Parse (some callers
4214 // need a full AST).
4215 // - The outer scope must allow lazy compilation of inner functions.
4216 // - The function mustn't be a function expression with an open parenthesis
4217 // before; we consider that a hint that the function will be called
4218 // immediately, and it would be a waste of time to make it lazily
4219 // compiled.
4220 // These are all things we can know at this point, without looking at the
4221 // function itself.
4222
4223 // In addition, we need to distinguish between these cases:
4224 // (function foo() {
4225 // bar = function() { return 1; }
4226 // })();
4227 // and
4228 // (function foo() {
4229 // var a = 1;
4230 // bar = function() { return a; }
4231 // })();
4232
4233 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
4234 // parenthesis before the function means that it will be called
4235 // immediately). The inner function *must* be parsed eagerly to resolve the
4236 // possible reference to the variable in foo's scope. However, it's possible
4237 // that it will be compiled lazily.
4238
4239 // To make this additional case work, both Parser and PreParser implement a
4240 // logic where only top-level functions will be parsed lazily.
4241 bool is_lazily_parsed = mode() == PARSE_LAZILY &&
4242 scope_->AllowsLazyParsing() &&
Ben Murdochc5610432016-08-08 18:44:38 +01004243 !function_state_->this_function_is_parenthesized();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004244
4245 // Eager or lazy parse?
4246 // If is_lazily_parsed, we'll parse lazy. If we can set a bookmark, we'll
4247 // pass it to SkipLazyFunctionBody, which may use it to abort lazy
4248 // parsing if it suspect that wasn't a good idea. If so, or if we didn't
4249 // try to lazy parse in the first place, we'll have to parse eagerly.
4250 Scanner::BookmarkScope bookmark(scanner());
4251 if (is_lazily_parsed) {
4252 Scanner::BookmarkScope* maybe_bookmark =
4253 bookmark.Set() ? &bookmark : nullptr;
4254 SkipLazyFunctionBody(&materialized_literal_count,
4255 &expected_property_count, /*CHECK_OK*/ ok,
4256 maybe_bookmark);
4257
4258 materialized_literal_count += formals.materialized_literals_count +
4259 function_state.materialized_literal_count();
4260
4261 if (bookmark.HasBeenReset()) {
4262 // Trigger eager (re-)parsing, just below this block.
4263 is_lazily_parsed = false;
4264
4265 // This is probably an initialization function. Inform the compiler it
4266 // should also eager-compile this function, and that we expect it to be
4267 // used once.
4268 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
4269 should_be_used_once_hint = true;
4270 }
4271 }
4272 if (!is_lazily_parsed) {
4273 // Determine whether the function body can be discarded after parsing.
4274 // The preconditions are:
4275 // - Lazy compilation has to be enabled.
4276 // - Neither V8 natives nor native function declarations can be allowed,
4277 // since parsing one would retroactively force the function to be
4278 // eagerly compiled.
4279 // - The invoker of this parser can't depend on the AST being eagerly
4280 // built (either because the function is about to be compiled, or
4281 // because the AST is going to be inspected for some reason).
4282 // - Because of the above, we can't be attempting to parse a
4283 // FunctionExpression; even without enclosing parentheses it might be
4284 // immediately invoked.
4285 // - The function literal shouldn't be hinted to eagerly compile.
Ben Murdochc5610432016-08-08 18:44:38 +01004286 // - For asm.js functions the body needs to be available when module
4287 // validation is active, because we examine the entire module at once.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004288 bool use_temp_zone =
4289 FLAG_lazy && !allow_natives() && extension_ == NULL && allow_lazy() &&
4290 function_type == FunctionLiteral::kDeclaration &&
Ben Murdochc5610432016-08-08 18:44:38 +01004291 eager_compile_hint != FunctionLiteral::kShouldEagerCompile &&
4292 !(FLAG_validate_asm && scope->asm_function());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004293 // Open a new BodyScope, which sets our AstNodeFactory to allocate in the
4294 // new temporary zone if the preconditions are satisfied, and ensures that
4295 // the previous zone is always restored after parsing the body.
4296 // For the purpose of scope analysis, some ZoneObjects allocated by the
4297 // factory must persist after the function body is thrown away and
4298 // temp_zone is deallocated. These objects are instead allocated in a
4299 // parser-persistent zone (see parser_zone_ in AstNodeFactory).
4300 {
Ben Murdochda12d292016-06-02 14:46:10 +01004301 Zone temp_zone(zone()->allocator());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004302 AstNodeFactory::BodyScope inner(factory(), &temp_zone, use_temp_zone);
4303
4304 body = ParseEagerFunctionBody(function_name, pos, formals, kind,
4305 function_type, CHECK_OK);
4306 }
4307 materialized_literal_count = function_state.materialized_literal_count();
4308 expected_property_count = function_state.expected_property_count();
4309 if (use_temp_zone) {
4310 // If the preconditions are correct the function body should never be
4311 // accessed, but do this anyway for better behaviour if they're wrong.
4312 body = NULL;
4313 }
4314 }
4315
4316 // Parsing the body may change the language mode in our scope.
4317 language_mode = scope->language_mode();
4318
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004319 // Validate name and parameter names. We can do this only after parsing the
4320 // function, since the function can declare itself strict.
4321 CheckFunctionName(language_mode, function_name, function_name_validity,
4322 function_name_location, CHECK_OK);
4323 const bool allow_duplicate_parameters =
4324 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
4325 ValidateFormalParameters(&formals_classifier, language_mode,
4326 allow_duplicate_parameters, CHECK_OK);
4327
4328 if (is_strict(language_mode)) {
4329 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
4330 CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01004331 CheckDecimalLiteralWithLeadingZero(use_counts_, scope->start_position(),
4332 scope->end_position());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004333 }
Ben Murdochc5610432016-08-08 18:44:38 +01004334 if (is_sloppy(language_mode)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004335 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK);
4336 }
Ben Murdochda12d292016-06-02 14:46:10 +01004337 CheckConflictingVarDeclarations(scope, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004338
4339 if (body) {
4340 // If body can be inspected, rewrite queued destructuring assignments
4341 ParserTraits::RewriteDestructuringAssignments();
4342 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01004343 has_duplicate_parameters =
4344 !formals_classifier.is_valid_formal_parameter_list_without_duplicates();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004345 }
4346
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004347 FunctionLiteral::ParameterFlag duplicate_parameters =
4348 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
4349 : FunctionLiteral::kNoDuplicateParameters;
4350
4351 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
4352 function_name, scope, body, materialized_literal_count,
4353 expected_property_count, arity, duplicate_parameters, function_type,
4354 eager_compile_hint, kind, pos);
4355 function_literal->set_function_token_position(function_token_pos);
4356 if (should_be_used_once_hint)
4357 function_literal->set_should_be_used_once_hint();
4358
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004359 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4360 return function_literal;
4361}
4362
Ben Murdochc5610432016-08-08 18:44:38 +01004363Expression* Parser::ParseAsyncFunctionExpression(bool* ok) {
4364 // AsyncFunctionDeclaration ::
4365 // async [no LineTerminator here] function ( FormalParameters[Await] )
4366 // { AsyncFunctionBody }
4367 //
4368 // async [no LineTerminator here] function BindingIdentifier[Await]
4369 // ( FormalParameters[Await] ) { AsyncFunctionBody }
4370 DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
4371 int pos = position();
4372 Expect(Token::FUNCTION, CHECK_OK);
4373 bool is_strict_reserved = false;
4374 const AstRawString* name = nullptr;
4375 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;
4376
4377 if (peek_any_identifier()) {
4378 type = FunctionLiteral::kNamedExpression;
4379 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
4380 if (this->IsAwait(name)) {
4381 ReportMessageAt(scanner()->location(),
4382 MessageTemplate::kAwaitBindingIdentifier);
4383 *ok = false;
4384 return nullptr;
4385 }
4386 }
4387 return ParseFunctionLiteral(name, scanner()->location(),
4388 is_strict_reserved ? kFunctionNameIsStrictReserved
4389 : kFunctionNameValidityUnknown,
4390 FunctionKind::kAsyncFunction, pos, type,
4391 language_mode(), CHECK_OK);
4392}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004393
4394void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
4395 int* expected_property_count, bool* ok,
4396 Scanner::BookmarkScope* bookmark) {
4397 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
4398 if (produce_cached_parse_data()) CHECK(log_);
4399
4400 int function_block_pos = position();
4401 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) {
4402 // If we have cached data, we use it to skip parsing the function body. The
4403 // data contains the information we need to construct the lazy function.
4404 FunctionEntry entry =
4405 cached_parse_data_->GetFunctionEntry(function_block_pos);
4406 // Check that cached data is valid. If not, mark it as invalid (the embedder
4407 // handles it). Note that end position greater than end of stream is safe,
4408 // and hard to check.
4409 if (entry.is_valid() && entry.end_pos() > function_block_pos) {
4410 scanner()->SeekForward(entry.end_pos() - 1);
4411
4412 scope_->set_end_position(entry.end_pos());
4413 Expect(Token::RBRACE, ok);
4414 if (!*ok) {
4415 return;
4416 }
4417 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
4418 *materialized_literal_count = entry.literal_count();
4419 *expected_property_count = entry.property_count();
4420 SetLanguageMode(scope_, entry.language_mode());
4421 if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage();
4422 if (entry.calls_eval()) scope_->RecordEvalCall();
4423 return;
4424 }
4425 cached_parse_data_->Reject();
4426 }
4427 // With no cached data, we partially parse the function, without building an
4428 // AST. This gathers the data needed to build a lazy function.
4429 SingletonLogger logger;
4430 PreParser::PreParseResult result =
4431 ParseLazyFunctionBodyWithPreParser(&logger, bookmark);
4432 if (bookmark && bookmark->HasBeenReset()) {
4433 return; // Return immediately if pre-parser devided to abort parsing.
4434 }
4435 if (result == PreParser::kPreParseStackOverflow) {
4436 // Propagate stack overflow.
4437 set_stack_overflow();
4438 *ok = false;
4439 return;
4440 }
4441 if (logger.has_error()) {
4442 ParserTraits::ReportMessageAt(
4443 Scanner::Location(logger.start(), logger.end()), logger.message(),
4444 logger.argument_opt(), logger.error_type());
4445 *ok = false;
4446 return;
4447 }
4448 scope_->set_end_position(logger.end());
4449 Expect(Token::RBRACE, ok);
4450 if (!*ok) {
4451 return;
4452 }
4453 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
4454 *materialized_literal_count = logger.literals();
4455 *expected_property_count = logger.properties();
4456 SetLanguageMode(scope_, logger.language_mode());
4457 if (logger.uses_super_property()) {
4458 scope_->RecordSuperPropertyUsage();
4459 }
4460 if (logger.calls_eval()) {
4461 scope_->RecordEvalCall();
4462 }
4463 if (produce_cached_parse_data()) {
4464 DCHECK(log_);
4465 // Position right after terminal '}'.
4466 int body_end = scanner()->location().end_pos;
4467 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count,
4468 *expected_property_count, scope_->language_mode(),
4469 scope_->uses_super_property(), scope_->calls_eval());
4470 }
4471}
4472
4473
4474Statement* Parser::BuildAssertIsCoercible(Variable* var) {
4475 // if (var === null || var === undefined)
4476 // throw /* type error kNonCoercible) */;
4477
4478 Expression* condition = factory()->NewBinaryOperation(
4479 Token::OR, factory()->NewCompareOperation(
4480 Token::EQ_STRICT, factory()->NewVariableProxy(var),
4481 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4482 RelocInfo::kNoPosition),
4483 factory()->NewCompareOperation(
4484 Token::EQ_STRICT, factory()->NewVariableProxy(var),
4485 factory()->NewNullLiteral(RelocInfo::kNoPosition),
4486 RelocInfo::kNoPosition),
4487 RelocInfo::kNoPosition);
4488 Expression* throw_type_error = this->NewThrowTypeError(
4489 MessageTemplate::kNonCoercible, ast_value_factory()->empty_string(),
4490 RelocInfo::kNoPosition);
4491 IfStatement* if_statement = factory()->NewIfStatement(
4492 condition, factory()->NewExpressionStatement(throw_type_error,
4493 RelocInfo::kNoPosition),
4494 factory()->NewEmptyStatement(RelocInfo::kNoPosition),
4495 RelocInfo::kNoPosition);
4496 return if_statement;
4497}
4498
4499
4500class InitializerRewriter : public AstExpressionVisitor {
4501 public:
4502 InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser,
4503 Scope* scope)
4504 : AstExpressionVisitor(stack_limit, root),
4505 parser_(parser),
4506 scope_(scope) {}
4507
4508 private:
Ben Murdoch097c5b22016-05-18 11:27:45 +01004509 void VisitExpression(Expression* expr) override {
4510 RewritableExpression* to_rewrite = expr->AsRewritableExpression();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004511 if (to_rewrite == nullptr || to_rewrite->is_rewritten()) return;
4512
4513 Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
4514 scope_);
4515 }
4516
Ben Murdoch097c5b22016-05-18 11:27:45 +01004517 // Code in function literals does not need to be eagerly rewritten, it will be
4518 // rewritten when scheduled.
4519 void VisitFunctionLiteral(FunctionLiteral* expr) override {}
4520
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004521 private:
4522 Parser* parser_;
4523 Scope* scope_;
4524};
4525
4526
4527void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) {
4528 InitializerRewriter rewriter(stack_limit_, expr, this, scope);
4529 rewriter.Run();
4530}
4531
4532
4533Block* Parser::BuildParameterInitializationBlock(
4534 const ParserFormalParameters& parameters, bool* ok) {
4535 DCHECK(!parameters.is_simple);
4536 DCHECK(scope_->is_function_scope());
4537 Block* init_block =
4538 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
4539 for (int i = 0; i < parameters.params.length(); ++i) {
4540 auto parameter = parameters.params[i];
4541 if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break;
4542 DeclarationDescriptor descriptor;
4543 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
4544 descriptor.parser = this;
4545 descriptor.scope = scope_;
4546 descriptor.hoist_scope = nullptr;
4547 descriptor.mode = LET;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004548 descriptor.declaration_pos = parameter.pattern->position();
4549 // The position that will be used by the AssignmentExpression
4550 // which copies from the temp parameter to the pattern.
4551 //
4552 // TODO(adamk): Should this be RelocInfo::kNoPosition, since
4553 // it's just copying from a temp var to the real param var?
4554 descriptor.initialization_pos = parameter.pattern->position();
4555 // The initializer position which will end up in,
4556 // Variable::initializer_position(), used for hole check elimination.
4557 int initializer_position = parameter.pattern->position();
4558 Expression* initial_value =
4559 factory()->NewVariableProxy(parameters.scope->parameter(i));
4560 if (parameter.initializer != nullptr) {
4561 // IS_UNDEFINED($param) ? initializer : $param
4562
4563 // Ensure initializer is rewritten
4564 RewriteParameterInitializer(parameter.initializer, scope_);
4565
4566 auto condition = factory()->NewCompareOperation(
4567 Token::EQ_STRICT,
4568 factory()->NewVariableProxy(parameters.scope->parameter(i)),
4569 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4570 RelocInfo::kNoPosition);
4571 initial_value = factory()->NewConditional(
4572 condition, parameter.initializer, initial_value,
4573 RelocInfo::kNoPosition);
4574 descriptor.initialization_pos = parameter.initializer->position();
4575 initializer_position = parameter.initializer_end_position;
4576 }
4577
4578 Scope* param_scope = scope_;
4579 Block* param_block = init_block;
4580 if (!parameter.is_simple() && scope_->calls_sloppy_eval()) {
4581 param_scope = NewScope(scope_, BLOCK_SCOPE);
4582 param_scope->set_is_declaration_scope();
Ben Murdochc5610432016-08-08 18:44:38 +01004583 param_scope->set_start_position(descriptor.initialization_pos);
4584 param_scope->set_end_position(parameter.initializer_end_position);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004585 param_scope->RecordEvalCall();
4586 param_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4587 param_block->set_scope(param_scope);
4588 descriptor.hoist_scope = scope_;
Ben Murdochc5610432016-08-08 18:44:38 +01004589 // Pass the appropriate scope in so that PatternRewriter can appropriately
4590 // rewrite inner initializers of the pattern to param_scope
4591 descriptor.scope = param_scope;
4592 // Rewrite the outer initializer to point to param_scope
4593 RewriteParameterInitializerScope(stack_limit(), initial_value, scope_,
4594 param_scope);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004595 }
4596
4597 {
4598 BlockState block_state(&scope_, param_scope);
4599 DeclarationParsingResult::Declaration decl(
4600 parameter.pattern, initializer_position, initial_value);
4601 PatternRewriter::DeclareAndInitializeVariables(param_block, &descriptor,
4602 &decl, nullptr, CHECK_OK);
4603 }
4604
4605 if (!parameter.is_simple() && scope_->calls_sloppy_eval()) {
4606 param_scope = param_scope->FinalizeBlockScope();
4607 if (param_scope != nullptr) {
4608 CheckConflictingVarDeclarations(param_scope, CHECK_OK);
4609 }
4610 init_block->statements()->Add(param_block, zone());
4611 }
4612 }
4613 return init_block;
4614}
4615
Ben Murdochc5610432016-08-08 18:44:38 +01004616Block* Parser::BuildRejectPromiseOnException(Block* block) {
4617 // try { <block> } catch (error) { return Promise.reject(error); }
4618 Block* try_block = block;
4619 Scope* catch_scope = NewScope(scope_, CATCH_SCOPE);
4620 catch_scope->set_is_hidden();
4621 Variable* catch_variable =
4622 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR,
4623 kCreatedInitialized, Variable::NORMAL);
4624 Block* catch_block =
4625 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
4626
4627 Expression* promise_reject = BuildPromiseReject(
4628 factory()->NewVariableProxy(catch_variable), RelocInfo::kNoPosition);
4629
4630 ReturnStatement* return_promise_reject =
4631 factory()->NewReturnStatement(promise_reject, RelocInfo::kNoPosition);
4632 catch_block->statements()->Add(return_promise_reject, zone());
4633 TryStatement* try_catch_statement =
4634 factory()->NewTryCatchStatement(try_block, catch_scope, catch_variable,
4635 catch_block, RelocInfo::kNoPosition);
4636
4637 block = factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
4638 block->statements()->Add(try_catch_statement, zone());
4639 return block;
4640}
4641
4642Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) {
4643 DCHECK_NOT_NULL(function_state_->generator_object_variable());
4644 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4645 args->Add(factory()->NewThisFunction(pos), zone());
4646 args->Add(IsArrowFunction(kind)
4647 ? GetLiteralUndefined(pos)
4648 : ThisExpression(scope_, factory(), RelocInfo::kNoPosition),
4649 zone());
4650 return factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args,
4651 pos);
4652}
4653
4654Expression* Parser::BuildPromiseResolve(Expression* value, int pos) {
4655 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
4656 args->Add(value, zone());
4657 return factory()->NewCallRuntime(Context::PROMISE_CREATE_RESOLVED_INDEX, args,
4658 pos);
4659}
4660
4661Expression* Parser::BuildPromiseReject(Expression* value, int pos) {
4662 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
4663 args->Add(value, zone());
4664 return factory()->NewCallRuntime(Context::PROMISE_CREATE_REJECTED_INDEX, args,
4665 pos);
4666}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004667
4668ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
4669 const AstRawString* function_name, int pos,
4670 const ParserFormalParameters& parameters, FunctionKind kind,
4671 FunctionLiteral::FunctionType function_type, bool* ok) {
4672 // Everything inside an eagerly parsed function will be parsed eagerly
4673 // (see comment above).
4674 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4675 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
4676
4677 static const int kFunctionNameAssignmentIndex = 0;
4678 if (function_type == FunctionLiteral::kNamedExpression) {
4679 DCHECK(function_name != NULL);
4680 // If we have a named function expression, we add a local variable
4681 // declaration to the body of the function with the name of the
4682 // function and let it refer to the function itself (closure).
4683 // Not having parsed the function body, the language mode may still change,
4684 // so we reserve a spot and create the actual const assignment later.
4685 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
4686 result->Add(NULL, zone());
4687 }
4688
4689 ZoneList<Statement*>* body = result;
4690 Scope* inner_scope = scope_;
4691 Block* inner_block = nullptr;
4692 if (!parameters.is_simple) {
4693 inner_scope = NewScope(scope_, BLOCK_SCOPE);
4694 inner_scope->set_is_declaration_scope();
4695 inner_scope->set_start_position(scanner()->location().beg_pos);
4696 inner_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4697 inner_block->set_scope(inner_scope);
4698 body = inner_block->statements();
4699 }
4700
4701 {
4702 BlockState block_state(&scope_, inner_scope);
4703
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004704 if (IsGeneratorFunction(kind)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01004705 // We produce:
4706 //
Ben Murdochda12d292016-06-02 14:46:10 +01004707 // try { InitialYield; ...body...; return {value: undefined, done: true} }
Ben Murdoch097c5b22016-05-18 11:27:45 +01004708 // finally { %GeneratorClose(generator) }
4709 //
4710 // - InitialYield yields the actual generator object.
Ben Murdochda12d292016-06-02 14:46:10 +01004711 // - Any return statement inside the body will have its argument wrapped
4712 // in a "done" iterator result object.
Ben Murdoch097c5b22016-05-18 11:27:45 +01004713 // - If the generator terminates for whatever reason, we must close it.
4714 // Hence the finally clause.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004715
Ben Murdoch097c5b22016-05-18 11:27:45 +01004716 Block* try_block =
4717 factory()->NewBlock(nullptr, 3, false, RelocInfo::kNoPosition);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004718
Ben Murdoch097c5b22016-05-18 11:27:45 +01004719 {
Ben Murdochc5610432016-08-08 18:44:38 +01004720 Expression* allocation = BuildCreateJSGeneratorObject(pos, kind);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004721 VariableProxy* init_proxy = factory()->NewVariableProxy(
4722 function_state_->generator_object_variable());
4723 Assignment* assignment = factory()->NewAssignment(
4724 Token::INIT, init_proxy, allocation, RelocInfo::kNoPosition);
4725 VariableProxy* get_proxy = factory()->NewVariableProxy(
4726 function_state_->generator_object_variable());
Ben Murdochda12d292016-06-02 14:46:10 +01004727 Yield* yield =
4728 factory()->NewYield(get_proxy, assignment, RelocInfo::kNoPosition);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004729 try_block->statements()->Add(
4730 factory()->NewExpressionStatement(yield, RelocInfo::kNoPosition),
4731 zone());
4732 }
4733
4734 ParseStatementList(try_block->statements(), Token::RBRACE, CHECK_OK);
4735
Ben Murdochda12d292016-06-02 14:46:10 +01004736 Statement* final_return = factory()->NewReturnStatement(
4737 BuildIteratorResult(nullptr, true), RelocInfo::kNoPosition);
4738 try_block->statements()->Add(final_return, zone());
Ben Murdoch097c5b22016-05-18 11:27:45 +01004739
4740 Block* finally_block =
4741 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
4742 ZoneList<Expression*>* args =
4743 new (zone()) ZoneList<Expression*>(1, zone());
4744 VariableProxy* call_proxy = factory()->NewVariableProxy(
4745 function_state_->generator_object_variable());
4746 args->Add(call_proxy, zone());
4747 Expression* call = factory()->NewCallRuntime(
4748 Runtime::kGeneratorClose, args, RelocInfo::kNoPosition);
4749 finally_block->statements()->Add(
4750 factory()->NewExpressionStatement(call, RelocInfo::kNoPosition),
4751 zone());
4752
4753 body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
4754 RelocInfo::kNoPosition),
4755 zone());
Ben Murdochc5610432016-08-08 18:44:38 +01004756 } else if (IsAsyncFunction(kind)) {
4757 const bool accept_IN = true;
4758 DesugarAsyncFunctionBody(function_name, inner_scope, body, nullptr, kind,
4759 FunctionBody::Normal, accept_IN, pos, CHECK_OK);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004760 } else {
4761 ParseStatementList(body, Token::RBRACE, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004762 }
4763
4764 if (IsSubclassConstructor(kind)) {
4765 body->Add(
4766 factory()->NewReturnStatement(
4767 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition),
4768 RelocInfo::kNoPosition),
4769 zone());
4770 }
4771 }
4772
4773 Expect(Token::RBRACE, CHECK_OK);
4774 scope_->set_end_position(scanner()->location().end_pos);
4775
4776 if (!parameters.is_simple) {
4777 DCHECK_NOT_NULL(inner_scope);
4778 DCHECK_EQ(body, inner_block->statements());
4779 SetLanguageMode(scope_, inner_scope->language_mode());
4780 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01004781
4782 if (IsAsyncFunction(kind)) {
4783 init_block = BuildRejectPromiseOnException(init_block);
4784 }
4785
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004786 DCHECK_NOT_NULL(init_block);
4787
4788 inner_scope->set_end_position(scanner()->location().end_pos);
4789 inner_scope = inner_scope->FinalizeBlockScope();
4790 if (inner_scope != nullptr) {
4791 CheckConflictingVarDeclarations(inner_scope, CHECK_OK);
4792 InsertShadowingVarBindingInitializers(inner_block);
4793 }
4794
4795 result->Add(init_block, zone());
4796 result->Add(inner_block, zone());
4797 }
4798
4799 if (function_type == FunctionLiteral::kNamedExpression) {
4800 // Now that we know the language mode, we can create the const assignment
4801 // in the previously reserved spot.
4802 // NOTE: We create a proxy and resolve it here so that in the
4803 // future we can change the AST to only refer to VariableProxies
4804 // instead of Variables and Proxies as is the case now.
4805 VariableMode fvar_mode = is_strict(language_mode()) ? CONST : CONST_LEGACY;
4806 Variable* fvar = new (zone())
4807 Variable(scope_, function_name, fvar_mode, Variable::NORMAL,
4808 kCreatedInitialized, kNotAssigned);
4809 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
4810 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
4811 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
4812 scope_->DeclareFunctionVar(fvar_declaration);
4813
4814 VariableProxy* fproxy = factory()->NewVariableProxy(fvar);
4815 result->Set(kFunctionNameAssignmentIndex,
4816 factory()->NewExpressionStatement(
4817 factory()->NewAssignment(Token::INIT, fproxy,
4818 factory()->NewThisFunction(pos),
4819 RelocInfo::kNoPosition),
4820 RelocInfo::kNoPosition));
4821 }
4822
Ben Murdochc5610432016-08-08 18:44:38 +01004823 MarkCollectedTailCallExpressions();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004824 return result;
4825}
4826
4827
4828PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
4829 SingletonLogger* logger, Scanner::BookmarkScope* bookmark) {
4830 // This function may be called on a background thread too; record only the
4831 // main thread preparse times.
4832 if (pre_parse_timer_ != NULL) {
4833 pre_parse_timer_->Start();
4834 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01004835 TRACE_EVENT0("v8", "V8.PreParse");
4836
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004837 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
4838
4839 if (reusable_preparser_ == NULL) {
4840 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
4841 NULL, stack_limit_);
4842 reusable_preparser_->set_allow_lazy(true);
4843#define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
4844 SET_ALLOW(natives);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004845 SET_ALLOW(harmony_do_expressions);
Ben Murdochc5610432016-08-08 18:44:38 +01004846 SET_ALLOW(harmony_for_in);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004847 SET_ALLOW(harmony_function_name);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004848 SET_ALLOW(harmony_function_sent);
Ben Murdochda12d292016-06-02 14:46:10 +01004849 SET_ALLOW(harmony_exponentiation_operator);
4850 SET_ALLOW(harmony_restrictive_declarations);
Ben Murdochc5610432016-08-08 18:44:38 +01004851 SET_ALLOW(harmony_async_await);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004852#undef SET_ALLOW
4853 }
4854 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4855 language_mode(), function_state_->kind(), scope_->has_simple_parameters(),
Ben Murdochc5610432016-08-08 18:44:38 +01004856 parsing_module_, logger, bookmark, use_counts_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004857 if (pre_parse_timer_ != NULL) {
4858 pre_parse_timer_->Stop();
4859 }
4860 return result;
4861}
4862
Ben Murdochda12d292016-06-02 14:46:10 +01004863ClassLiteral* Parser::ParseClassLiteral(ExpressionClassifier* classifier,
4864 const AstRawString* name,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004865 Scanner::Location class_name_location,
4866 bool name_is_strict_reserved, int pos,
4867 bool* ok) {
4868 // All parts of a ClassDeclaration and ClassExpression are strict code.
4869 if (name_is_strict_reserved) {
4870 ReportMessageAt(class_name_location,
4871 MessageTemplate::kUnexpectedStrictReserved);
4872 *ok = false;
4873 return NULL;
4874 }
4875 if (IsEvalOrArguments(name)) {
4876 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
4877 *ok = false;
4878 return NULL;
4879 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004880
4881 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
4882 BlockState block_state(&scope_, block_scope);
4883 RaiseLanguageMode(STRICT);
4884 scope_->SetScopeName(name);
4885
4886 VariableProxy* proxy = NULL;
4887 if (name != NULL) {
4888 proxy = NewUnresolved(name, CONST);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004889 Declaration* declaration =
4890 factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004891 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
4892 }
4893
4894 Expression* extends = NULL;
4895 if (Check(Token::EXTENDS)) {
4896 block_scope->set_start_position(scanner()->location().end_pos);
Ben Murdochda12d292016-06-02 14:46:10 +01004897 ExpressionClassifier extends_classifier(this);
4898 extends = ParseLeftHandSideExpression(&extends_classifier, CHECK_OK);
Ben Murdochc5610432016-08-08 18:44:38 +01004899 CheckNoTailCallExpressions(&extends_classifier, CHECK_OK);
Ben Murdochda12d292016-06-02 14:46:10 +01004900 RewriteNonPattern(&extends_classifier, CHECK_OK);
4901 if (classifier != nullptr) {
4902 classifier->Accumulate(&extends_classifier,
4903 ExpressionClassifier::ExpressionProductions);
4904 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004905 } else {
4906 block_scope->set_start_position(scanner()->location().end_pos);
4907 }
4908
4909
4910 ClassLiteralChecker checker(this);
4911 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
4912 FunctionLiteral* constructor = NULL;
4913 bool has_seen_constructor = false;
4914
4915 Expect(Token::LBRACE, CHECK_OK);
4916
4917 const bool has_extends = extends != nullptr;
4918 while (peek() != Token::RBRACE) {
4919 if (Check(Token::SEMICOLON)) continue;
4920 FuncNameInferrer::State fni_state(fni_);
4921 const bool in_class = true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004922 bool is_computed_name = false; // Classes do not care about computed
4923 // property names here.
Ben Murdochda12d292016-06-02 14:46:10 +01004924 ExpressionClassifier property_classifier(this);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004925 const AstRawString* property_name = nullptr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004926 ObjectLiteral::Property* property = ParsePropertyDefinition(
Ben Murdochc5610432016-08-08 18:44:38 +01004927 &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name,
Ben Murdochda12d292016-06-02 14:46:10 +01004928 &has_seen_constructor, &property_classifier, &property_name, CHECK_OK);
4929 RewriteNonPattern(&property_classifier, CHECK_OK);
4930 if (classifier != nullptr) {
4931 classifier->Accumulate(&property_classifier,
4932 ExpressionClassifier::ExpressionProductions);
4933 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004934
4935 if (has_seen_constructor && constructor == NULL) {
4936 constructor = GetPropertyValue(property)->AsFunctionLiteral();
4937 DCHECK_NOT_NULL(constructor);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004938 constructor->set_raw_name(
4939 name != nullptr ? name : ast_value_factory()->empty_string());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004940 } else {
4941 properties->Add(property, zone());
4942 }
4943
4944 if (fni_ != NULL) fni_->Infer();
4945
Ben Murdoch097c5b22016-05-18 11:27:45 +01004946 if (allow_harmony_function_name() &&
4947 property_name != ast_value_factory()->constructor_string()) {
4948 SetFunctionNameFromPropertyName(property, property_name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004949 }
4950 }
4951
4952 Expect(Token::RBRACE, CHECK_OK);
4953 int end_pos = scanner()->location().end_pos;
4954
4955 if (constructor == NULL) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01004956 constructor = DefaultConstructor(name, extends != NULL, block_scope, pos,
4957 end_pos, block_scope->language_mode());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004958 }
4959
Ben Murdochda12d292016-06-02 14:46:10 +01004960 // Note that we do not finalize this block scope because it is
4961 // used as a sentinel value indicating an anonymous class.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004962 block_scope->set_end_position(end_pos);
4963
4964 if (name != NULL) {
4965 DCHECK_NOT_NULL(proxy);
4966 proxy->var()->set_initializer_position(end_pos);
4967 }
4968
Ben Murdoch097c5b22016-05-18 11:27:45 +01004969 return factory()->NewClassLiteral(block_scope, proxy, extends, constructor,
4970 properties, pos, end_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004971}
4972
4973
4974Expression* Parser::ParseV8Intrinsic(bool* ok) {
4975 // CallRuntime ::
4976 // '%' Identifier Arguments
4977
4978 int pos = peek_position();
4979 Expect(Token::MOD, CHECK_OK);
4980 // Allow "eval" or "arguments" for backward compatibility.
4981 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers,
4982 CHECK_OK);
4983 Scanner::Location spread_pos;
Ben Murdoch097c5b22016-05-18 11:27:45 +01004984 ExpressionClassifier classifier(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004985 ZoneList<Expression*>* args =
4986 ParseArguments(&spread_pos, &classifier, CHECK_OK);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004987
4988 DCHECK(!spread_pos.IsValid());
4989
4990 if (extension_ != NULL) {
4991 // The extension structures are only accessible while parsing the
4992 // very first time not when reparsing because of lazy compilation.
4993 scope_->DeclarationScope()->ForceEagerCompilation();
4994 }
4995
4996 const Runtime::Function* function = Runtime::FunctionForName(name->string());
4997
4998 if (function != NULL) {
4999 // Check for possible name clash.
5000 DCHECK_EQ(Context::kNotFound,
5001 Context::IntrinsicIndexForName(name->string()));
5002 // Check for built-in IS_VAR macro.
5003 if (function->function_id == Runtime::kIS_VAR) {
5004 DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
5005 // %IS_VAR(x) evaluates to x if x is a variable,
5006 // leads to a parse error otherwise. Could be implemented as an
5007 // inline function %_IS_VAR(x) to eliminate this special case.
5008 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
5009 return args->at(0);
5010 } else {
5011 ReportMessage(MessageTemplate::kNotIsvar);
5012 *ok = false;
5013 return NULL;
5014 }
5015 }
5016
5017 // Check that the expected number of arguments are being passed.
5018 if (function->nargs != -1 && function->nargs != args->length()) {
Ben Murdochda12d292016-06-02 14:46:10 +01005019 ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005020 *ok = false;
5021 return NULL;
5022 }
5023
5024 return factory()->NewCallRuntime(function, args, pos);
5025 }
5026
5027 int context_index = Context::IntrinsicIndexForName(name->string());
5028
5029 // Check that the function is defined.
5030 if (context_index == Context::kNotFound) {
5031 ParserTraits::ReportMessage(MessageTemplate::kNotDefined, name);
5032 *ok = false;
5033 return NULL;
5034 }
5035
5036 return factory()->NewCallRuntime(context_index, args, pos);
5037}
5038
5039
5040Literal* Parser::GetLiteralUndefined(int position) {
5041 return factory()->NewUndefinedLiteral(position);
5042}
5043
5044
5045void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
5046 Declaration* decl = scope->CheckConflictingVarDeclarations();
5047 if (decl != NULL) {
5048 // In ES6, conflicting variable bindings are early errors.
5049 const AstRawString* name = decl->proxy()->raw_name();
5050 int position = decl->proxy()->position();
5051 Scanner::Location location = position == RelocInfo::kNoPosition
5052 ? Scanner::Location::invalid()
5053 : Scanner::Location(position, position + 1);
5054 ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration,
5055 name);
5056 *ok = false;
5057 }
5058}
5059
5060
5061void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
5062 // For each var-binding that shadows a parameter, insert an assignment
5063 // initializing the variable with the parameter.
5064 Scope* inner_scope = inner_block->scope();
5065 DCHECK(inner_scope->is_declaration_scope());
5066 Scope* function_scope = inner_scope->outer_scope();
5067 DCHECK(function_scope->is_function_scope());
5068 ZoneList<Declaration*>* decls = inner_scope->declarations();
5069 for (int i = 0; i < decls->length(); ++i) {
5070 Declaration* decl = decls->at(i);
5071 if (decl->mode() != VAR || !decl->IsVariableDeclaration()) continue;
5072 const AstRawString* name = decl->proxy()->raw_name();
5073 Variable* parameter = function_scope->LookupLocal(name);
5074 if (parameter == nullptr) continue;
5075 VariableProxy* to = inner_scope->NewUnresolved(factory(), name);
5076 VariableProxy* from = factory()->NewVariableProxy(parameter);
5077 Expression* assignment = factory()->NewAssignment(
5078 Token::ASSIGN, to, from, RelocInfo::kNoPosition);
5079 Statement* statement = factory()->NewExpressionStatement(
5080 assignment, RelocInfo::kNoPosition);
5081 inner_block->statements()->InsertAt(0, statement, zone());
5082 }
5083}
5084
5085
5086void Parser::InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok) {
5087 // For each variable which is used as a function declaration in a sloppy
5088 // block,
5089 DCHECK(scope->is_declaration_scope());
5090 SloppyBlockFunctionMap* map = scope->sloppy_block_function_map();
5091 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
5092 AstRawString* name = static_cast<AstRawString*>(p->key);
5093 // If the variable wouldn't conflict with a lexical declaration,
5094 Variable* var = scope->LookupLocal(name);
5095 if (var == nullptr || !IsLexicalVariableMode(var->mode())) {
5096 // Declare a var-style binding for the function in the outer scope
5097 VariableProxy* proxy = scope->NewUnresolved(factory(), name);
5098 Declaration* declaration = factory()->NewVariableDeclaration(
5099 proxy, VAR, scope, RelocInfo::kNoPosition);
5100 Declare(declaration, DeclarationDescriptor::NORMAL, true, ok, scope);
5101 DCHECK(ok); // Based on the preceding check, this should not fail
5102 if (!ok) return;
5103
5104 // Write in assignments to var for each block-scoped function declaration
5105 auto delegates = static_cast<SloppyBlockFunctionMap::Vector*>(p->value);
5106 for (SloppyBlockFunctionStatement* delegate : *delegates) {
5107 // Read from the local lexical scope and write to the function scope
5108 VariableProxy* to = scope->NewUnresolved(factory(), name);
5109 VariableProxy* from = delegate->scope()->NewUnresolved(factory(), name);
5110 Expression* assignment = factory()->NewAssignment(
5111 Token::ASSIGN, to, from, RelocInfo::kNoPosition);
5112 Statement* statement = factory()->NewExpressionStatement(
5113 assignment, RelocInfo::kNoPosition);
5114 delegate->set_statement(statement);
5115 }
5116 }
5117 }
5118}
5119
5120
5121// ----------------------------------------------------------------------------
5122// Parser support
5123
5124bool Parser::TargetStackContainsLabel(const AstRawString* label) {
5125 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
5126 if (ContainsLabel(t->statement()->labels(), label)) return true;
5127 }
5128 return false;
5129}
5130
5131
5132BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
5133 bool* ok) {
5134 bool anonymous = label == NULL;
5135 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
5136 BreakableStatement* stat = t->statement();
5137 if ((anonymous && stat->is_target_for_anonymous()) ||
5138 (!anonymous && ContainsLabel(stat->labels(), label))) {
5139 return stat;
5140 }
5141 }
5142 return NULL;
5143}
5144
5145
5146IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
5147 bool* ok) {
5148 bool anonymous = label == NULL;
5149 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
5150 IterationStatement* stat = t->statement()->AsIterationStatement();
5151 if (stat == NULL) continue;
5152
5153 DCHECK(stat->is_target_for_anonymous());
5154 if (anonymous || ContainsLabel(stat->labels(), label)) {
5155 return stat;
5156 }
5157 }
5158 return NULL;
5159}
5160
5161
5162void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
5163 if (scanner_.source_url()->length() > 0) {
5164 Handle<String> source_url = scanner_.source_url()->Internalize(isolate);
5165 script->set_source_url(*source_url);
5166 }
5167 if (scanner_.source_mapping_url()->length() > 0) {
5168 Handle<String> source_mapping_url =
5169 scanner_.source_mapping_url()->Internalize(isolate);
5170 script->set_source_mapping_url(*source_mapping_url);
5171 }
5172}
5173
5174
5175void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) {
5176 // Internalize strings.
5177 ast_value_factory()->Internalize(isolate);
5178
5179 // Error processing.
5180 if (error) {
5181 if (stack_overflow()) {
5182 isolate->StackOverflow();
5183 } else {
5184 DCHECK(pending_error_handler_.has_pending_error());
5185 pending_error_handler_.ThrowPendingError(isolate, script);
5186 }
5187 }
5188
5189 // Move statistics to Isolate.
5190 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
5191 ++feature) {
5192 for (int i = 0; i < use_counts_[feature]; ++i) {
5193 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
5194 }
5195 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01005196 if (scanner_.FoundHtmlComment()) {
5197 isolate->CountUsage(v8::Isolate::kHtmlComment);
5198 if (script->line_offset() == 0 && script->column_offset() == 0) {
5199 isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
5200 }
5201 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005202 isolate->counters()->total_preparse_skipped()->Increment(
5203 total_preparse_skipped_);
5204}
5205
5206
5207// ----------------------------------------------------------------------------
5208// The Parser interface.
5209
5210
5211bool Parser::ParseStatic(ParseInfo* info) {
5212 Parser parser(info);
5213 if (parser.Parse(info)) {
5214 info->set_language_mode(info->literal()->language_mode());
5215 return true;
5216 }
5217 return false;
5218}
5219
5220
5221bool Parser::Parse(ParseInfo* info) {
5222 DCHECK(info->literal() == NULL);
5223 FunctionLiteral* result = NULL;
5224 // Ok to use Isolate here; this function is only called in the main thread.
5225 DCHECK(parsing_on_main_thread_);
5226 Isolate* isolate = info->isolate();
5227 pre_parse_timer_ = isolate->counters()->pre_parse();
5228 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) {
5229 // If intrinsics are allowed, the Parser cannot operate independent of the
5230 // V8 heap because of Runtime. Tell the string table to internalize strings
5231 // and values right after they're created.
5232 ast_value_factory()->Internalize(isolate);
5233 }
5234
5235 if (info->is_lazy()) {
5236 DCHECK(!info->is_eval());
5237 if (info->shared_info()->is_function()) {
5238 result = ParseLazy(isolate, info);
5239 } else {
5240 result = ParseProgram(isolate, info);
5241 }
5242 } else {
5243 SetCachedData(info);
5244 result = ParseProgram(isolate, info);
5245 }
5246 info->set_literal(result);
5247
5248 Internalize(isolate, info->script(), result == NULL);
5249 DCHECK(ast_value_factory()->IsInternalized());
5250 return (result != NULL);
5251}
5252
5253
5254void Parser::ParseOnBackground(ParseInfo* info) {
5255 parsing_on_main_thread_ = false;
5256
5257 DCHECK(info->literal() == NULL);
5258 FunctionLiteral* result = NULL;
5259 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
5260
5261 CompleteParserRecorder recorder;
5262 if (produce_cached_parse_data()) log_ = &recorder;
5263
5264 DCHECK(info->source_stream() != NULL);
5265 ExternalStreamingStream stream(info->source_stream(),
5266 info->source_stream_encoding());
5267 scanner_.Initialize(&stream);
5268 DCHECK(info->context().is_null() || info->context()->IsNativeContext());
5269
5270 // When streaming, we don't know the length of the source until we have parsed
5271 // it. The raw data can be UTF-8, so we wouldn't know the source length until
5272 // we have decoded it anyway even if we knew the raw data length (which we
5273 // don't). We work around this by storing all the scopes which need their end
5274 // position set at the end of the script (the top scope and possible eval
5275 // scopes) and set their end position after we know the script length.
5276 result = DoParseProgram(info);
5277
5278 info->set_literal(result);
5279
5280 // We cannot internalize on a background thread; a foreground task will take
5281 // care of calling Parser::Internalize just before compilation.
5282
5283 if (produce_cached_parse_data()) {
5284 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
5285 log_ = NULL;
5286 }
5287}
5288
5289
5290ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
5291 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
5292}
5293
5294
5295void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
5296 int pos = scanner()->location().beg_pos;
5297 int end = scanner()->location().end_pos - (tail ? 1 : 2);
5298 const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
5299 const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
5300 Literal* cooked = factory()->NewStringLiteral(tv, pos);
5301 Literal* raw = factory()->NewStringLiteral(trv, pos);
5302 (*state)->AddTemplateSpan(cooked, raw, end, zone());
5303}
5304
5305
5306void Parser::AddTemplateExpression(TemplateLiteralState* state,
5307 Expression* expression) {
5308 (*state)->AddExpression(expression, zone());
5309}
5310
5311
5312Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
5313 Expression* tag) {
5314 TemplateLiteral* lit = *state;
5315 int pos = lit->position();
5316 const ZoneList<Expression*>* cooked_strings = lit->cooked();
5317 const ZoneList<Expression*>* raw_strings = lit->raw();
5318 const ZoneList<Expression*>* expressions = lit->expressions();
5319 DCHECK_EQ(cooked_strings->length(), raw_strings->length());
5320 DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
5321
5322 if (!tag) {
5323 // Build tree of BinaryOps to simplify code-generation
5324 Expression* expr = cooked_strings->at(0);
5325 int i = 0;
5326 while (i < expressions->length()) {
5327 Expression* sub = expressions->at(i++);
5328 Expression* cooked_str = cooked_strings->at(i);
5329
5330 // Let middle be ToString(sub).
5331 ZoneList<Expression*>* args =
5332 new (zone()) ZoneList<Expression*>(1, zone());
5333 args->Add(sub, zone());
5334 Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString,
5335 args, sub->position());
5336
5337 expr = factory()->NewBinaryOperation(
5338 Token::ADD, factory()->NewBinaryOperation(
5339 Token::ADD, expr, middle, expr->position()),
5340 cooked_str, sub->position());
5341 }
5342 return expr;
5343 } else {
5344 uint32_t hash = ComputeTemplateLiteralHash(lit);
5345
5346 int cooked_idx = function_state_->NextMaterializedLiteralIndex();
5347 int raw_idx = function_state_->NextMaterializedLiteralIndex();
5348
5349 // $getTemplateCallSite
5350 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
5351 args->Add(factory()->NewArrayLiteral(
5352 const_cast<ZoneList<Expression*>*>(cooked_strings),
Ben Murdochda12d292016-06-02 14:46:10 +01005353 cooked_idx, pos),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005354 zone());
5355 args->Add(
5356 factory()->NewArrayLiteral(
Ben Murdochda12d292016-06-02 14:46:10 +01005357 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005358 zone());
5359
5360 // Ensure hash is suitable as a Smi value
5361 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
5362 args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone());
5363
5364 Expression* call_site = factory()->NewCallRuntime(
5365 Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start);
5366
5367 // Call TagFn
5368 ZoneList<Expression*>* call_args =
5369 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
5370 call_args->Add(call_site, zone());
5371 call_args->AddAll(*expressions, zone());
5372 return factory()->NewCall(tag, call_args, pos);
5373 }
5374}
5375
5376
5377uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
5378 const ZoneList<Expression*>* raw_strings = lit->raw();
5379 int total = raw_strings->length();
5380 DCHECK(total);
5381
5382 uint32_t running_hash = 0;
5383
5384 for (int index = 0; index < total; ++index) {
5385 if (index) {
5386 running_hash = StringHasher::ComputeRunningHashOneByte(
5387 running_hash, "${}", 3);
5388 }
5389
5390 const AstRawString* raw_string =
5391 raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
5392 if (raw_string->is_one_byte()) {
5393 const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
5394 running_hash = StringHasher::ComputeRunningHashOneByte(
5395 running_hash, data, raw_string->length());
5396 } else {
5397 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
5398 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
5399 raw_string->length());
5400 }
5401 }
5402
5403 return running_hash;
5404}
5405
5406
5407ZoneList<v8::internal::Expression*>* Parser::PrepareSpreadArguments(
5408 ZoneList<v8::internal::Expression*>* list) {
5409 ZoneList<v8::internal::Expression*>* args =
5410 new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
5411 if (list->length() == 1) {
5412 // Spread-call with single spread argument produces an InternalArray
5413 // containing the values from the array.
5414 //
5415 // Function is called or constructed with the produced array of arguments
5416 //
5417 // EG: Apply(Func, Spread(spread0))
5418 ZoneList<Expression*>* spread_list =
5419 new (zone()) ZoneList<Expression*>(0, zone());
5420 spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
5421 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
5422 spread_list, RelocInfo::kNoPosition),
5423 zone());
5424 return args;
5425 } else {
5426 // Spread-call with multiple arguments produces array literals for each
5427 // sequences of unspread arguments, and converts each spread iterable to
5428 // an Internal array. Finally, all of these produced arrays are flattened
5429 // into a single InternalArray, containing the arguments for the call.
5430 //
5431 // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
5432 // Spread(spread1), [unspread2, unspread3]))
5433 int i = 0;
5434 int n = list->length();
5435 while (i < n) {
5436 if (!list->at(i)->IsSpread()) {
5437 ZoneList<v8::internal::Expression*>* unspread =
5438 new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
5439
5440 // Push array of unspread parameters
5441 while (i < n && !list->at(i)->IsSpread()) {
5442 unspread->Add(list->at(i++), zone());
5443 }
5444 int literal_index = function_state_->NextMaterializedLiteralIndex();
5445 args->Add(factory()->NewArrayLiteral(unspread, literal_index,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005446 RelocInfo::kNoPosition),
5447 zone());
5448
5449 if (i == n) break;
5450 }
5451
5452 // Push eagerly spread argument
5453 ZoneList<v8::internal::Expression*>* spread_list =
5454 new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
5455 spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
5456 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
5457 spread_list, RelocInfo::kNoPosition),
5458 zone());
5459 }
5460
5461 list = new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
5462 list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
5463 RelocInfo::kNoPosition),
5464 zone());
5465 return list;
5466 }
5467 UNREACHABLE();
5468}
5469
5470
5471Expression* Parser::SpreadCall(Expression* function,
5472 ZoneList<v8::internal::Expression*>* args,
5473 int pos) {
5474 if (function->IsSuperCallReference()) {
5475 // Super calls
5476 // $super_constructor = %_GetSuperConstructor(<this-function>)
5477 // %reflect_construct($super_constructor, args, new.target)
5478 ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
5479 tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
5480 Expression* super_constructor = factory()->NewCallRuntime(
5481 Runtime::kInlineGetSuperConstructor, tmp, pos);
5482 args->InsertAt(0, super_constructor, zone());
5483 args->Add(function->AsSuperCallReference()->new_target_var(), zone());
5484 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
5485 pos);
5486 } else {
5487 if (function->IsProperty()) {
5488 // Method calls
5489 if (function->AsProperty()->IsSuperAccess()) {
5490 Expression* home =
5491 ThisExpression(scope_, factory(), RelocInfo::kNoPosition);
5492 args->InsertAt(0, function, zone());
5493 args->InsertAt(1, home, zone());
5494 } else {
5495 Variable* temp =
5496 scope_->NewTemporary(ast_value_factory()->empty_string());
5497 VariableProxy* obj = factory()->NewVariableProxy(temp);
5498 Assignment* assign_obj = factory()->NewAssignment(
5499 Token::ASSIGN, obj, function->AsProperty()->obj(),
5500 RelocInfo::kNoPosition);
5501 function = factory()->NewProperty(
5502 assign_obj, function->AsProperty()->key(), RelocInfo::kNoPosition);
5503 args->InsertAt(0, function, zone());
5504 obj = factory()->NewVariableProxy(temp);
5505 args->InsertAt(1, obj, zone());
5506 }
5507 } else {
5508 // Non-method calls
5509 args->InsertAt(0, function, zone());
5510 args->InsertAt(1, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
5511 zone());
5512 }
5513 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
5514 }
5515}
5516
5517
5518Expression* Parser::SpreadCallNew(Expression* function,
5519 ZoneList<v8::internal::Expression*>* args,
5520 int pos) {
5521 args->InsertAt(0, function, zone());
5522
5523 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
5524}
5525
5526
5527void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
5528 v8::Isolate::UseCounterFeature feature;
5529 if (is_sloppy(mode))
5530 feature = v8::Isolate::kSloppyMode;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005531 else if (is_strict(mode))
5532 feature = v8::Isolate::kStrictMode;
5533 else
5534 UNREACHABLE();
5535 ++use_counts_[feature];
5536 scope->SetLanguageMode(mode);
5537}
5538
5539
5540void Parser::RaiseLanguageMode(LanguageMode mode) {
Ben Murdochda12d292016-06-02 14:46:10 +01005541 LanguageMode old = scope_->language_mode();
5542 SetLanguageMode(scope_, old > mode ? old : mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005543}
5544
Ben Murdochc5610432016-08-08 18:44:38 +01005545void Parser::MarkCollectedTailCallExpressions() {
5546 const ZoneList<Expression*>& tail_call_expressions =
5547 function_state_->tail_call_expressions().expressions();
5548 for (int i = 0; i < tail_call_expressions.length(); ++i) {
5549 Expression* expression = tail_call_expressions[i];
5550 // If only FLAG_harmony_explicit_tailcalls is enabled then expression
5551 // must be a Call expression.
5552 DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls ||
5553 expression->IsCall());
5554 MarkTailPosition(expression);
5555 }
5556}
5557
5558Expression* ParserTraits::ExpressionListToExpression(
5559 ZoneList<Expression*>* args) {
5560 AstNodeFactory* factory = parser_->factory();
5561 Expression* expr = args->at(0);
5562 for (int i = 1; i < args->length(); ++i) {
5563 expr = factory->NewBinaryOperation(Token::COMMA, expr, args->at(i),
5564 expr->position());
5565 }
5566 return expr;
5567}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005568
5569void ParserTraits::RewriteDestructuringAssignments() {
5570 parser_->RewriteDestructuringAssignments();
5571}
5572
Ben Murdochda12d292016-06-02 14:46:10 +01005573Expression* ParserTraits::RewriteExponentiation(Expression* left,
5574 Expression* right, int pos) {
5575 return parser_->RewriteExponentiation(left, right, pos);
5576}
5577
5578Expression* ParserTraits::RewriteAssignExponentiation(Expression* left,
5579 Expression* right,
5580 int pos) {
5581 return parser_->RewriteAssignExponentiation(left, right, pos);
5582}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005583
Ben Murdoch097c5b22016-05-18 11:27:45 +01005584void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier,
5585 bool* ok) {
5586 parser_->RewriteNonPattern(classifier, ok);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005587}
5588
Ben Murdochc5610432016-08-08 18:44:38 +01005589Expression* ParserTraits::RewriteAwaitExpression(Expression* value, int pos) {
5590 // yield %AsyncFunctionAwait(.generator_object, <operand>)
5591 Variable* generator_object_variable =
5592 parser_->function_state_->generator_object_variable();
5593
5594 // If generator_object_variable is null,
5595 if (!generator_object_variable) return value;
5596
5597 Expression* generator_object =
5598 parser_->factory()->NewVariableProxy(generator_object_variable);
5599
5600 ZoneList<Expression*>* async_function_await_args =
5601 new (zone()) ZoneList<Expression*>(2, zone());
5602 async_function_await_args->Add(generator_object, zone());
5603 async_function_await_args->Add(value, zone());
5604 Expression* async_function_await = parser_->factory()->NewCallRuntime(
5605 Context::ASYNC_FUNCTION_AWAIT_INDEX, async_function_await_args,
5606 RelocInfo::kNoPosition);
5607
5608 generator_object =
5609 parser_->factory()->NewVariableProxy(generator_object_variable);
5610 return parser_->factory()->NewYield(generator_object, async_function_await,
5611 pos);
5612}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005613
Ben Murdoch097c5b22016-05-18 11:27:45 +01005614Zone* ParserTraits::zone() const {
5615 return parser_->function_state_->scope()->zone();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005616}
5617
5618
Ben Murdoch097c5b22016-05-18 11:27:45 +01005619ZoneList<Expression*>* ParserTraits::GetNonPatternList() const {
5620 return parser_->function_state_->non_patterns_to_rewrite();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005621}
5622
5623
Ben Murdoch097c5b22016-05-18 11:27:45 +01005624class NonPatternRewriter : public AstExpressionRewriter {
5625 public:
5626 NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
5627 : AstExpressionRewriter(stack_limit), parser_(parser) {}
5628 ~NonPatternRewriter() override {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005629
Ben Murdoch097c5b22016-05-18 11:27:45 +01005630 private:
5631 bool RewriteExpression(Expression* expr) override {
5632 if (expr->IsRewritableExpression()) return true;
5633 // Rewrite only what could have been a pattern but is not.
5634 if (expr->IsArrayLiteral()) {
5635 // Spread rewriting in array literals.
5636 ArrayLiteral* lit = expr->AsArrayLiteral();
5637 VisitExpressions(lit->values());
5638 replacement_ = parser_->RewriteSpreads(lit);
5639 return false;
5640 }
5641 if (expr->IsObjectLiteral()) {
5642 return true;
5643 }
5644 if (expr->IsBinaryOperation() &&
5645 expr->AsBinaryOperation()->op() == Token::COMMA) {
5646 return true;
5647 }
5648 // Everything else does not need rewriting.
5649 return false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005650 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01005651
5652 void VisitObjectLiteralProperty(ObjectLiteralProperty* property) override {
5653 if (property == nullptr) return;
5654 // Do not rewrite (computed) key expressions
5655 AST_REWRITE_PROPERTY(Expression, property, value);
5656 }
5657
5658 Parser* parser_;
5659};
5660
5661
5662void Parser::RewriteNonPattern(ExpressionClassifier* classifier, bool* ok) {
5663 ValidateExpression(classifier, ok);
5664 if (!*ok) return;
5665 auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite();
5666 int begin = classifier->GetNonPatternBegin();
5667 int end = non_patterns_to_rewrite->length();
5668 if (begin < end) {
5669 NonPatternRewriter rewriter(stack_limit_, this);
5670 for (int i = begin; i < end; i++) {
5671 DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression());
5672 rewriter.Rewrite(non_patterns_to_rewrite->at(i));
5673 }
5674 non_patterns_to_rewrite->Rewind(begin);
5675 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005676}
5677
5678
5679void Parser::RewriteDestructuringAssignments() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01005680 const auto& assignments =
5681 function_state_->destructuring_assignments_to_rewrite();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005682 for (int i = assignments.length() - 1; i >= 0; --i) {
5683 // Rewrite list in reverse, so that nested assignment patterns are rewritten
5684 // correctly.
Ben Murdoch097c5b22016-05-18 11:27:45 +01005685 const DestructuringAssignment& pair = assignments.at(i);
5686 RewritableExpression* to_rewrite =
5687 pair.assignment->AsRewritableExpression();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005688 DCHECK_NOT_NULL(to_rewrite);
5689 if (!to_rewrite->is_rewritten()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01005690 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite,
5691 pair.scope);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005692 }
5693 }
5694}
5695
Ben Murdochda12d292016-06-02 14:46:10 +01005696Expression* Parser::RewriteExponentiation(Expression* left, Expression* right,
5697 int pos) {
5698 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
5699 args->Add(left, zone());
5700 args->Add(right, zone());
5701 return factory()->NewCallRuntime(Context::MATH_POW_METHOD_INDEX, args, pos);
5702}
5703
5704Expression* Parser::RewriteAssignExponentiation(Expression* left,
5705 Expression* right, int pos) {
5706 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
5707 if (left->IsVariableProxy()) {
5708 VariableProxy* lhs = left->AsVariableProxy();
5709
5710 Expression* result;
5711 DCHECK_NOT_NULL(lhs->raw_name());
5712 result =
5713 this->ExpressionFromIdentifier(lhs->raw_name(), lhs->position(),
5714 lhs->end_position(), scope_, factory());
5715 args->Add(left, zone());
5716 args->Add(right, zone());
5717 Expression* call =
5718 factory()->NewCallRuntime(Context::MATH_POW_METHOD_INDEX, args, pos);
5719 return factory()->NewAssignment(Token::ASSIGN, result, call, pos);
5720 } else if (left->IsProperty()) {
5721 Property* prop = left->AsProperty();
5722 auto temp_obj = scope_->NewTemporary(ast_value_factory()->empty_string());
5723 auto temp_key = scope_->NewTemporary(ast_value_factory()->empty_string());
5724 Expression* assign_obj = factory()->NewAssignment(
5725 Token::ASSIGN, factory()->NewVariableProxy(temp_obj), prop->obj(),
5726 RelocInfo::kNoPosition);
5727 Expression* assign_key = factory()->NewAssignment(
5728 Token::ASSIGN, factory()->NewVariableProxy(temp_key), prop->key(),
5729 RelocInfo::kNoPosition);
5730 args->Add(factory()->NewProperty(factory()->NewVariableProxy(temp_obj),
5731 factory()->NewVariableProxy(temp_key),
5732 left->position()),
5733 zone());
5734 args->Add(right, zone());
5735 Expression* call =
5736 factory()->NewCallRuntime(Context::MATH_POW_METHOD_INDEX, args, pos);
5737 Expression* target = factory()->NewProperty(
5738 factory()->NewVariableProxy(temp_obj),
5739 factory()->NewVariableProxy(temp_key), RelocInfo::kNoPosition);
5740 Expression* assign =
5741 factory()->NewAssignment(Token::ASSIGN, target, call, pos);
5742 return factory()->NewBinaryOperation(
5743 Token::COMMA, assign_obj,
5744 factory()->NewBinaryOperation(Token::COMMA, assign_key, assign, pos),
5745 pos);
5746 }
5747 UNREACHABLE();
5748 return nullptr;
5749}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005750
Ben Murdoch097c5b22016-05-18 11:27:45 +01005751Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
5752 // Array literals containing spreads are rewritten using do expressions, e.g.
5753 // [1, 2, 3, ...x, 4, ...y, 5]
5754 // is roughly rewritten as:
5755 // do {
5756 // $R = [1, 2, 3];
5757 // for ($i of x) %AppendElement($R, $i);
5758 // %AppendElement($R, 4);
5759 // for ($j of y) %AppendElement($R, $j);
5760 // %AppendElement($R, 5);
5761 // $R
5762 // }
5763 // where $R, $i and $j are fresh temporary variables.
5764 ZoneList<Expression*>::iterator s = lit->FirstSpread();
5765 if (s == lit->EndValue()) return nullptr; // no spread, no rewriting...
5766 Variable* result =
5767 scope_->NewTemporary(ast_value_factory()->dot_result_string());
5768 // NOTE: The value assigned to R is the whole original array literal,
5769 // spreads included. This will be fixed before the rewritten AST is returned.
5770 // $R = lit
5771 Expression* init_result =
5772 factory()->NewAssignment(Token::INIT, factory()->NewVariableProxy(result),
5773 lit, RelocInfo::kNoPosition);
5774 Block* do_block =
5775 factory()->NewBlock(nullptr, 16, false, RelocInfo::kNoPosition);
5776 do_block->statements()->Add(
5777 factory()->NewExpressionStatement(init_result, RelocInfo::kNoPosition),
5778 zone());
5779 // Traverse the array literal starting from the first spread.
5780 while (s != lit->EndValue()) {
5781 Expression* value = *s++;
5782 Spread* spread = value->AsSpread();
5783 if (spread == nullptr) {
5784 // If the element is not a spread, we're adding a single:
5785 // %AppendElement($R, value)
5786 ZoneList<Expression*>* append_element_args = NewExpressionList(2, zone());
5787 append_element_args->Add(factory()->NewVariableProxy(result), zone());
5788 append_element_args->Add(value, zone());
5789 do_block->statements()->Add(
5790 factory()->NewExpressionStatement(
5791 factory()->NewCallRuntime(Runtime::kAppendElement,
5792 append_element_args,
5793 RelocInfo::kNoPosition),
5794 RelocInfo::kNoPosition),
5795 zone());
5796 } else {
5797 // If it's a spread, we're adding a for/of loop iterating through it.
5798 Variable* each =
5799 scope_->NewTemporary(ast_value_factory()->dot_for_string());
5800 Expression* subject = spread->expression();
Ben Murdoch097c5b22016-05-18 11:27:45 +01005801 // %AppendElement($R, each)
5802 Statement* append_body;
5803 {
5804 ZoneList<Expression*>* append_element_args =
5805 NewExpressionList(2, zone());
5806 append_element_args->Add(factory()->NewVariableProxy(result), zone());
5807 append_element_args->Add(factory()->NewVariableProxy(each), zone());
5808 append_body = factory()->NewExpressionStatement(
5809 factory()->NewCallRuntime(Runtime::kAppendElement,
5810 append_element_args,
5811 RelocInfo::kNoPosition),
5812 RelocInfo::kNoPosition);
5813 }
5814 // for (each of spread) %AppendElement($R, each)
5815 ForEachStatement* loop = factory()->NewForEachStatement(
5816 ForEachStatement::ITERATE, nullptr, RelocInfo::kNoPosition);
Ben Murdochda12d292016-06-02 14:46:10 +01005817 InitializeForOfStatement(loop->AsForOfStatement(),
5818 factory()->NewVariableProxy(each), subject,
Ben Murdochc5610432016-08-08 18:44:38 +01005819 append_body);
Ben Murdochda12d292016-06-02 14:46:10 +01005820 do_block->statements()->Add(loop, zone());
Ben Murdoch097c5b22016-05-18 11:27:45 +01005821 }
5822 }
5823 // Now, rewind the original array literal to truncate everything from the
5824 // first spread (included) until the end. This fixes $R's initialization.
5825 lit->RewindSpreads();
5826 return factory()->NewDoExpression(do_block, result, lit->position());
5827}
5828
5829
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005830void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01005831 DCHECK(expr->IsRewritableExpression());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005832 parser_->function_state_->AddDestructuringAssignment(
5833 Parser::DestructuringAssignment(expr, parser_->scope_));
5834}
5835
5836
Ben Murdoch097c5b22016-05-18 11:27:45 +01005837void ParserTraits::QueueNonPatternForRewriting(Expression* expr) {
5838 DCHECK(expr->IsRewritableExpression());
5839 parser_->function_state_->AddNonPatternForRewriting(expr);
5840}
5841
5842
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005843void ParserTraits::SetFunctionNameFromPropertyName(
5844 ObjectLiteralProperty* property, const AstRawString* name) {
5845 Expression* value = property->value();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005846
Ben Murdoch097c5b22016-05-18 11:27:45 +01005847 // Computed name setting must happen at runtime.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005848 if (property->is_computed_name()) return;
Ben Murdoch097c5b22016-05-18 11:27:45 +01005849
5850 // Getter and setter names are handled here because their names
5851 // change in ES2015, even though they are not anonymous.
5852 auto function = value->AsFunctionLiteral();
5853 if (function != nullptr) {
5854 bool is_getter = property->kind() == ObjectLiteralProperty::GETTER;
5855 bool is_setter = property->kind() == ObjectLiteralProperty::SETTER;
5856 if (is_getter || is_setter) {
5857 DCHECK_NOT_NULL(name);
5858 const AstRawString* prefix =
5859 is_getter ? parser_->ast_value_factory()->get_space_string()
5860 : parser_->ast_value_factory()->set_space_string();
5861 function->set_raw_name(
5862 parser_->ast_value_factory()->NewConsString(prefix, name));
5863 return;
5864 }
5865 }
5866
5867 if (!value->IsAnonymousFunctionDefinition()) return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005868 DCHECK_NOT_NULL(name);
5869
5870 // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
5871 // of an object literal.
5872 if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return;
5873
Ben Murdoch097c5b22016-05-18 11:27:45 +01005874 if (function != nullptr) {
5875 function->set_raw_name(name);
5876 DCHECK_EQ(ObjectLiteralProperty::COMPUTED, property->kind());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005877 } else {
5878 DCHECK(value->IsClassLiteral());
5879 DCHECK_EQ(ObjectLiteralProperty::COMPUTED, property->kind());
Ben Murdoch097c5b22016-05-18 11:27:45 +01005880 value->AsClassLiteral()->constructor()->set_raw_name(name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005881 }
5882}
5883
5884
5885void ParserTraits::SetFunctionNameFromIdentifierRef(Expression* value,
5886 Expression* identifier) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01005887 if (!value->IsAnonymousFunctionDefinition()) return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005888 if (!identifier->IsVariableProxy()) return;
5889
5890 auto name = identifier->AsVariableProxy()->raw_name();
5891 DCHECK_NOT_NULL(name);
5892
Ben Murdoch097c5b22016-05-18 11:27:45 +01005893 auto function = value->AsFunctionLiteral();
5894 if (function != nullptr) {
5895 function->set_raw_name(name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005896 } else {
5897 DCHECK(value->IsClassLiteral());
Ben Murdoch097c5b22016-05-18 11:27:45 +01005898 value->AsClassLiteral()->constructor()->set_raw_name(name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005899 }
5900}
5901
5902
Ben Murdoch097c5b22016-05-18 11:27:45 +01005903// Desugaring of yield*
5904// ====================
5905//
5906// With the help of do-expressions and function.sent, we desugar yield* into a
5907// loop containing a "raw" yield (a yield that doesn't wrap an iterator result
5908// object around its argument). Concretely, "yield* iterable" turns into
5909// roughly the following code:
5910//
5911// do {
5912// const kNext = 0;
5913// const kReturn = 1;
5914// const kThrow = 2;
5915//
5916// let input = function.sent;
5917// let mode = kNext;
5918// let output = undefined;
5919//
5920// let iterator = iterable[Symbol.iterator]();
5921// if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid);
5922//
5923// while (true) {
5924// // From the generator to the iterator:
5925// // Forward input according to resume mode and obtain output.
5926// switch (mode) {
5927// case kNext:
5928// output = iterator.next(input);
5929// if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
5930// break;
5931// case kReturn:
5932// IteratorClose(iterator, input, output); // See below.
5933// break;
5934// case kThrow:
5935// let iteratorThrow = iterator.throw;
5936// if (IS_NULL_OR_UNDEFINED(iteratorThrow)) {
5937// IteratorClose(iterator); // See below.
5938// throw MakeTypeError(kThrowMethodMissing);
5939// }
5940// output = %_Call(iteratorThrow, iterator, input);
5941// if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
5942// break;
5943// }
5944// if (output.done) break;
5945//
5946// // From the generator to its user:
5947// // Forward output, receive new input, and determine resume mode.
5948// mode = kReturn;
5949// try {
5950// try {
5951// RawYield(output); // See explanation above.
5952// mode = kNext;
5953// } catch (error) {
5954// mode = kThrow;
5955// }
5956// } finally {
5957// input = function.sent;
5958// continue;
5959// }
5960// }
5961//
Ben Murdochc5610432016-08-08 18:44:38 +01005962// if (mode === kReturn) {
5963// return {value: output.value, done: true};
5964// }
5965// output.value
Ben Murdoch097c5b22016-05-18 11:27:45 +01005966// }
5967//
5968// IteratorClose(iterator) expands to the following:
5969//
5970// let iteratorReturn = iterator.return;
Ben Murdochc5610432016-08-08 18:44:38 +01005971// if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
5972// let output = %_Call(iteratorReturn, iterator);
5973// if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
5974// }
Ben Murdoch097c5b22016-05-18 11:27:45 +01005975//
5976// IteratorClose(iterator, input, output) expands to the following:
5977//
5978// let iteratorReturn = iterator.return;
5979// if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input;
5980// output = %_Call(iteratorReturn, iterator, input);
5981// if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
5982
Ben Murdoch097c5b22016-05-18 11:27:45 +01005983Expression* ParserTraits::RewriteYieldStar(
5984 Expression* generator, Expression* iterable, int pos) {
5985
5986 const int nopos = RelocInfo::kNoPosition;
5987
5988 auto factory = parser_->factory();
5989 auto avfactory = parser_->ast_value_factory();
5990 auto scope = parser_->scope_;
5991 auto zone = parser_->zone();
5992
5993
5994 // Forward definition for break/continue statements.
5995 WhileStatement* loop = factory->NewWhileStatement(nullptr, nopos);
5996
5997
5998 // let input = undefined;
5999 Variable* var_input = scope->NewTemporary(avfactory->empty_string());
6000 Statement* initialize_input;
6001 {
6002 Expression* input_proxy = factory->NewVariableProxy(var_input);
6003 Expression* assignment = factory->NewAssignment(
6004 Token::ASSIGN, input_proxy, factory->NewUndefinedLiteral(nopos), nopos);
6005 initialize_input = factory->NewExpressionStatement(assignment, nopos);
6006 }
6007
6008
6009 // let mode = kNext;
6010 Variable* var_mode = scope->NewTemporary(avfactory->empty_string());
6011 Statement* initialize_mode;
6012 {
6013 Expression* mode_proxy = factory->NewVariableProxy(var_mode);
Ben Murdochc5610432016-08-08 18:44:38 +01006014 Expression* knext = factory->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006015 Expression* assignment =
6016 factory->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
6017 initialize_mode = factory->NewExpressionStatement(assignment, nopos);
6018 }
6019
6020
6021 // let output = undefined;
6022 Variable* var_output = scope->NewTemporary(avfactory->empty_string());
6023 Statement* initialize_output;
6024 {
6025 Expression* output_proxy = factory->NewVariableProxy(var_output);
6026 Expression* assignment = factory->NewAssignment(
6027 Token::ASSIGN, output_proxy, factory->NewUndefinedLiteral(nopos),
6028 nopos);
6029 initialize_output = factory->NewExpressionStatement(assignment, nopos);
6030 }
6031
6032
6033 // let iterator = iterable[Symbol.iterator];
6034 Variable* var_iterator = scope->NewTemporary(avfactory->empty_string());
6035 Statement* get_iterator;
6036 {
6037 Expression* iterator = GetIterator(iterable, factory, nopos);
6038 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
6039 Expression* assignment = factory->NewAssignment(
6040 Token::ASSIGN, iterator_proxy, iterator, nopos);
6041 get_iterator = factory->NewExpressionStatement(assignment, nopos);
6042 }
6043
6044
6045 // if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid);
6046 Statement* validate_iterator;
6047 {
6048 Expression* is_receiver_call;
6049 {
6050 auto args = new (zone) ZoneList<Expression*>(1, zone);
6051 args->Add(factory->NewVariableProxy(var_iterator), zone);
6052 is_receiver_call =
6053 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6054 }
6055
6056 Statement* throw_call;
6057 {
6058 Expression* call = NewThrowTypeError(
6059 MessageTemplate::kSymbolIteratorInvalid, avfactory->empty_string(),
6060 nopos);
6061 throw_call = factory->NewExpressionStatement(call, nopos);
6062 }
6063
6064 validate_iterator = factory->NewIfStatement(
6065 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6066 }
6067
6068
6069 // output = iterator.next(input);
6070 Statement* call_next;
6071 {
6072 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
6073 Expression* literal =
6074 factory->NewStringLiteral(avfactory->next_string(), nopos);
6075 Expression* next_property =
6076 factory->NewProperty(iterator_proxy, literal, nopos);
6077 Expression* input_proxy = factory->NewVariableProxy(var_input);
6078 auto args = new (zone) ZoneList<Expression*>(1, zone);
6079 args->Add(input_proxy, zone);
6080 Expression* call = factory->NewCall(next_property, args, nopos);
6081 Expression* output_proxy = factory->NewVariableProxy(var_output);
6082 Expression* assignment =
6083 factory->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
6084 call_next = factory->NewExpressionStatement(assignment, nopos);
6085 }
6086
6087
6088 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6089 Statement* validate_next_output;
6090 {
6091 Expression* is_receiver_call;
6092 {
6093 auto args = new (zone) ZoneList<Expression*>(1, zone);
6094 args->Add(factory->NewVariableProxy(var_output), zone);
6095 is_receiver_call =
6096 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6097 }
6098
6099 Statement* throw_call;
6100 {
6101 auto args = new (zone) ZoneList<Expression*>(1, zone);
6102 args->Add(factory->NewVariableProxy(var_output), zone);
6103 Expression* call = factory->NewCallRuntime(
6104 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6105 throw_call = factory->NewExpressionStatement(call, nopos);
6106 }
6107
6108 validate_next_output = factory->NewIfStatement(
6109 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6110 }
6111
6112
6113 // let iteratorThrow = iterator.throw;
6114 Variable* var_throw = scope->NewTemporary(avfactory->empty_string());
6115 Statement* get_throw;
6116 {
6117 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
6118 Expression* literal =
6119 factory->NewStringLiteral(avfactory->throw_string(), nopos);
6120 Expression* property =
6121 factory->NewProperty(iterator_proxy, literal, nopos);
6122 Expression* throw_proxy = factory->NewVariableProxy(var_throw);
6123 Expression* assignment = factory->NewAssignment(
6124 Token::ASSIGN, throw_proxy, property, nopos);
6125 get_throw = factory->NewExpressionStatement(assignment, nopos);
6126 }
6127
6128
6129 // if (IS_NULL_OR_UNDEFINED(iteratorThrow) {
6130 // IteratorClose(iterator);
6131 // throw MakeTypeError(kThrowMethodMissing);
6132 // }
6133 Statement* check_throw;
6134 {
6135 Expression* condition = factory->NewCompareOperation(
6136 Token::EQ, factory->NewVariableProxy(var_throw),
6137 factory->NewNullLiteral(nopos), nopos);
6138
6139 Expression* call = NewThrowTypeError(
6140 MessageTemplate::kThrowMethodMissing,
6141 avfactory->empty_string(), nopos);
6142 Statement* throw_call = factory->NewExpressionStatement(call, nopos);
6143
6144 Block* then = factory->NewBlock(nullptr, 4+1, false, nopos);
Ben Murdochc5610432016-08-08 18:44:38 +01006145 parser_->BuildIteratorCloseForCompletion(
6146 then->statements(), var_iterator,
6147 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos));
Ben Murdoch097c5b22016-05-18 11:27:45 +01006148 then->statements()->Add(throw_call, zone);
6149 check_throw = factory->NewIfStatement(
6150 condition, then, factory->NewEmptyStatement(nopos), nopos);
6151 }
6152
6153
6154 // output = %_Call(iteratorThrow, iterator, input);
6155 Statement* call_throw;
6156 {
6157 auto args = new (zone) ZoneList<Expression*>(3, zone);
6158 args->Add(factory->NewVariableProxy(var_throw), zone);
6159 args->Add(factory->NewVariableProxy(var_iterator), zone);
6160 args->Add(factory->NewVariableProxy(var_input), zone);
6161 Expression* call =
6162 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6163 Expression* assignment = factory->NewAssignment(
6164 Token::ASSIGN, factory->NewVariableProxy(var_output), call, nopos);
6165 call_throw = factory->NewExpressionStatement(assignment, nopos);
6166 }
6167
6168
6169 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6170 Statement* validate_throw_output;
6171 {
6172 Expression* is_receiver_call;
6173 {
6174 auto args = new (zone) ZoneList<Expression*>(1, zone);
6175 args->Add(factory->NewVariableProxy(var_output), zone);
6176 is_receiver_call =
6177 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6178 }
6179
6180 Statement* throw_call;
6181 {
6182 auto args = new (zone) ZoneList<Expression*>(1, zone);
6183 args->Add(factory->NewVariableProxy(var_output), zone);
6184 Expression* call = factory->NewCallRuntime(
6185 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6186 throw_call = factory->NewExpressionStatement(call, nopos);
6187 }
6188
6189 validate_throw_output = factory->NewIfStatement(
6190 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6191 }
6192
6193
6194 // if (output.done) break;
6195 Statement* if_done;
6196 {
6197 Expression* output_proxy = factory->NewVariableProxy(var_output);
6198 Expression* literal =
6199 factory->NewStringLiteral(avfactory->done_string(), nopos);
6200 Expression* property = factory->NewProperty(output_proxy, literal, nopos);
6201 BreakStatement* break_loop = factory->NewBreakStatement(loop, nopos);
6202 if_done = factory->NewIfStatement(
6203 property, break_loop, factory->NewEmptyStatement(nopos), nopos);
6204 }
6205
6206
6207 // mode = kReturn;
6208 Statement* set_mode_return;
6209 {
6210 Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6211 Expression* kreturn =
Ben Murdochc5610432016-08-08 18:44:38 +01006212 factory->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006213 Expression* assignment =
6214 factory->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos);
6215 set_mode_return = factory->NewExpressionStatement(assignment, nopos);
6216 }
6217
Ben Murdochda12d292016-06-02 14:46:10 +01006218 // Yield(output);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006219 Statement* yield_output;
6220 {
6221 Expression* output_proxy = factory->NewVariableProxy(var_output);
Ben Murdochda12d292016-06-02 14:46:10 +01006222 Yield* yield = factory->NewYield(generator, output_proxy, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006223 yield_output = factory->NewExpressionStatement(yield, nopos);
6224 }
6225
6226
6227 // mode = kNext;
6228 Statement* set_mode_next;
6229 {
6230 Expression* mode_proxy = factory->NewVariableProxy(var_mode);
Ben Murdochc5610432016-08-08 18:44:38 +01006231 Expression* knext = factory->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006232 Expression* assignment =
6233 factory->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
6234 set_mode_next = factory->NewExpressionStatement(assignment, nopos);
6235 }
6236
6237
6238 // mode = kThrow;
6239 Statement* set_mode_throw;
6240 {
6241 Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6242 Expression* kthrow =
Ben Murdochc5610432016-08-08 18:44:38 +01006243 factory->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006244 Expression* assignment =
6245 factory->NewAssignment(Token::ASSIGN, mode_proxy, kthrow, nopos);
6246 set_mode_throw = factory->NewExpressionStatement(assignment, nopos);
6247 }
6248
6249
6250 // input = function.sent;
6251 Statement* get_input;
6252 {
6253 Expression* function_sent = FunctionSentExpression(scope, factory, nopos);
6254 Expression* input_proxy = factory->NewVariableProxy(var_input);
6255 Expression* assignment = factory->NewAssignment(
6256 Token::ASSIGN, input_proxy, function_sent, nopos);
6257 get_input = factory->NewExpressionStatement(assignment, nopos);
6258 }
6259
6260
Ben Murdochc5610432016-08-08 18:44:38 +01006261 // if (mode === kReturn) {
6262 // return {value: output.value, done: true};
6263 // }
6264 Statement* maybe_return_value;
6265 {
6266 Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6267 Expression* kreturn =
6268 factory->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
6269 Expression* condition = factory->NewCompareOperation(
6270 Token::EQ_STRICT, mode_proxy, kreturn, nopos);
6271
6272 Expression* output_proxy = factory->NewVariableProxy(var_output);
6273 Expression* literal =
6274 factory->NewStringLiteral(avfactory->value_string(), nopos);
6275 Expression* property = factory->NewProperty(output_proxy, literal, nopos);
6276 Statement* return_value =
6277 factory->NewReturnStatement(BuildIteratorResult(property, true), nopos);
6278
6279 maybe_return_value = factory->NewIfStatement(
6280 condition, return_value, factory->NewEmptyStatement(nopos), nopos);
6281 }
6282
6283
6284 // output.value
Ben Murdoch097c5b22016-05-18 11:27:45 +01006285 Statement* get_value;
6286 {
6287 Expression* output_proxy = factory->NewVariableProxy(var_output);
6288 Expression* literal =
6289 factory->NewStringLiteral(avfactory->value_string(), nopos);
6290 Expression* property = factory->NewProperty(output_proxy, literal, nopos);
6291 get_value = factory->NewExpressionStatement(property, nopos);
6292 }
6293
6294
6295 // Now put things together.
6296
6297
6298 // try { ... } catch(e) { ... }
6299 Statement* try_catch;
6300 {
6301 Block* try_block = factory->NewBlock(nullptr, 2, false, nopos);
6302 try_block->statements()->Add(yield_output, zone);
6303 try_block->statements()->Add(set_mode_next, zone);
6304
6305 Block* catch_block = factory->NewBlock(nullptr, 1, false, nopos);
6306 catch_block->statements()->Add(set_mode_throw, zone);
6307
6308 Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
Ben Murdochc5610432016-08-08 18:44:38 +01006309 catch_scope->set_is_hidden();
Ben Murdoch097c5b22016-05-18 11:27:45 +01006310 const AstRawString* name = avfactory->dot_catch_string();
6311 Variable* catch_variable =
6312 catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
6313 Variable::NORMAL);
6314
6315 try_catch = factory->NewTryCatchStatement(
6316 try_block, catch_scope, catch_variable, catch_block, nopos);
6317 }
6318
6319
6320 // try { ... } finally { ... }
6321 Statement* try_finally;
6322 {
6323 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6324 try_block->statements()->Add(try_catch, zone);
6325
6326 Block* finally = factory->NewBlock(nullptr, 2, false, nopos);
6327 finally->statements()->Add(get_input, zone);
6328 finally->statements()->Add(
6329 factory->NewContinueStatement(loop, nopos), zone);
6330
6331 try_finally = factory->NewTryFinallyStatement(try_block, finally, nopos);
6332 }
6333
6334
6335 // switch (mode) { ... }
6336 SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos);
6337 {
6338 auto case_next = new (zone) ZoneList<Statement*>(3, zone);
6339 case_next->Add(call_next, zone);
6340 case_next->Add(validate_next_output, zone);
6341 case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6342
6343 auto case_return = new (zone) ZoneList<Statement*>(5, zone);
Ben Murdochc5610432016-08-08 18:44:38 +01006344 BuildIteratorClose(case_return, var_iterator, var_input, var_output);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006345 case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6346
6347 auto case_throw = new (zone) ZoneList<Statement*>(5, zone);
6348 case_throw->Add(get_throw, zone);
6349 case_throw->Add(check_throw, zone);
6350 case_throw->Add(call_throw, zone);
6351 case_throw->Add(validate_throw_output, zone);
6352 case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6353
6354 auto cases = new (zone) ZoneList<CaseClause*>(3, zone);
Ben Murdochc5610432016-08-08 18:44:38 +01006355 Expression* knext = factory->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006356 Expression* kreturn =
Ben Murdochc5610432016-08-08 18:44:38 +01006357 factory->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006358 Expression* kthrow =
Ben Murdochc5610432016-08-08 18:44:38 +01006359 factory->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006360 cases->Add(factory->NewCaseClause(knext, case_next, nopos), zone);
6361 cases->Add(factory->NewCaseClause(kreturn, case_return, nopos), zone);
6362 cases->Add(factory->NewCaseClause(kthrow, case_throw, nopos), zone);
6363
6364 switch_mode->Initialize(factory->NewVariableProxy(var_mode), cases);
6365 }
6366
6367
6368 // while (true) { ... }
6369 // Already defined earlier: WhileStatement* loop = ...
6370 {
6371 Block* loop_body = factory->NewBlock(nullptr, 4, false, nopos);
6372 loop_body->statements()->Add(switch_mode, zone);
6373 loop_body->statements()->Add(if_done, zone);
6374 loop_body->statements()->Add(set_mode_return, zone);
6375 loop_body->statements()->Add(try_finally, zone);
6376
6377 loop->Initialize(factory->NewBooleanLiteral(true, nopos), loop_body);
6378 }
6379
6380
6381 // do { ... }
6382 DoExpression* yield_star;
6383 {
6384 // The rewriter needs to process the get_value statement only, hence we
6385 // put the preceding statements into an init block.
6386
Ben Murdochc5610432016-08-08 18:44:38 +01006387 Block* do_block_ = factory->NewBlock(nullptr, 7, true, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006388 do_block_->statements()->Add(initialize_input, zone);
6389 do_block_->statements()->Add(initialize_mode, zone);
6390 do_block_->statements()->Add(initialize_output, zone);
6391 do_block_->statements()->Add(get_iterator, zone);
6392 do_block_->statements()->Add(validate_iterator, zone);
6393 do_block_->statements()->Add(loop, zone);
Ben Murdochc5610432016-08-08 18:44:38 +01006394 do_block_->statements()->Add(maybe_return_value, zone);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006395
6396 Block* do_block = factory->NewBlock(nullptr, 2, false, nopos);
6397 do_block->statements()->Add(do_block_, zone);
6398 do_block->statements()->Add(get_value, zone);
6399
6400 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string());
6401 yield_star = factory->NewDoExpression(do_block, dot_result, nopos);
6402 Rewriter::Rewrite(parser_, yield_star, avfactory);
6403 }
6404
6405 return yield_star;
6406}
6407
Ben Murdochda12d292016-06-02 14:46:10 +01006408Statement* ParserTraits::CheckCallable(Variable* var, Expression* error,
6409 int pos) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01006410 auto factory = parser_->factory();
6411 auto avfactory = parser_->ast_value_factory();
6412 const int nopos = RelocInfo::kNoPosition;
6413 Statement* validate_var;
6414 {
6415 Expression* type_of = factory->NewUnaryOperation(
6416 Token::TYPEOF, factory->NewVariableProxy(var), nopos);
6417 Expression* function_literal =
6418 factory->NewStringLiteral(avfactory->function_string(), nopos);
6419 Expression* condition = factory->NewCompareOperation(
6420 Token::EQ_STRICT, type_of, function_literal, nopos);
6421
Ben Murdochda12d292016-06-02 14:46:10 +01006422 Statement* throw_call = factory->NewExpressionStatement(error, pos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006423
6424 validate_var = factory->NewIfStatement(
6425 condition, factory->NewEmptyStatement(nopos), throw_call, nopos);
6426 }
6427 return validate_var;
6428}
6429
6430void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements,
Ben Murdochc5610432016-08-08 18:44:38 +01006431 Variable* iterator, Variable* input,
Ben Murdoch097c5b22016-05-18 11:27:45 +01006432 Variable* var_output) {
6433 //
6434 // This function adds four statements to [statements], corresponding to the
6435 // following code:
6436 //
6437 // let iteratorReturn = iterator.return;
Ben Murdochc5610432016-08-08 18:44:38 +01006438 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
6439 // return {value: input, done: true};
6440 // }
6441 // output = %_Call(iteratorReturn, iterator, input);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006442 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6443 //
6444
6445 const int nopos = RelocInfo::kNoPosition;
6446 auto factory = parser_->factory();
6447 auto avfactory = parser_->ast_value_factory();
6448 auto zone = parser_->zone();
6449
6450 // let iteratorReturn = iterator.return;
6451 Variable* var_return = var_output; // Reusing the output variable.
6452 Statement* get_return;
6453 {
6454 Expression* iterator_proxy = factory->NewVariableProxy(iterator);
6455 Expression* literal =
6456 factory->NewStringLiteral(avfactory->return_string(), nopos);
6457 Expression* property =
6458 factory->NewProperty(iterator_proxy, literal, nopos);
6459 Expression* return_proxy = factory->NewVariableProxy(var_return);
6460 Expression* assignment = factory->NewAssignment(
6461 Token::ASSIGN, return_proxy, property, nopos);
6462 get_return = factory->NewExpressionStatement(assignment, nopos);
6463 }
6464
Ben Murdochc5610432016-08-08 18:44:38 +01006465 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
6466 // return {value: input, done: true};
6467 // }
Ben Murdoch097c5b22016-05-18 11:27:45 +01006468 Statement* check_return;
6469 {
6470 Expression* condition = factory->NewCompareOperation(
6471 Token::EQ, factory->NewVariableProxy(var_return),
6472 factory->NewNullLiteral(nopos), nopos);
6473
Ben Murdochc5610432016-08-08 18:44:38 +01006474 Expression* value = factory->NewVariableProxy(input);
Ben Murdochda12d292016-06-02 14:46:10 +01006475
Ben Murdochc5610432016-08-08 18:44:38 +01006476 Statement* return_input =
6477 factory->NewReturnStatement(BuildIteratorResult(value, true), nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006478
6479 check_return = factory->NewIfStatement(
6480 condition, return_input, factory->NewEmptyStatement(nopos), nopos);
6481 }
6482
Ben Murdochc5610432016-08-08 18:44:38 +01006483 // output = %_Call(iteratorReturn, iterator, input);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006484 Statement* call_return;
6485 {
6486 auto args = new (zone) ZoneList<Expression*>(3, zone);
6487 args->Add(factory->NewVariableProxy(var_return), zone);
6488 args->Add(factory->NewVariableProxy(iterator), zone);
Ben Murdochc5610432016-08-08 18:44:38 +01006489 args->Add(factory->NewVariableProxy(input), zone);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006490
6491 Expression* call =
6492 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6493 Expression* output_proxy = factory->NewVariableProxy(var_output);
6494 Expression* assignment = factory->NewAssignment(
6495 Token::ASSIGN, output_proxy, call, nopos);
6496 call_return = factory->NewExpressionStatement(assignment, nopos);
6497 }
6498
6499 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
6500 Statement* validate_output;
6501 {
6502 Expression* is_receiver_call;
6503 {
6504 auto args = new (zone) ZoneList<Expression*>(1, zone);
6505 args->Add(factory->NewVariableProxy(var_output), zone);
6506 is_receiver_call =
6507 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6508 }
6509
6510 Statement* throw_call;
6511 {
6512 auto args = new (zone) ZoneList<Expression*>(1, zone);
6513 args->Add(factory->NewVariableProxy(var_output), zone);
6514 Expression* call = factory->NewCallRuntime(
6515 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6516 throw_call = factory->NewExpressionStatement(call, nopos);
6517 }
6518
6519 validate_output = factory->NewIfStatement(
6520 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6521 }
6522
6523 statements->Add(get_return, zone);
6524 statements->Add(check_return, zone);
6525 statements->Add(call_return, zone);
6526 statements->Add(validate_output, zone);
6527}
6528
Ben Murdochda12d292016-06-02 14:46:10 +01006529void ParserTraits::FinalizeIteratorUse(Variable* completion,
6530 Expression* condition, Variable* iter,
6531 Block* iterator_use, Block* target) {
6532 if (!FLAG_harmony_iterator_close) return;
Ben Murdoch097c5b22016-05-18 11:27:45 +01006533
Ben Murdochda12d292016-06-02 14:46:10 +01006534 //
6535 // This function adds two statements to [target], corresponding to the
6536 // following code:
6537 //
6538 // completion = kNormalCompletion;
6539 // try {
6540 // try {
6541 // iterator_use
6542 // } catch(e) {
6543 // if (completion === kAbruptCompletion) completion = kThrowCompletion;
6544 // %ReThrow(e);
6545 // }
6546 // } finally {
6547 // if (condition) {
6548 // #BuildIteratorCloseForCompletion(iter, completion)
6549 // }
6550 // }
6551 //
6552
6553 const int nopos = RelocInfo::kNoPosition;
6554 auto factory = parser_->factory();
6555 auto avfactory = parser_->ast_value_factory();
6556 auto scope = parser_->scope_;
6557 auto zone = parser_->zone();
6558
6559 // completion = kNormalCompletion;
6560 Statement* initialize_completion;
6561 {
6562 Expression* proxy = factory->NewVariableProxy(completion);
6563 Expression* assignment = factory->NewAssignment(
6564 Token::ASSIGN, proxy,
6565 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
6566 initialize_completion = factory->NewExpressionStatement(assignment, nopos);
6567 }
6568
6569 // if (completion === kAbruptCompletion) completion = kThrowCompletion;
6570 Statement* set_completion_throw;
6571 {
6572 Expression* condition = factory->NewCompareOperation(
6573 Token::EQ_STRICT, factory->NewVariableProxy(completion),
6574 factory->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
6575
6576 Expression* proxy = factory->NewVariableProxy(completion);
6577 Expression* assignment = factory->NewAssignment(
6578 Token::ASSIGN, proxy,
6579 factory->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
6580 Statement* statement = factory->NewExpressionStatement(assignment, nopos);
6581 set_completion_throw = factory->NewIfStatement(
6582 condition, statement, factory->NewEmptyStatement(nopos), nopos);
6583 }
6584
6585 // if (condition) {
6586 // #BuildIteratorCloseForCompletion(iter, completion)
6587 // }
6588 Block* maybe_close;
6589 {
6590 Block* block = factory->NewBlock(nullptr, 2, true, nopos);
Ben Murdochc5610432016-08-08 18:44:38 +01006591 Expression* proxy = factory->NewVariableProxy(completion);
6592 parser_->BuildIteratorCloseForCompletion(block->statements(), iter, proxy);
Ben Murdochda12d292016-06-02 14:46:10 +01006593 DCHECK(block->statements()->length() == 2);
6594
6595 maybe_close = factory->NewBlock(nullptr, 1, true, nopos);
6596 maybe_close->statements()->Add(
6597 factory->NewIfStatement(condition, block,
6598 factory->NewEmptyStatement(nopos), nopos),
6599 zone);
6600 }
6601
6602 // try { #try_block }
6603 // catch(e) {
6604 // #set_completion_throw;
6605 // %ReThrow(e);
6606 // }
6607 Statement* try_catch;
6608 {
6609 Scope* catch_scope = parser_->NewScope(scope, CATCH_SCOPE);
6610 Variable* catch_variable =
6611 catch_scope->DeclareLocal(avfactory->dot_catch_string(), VAR,
6612 kCreatedInitialized, Variable::NORMAL);
Ben Murdochc5610432016-08-08 18:44:38 +01006613 catch_scope->set_is_hidden();
Ben Murdochda12d292016-06-02 14:46:10 +01006614
6615 Statement* rethrow;
6616 // We use %ReThrow rather than the ordinary throw because we want to
6617 // preserve the original exception message. This is also why we create a
6618 // TryCatchStatementForReThrow below (which does not clear the pending
6619 // message), rather than a TryCatchStatement.
6620 {
6621 auto args = new (zone) ZoneList<Expression*>(1, zone);
6622 args->Add(factory->NewVariableProxy(catch_variable), zone);
6623 rethrow = factory->NewExpressionStatement(
6624 factory->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
6625 }
6626
6627 Block* catch_block = factory->NewBlock(nullptr, 2, false, nopos);
6628 catch_block->statements()->Add(set_completion_throw, zone);
6629 catch_block->statements()->Add(rethrow, zone);
6630
6631 try_catch = factory->NewTryCatchStatementForReThrow(
6632 iterator_use, catch_scope, catch_variable, catch_block, nopos);
6633 }
6634
6635 // try { #try_catch } finally { #maybe_close }
6636 Statement* try_finally;
6637 {
6638 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6639 try_block->statements()->Add(try_catch, zone);
6640
6641 try_finally =
6642 factory->NewTryFinallyStatement(try_block, maybe_close, nopos);
6643 }
6644
6645 target->statements()->Add(initialize_completion, zone);
6646 target->statements()->Add(try_finally, zone);
6647}
Ben Murdoch097c5b22016-05-18 11:27:45 +01006648
6649void ParserTraits::BuildIteratorCloseForCompletion(
6650 ZoneList<Statement*>* statements, Variable* iterator,
Ben Murdochc5610432016-08-08 18:44:38 +01006651 Expression* completion) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01006652 //
6653 // This function adds two statements to [statements], corresponding to the
6654 // following code:
6655 //
6656 // let iteratorReturn = iterator.return;
6657 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
Ben Murdochda12d292016-06-02 14:46:10 +01006658 // if (completion === kThrowCompletion) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01006659 // if (!IS_CALLABLE(iteratorReturn)) {
6660 // throw MakeTypeError(kReturnMethodNotCallable);
6661 // }
Ben Murdochda12d292016-06-02 14:46:10 +01006662 // try { %_Call(iteratorReturn, iterator) } catch (_) { }
Ben Murdoch097c5b22016-05-18 11:27:45 +01006663 // } else {
Ben Murdochda12d292016-06-02 14:46:10 +01006664 // let output = %_Call(iteratorReturn, iterator);
6665 // if (!IS_RECEIVER(output)) {
6666 // %ThrowIterResultNotAnObject(output);
6667 // }
Ben Murdoch097c5b22016-05-18 11:27:45 +01006668 // }
Ben Murdoch097c5b22016-05-18 11:27:45 +01006669 // }
6670 //
6671
6672 const int nopos = RelocInfo::kNoPosition;
6673 auto factory = parser_->factory();
6674 auto avfactory = parser_->ast_value_factory();
6675 auto scope = parser_->scope_;
6676 auto zone = parser_->zone();
6677
Ben Murdoch097c5b22016-05-18 11:27:45 +01006678
6679 // let iteratorReturn = iterator.return;
Ben Murdochda12d292016-06-02 14:46:10 +01006680 Variable* var_return = scope->NewTemporary(avfactory->empty_string());
Ben Murdoch097c5b22016-05-18 11:27:45 +01006681 Statement* get_return;
6682 {
6683 Expression* iterator_proxy = factory->NewVariableProxy(iterator);
6684 Expression* literal =
6685 factory->NewStringLiteral(avfactory->return_string(), nopos);
6686 Expression* property =
6687 factory->NewProperty(iterator_proxy, literal, nopos);
6688 Expression* return_proxy = factory->NewVariableProxy(var_return);
6689 Expression* assignment = factory->NewAssignment(
6690 Token::ASSIGN, return_proxy, property, nopos);
6691 get_return = factory->NewExpressionStatement(assignment, nopos);
6692 }
6693
6694 // if (!IS_CALLABLE(iteratorReturn)) {
6695 // throw MakeTypeError(kReturnMethodNotCallable);
6696 // }
6697 Statement* check_return_callable;
6698 {
6699 Expression* throw_expr = NewThrowTypeError(
6700 MessageTemplate::kReturnMethodNotCallable,
6701 avfactory->empty_string(), nopos);
Ben Murdochda12d292016-06-02 14:46:10 +01006702 check_return_callable = CheckCallable(var_return, throw_expr, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006703 }
6704
Ben Murdochda12d292016-06-02 14:46:10 +01006705 // try { %_Call(iteratorReturn, iterator) } catch (_) { }
Ben Murdoch097c5b22016-05-18 11:27:45 +01006706 Statement* try_call_return;
6707 {
6708 auto args = new (zone) ZoneList<Expression*>(2, zone);
6709 args->Add(factory->NewVariableProxy(var_return), zone);
6710 args->Add(factory->NewVariableProxy(iterator), zone);
6711
6712 Expression* call =
6713 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006714
6715 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
Ben Murdochda12d292016-06-02 14:46:10 +01006716 try_block->statements()->Add(factory->NewExpressionStatement(call, nopos),
6717 zone);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006718
6719 Block* catch_block = factory->NewBlock(nullptr, 0, false, nopos);
6720
6721 Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
6722 Variable* catch_variable = catch_scope->DeclareLocal(
6723 avfactory->dot_catch_string(), VAR, kCreatedInitialized,
6724 Variable::NORMAL);
Ben Murdochc5610432016-08-08 18:44:38 +01006725 catch_scope->set_is_hidden();
Ben Murdoch097c5b22016-05-18 11:27:45 +01006726
6727 try_call_return = factory->NewTryCatchStatement(
6728 try_block, catch_scope, catch_variable, catch_block, nopos);
6729 }
6730
Ben Murdochda12d292016-06-02 14:46:10 +01006731 // let output = %_Call(iteratorReturn, iterator);
6732 // if (!IS_RECEIVER(output)) {
6733 // %ThrowIteratorResultNotAnObject(output);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006734 // }
Ben Murdochda12d292016-06-02 14:46:10 +01006735 Block* validate_return;
Ben Murdoch097c5b22016-05-18 11:27:45 +01006736 {
Ben Murdochda12d292016-06-02 14:46:10 +01006737 Variable* var_output = scope->NewTemporary(avfactory->empty_string());
6738 Statement* call_return;
6739 {
6740 auto args = new (zone) ZoneList<Expression*>(2, zone);
6741 args->Add(factory->NewVariableProxy(var_return), zone);
6742 args->Add(factory->NewVariableProxy(iterator), zone);
6743 Expression* call =
6744 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006745
Ben Murdochda12d292016-06-02 14:46:10 +01006746 Expression* output_proxy = factory->NewVariableProxy(var_output);
6747 Expression* assignment =
6748 factory->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
6749 call_return = factory->NewExpressionStatement(assignment, nopos);
6750 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01006751
Ben Murdoch097c5b22016-05-18 11:27:45 +01006752 Expression* is_receiver_call;
6753 {
6754 auto args = new (zone) ZoneList<Expression*>(1, zone);
6755 args->Add(factory->NewVariableProxy(var_output), zone);
6756 is_receiver_call =
6757 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6758 }
6759
6760 Statement* throw_call;
6761 {
6762 auto args = new (zone) ZoneList<Expression*>(1, zone);
6763 args->Add(factory->NewVariableProxy(var_output), zone);
6764 Expression* call = factory->NewCallRuntime(
6765 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6766 throw_call = factory->NewExpressionStatement(call, nopos);
6767 }
6768
Ben Murdochda12d292016-06-02 14:46:10 +01006769 Statement* check_return = factory->NewIfStatement(
Ben Murdoch097c5b22016-05-18 11:27:45 +01006770 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
Ben Murdochda12d292016-06-02 14:46:10 +01006771
6772 validate_return = factory->NewBlock(nullptr, 2, false, nopos);
6773 validate_return->statements()->Add(call_return, zone);
6774 validate_return->statements()->Add(check_return, zone);
6775 }
6776
6777 // if (completion === kThrowCompletion) {
6778 // #check_return_callable;
6779 // #try_call_return;
6780 // } else {
6781 // #validate_return;
6782 // }
6783 Statement* call_return_carefully;
6784 {
6785 Expression* condition = factory->NewCompareOperation(
Ben Murdochc5610432016-08-08 18:44:38 +01006786 Token::EQ_STRICT, completion,
Ben Murdochda12d292016-06-02 14:46:10 +01006787 factory->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
6788
6789 Block* then_block = factory->NewBlock(nullptr, 2, false, nopos);
6790 then_block->statements()->Add(check_return_callable, zone);
6791 then_block->statements()->Add(try_call_return, zone);
6792
6793 call_return_carefully =
6794 factory->NewIfStatement(condition, then_block, validate_return, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006795 }
6796
6797 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
6798 Statement* maybe_call_return;
6799 {
6800 Expression* condition = factory->NewCompareOperation(
6801 Token::EQ, factory->NewVariableProxy(var_return),
6802 factory->NewNullLiteral(nopos), nopos);
6803
Ben Murdochda12d292016-06-02 14:46:10 +01006804 maybe_call_return =
6805 factory->NewIfStatement(condition, factory->NewEmptyStatement(nopos),
6806 call_return_carefully, nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006807 }
6808
6809
6810 statements->Add(get_return, zone);
6811 statements->Add(maybe_call_return, zone);
6812}
6813
6814
6815Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) {
6816 if (!FLAG_harmony_iterator_close) return loop;
6817
6818 //
6819 // This function replaces the loop with the following wrapping:
6820 //
Ben Murdochda12d292016-06-02 14:46:10 +01006821 // let each;
6822 // let completion = kNormalCompletion;
Ben Murdoch097c5b22016-05-18 11:27:45 +01006823 // try {
Ben Murdochda12d292016-06-02 14:46:10 +01006824 // try {
6825 // #loop;
6826 // } catch(e) {
6827 // if (completion === kAbruptCompletion) completion = kThrowCompletion;
6828 // %ReThrow(e);
6829 // }
Ben Murdoch097c5b22016-05-18 11:27:45 +01006830 // } finally {
Ben Murdochda12d292016-06-02 14:46:10 +01006831 // if (!(completion === kNormalCompletion || IS_UNDEFINED(#iterator))) {
6832 // #BuildIteratorCloseForCompletion(#iterator, completion)
Ben Murdoch097c5b22016-05-18 11:27:45 +01006833 // }
6834 // }
6835 //
6836 // where the loop's body is wrapped as follows:
6837 //
6838 // {
Ben Murdoch097c5b22016-05-18 11:27:45 +01006839 // #loop-body
Ben Murdochda12d292016-06-02 14:46:10 +01006840 // {{completion = kNormalCompletion;}}
Ben Murdoch097c5b22016-05-18 11:27:45 +01006841 // }
Ben Murdochda12d292016-06-02 14:46:10 +01006842 //
6843 // and the loop's assign_each is wrapped as follows
6844 //
6845 // do {
6846 // {{completion = kAbruptCompletion;}}
6847 // #assign-each
6848 // }
6849 //
Ben Murdoch097c5b22016-05-18 11:27:45 +01006850
6851 const int nopos = RelocInfo::kNoPosition;
6852 auto factory = parser_->factory();
6853 auto avfactory = parser_->ast_value_factory();
6854 auto scope = parser_->scope_;
6855 auto zone = parser_->zone();
6856
Ben Murdoch097c5b22016-05-18 11:27:45 +01006857 Variable* var_completion = scope->NewTemporary(avfactory->empty_string());
Ben Murdochda12d292016-06-02 14:46:10 +01006858
6859 // let each;
6860 Variable* var_each = scope->NewTemporary(avfactory->empty_string());
6861 Statement* initialize_each;
Ben Murdoch097c5b22016-05-18 11:27:45 +01006862 {
Ben Murdochda12d292016-06-02 14:46:10 +01006863 Expression* proxy = factory->NewVariableProxy(var_each);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006864 Expression* assignment = factory->NewAssignment(
6865 Token::ASSIGN, proxy,
Ben Murdochda12d292016-06-02 14:46:10 +01006866 factory->NewUndefinedLiteral(nopos), nopos);
6867 initialize_each =
Ben Murdoch097c5b22016-05-18 11:27:45 +01006868 factory->NewExpressionStatement(assignment, nopos);
6869 }
6870
Ben Murdochda12d292016-06-02 14:46:10 +01006871 // !(completion === kNormalCompletion || IS_UNDEFINED(#iterator))
6872 Expression* closing_condition;
Ben Murdoch097c5b22016-05-18 11:27:45 +01006873 {
Ben Murdochda12d292016-06-02 14:46:10 +01006874 Expression* lhs = factory->NewCompareOperation(
Ben Murdoch097c5b22016-05-18 11:27:45 +01006875 Token::EQ_STRICT, factory->NewVariableProxy(var_completion),
Ben Murdochda12d292016-06-02 14:46:10 +01006876 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
6877 Expression* rhs = factory->NewCompareOperation(
Ben Murdoch097c5b22016-05-18 11:27:45 +01006878 Token::EQ_STRICT, factory->NewVariableProxy(loop->iterator()),
6879 factory->NewUndefinedLiteral(nopos), nopos);
Ben Murdochda12d292016-06-02 14:46:10 +01006880 closing_condition = factory->NewUnaryOperation(
6881 Token::NOT, factory->NewBinaryOperation(Token::OR, lhs, rhs, nopos),
6882 nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006883 }
6884
Ben Murdochda12d292016-06-02 14:46:10 +01006885 // {{completion = kNormalCompletion;}}
Ben Murdoch097c5b22016-05-18 11:27:45 +01006886 Statement* set_completion_normal;
6887 {
6888 Expression* proxy = factory->NewVariableProxy(var_completion);
6889 Expression* assignment = factory->NewAssignment(
Ben Murdochda12d292016-06-02 14:46:10 +01006890 Token::ASSIGN, proxy,
6891 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
Ben Murdoch097c5b22016-05-18 11:27:45 +01006892
6893 Block* block = factory->NewBlock(nullptr, 1, true, nopos);
6894 block->statements()->Add(
6895 factory->NewExpressionStatement(assignment, nopos), zone);
6896 set_completion_normal = block;
6897 }
6898
Ben Murdochda12d292016-06-02 14:46:10 +01006899 // {{completion = kAbruptCompletion;}}
6900 Statement* set_completion_abrupt;
6901 {
6902 Expression* proxy = factory->NewVariableProxy(var_completion);
6903 Expression* assignment = factory->NewAssignment(
6904 Token::ASSIGN, proxy,
6905 factory->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
6906
6907 Block* block = factory->NewBlock(nullptr, 1, true, nopos);
6908 block->statements()->Add(factory->NewExpressionStatement(assignment, nopos),
6909 zone);
6910 set_completion_abrupt = block;
6911 }
6912
6913 // { #loop-body; #set_completion_normal }
Ben Murdoch097c5b22016-05-18 11:27:45 +01006914 Block* new_body = factory->NewBlock(nullptr, 2, false, nopos);
Ben Murdochda12d292016-06-02 14:46:10 +01006915 {
6916 new_body->statements()->Add(loop->body(), zone);
6917 new_body->statements()->Add(set_completion_normal, zone);
6918 }
6919
6920 // { #set_completion_abrupt; #assign-each }
6921 Block* new_assign_each = factory->NewBlock(nullptr, 2, false, nopos);
6922 {
6923 new_assign_each->statements()->Add(set_completion_abrupt, zone);
6924 new_assign_each->statements()->Add(
6925 factory->NewExpressionStatement(loop->assign_each(), nopos), zone);
6926 }
6927
6928 // Now put things together.
Ben Murdoch097c5b22016-05-18 11:27:45 +01006929
6930 loop->set_body(new_body);
Ben Murdochda12d292016-06-02 14:46:10 +01006931 loop->set_assign_each(
6932 factory->NewDoExpression(new_assign_each, var_each, nopos));
6933
6934 Statement* final_loop;
6935 {
6936 Block* target = factory->NewBlock(nullptr, 3, false, nopos);
6937 target->statements()->Add(initialize_each, zone);
6938
6939 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6940 try_block->statements()->Add(loop, zone);
6941
6942 FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(),
6943 try_block, target);
6944 final_loop = target;
6945 }
6946
Ben Murdoch097c5b22016-05-18 11:27:45 +01006947 return final_loop;
6948}
6949
6950
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006951} // namespace internal
6952} // namespace v8