1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/v8.h"
6
7 #include "src/api.h"
8 #include "src/ast.h"
9 #include "src/bootstrapper.h"
10 #include "src/char-predicates-inl.h"
11 #include "src/codegen.h"
12 #include "src/compiler.h"
13 #include "src/messages.h"
14 #include "src/parser.h"
15 #include "src/platform.h"
16 #include "src/preparser.h"
17 #include "src/runtime.h"
18 #include "src/scanner-character-streams.h"
19 #include "src/scopeinfo.h"
20 #include "src/string-stream.h"
21
22 namespace v8 {
23 namespace internal {
24
RegExpBuilder(Zone * zone)25 RegExpBuilder::RegExpBuilder(Zone* zone)
26 : zone_(zone),
27 pending_empty_(false),
28 characters_(NULL),
29 terms_(),
30 alternatives_()
31 #ifdef DEBUG
32 , last_added_(ADD_NONE)
33 #endif
34 {}
35
36
FlushCharacters()37 void RegExpBuilder::FlushCharacters() {
38 pending_empty_ = false;
39 if (characters_ != NULL) {
40 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
41 characters_ = NULL;
42 text_.Add(atom, zone());
43 LAST(ADD_ATOM);
44 }
45 }
46
47
FlushText()48 void RegExpBuilder::FlushText() {
49 FlushCharacters();
50 int num_text = text_.length();
51 if (num_text == 0) {
52 return;
53 } else if (num_text == 1) {
54 terms_.Add(text_.last(), zone());
55 } else {
56 RegExpText* text = new(zone()) RegExpText(zone());
57 for (int i = 0; i < num_text; i++)
58 text_.Get(i)->AppendToText(text, zone());
59 terms_.Add(text, zone());
60 }
61 text_.Clear();
62 }
63
64
AddCharacter(uc16 c)65 void RegExpBuilder::AddCharacter(uc16 c) {
66 pending_empty_ = false;
67 if (characters_ == NULL) {
68 characters_ = new(zone()) ZoneList<uc16>(4, zone());
69 }
70 characters_->Add(c, zone());
71 LAST(ADD_CHAR);
72 }
73
74
AddEmpty()75 void RegExpBuilder::AddEmpty() {
76 pending_empty_ = true;
77 }
78
79
AddAtom(RegExpTree * term)80 void RegExpBuilder::AddAtom(RegExpTree* term) {
81 if (term->IsEmpty()) {
82 AddEmpty();
83 return;
84 }
85 if (term->IsTextElement()) {
86 FlushCharacters();
87 text_.Add(term, zone());
88 } else {
89 FlushText();
90 terms_.Add(term, zone());
91 }
92 LAST(ADD_ATOM);
93 }
94
95
AddAssertion(RegExpTree * assert)96 void RegExpBuilder::AddAssertion(RegExpTree* assert) {
97 FlushText();
98 terms_.Add(assert, zone());
99 LAST(ADD_ASSERT);
100 }
101
102
NewAlternative()103 void RegExpBuilder::NewAlternative() {
104 FlushTerms();
105 }
106
107
FlushTerms()108 void RegExpBuilder::FlushTerms() {
109 FlushText();
110 int num_terms = terms_.length();
111 RegExpTree* alternative;
112 if (num_terms == 0) {
113 alternative = RegExpEmpty::GetInstance();
114 } else if (num_terms == 1) {
115 alternative = terms_.last();
116 } else {
117 alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
118 }
119 alternatives_.Add(alternative, zone());
120 terms_.Clear();
121 LAST(ADD_NONE);
122 }
123
124
ToRegExp()125 RegExpTree* RegExpBuilder::ToRegExp() {
126 FlushTerms();
127 int num_alternatives = alternatives_.length();
128 if (num_alternatives == 0) {
129 return RegExpEmpty::GetInstance();
130 }
131 if (num_alternatives == 1) {
132 return alternatives_.last();
133 }
134 return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
135 }
136
137
AddQuantifierToAtom(int min,int max,RegExpQuantifier::QuantifierType quantifier_type)138 void RegExpBuilder::AddQuantifierToAtom(
139 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
140 if (pending_empty_) {
141 pending_empty_ = false;
142 return;
143 }
144 RegExpTree* atom;
145 if (characters_ != NULL) {
146 ASSERT(last_added_ == ADD_CHAR);
147 // Last atom was character.
148 Vector<const uc16> char_vector = characters_->ToConstVector();
149 int num_chars = char_vector.length();
150 if (num_chars > 1) {
151 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
152 text_.Add(new(zone()) RegExpAtom(prefix), zone());
153 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
154 }
155 characters_ = NULL;
156 atom = new(zone()) RegExpAtom(char_vector);
157 FlushText();
158 } else if (text_.length() > 0) {
159 ASSERT(last_added_ == ADD_ATOM);
160 atom = text_.RemoveLast();
161 FlushText();
162 } else if (terms_.length() > 0) {
163 ASSERT(last_added_ == ADD_ATOM);
164 atom = terms_.RemoveLast();
165 if (atom->max_match() == 0) {
166 // Guaranteed to only match an empty string.
167 LAST(ADD_TERM);
168 if (min == 0) {
169 return;
170 }
171 terms_.Add(atom, zone());
172 return;
173 }
174 } else {
175 // Only call immediately after adding an atom or character!
176 UNREACHABLE();
177 return;
178 }
179 terms_.Add(
180 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
181 LAST(ADD_TERM);
182 }
183
184
New(const char * data,int length)185 ScriptData* ScriptData::New(const char* data, int length) {
186 // The length is obviously invalid.
187 if (length % sizeof(unsigned) != 0) {
188 return NULL;
189 }
190
191 int deserialized_data_length = length / sizeof(unsigned);
192 unsigned* deserialized_data;
193 bool owns_store = reinterpret_cast<intptr_t>(data) % sizeof(unsigned) != 0;
194 if (owns_store) {
195 // Copy the data to align it.
196 deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
197 i::CopyBytes(reinterpret_cast<char*>(deserialized_data),
198 data, static_cast<size_t>(length));
199 } else {
200 // If aligned, don't create a copy of the data.
201 deserialized_data = reinterpret_cast<unsigned*>(const_cast<char*>(data));
202 }
203 return new ScriptData(
204 Vector<unsigned>(deserialized_data, deserialized_data_length),
205 owns_store);
206 }
207
208
GetFunctionEntry(int start)209 FunctionEntry ScriptData::GetFunctionEntry(int start) {
210 // The current pre-data entry must be a FunctionEntry with the given
211 // start position.
212 if ((function_index_ + FunctionEntry::kSize <= store_.length())
213 && (static_cast<int>(store_[function_index_]) == start)) {
214 int index = function_index_;
215 function_index_ += FunctionEntry::kSize;
216 return FunctionEntry(store_.SubVector(index,
217 index + FunctionEntry::kSize));
218 }
219 return FunctionEntry();
220 }
221
222
GetSymbolIdentifier()223 int ScriptData::GetSymbolIdentifier() {
224 return ReadNumber(&symbol_data_);
225 }
226
227
SanityCheck()228 bool ScriptData::SanityCheck() {
229 // Check that the header data is valid and doesn't specify
230 // point to positions outside the store.
231 if (store_.length() < PreparseDataConstants::kHeaderSize) return false;
232 if (magic() != PreparseDataConstants::kMagicNumber) return false;
233 if (version() != PreparseDataConstants::kCurrentVersion) return false;
234 if (has_error()) {
235 // Extra sane sanity check for error message encoding.
236 if (store_.length() <= PreparseDataConstants::kHeaderSize
237 + PreparseDataConstants::kMessageTextPos) {
238 return false;
239 }
240 if (Read(PreparseDataConstants::kMessageStartPos) >
241 Read(PreparseDataConstants::kMessageEndPos)) {
242 return false;
243 }
244 unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
245 int pos = PreparseDataConstants::kMessageTextPos;
246 for (unsigned int i = 0; i <= arg_count; i++) {
247 if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) {
248 return false;
249 }
250 int length = static_cast<int>(Read(pos));
251 if (length < 0) return false;
252 pos += 1 + length;
253 }
254 if (store_.length() < PreparseDataConstants::kHeaderSize + pos) {
255 return false;
256 }
257 return true;
258 }
259 // Check that the space allocated for function entries is sane.
260 int functions_size =
261 static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]);
262 if (functions_size < 0) return false;
263 if (functions_size % FunctionEntry::kSize != 0) return false;
264 // Check that the total size has room for header and function entries.
265 int minimum_size =
266 PreparseDataConstants::kHeaderSize + functions_size;
267 if (store_.length() < minimum_size) return false;
268 return true;
269 }
270
271
272
ReadString(unsigned * start,int * chars)273 const char* ScriptData::ReadString(unsigned* start, int* chars) {
274 int length = start[0];
275 char* result = NewArray<char>(length + 1);
276 for (int i = 0; i < length; i++) {
277 result[i] = start[i + 1];
278 }
279 result[length] = '\0';
280 if (chars != NULL) *chars = length;
281 return result;
282 }
283
284
MessageLocation() const285 Scanner::Location ScriptData::MessageLocation() const {
286 int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
287 int end_pos = Read(PreparseDataConstants::kMessageEndPos);
288 return Scanner::Location(beg_pos, end_pos);
289 }
290
291
IsReferenceError() const292 bool ScriptData::IsReferenceError() const {
293 return Read(PreparseDataConstants::kIsReferenceErrorPos);
294 }
295
296
BuildMessage() const297 const char* ScriptData::BuildMessage() const {
298 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
299 return ReadString(start, NULL);
300 }
301
302
BuildArg() const303 const char* ScriptData::BuildArg() const {
304 int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
305 ASSERT(arg_count == 0 || arg_count == 1);
306 if (arg_count == 0) {
307 return NULL;
308 }
309 // Position after text found by skipping past length field and
310 // length field content words.
311 int pos = PreparseDataConstants::kMessageTextPos + 1
312 + Read(PreparseDataConstants::kMessageTextPos);
313 int count = 0;
314 return ReadString(ReadAddress(pos), &count);
315 }
316
317
Read(int position) const318 unsigned ScriptData::Read(int position) const {
319 return store_[PreparseDataConstants::kHeaderSize + position];
320 }
321
322
ReadAddress(int position) const323 unsigned* ScriptData::ReadAddress(int position) const {
324 return &store_[PreparseDataConstants::kHeaderSize + position];
325 }
326
327
NewScope(Scope * parent,ScopeType scope_type)328 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
329 Scope* result = new(zone()) Scope(parent, scope_type, zone());
330 result->Initialize();
331 return result;
332 }
333
334
335 // ----------------------------------------------------------------------------
336 // Target is a support class to facilitate manipulation of the
337 // Parser's target_stack_ (the stack of potential 'break' and
338 // 'continue' statement targets). Upon construction, a new target is
339 // added; it is removed upon destruction.
340
341 class Target BASE_EMBEDDED {
342 public:
Target(Target ** variable,AstNode * node)343 Target(Target** variable, AstNode* node)
344 : variable_(variable), node_(node), previous_(*variable) {
345 *variable = this;
346 }
347
~Target()348 ~Target() {
349 *variable_ = previous_;
350 }
351
previous()352 Target* previous() { return previous_; }
node()353 AstNode* node() { return node_; }
354
355 private:
356 Target** variable_;
357 AstNode* node_;
358 Target* previous_;
359 };
360
361
362 class TargetScope BASE_EMBEDDED {
363 public:
TargetScope(Target ** variable)364 explicit TargetScope(Target** variable)
365 : variable_(variable), previous_(*variable) {
366 *variable = NULL;
367 }
368
~TargetScope()369 ~TargetScope() {
370 *variable_ = previous_;
371 }
372
373 private:
374 Target** variable_;
375 Target* previous_;
376 };
377
378
379 // ----------------------------------------------------------------------------
380 // The CHECK_OK macro is a convenient macro to enforce error
381 // handling for functions that may fail (by returning !*ok).
382 //
383 // CAUTION: This macro appends extra statements after a call,
384 // thus it must never be used where only a single statement
385 // is correct (e.g. an if statement branch w/o braces)!
386
387 #define CHECK_OK ok); \
388 if (!*ok) return NULL; \
389 ((void)0
390 #define DUMMY ) // to make indentation work
391 #undef DUMMY
392
393 #define CHECK_FAILED /**/); \
394 if (failed_) return NULL; \
395 ((void)0
396 #define DUMMY ) // to make indentation work
397 #undef DUMMY
398
399 // ----------------------------------------------------------------------------
400 // Implementation of Parser
401
IsEvalOrArguments(Handle<String> identifier) const402 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const {
403 Factory* factory = parser_->isolate()->factory();
404 return identifier.is_identical_to(factory->eval_string())
405 || identifier.is_identical_to(factory->arguments_string());
406 }
407
408
IsThisProperty(Expression * expression)409 bool ParserTraits::IsThisProperty(Expression* expression) {
410 ASSERT(expression != NULL);
411 Property* property = expression->AsProperty();
412 return property != NULL &&
413 property->obj()->AsVariableProxy() != NULL &&
414 property->obj()->AsVariableProxy()->is_this();
415 }
416
417
IsIdentifier(Expression * expression)418 bool ParserTraits::IsIdentifier(Expression* expression) {
419 VariableProxy* operand = expression->AsVariableProxy();
420 return operand != NULL && !operand->is_this();
421 }
422
423
PushPropertyName(FuncNameInferrer * fni,Expression * expression)424 void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
425 Expression* expression) {
426 if (expression->IsPropertyName()) {
427 fni->PushLiteralName(expression->AsLiteral()->AsPropertyName());
428 } else {
429 fni->PushLiteralName(
430 parser_->isolate()->factory()->anonymous_function_string());
431 }
432 }
433
434
CheckAssigningFunctionLiteralToProperty(Expression * left,Expression * right)435 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
436 Expression* right) {
437 ASSERT(left != NULL);
438 if (left->AsProperty() != NULL &&
439 right->AsFunctionLiteral() != NULL) {
440 right->AsFunctionLiteral()->set_pretenure();
441 }
442 }
443
444
CheckPossibleEvalCall(Expression * expression,Scope * scope)445 void ParserTraits::CheckPossibleEvalCall(Expression* expression,
446 Scope* scope) {
447 VariableProxy* callee = expression->AsVariableProxy();
448 if (callee != NULL &&
449 callee->IsVariable(parser_->isolate()->factory()->eval_string())) {
450 scope->DeclarationScope()->RecordEvalCall();
451 }
452 }
453
454
MarkExpressionAsLValue(Expression * expression)455 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) {
456 VariableProxy* proxy = expression != NULL
457 ? expression->AsVariableProxy()
458 : NULL;
459 if (proxy != NULL) proxy->MarkAsLValue();
460 return expression;
461 }
462
463
ShortcutNumericLiteralBinaryExpression(Expression ** x,Expression * y,Token::Value op,int pos,AstNodeFactory<AstConstructionVisitor> * factory)464 bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
465 Expression** x, Expression* y, Token::Value op, int pos,
466 AstNodeFactory<AstConstructionVisitor>* factory) {
467 if ((*x)->AsLiteral() && (*x)->AsLiteral()->value()->IsNumber() &&
468 y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) {
469 double x_val = (*x)->AsLiteral()->value()->Number();
470 double y_val = y->AsLiteral()->value()->Number();
471 switch (op) {
472 case Token::ADD:
473 *x = factory->NewNumberLiteral(x_val + y_val, pos);
474 return true;
475 case Token::SUB:
476 *x = factory->NewNumberLiteral(x_val - y_val, pos);
477 return true;
478 case Token::MUL:
479 *x = factory->NewNumberLiteral(x_val * y_val, pos);
480 return true;
481 case Token::DIV:
482 *x = factory->NewNumberLiteral(x_val / y_val, pos);
483 return true;
484 case Token::BIT_OR: {
485 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
486 *x = factory->NewNumberLiteral(value, pos);
487 return true;
488 }
489 case Token::BIT_AND: {
490 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
491 *x = factory->NewNumberLiteral(value, pos);
492 return true;
493 }
494 case Token::BIT_XOR: {
495 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
496 *x = factory->NewNumberLiteral(value, pos);
497 return true;
498 }
499 case Token::SHL: {
500 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
501 *x = factory->NewNumberLiteral(value, pos);
502 return true;
503 }
504 case Token::SHR: {
505 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
506 uint32_t value = DoubleToUint32(x_val) >> shift;
507 *x = factory->NewNumberLiteral(value, pos);
508 return true;
509 }
510 case Token::SAR: {
511 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
512 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
513 *x = factory->NewNumberLiteral(value, pos);
514 return true;
515 }
516 default:
517 break;
518 }
519 }
520 return false;
521 }
522
523
BuildUnaryExpression(Expression * expression,Token::Value op,int pos,AstNodeFactory<AstConstructionVisitor> * factory)524 Expression* ParserTraits::BuildUnaryExpression(
525 Expression* expression, Token::Value op, int pos,
526 AstNodeFactory<AstConstructionVisitor>* factory) {
527 ASSERT(expression != NULL);
528 if (expression->IsLiteral()) {
529 Handle<Object> literal = expression->AsLiteral()->value();
530 if (op == Token::NOT) {
531 // Convert the literal to a boolean condition and negate it.
532 bool condition = literal->BooleanValue();
533 Handle<Object> result =
534 parser_->isolate()->factory()->ToBoolean(!condition);
535 return factory->NewLiteral(result, pos);
536 } else if (literal->IsNumber()) {
537 // Compute some expressions involving only number literals.
538 double value = literal->Number();
539 switch (op) {
540 case Token::ADD:
541 return expression;
542 case Token::SUB:
543 return factory->NewNumberLiteral(-value, pos);
544 case Token::BIT_NOT:
545 return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
546 default:
547 break;
548 }
549 }
550 }
551 // Desugar '+foo' => 'foo*1'
552 if (op == Token::ADD) {
553 return factory->NewBinaryOperation(
554 Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos);
555 }
556 // The same idea for '-foo' => 'foo*(-1)'.
557 if (op == Token::SUB) {
558 return factory->NewBinaryOperation(
559 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
560 }
561 // ...and one more time for '~foo' => 'foo^(~0)'.
562 if (op == Token::BIT_NOT) {
563 return factory->NewBinaryOperation(
564 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
565 }
566 return factory->NewUnaryOperation(op, expression, pos);
567 }
568
569
NewThrowReferenceError(const char * message,int pos)570 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) {
571 return NewThrowError(
572 parser_->isolate()->factory()->MakeReferenceError_string(),
573 message, HandleVector<Object>(NULL, 0), pos);
574 }
575
576
NewThrowSyntaxError(const char * message,Handle<Object> arg,int pos)577 Expression* ParserTraits::NewThrowSyntaxError(
578 const char* message, Handle<Object> arg, int pos) {
579 int argc = arg.is_null() ? 0 : 1;
580 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc);
581 return NewThrowError(
582 parser_->isolate()->factory()->MakeSyntaxError_string(),
583 message, arguments, pos);
584 }
585
586
NewThrowTypeError(const char * message,Handle<Object> arg,int pos)587 Expression* ParserTraits::NewThrowTypeError(
588 const char* message, Handle<Object> arg, int pos) {
589 int argc = arg.is_null() ? 0 : 1;
590 Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc);
591 return NewThrowError(
592 parser_->isolate()->factory()->MakeTypeError_string(),
593 message, arguments, pos);
594 }
595
596
NewThrowError(Handle<String> constructor,const char * message,Vector<Handle<Object>> arguments,int pos)597 Expression* ParserTraits::NewThrowError(
598 Handle<String> constructor, const char* message,
599 Vector<Handle<Object> > arguments, int pos) {
600 Zone* zone = parser_->zone();
601 Factory* factory = parser_->isolate()->factory();
602 int argc = arguments.length();
603 Handle<FixedArray> elements = factory->NewFixedArray(argc, TENURED);
604 for (int i = 0; i < argc; i++) {
605 Handle<Object> element = arguments[i];
606 if (!element.is_null()) {
607 elements->set(i, *element);
608 }
609 }
610 Handle<JSArray> array =
611 factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED);
612
613 ZoneList<Expression*>* args = new(zone) ZoneList<Expression*>(2, zone);
614 Handle<String> type = factory->InternalizeUtf8String(message);
615 args->Add(parser_->factory()->NewLiteral(type, pos), zone);
616 args->Add(parser_->factory()->NewLiteral(array, pos), zone);
617 CallRuntime* call_constructor =
618 parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
619 return parser_->factory()->NewThrow(call_constructor, pos);
620 }
621
622
ReportMessageAt(Scanner::Location source_location,const char * message,const char * arg,bool is_reference_error)623 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
624 const char* message,
625 const char* arg,
626 bool is_reference_error) {
627 if (parser_->stack_overflow()) {
628 // Suppress the error message (syntax error or such) in the presence of a
629 // stack overflow. The isolate allows only one pending exception at at time
630 // and we want to report the stack overflow later.
631 return;
632 }
633 parser_->has_pending_error_ = true;
634 parser_->pending_error_location_ = source_location;
635 parser_->pending_error_message_ = message;
636 parser_->pending_error_char_arg_ = arg;
637 parser_->pending_error_arg_ = Handle<String>();
638 parser_->pending_error_is_reference_error_ = is_reference_error;
639 }
640
641
ReportMessage(const char * message,MaybeHandle<String> arg,bool is_reference_error)642 void ParserTraits::ReportMessage(const char* message,
643 MaybeHandle<String> arg,
644 bool is_reference_error) {
645 Scanner::Location source_location = parser_->scanner()->location();
646 ReportMessageAt(source_location, message, arg, is_reference_error);
647 }
648
649
ReportMessageAt(Scanner::Location source_location,const char * message,MaybeHandle<String> arg,bool is_reference_error)650 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
651 const char* message,
652 MaybeHandle<String> arg,
653 bool is_reference_error) {
654 if (parser_->stack_overflow()) {
655 // Suppress the error message (syntax error or such) in the presence of a
656 // stack overflow. The isolate allows only one pending exception at at time
657 // and we want to report the stack overflow later.
658 return;
659 }
660 parser_->has_pending_error_ = true;
661 parser_->pending_error_location_ = source_location;
662 parser_->pending_error_message_ = message;
663 parser_->pending_error_char_arg_ = NULL;
664 parser_->pending_error_arg_ = arg;
665 parser_->pending_error_is_reference_error_ = is_reference_error;
666 }
667
668
GetSymbol(Scanner * scanner)669 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) {
670 Handle<String> result =
671 parser_->scanner()->AllocateInternalizedString(parser_->isolate());
672 ASSERT(!result.is_null());
673 return result;
674 }
675
676
NextLiteralString(Scanner * scanner,PretenureFlag tenured)677 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner,
678 PretenureFlag tenured) {
679 return scanner->AllocateNextLiteralString(parser_->isolate(), tenured);
680 }
681
682
ThisExpression(Scope * scope,AstNodeFactory<AstConstructionVisitor> * factory)683 Expression* ParserTraits::ThisExpression(
684 Scope* scope,
685 AstNodeFactory<AstConstructionVisitor>* factory) {
686 return factory->NewVariableProxy(scope->receiver());
687 }
688
689
ExpressionFromLiteral(Token::Value token,int pos,Scanner * scanner,AstNodeFactory<AstConstructionVisitor> * factory)690 Literal* ParserTraits::ExpressionFromLiteral(
691 Token::Value token, int pos,
692 Scanner* scanner,
693 AstNodeFactory<AstConstructionVisitor>* factory) {
694 Factory* isolate_factory = parser_->isolate()->factory();
695 switch (token) {
696 case Token::NULL_LITERAL:
697 return factory->NewLiteral(isolate_factory->null_value(), pos);
698 case Token::TRUE_LITERAL:
699 return factory->NewLiteral(isolate_factory->true_value(), pos);
700 case Token::FALSE_LITERAL:
701 return factory->NewLiteral(isolate_factory->false_value(), pos);
702 case Token::NUMBER: {
703 double value = scanner->DoubleValue();
704 return factory->NewNumberLiteral(value, pos);
705 }
706 default:
707 ASSERT(false);
708 }
709 return NULL;
710 }
711
712
ExpressionFromIdentifier(Handle<String> name,int pos,Scope * scope,AstNodeFactory<AstConstructionVisitor> * factory)713 Expression* ParserTraits::ExpressionFromIdentifier(
714 Handle<String> name, int pos, Scope* scope,
715 AstNodeFactory<AstConstructionVisitor>* factory) {
716 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
717 // The name may refer to a module instance object, so its type is unknown.
718 #ifdef DEBUG
719 if (FLAG_print_interface_details)
720 PrintF("# Variable %s ", name->ToAsciiArray());
721 #endif
722 Interface* interface = Interface::NewUnknown(parser_->zone());
723 return scope->NewUnresolved(factory, name, interface, pos);
724 }
725
726
ExpressionFromString(int pos,Scanner * scanner,AstNodeFactory<AstConstructionVisitor> * factory)727 Expression* ParserTraits::ExpressionFromString(
728 int pos, Scanner* scanner,
729 AstNodeFactory<AstConstructionVisitor>* factory) {
730 Handle<String> symbol = GetSymbol(scanner);
731 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
732 return factory->NewLiteral(symbol, pos);
733 }
734
735
GetLiteralTheHole(int position,AstNodeFactory<AstConstructionVisitor> * factory)736 Literal* ParserTraits::GetLiteralTheHole(
737 int position, AstNodeFactory<AstConstructionVisitor>* factory) {
738 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(),
739 RelocInfo::kNoPosition);
740 }
741
742
ParseV8Intrinsic(bool * ok)743 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
744 return parser_->ParseV8Intrinsic(ok);
745 }
746
747
ParseFunctionLiteral(Handle<String> name,Scanner::Location function_name_location,bool name_is_strict_reserved,bool is_generator,int function_token_position,FunctionLiteral::FunctionType type,FunctionLiteral::ArityRestriction arity_restriction,bool * ok)748 FunctionLiteral* ParserTraits::ParseFunctionLiteral(
749 Handle<String> name,
750 Scanner::Location function_name_location,
751 bool name_is_strict_reserved,
752 bool is_generator,
753 int function_token_position,
754 FunctionLiteral::FunctionType type,
755 FunctionLiteral::ArityRestriction arity_restriction,
756 bool* ok) {
757 return parser_->ParseFunctionLiteral(name, function_name_location,
758 name_is_strict_reserved, is_generator,
759 function_token_position, type,
760 arity_restriction, ok);
761 }
762
763
Parser(CompilationInfo * info)764 Parser::Parser(CompilationInfo* info)
765 : ParserBase<ParserTraits>(&scanner_,
766 info->isolate()->stack_guard()->real_climit(),
767 info->extension(),
768 NULL,
769 info->zone(),
770 this),
771 isolate_(info->isolate()),
772 script_(info->script()),
773 scanner_(isolate_->unicode_cache()),
774 reusable_preparser_(NULL),
775 original_scope_(NULL),
776 target_stack_(NULL),
777 cached_data_(NULL),
778 cached_data_mode_(NO_CACHED_DATA),
779 info_(info),
780 has_pending_error_(false),
781 pending_error_message_(NULL),
782 pending_error_char_arg_(NULL) {
783 ASSERT(!script_.is_null());
784 isolate_->set_ast_node_id(0);
785 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
786 set_allow_modules(!info->is_native() && FLAG_harmony_modules);
787 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
788 set_allow_lazy(false); // Must be explicitly enabled.
789 set_allow_generators(FLAG_harmony_generators);
790 set_allow_for_of(FLAG_harmony_iteration);
791 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
792 }
793
794
ParseProgram()795 FunctionLiteral* Parser::ParseProgram() {
796 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
797 // see comment for HistogramTimerScope class.
798 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true);
799 Handle<String> source(String::cast(script_->source()));
800 isolate()->counters()->total_parse_size()->Increment(source->length());
801 ElapsedTimer timer;
802 if (FLAG_trace_parse) {
803 timer.Start();
804 }
805 fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
806
807 // Initialize parser state.
808 CompleteParserRecorder recorder;
809 if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
810 log_ = &recorder;
811 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) {
812 (*cached_data_)->Initialize();
813 }
814
815 source = String::Flatten(source);
816 FunctionLiteral* result;
817 if (source->IsExternalTwoByteString()) {
818 // Notice that the stream is destroyed at the end of the branch block.
819 // The last line of the blocks can't be moved outside, even though they're
820 // identical calls.
821 ExternalTwoByteStringUtf16CharacterStream stream(
822 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
823 scanner_.Initialize(&stream);
824 result = DoParseProgram(info(), source);
825 } else {
826 GenericStringUtf16CharacterStream stream(source, 0, source->length());
827 scanner_.Initialize(&stream);
828 result = DoParseProgram(info(), source);
829 }
830
831 if (FLAG_trace_parse && result != NULL) {
832 double ms = timer.Elapsed().InMillisecondsF();
833 if (info()->is_eval()) {
834 PrintF("[parsing eval");
835 } else if (info()->script()->name()->IsString()) {
836 String* name = String::cast(info()->script()->name());
837 SmartArrayPointer<char> name_chars = name->ToCString();
838 PrintF("[parsing script: %s", name_chars.get());
839 } else {
840 PrintF("[parsing script");
841 }
842 PrintF(" - took %0.3f ms]\n", ms);
843 }
844 if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
845 if (result != NULL) {
846 Vector<unsigned> store = recorder.ExtractData();
847 *cached_data_ = new ScriptData(store);
848 }
849 log_ = NULL;
850 }
851 return result;
852 }
853
854
DoParseProgram(CompilationInfo * info,Handle<String> source)855 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
856 Handle<String> source) {
857 ASSERT(scope_ == NULL);
858 ASSERT(target_stack_ == NULL);
859
860 Handle<String> no_name = isolate()->factory()->empty_string();
861
862 FunctionLiteral* result = NULL;
863 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE);
864 info->SetGlobalScope(scope);
865 if (!info->context().is_null()) {
866 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone());
867 }
868 original_scope_ = scope;
869 if (info->is_eval()) {
870 if (!scope->is_global_scope() || info->strict_mode() == STRICT) {
871 scope = NewScope(scope, EVAL_SCOPE);
872 }
873 } else if (info->is_global()) {
874 scope = NewScope(scope, GLOBAL_SCOPE);
875 }
876 scope->set_start_position(0);
877 scope->set_end_position(source->length());
878
879 // Compute the parsing mode.
880 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
881 if (allow_natives_syntax() ||
882 extension_ != NULL ||
883 scope->is_eval_scope()) {
884 mode = PARSE_EAGERLY;
885 }
886 ParsingModeScope parsing_mode(this, mode);
887
888 // Enters 'scope'.
889 FunctionState function_state(&function_state_, &scope_, scope, zone());
890
891 scope_->SetStrictMode(info->strict_mode());
892 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
893 bool ok = true;
894 int beg_pos = scanner()->location().beg_pos;
895 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok);
896 if (ok && strict_mode() == STRICT) {
897 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
898 }
899
900 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) {
901 CheckConflictingVarDeclarations(scope_, &ok);
902 }
903
904 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
905 if (body->length() != 1 ||
906 !body->at(0)->IsExpressionStatement() ||
907 !body->at(0)->AsExpressionStatement()->
908 expression()->IsFunctionLiteral()) {
909 ReportMessage("single_function_literal");
910 ok = false;
911 }
912 }
913
914 if (ok) {
915 result = factory()->NewFunctionLiteral(
916 no_name,
917 scope_,
918 body,
919 function_state.materialized_literal_count(),
920 function_state.expected_property_count(),
921 function_state.handler_count(),
922 0,
923 FunctionLiteral::kNoDuplicateParameters,
924 FunctionLiteral::ANONYMOUS_EXPRESSION,
925 FunctionLiteral::kGlobalOrEval,
926 FunctionLiteral::kNotParenthesized,
927 FunctionLiteral::kNotGenerator,
928 0);
929 result->set_ast_properties(factory()->visitor()->ast_properties());
930 result->set_dont_optimize_reason(
931 factory()->visitor()->dont_optimize_reason());
932 } else if (stack_overflow()) {
933 isolate()->StackOverflow();
934 } else {
935 ThrowPendingError();
936 }
937 }
938
939 // Make sure the target stack is empty.
940 ASSERT(target_stack_ == NULL);
941
942 return result;
943 }
944
945
ParseLazy()946 FunctionLiteral* Parser::ParseLazy() {
947 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy());
948 Handle<String> source(String::cast(script_->source()));
949 isolate()->counters()->total_parse_size()->Increment(source->length());
950 ElapsedTimer timer;
951 if (FLAG_trace_parse) {
952 timer.Start();
953 }
954 Handle<SharedFunctionInfo> shared_info = info()->shared_info();
955
956 // Initialize parser state.
957 source = String::Flatten(source);
958 FunctionLiteral* result;
959 if (source->IsExternalTwoByteString()) {
960 ExternalTwoByteStringUtf16CharacterStream stream(
961 Handle<ExternalTwoByteString>::cast(source),
962 shared_info->start_position(),
963 shared_info->end_position());
964 result = ParseLazy(&stream);
965 } else {
966 GenericStringUtf16CharacterStream stream(source,
967 shared_info->start_position(),
968 shared_info->end_position());
969 result = ParseLazy(&stream);
970 }
971
972 if (FLAG_trace_parse && result != NULL) {
973 double ms = timer.Elapsed().InMillisecondsF();
974 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
975 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
976 }
977 return result;
978 }
979
980
ParseLazy(Utf16CharacterStream * source)981 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
982 Handle<SharedFunctionInfo> shared_info = info()->shared_info();
983 scanner_.Initialize(source);
984 ASSERT(scope_ == NULL);
985 ASSERT(target_stack_ == NULL);
986
987 Handle<String> name(String::cast(shared_info->name()));
988 fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
989 fni_->PushEnclosingName(name);
990
991 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
992
993 // Place holder for the result.
994 FunctionLiteral* result = NULL;
995
996 {
997 // Parse the function literal.
998 Scope* scope = NewScope(scope_, GLOBAL_SCOPE);
999 info()->SetGlobalScope(scope);
1000 if (!info()->closure().is_null()) {
1001 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
1002 zone());
1003 }
1004 original_scope_ = scope;
1005 FunctionState function_state(&function_state_, &scope_, scope, zone());
1006 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
1007 ASSERT(info()->strict_mode() == shared_info->strict_mode());
1008 scope->SetStrictMode(shared_info->strict_mode());
1009 FunctionLiteral::FunctionType function_type = shared_info->is_expression()
1010 ? (shared_info->is_anonymous()
1011 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1012 : FunctionLiteral::NAMED_EXPRESSION)
1013 : FunctionLiteral::DECLARATION;
1014 bool ok = true;
1015 result = ParseFunctionLiteral(name,
1016 Scanner::Location::invalid(),
1017 false, // Strict mode name already checked.
1018 shared_info->is_generator(),
1019 RelocInfo::kNoPosition,
1020 function_type,
1021 FunctionLiteral::NORMAL_ARITY,
1022 &ok);
1023 // Make sure the results agree.
1024 ASSERT(ok == (result != NULL));
1025 }
1026
1027 // Make sure the target stack is empty.
1028 ASSERT(target_stack_ == NULL);
1029
1030 if (result == NULL) {
1031 if (stack_overflow()) {
1032 isolate()->StackOverflow();
1033 } else {
1034 ThrowPendingError();
1035 }
1036 } else {
1037 Handle<String> inferred_name(shared_info->inferred_name());
1038 result->set_inferred_name(inferred_name);
1039 }
1040 return result;
1041 }
1042
1043
ParseSourceElements(ZoneList<Statement * > * processor,int end_token,bool is_eval,bool is_global,bool * ok)1044 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1045 int end_token,
1046 bool is_eval,
1047 bool is_global,
1048 bool* ok) {
1049 // SourceElements ::
1050 // (ModuleElement)* <end_token>
1051
1052 // Allocate a target stack to use for this set of source
1053 // elements. This way, all scripts and functions get their own
1054 // target stack thus avoiding illegal breaks and continues across
1055 // functions.
1056 TargetScope scope(&this->target_stack_);
1057
1058 ASSERT(processor != NULL);
1059 bool directive_prologue = true; // Parsing directive prologue.
1060
1061 while (peek() != end_token) {
1062 if (directive_prologue && peek() != Token::STRING) {
1063 directive_prologue = false;
1064 }
1065
1066 Scanner::Location token_loc = scanner()->peek_location();
1067 Statement* stat;
1068 if (is_global && !is_eval) {
1069 stat = ParseModuleElement(NULL, CHECK_OK);
1070 } else {
1071 stat = ParseBlockElement(NULL, CHECK_OK);
1072 }
1073 if (stat == NULL || stat->IsEmpty()) {
1074 directive_prologue = false; // End of directive prologue.
1075 continue;
1076 }
1077
1078 if (directive_prologue) {
1079 // A shot at a directive.
1080 ExpressionStatement* e_stat;
1081 Literal* literal;
1082 // Still processing directive prologue?
1083 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1084 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1085 literal->value()->IsString()) {
1086 Handle<String> directive = Handle<String>::cast(literal->value());
1087
1088 // Check "use strict" directive (ES5 14.1).
1089 if (strict_mode() == SLOPPY &&
1090 String::Equals(isolate()->factory()->use_strict_string(),
1091 directive) &&
1092 token_loc.end_pos - token_loc.beg_pos ==
1093 isolate()->heap()->use_strict_string()->length() + 2) {
1094 // TODO(mstarzinger): Global strict eval calls, need their own scope
1095 // as specified in ES5 10.4.2(3). The correct fix would be to always
1096 // add this scope in DoParseProgram(), but that requires adaptations
1097 // all over the code base, so we go with a quick-fix for now.
1098 // In the same manner, we have to patch the parsing mode.
1099 if (is_eval && !scope_->is_eval_scope()) {
1100 ASSERT(scope_->is_global_scope());
1101 Scope* scope = NewScope(scope_, EVAL_SCOPE);
1102 scope->set_start_position(scope_->start_position());
1103 scope->set_end_position(scope_->end_position());
1104 scope_ = scope;
1105 mode_ = PARSE_EAGERLY;
1106 }
1107 scope_->SetStrictMode(STRICT);
1108 // "use strict" is the only directive for now.
1109 directive_prologue = false;
1110 }
1111 } else {
1112 // End of the directive prologue.
1113 directive_prologue = false;
1114 }
1115 }
1116
1117 processor->Add(stat, zone());
1118 }
1119
1120 return 0;
1121 }
1122
1123
ParseModuleElement(ZoneStringList * labels,bool * ok)1124 Statement* Parser::ParseModuleElement(ZoneStringList* labels,
1125 bool* ok) {
1126 // (Ecma 262 5th Edition, clause 14):
1127 // SourceElement:
1128 // Statement
1129 // FunctionDeclaration
1130 //
1131 // In harmony mode we allow additionally the following productions
1132 // ModuleElement:
1133 // LetDeclaration
1134 // ConstDeclaration
1135 // ModuleDeclaration
1136 // ImportDeclaration
1137 // ExportDeclaration
1138 // GeneratorDeclaration
1139
1140 switch (peek()) {
1141 case Token::FUNCTION:
1142 return ParseFunctionDeclaration(NULL, ok);
1143 case Token::LET:
1144 case Token::CONST:
1145 return ParseVariableStatement(kModuleElement, NULL, ok);
1146 case Token::IMPORT:
1147 return ParseImportDeclaration(ok);
1148 case Token::EXPORT:
1149 return ParseExportDeclaration(ok);
1150 default: {
1151 Statement* stmt = ParseStatement(labels, CHECK_OK);
1152 // Handle 'module' as a context-sensitive keyword.
1153 if (FLAG_harmony_modules &&
1154 peek() == Token::IDENTIFIER &&
1155 !scanner()->HasAnyLineTerminatorBeforeNext() &&
1156 stmt != NULL) {
1157 ExpressionStatement* estmt = stmt->AsExpressionStatement();
1158 if (estmt != NULL &&
1159 estmt->expression()->AsVariableProxy() != NULL &&
1160 String::Equals(isolate()->factory()->module_string(),
1161 estmt->expression()->AsVariableProxy()->name()) &&
1162 !scanner()->literal_contains_escapes()) {
1163 return ParseModuleDeclaration(NULL, ok);
1164 }
1165 }
1166 return stmt;
1167 }
1168 }
1169 }
1170
1171
ParseModuleDeclaration(ZoneStringList * names,bool * ok)1172 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
1173 // ModuleDeclaration:
1174 // 'module' Identifier Module
1175
1176 int pos = peek_position();
1177 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1178
1179 #ifdef DEBUG
1180 if (FLAG_print_interface_details)
1181 PrintF("# Module %s...\n", name->ToAsciiArray());
1182 #endif
1183
1184 Module* module = ParseModule(CHECK_OK);
1185 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface());
1186 Declaration* declaration =
1187 factory()->NewModuleDeclaration(proxy, module, scope_, pos);
1188 Declare(declaration, true, CHECK_OK);
1189
1190 #ifdef DEBUG
1191 if (FLAG_print_interface_details)
1192 PrintF("# Module %s.\n", name->ToAsciiArray());
1193
1194 if (FLAG_print_interfaces) {
1195 PrintF("module %s : ", name->ToAsciiArray());
1196 module->interface()->Print();
1197 }
1198 #endif
1199
1200 if (names) names->Add(name, zone());
1201 if (module->body() == NULL)
1202 return factory()->NewEmptyStatement(pos);
1203 else
1204 return factory()->NewModuleStatement(proxy, module->body(), pos);
1205 }
1206
1207
ParseModule(bool * ok)1208 Module* Parser::ParseModule(bool* ok) {
1209 // Module:
1210 // '{' ModuleElement '}'
1211 // '=' ModulePath ';'
1212 // 'at' String ';'
1213
1214 switch (peek()) {
1215 case Token::LBRACE:
1216 return ParseModuleLiteral(ok);
1217
1218 case Token::ASSIGN: {
1219 Expect(Token::ASSIGN, CHECK_OK);
1220 Module* result = ParseModulePath(CHECK_OK);
1221 ExpectSemicolon(CHECK_OK);
1222 return result;
1223 }
1224
1225 default: {
1226 ExpectContextualKeyword(CStrVector("at"), CHECK_OK);
1227 Module* result = ParseModuleUrl(CHECK_OK);
1228 ExpectSemicolon(CHECK_OK);
1229 return result;
1230 }
1231 }
1232 }
1233
1234
ParseModuleLiteral(bool * ok)1235 Module* Parser::ParseModuleLiteral(bool* ok) {
1236 // Module:
1237 // '{' ModuleElement '}'
1238
1239 int pos = peek_position();
1240 // Construct block expecting 16 statements.
1241 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition);
1242 #ifdef DEBUG
1243 if (FLAG_print_interface_details) PrintF("# Literal ");
1244 #endif
1245 Scope* scope = NewScope(scope_, MODULE_SCOPE);
1246
1247 Expect(Token::LBRACE, CHECK_OK);
1248 scope->set_start_position(scanner()->location().beg_pos);
1249 scope->SetStrictMode(STRICT);
1250
1251 {
1252 BlockState block_state(&scope_, scope);
1253 TargetCollector collector(zone());
1254 Target target(&this->target_stack_, &collector);
1255 Target target_body(&this->target_stack_, body);
1256
1257 while (peek() != Token::RBRACE) {
1258 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1259 if (stat && !stat->IsEmpty()) {
1260 body->AddStatement(stat, zone());
1261 }
1262 }
1263 }
1264
1265 Expect(Token::RBRACE, CHECK_OK);
1266 scope->set_end_position(scanner()->location().end_pos);
1267 body->set_scope(scope);
1268
1269 // Check that all exports are bound.
1270 Interface* interface = scope->interface();
1271 for (Interface::Iterator it = interface->iterator();
1272 !it.done(); it.Advance()) {
1273 if (scope->LookupLocal(it.name()) == NULL) {
1274 ParserTraits::ReportMessage("module_export_undefined", it.name());
1275 *ok = false;
1276 return NULL;
1277 }
1278 }
1279
1280 interface->MakeModule(ok);
1281 ASSERT(*ok);
1282 interface->Freeze(ok);
1283 ASSERT(*ok);
1284 return factory()->NewModuleLiteral(body, interface, pos);
1285 }
1286
1287
ParseModulePath(bool * ok)1288 Module* Parser::ParseModulePath(bool* ok) {
1289 // ModulePath:
1290 // Identifier
1291 // ModulePath '.' Identifier
1292
1293 int pos = peek_position();
1294 Module* result = ParseModuleVariable(CHECK_OK);
1295 while (Check(Token::PERIOD)) {
1296 Handle<String> name = ParseIdentifierName(CHECK_OK);
1297 #ifdef DEBUG
1298 if (FLAG_print_interface_details)
1299 PrintF("# Path .%s ", name->ToAsciiArray());
1300 #endif
1301 Module* member = factory()->NewModulePath(result, name, pos);
1302 result->interface()->Add(name, member->interface(), zone(), ok);
1303 if (!*ok) {
1304 #ifdef DEBUG
1305 if (FLAG_print_interfaces) {
1306 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray());
1307 PrintF("result: ");
1308 result->interface()->Print();
1309 PrintF("member: ");
1310 member->interface()->Print();
1311 }
1312 #endif
1313 ParserTraits::ReportMessage("invalid_module_path", name);
1314 return NULL;
1315 }
1316 result = member;
1317 }
1318
1319 return result;
1320 }
1321
1322
ParseModuleVariable(bool * ok)1323 Module* Parser::ParseModuleVariable(bool* ok) {
1324 // ModulePath:
1325 // Identifier
1326
1327 int pos = peek_position();
1328 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1329 #ifdef DEBUG
1330 if (FLAG_print_interface_details)
1331 PrintF("# Module variable %s ", name->ToAsciiArray());
1332 #endif
1333 VariableProxy* proxy = scope_->NewUnresolved(
1334 factory(), name, Interface::NewModule(zone()),
1335 scanner()->location().beg_pos);
1336
1337 return factory()->NewModuleVariable(proxy, pos);
1338 }
1339
1340
ParseModuleUrl(bool * ok)1341 Module* Parser::ParseModuleUrl(bool* ok) {
1342 // Module:
1343 // String
1344
1345 int pos = peek_position();
1346 Expect(Token::STRING, CHECK_OK);
1347 Handle<String> symbol = GetSymbol();
1348
1349 // TODO(ES6): Request JS resource from environment...
1350
1351 #ifdef DEBUG
1352 if (FLAG_print_interface_details) PrintF("# Url ");
1353 #endif
1354
1355 // Create an empty literal as long as the feature isn't finished.
1356 USE(symbol);
1357 Scope* scope = NewScope(scope_, MODULE_SCOPE);
1358 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
1359 body->set_scope(scope);
1360 Interface* interface = scope->interface();
1361 Module* result = factory()->NewModuleLiteral(body, interface, pos);
1362 interface->Freeze(ok);
1363 ASSERT(*ok);
1364 interface->Unify(scope->interface(), zone(), ok);
1365 ASSERT(*ok);
1366 return result;
1367 }
1368
1369
ParseModuleSpecifier(bool * ok)1370 Module* Parser::ParseModuleSpecifier(bool* ok) {
1371 // ModuleSpecifier:
1372 // String
1373 // ModulePath
1374
1375 if (peek() == Token::STRING) {
1376 return ParseModuleUrl(ok);
1377 } else {
1378 return ParseModulePath(ok);
1379 }
1380 }
1381
1382
ParseImportDeclaration(bool * ok)1383 Block* Parser::ParseImportDeclaration(bool* ok) {
1384 // ImportDeclaration:
1385 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';'
1386 //
1387 // TODO(ES6): implement destructuring ImportSpecifiers
1388
1389 int pos = peek_position();
1390 Expect(Token::IMPORT, CHECK_OK);
1391 ZoneStringList names(1, zone());
1392
1393 Handle<String> name = ParseIdentifierName(CHECK_OK);
1394 names.Add(name, zone());
1395 while (peek() == Token::COMMA) {
1396 Consume(Token::COMMA);
1397 name = ParseIdentifierName(CHECK_OK);
1398 names.Add(name, zone());
1399 }
1400
1401 ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1402 Module* module = ParseModuleSpecifier(CHECK_OK);
1403 ExpectSemicolon(CHECK_OK);
1404
1405 // Generate a separate declaration for each identifier.
1406 // TODO(ES6): once we implement destructuring, make that one declaration.
1407 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
1408 for (int i = 0; i < names.length(); ++i) {
1409 #ifdef DEBUG
1410 if (FLAG_print_interface_details)
1411 PrintF("# Import %s ", names[i]->ToAsciiArray());
1412 #endif
1413 Interface* interface = Interface::NewUnknown(zone());
1414 module->interface()->Add(names[i], interface, zone(), ok);
1415 if (!*ok) {
1416 #ifdef DEBUG
1417 if (FLAG_print_interfaces) {
1418 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray());
1419 PrintF("module: ");
1420 module->interface()->Print();
1421 }
1422 #endif
1423 ParserTraits::ReportMessage("invalid_module_path", name);
1424 return NULL;
1425 }
1426 VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1427 Declaration* declaration =
1428 factory()->NewImportDeclaration(proxy, module, scope_, pos);
1429 Declare(declaration, true, CHECK_OK);
1430 }
1431
1432 return block;
1433 }
1434
1435
ParseExportDeclaration(bool * ok)1436 Statement* Parser::ParseExportDeclaration(bool* ok) {
1437 // ExportDeclaration:
1438 // 'export' Identifier (',' Identifier)* ';'
1439 // 'export' VariableDeclaration
1440 // 'export' FunctionDeclaration
1441 // 'export' GeneratorDeclaration
1442 // 'export' ModuleDeclaration
1443 //
1444 // TODO(ES6): implement structuring ExportSpecifiers
1445
1446 Expect(Token::EXPORT, CHECK_OK);
1447
1448 Statement* result = NULL;
1449 ZoneStringList names(1, zone());
1450 switch (peek()) {
1451 case Token::IDENTIFIER: {
1452 int pos = position();
1453 Handle<String> name =
1454 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1455 // Handle 'module' as a context-sensitive keyword.
1456 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) {
1457 names.Add(name, zone());
1458 while (peek() == Token::COMMA) {
1459 Consume(Token::COMMA);
1460 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
1461 names.Add(name, zone());
1462 }
1463 ExpectSemicolon(CHECK_OK);
1464 result = factory()->NewEmptyStatement(pos);
1465 } else {
1466 result = ParseModuleDeclaration(&names, CHECK_OK);
1467 }
1468 break;
1469 }
1470
1471 case Token::FUNCTION:
1472 result = ParseFunctionDeclaration(&names, CHECK_OK);
1473 break;
1474
1475 case Token::VAR:
1476 case Token::LET:
1477 case Token::CONST:
1478 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK);
1479 break;
1480
1481 default:
1482 *ok = false;
1483 ReportUnexpectedToken(scanner()->current_token());
1484 return NULL;
1485 }
1486
1487 // Extract declared names into export declarations and interface.
1488 Interface* interface = scope_->interface();
1489 for (int i = 0; i < names.length(); ++i) {
1490 #ifdef DEBUG
1491 if (FLAG_print_interface_details)
1492 PrintF("# Export %s ", names[i]->ToAsciiArray());
1493 #endif
1494 Interface* inner = Interface::NewUnknown(zone());
1495 interface->Add(names[i], inner, zone(), CHECK_OK);
1496 if (!*ok)
1497 return NULL;
1498 VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1499 USE(proxy);
1500 // TODO(rossberg): Rethink whether we actually need to store export
1501 // declarations (for compilation?).
1502 // ExportDeclaration* declaration =
1503 // factory()->NewExportDeclaration(proxy, scope_, position);
1504 // scope_->AddDeclaration(declaration);
1505 }
1506
1507 ASSERT(result != NULL);
1508 return result;
1509 }
1510
1511
ParseBlockElement(ZoneStringList * labels,bool * ok)1512 Statement* Parser::ParseBlockElement(ZoneStringList* labels,
1513 bool* ok) {
1514 // (Ecma 262 5th Edition, clause 14):
1515 // SourceElement:
1516 // Statement
1517 // FunctionDeclaration
1518 //
1519 // In harmony mode we allow additionally the following productions
1520 // BlockElement (aka SourceElement):
1521 // LetDeclaration
1522 // ConstDeclaration
1523 // GeneratorDeclaration
1524
1525 switch (peek()) {
1526 case Token::FUNCTION:
1527 return ParseFunctionDeclaration(NULL, ok);
1528 case Token::LET:
1529 case Token::CONST:
1530 return ParseVariableStatement(kModuleElement, NULL, ok);
1531 default:
1532 return ParseStatement(labels, ok);
1533 }
1534 }
1535
1536
ParseStatement(ZoneStringList * labels,bool * ok)1537 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
1538 // Statement ::
1539 // Block
1540 // VariableStatement
1541 // EmptyStatement
1542 // ExpressionStatement
1543 // IfStatement
1544 // IterationStatement
1545 // ContinueStatement
1546 // BreakStatement
1547 // ReturnStatement
1548 // WithStatement
1549 // LabelledStatement
1550 // SwitchStatement
1551 // ThrowStatement
1552 // TryStatement
1553 // DebuggerStatement
1554
1555 // Note: Since labels can only be used by 'break' and 'continue'
1556 // statements, which themselves are only valid within blocks,
1557 // iterations or 'switch' statements (i.e., BreakableStatements),
1558 // labels can be simply ignored in all other cases; except for
1559 // trivial labeled break statements 'label: break label' which is
1560 // parsed into an empty statement.
1561 switch (peek()) {
1562 case Token::LBRACE:
1563 return ParseBlock(labels, ok);
1564
1565 case Token::CONST: // fall through
1566 case Token::LET:
1567 case Token::VAR:
1568 return ParseVariableStatement(kStatement, NULL, ok);
1569
1570 case Token::SEMICOLON:
1571 Next();
1572 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1573
1574 case Token::IF:
1575 return ParseIfStatement(labels, ok);
1576
1577 case Token::DO:
1578 return ParseDoWhileStatement(labels, ok);
1579
1580 case Token::WHILE:
1581 return ParseWhileStatement(labels, ok);
1582
1583 case Token::FOR:
1584 return ParseForStatement(labels, ok);
1585
1586 case Token::CONTINUE:
1587 return ParseContinueStatement(ok);
1588
1589 case Token::BREAK:
1590 return ParseBreakStatement(labels, ok);
1591
1592 case Token::RETURN:
1593 return ParseReturnStatement(ok);
1594
1595 case Token::WITH:
1596 return ParseWithStatement(labels, ok);
1597
1598 case Token::SWITCH:
1599 return ParseSwitchStatement(labels, ok);
1600
1601 case Token::THROW:
1602 return ParseThrowStatement(ok);
1603
1604 case Token::TRY: {
1605 // NOTE: It is somewhat complicated to have labels on
1606 // try-statements. When breaking out of a try-finally statement,
1607 // one must take great care not to treat it as a
1608 // fall-through. It is much easier just to wrap the entire
1609 // try-statement in a statement block and put the labels there
1610 Block* result =
1611 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
1612 Target target(&this->target_stack_, result);
1613 TryStatement* statement = ParseTryStatement(CHECK_OK);
1614 if (result) result->AddStatement(statement, zone());
1615 return result;
1616 }
1617
1618 case Token::FUNCTION: {
1619 // FunctionDeclaration is only allowed in the context of SourceElements
1620 // (Ecma 262 5th Edition, clause 14):
1621 // SourceElement:
1622 // Statement
1623 // FunctionDeclaration
1624 // Common language extension is to allow function declaration in place
1625 // of any statement. This language extension is disabled in strict mode.
1626 //
1627 // In Harmony mode, this case also handles the extension:
1628 // Statement:
1629 // GeneratorDeclaration
1630 if (strict_mode() == STRICT) {
1631 ReportMessageAt(scanner()->peek_location(), "strict_function");
1632 *ok = false;
1633 return NULL;
1634 }
1635 return ParseFunctionDeclaration(NULL, ok);
1636 }
1637
1638 case Token::DEBUGGER:
1639 return ParseDebuggerStatement(ok);
1640
1641 default:
1642 return ParseExpressionOrLabelledStatement(labels, ok);
1643 }
1644 }
1645
1646
NewUnresolved(Handle<String> name,VariableMode mode,Interface * interface)1647 VariableProxy* Parser::NewUnresolved(
1648 Handle<String> name, VariableMode mode, Interface* interface) {
1649 // If we are inside a function, a declaration of a var/const variable is a
1650 // truly local variable, and the scope of the variable is always the function
1651 // scope.
1652 // Let/const variables in harmony mode are always added to the immediately
1653 // enclosing scope.
1654 return DeclarationScope(mode)->NewUnresolved(
1655 factory(), name, interface, position());
1656 }
1657
1658
Declare(Declaration * declaration,bool resolve,bool * ok)1659 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1660 VariableProxy* proxy = declaration->proxy();
1661 Handle<String> name = proxy->name();
1662 VariableMode mode = declaration->mode();
1663 Scope* declaration_scope = DeclarationScope(mode);
1664 Variable* var = NULL;
1665
1666 // If a suitable scope exists, then we can statically declare this
1667 // variable and also set its mode. In any case, a Declaration node
1668 // will be added to the scope so that the declaration can be added
1669 // to the corresponding activation frame at runtime if necessary.
1670 // For instance declarations inside an eval scope need to be added
1671 // to the calling function context.
1672 // Similarly, strict mode eval scope does not leak variable declarations to
1673 // the caller's scope so we declare all locals, too.
1674 if (declaration_scope->is_function_scope() ||
1675 declaration_scope->is_strict_eval_scope() ||
1676 declaration_scope->is_block_scope() ||
1677 declaration_scope->is_module_scope() ||
1678 declaration_scope->is_global_scope()) {
1679 // Declare the variable in the declaration scope.
1680 // For the global scope, we have to check for collisions with earlier
1681 // (i.e., enclosing) global scopes, to maintain the illusion of a single
1682 // global scope.
1683 var = declaration_scope->is_global_scope()
1684 ? declaration_scope->Lookup(name)
1685 : declaration_scope->LookupLocal(name);
1686 if (var == NULL) {
1687 // Declare the name.
1688 var = declaration_scope->DeclareLocal(
1689 name, mode, declaration->initialization(), proxy->interface());
1690 } else if ((mode != VAR || var->mode() != VAR) &&
1691 (!declaration_scope->is_global_scope() ||
1692 IsLexicalVariableMode(mode) ||
1693 IsLexicalVariableMode(var->mode()))) {
1694 // The name was declared in this scope before; check for conflicting
1695 // re-declarations. We have a conflict if either of the declarations is
1696 // not a var (in the global scope, we also have to ignore legacy const for
1697 // compatibility). There is similar code in runtime.cc in the Declare
1698 // functions. The function CheckNonConflictingScope checks for conflicting
1699 // var and let bindings from different scopes whereas this is a check for
1700 // conflicting declarations within the same scope. This check also covers
1701 // the special case
1702 //
1703 // function () { let x; { var x; } }
1704 //
1705 // because the var declaration is hoisted to the function scope where 'x'
1706 // is already bound.
1707 ASSERT(IsDeclaredVariableMode(var->mode()));
1708 if (allow_harmony_scoping() && strict_mode() == STRICT) {
1709 // In harmony we treat re-declarations as early errors. See
1710 // ES5 16 for a definition of early errors.
1711 ParserTraits::ReportMessage("var_redeclaration", name);
1712 *ok = false;
1713 return;
1714 }
1715 Expression* expression = NewThrowTypeError(
1716 "var_redeclaration", name, declaration->position());
1717 declaration_scope->SetIllegalRedeclaration(expression);
1718 }
1719 }
1720
1721 // We add a declaration node for every declaration. The compiler
1722 // will only generate code if necessary. In particular, declarations
1723 // for inner local variables that do not represent functions won't
1724 // result in any generated code.
1725 //
1726 // Note that we always add an unresolved proxy even if it's not
1727 // used, simply because we don't know in this method (w/o extra
1728 // parameters) if the proxy is needed or not. The proxy will be
1729 // bound during variable resolution time unless it was pre-bound
1730 // below.
1731 //
1732 // WARNING: This will lead to multiple declaration nodes for the
1733 // same variable if it is declared several times. This is not a
1734 // semantic issue as long as we keep the source order, but it may be
1735 // a performance issue since it may lead to repeated
1736 // RuntimeHidden_DeclareContextSlot calls.
1737 declaration_scope->AddDeclaration(declaration);
1738
1739 if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) {
1740 // For global const variables we bind the proxy to a variable.
1741 ASSERT(resolve); // should be set by all callers
1742 Variable::Kind kind = Variable::NORMAL;
1743 var = new(zone()) Variable(
1744 declaration_scope, name, mode, true, kind,
1745 kNeedsInitialization, proxy->interface());
1746 } else if (declaration_scope->is_eval_scope() &&
1747 declaration_scope->strict_mode() == SLOPPY) {
1748 // For variable declarations in a sloppy eval scope the proxy is bound
1749 // to a lookup variable to force a dynamic declaration using the
1750 // DeclareContextSlot runtime function.
1751 Variable::Kind kind = Variable::NORMAL;
1752 var = new(zone()) Variable(
1753 declaration_scope, name, mode, true, kind,
1754 declaration->initialization(), proxy->interface());
1755 var->AllocateTo(Variable::LOOKUP, -1);
1756 resolve = true;
1757 }
1758
1759 // If requested and we have a local variable, bind the proxy to the variable
1760 // at parse-time. This is used for functions (and consts) declared inside
1761 // statements: the corresponding function (or const) variable must be in the
1762 // function scope and not a statement-local scope, e.g. as provided with a
1763 // 'with' statement:
1764 //
1765 // with (obj) {
1766 // function f() {}
1767 // }
1768 //
1769 // which is translated into:
1770 //
1771 // with (obj) {
1772 // // in this case this is not: 'var f; f = function () {};'
1773 // var f = function () {};
1774 // }
1775 //
1776 // Note that if 'f' is accessed from inside the 'with' statement, it
1777 // will be allocated in the context (because we must be able to look
1778 // it up dynamically) but it will also be accessed statically, i.e.,
1779 // with a context slot index and a context chain length for this
1780 // initialization code. Thus, inside the 'with' statement, we need
1781 // both access to the static and the dynamic context chain; the
1782 // runtime needs to provide both.
1783 if (resolve && var != NULL) {
1784 proxy->BindTo(var);
1785
1786 if (FLAG_harmony_modules) {
1787 bool ok;
1788 #ifdef DEBUG
1789 if (FLAG_print_interface_details)
1790 PrintF("# Declare %s\n", var->name()->ToAsciiArray());
1791 #endif
1792 proxy->interface()->Unify(var->interface(), zone(), &ok);
1793 if (!ok) {
1794 #ifdef DEBUG
1795 if (FLAG_print_interfaces) {
1796 PrintF("DECLARE TYPE ERROR\n");
1797 PrintF("proxy: ");
1798 proxy->interface()->Print();
1799 PrintF("var: ");
1800 var->interface()->Print();
1801 }
1802 #endif
1803 ParserTraits::ReportMessage("module_type_error", name);
1804 }
1805 }
1806 }
1807 }
1808
1809
1810 // Language extension which is only enabled for source files loaded
1811 // through the API's extension mechanism. A native function
1812 // declaration is resolved by looking up the function through a
1813 // callback provided by the extension.
ParseNativeDeclaration(bool * ok)1814 Statement* Parser::ParseNativeDeclaration(bool* ok) {
1815 int pos = peek_position();
1816 Expect(Token::FUNCTION, CHECK_OK);
1817 // Allow "eval" or "arguments" for backward compatibility.
1818 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1819 Expect(Token::LPAREN, CHECK_OK);
1820 bool done = (peek() == Token::RPAREN);
1821 while (!done) {
1822 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1823 done = (peek() == Token::RPAREN);
1824 if (!done) {
1825 Expect(Token::COMMA, CHECK_OK);
1826 }
1827 }
1828 Expect(Token::RPAREN, CHECK_OK);
1829 Expect(Token::SEMICOLON, CHECK_OK);
1830
1831 // Make sure that the function containing the native declaration
1832 // isn't lazily compiled. The extension structures are only
1833 // accessible while parsing the first time not when reparsing
1834 // because of lazy compilation.
1835 DeclarationScope(VAR)->ForceEagerCompilation();
1836
1837 // TODO(1240846): It's weird that native function declarations are
1838 // introduced dynamically when we meet their declarations, whereas
1839 // other functions are set up when entering the surrounding scope.
1840 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue());
1841 Declaration* declaration =
1842 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
1843 Declare(declaration, true, CHECK_OK);
1844 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
1845 name, extension_, RelocInfo::kNoPosition);
1846 return factory()->NewExpressionStatement(
1847 factory()->NewAssignment(
1848 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition),
1849 pos);
1850 }
1851
1852
ParseFunctionDeclaration(ZoneStringList * names,bool * ok)1853 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
1854 // FunctionDeclaration ::
1855 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1856 // GeneratorDeclaration ::
1857 // 'function' '*' Identifier '(' FormalParameterListopt ')'
1858 // '{' FunctionBody '}'
1859 Expect(Token::FUNCTION, CHECK_OK);
1860 int pos = position();
1861 bool is_generator = allow_generators() && Check(Token::MUL);
1862 bool is_strict_reserved = false;
1863 Handle<String> name = ParseIdentifierOrStrictReservedWord(
1864 &is_strict_reserved, CHECK_OK);
1865 FunctionLiteral* fun = ParseFunctionLiteral(name,
1866 scanner()->location(),
1867 is_strict_reserved,
1868 is_generator,
1869 pos,
1870 FunctionLiteral::DECLARATION,
1871 FunctionLiteral::NORMAL_ARITY,
1872 CHECK_OK);
1873 // Even if we're not at the top-level of the global or a function
1874 // scope, we treat it as such and introduce the function with its
1875 // initial value upon entering the corresponding scope.
1876 // In extended mode, a function behaves as a lexical binding, except in the
1877 // global scope.
1878 VariableMode mode =
1879 allow_harmony_scoping() &&
1880 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR;
1881 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
1882 Declaration* declaration =
1883 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
1884 Declare(declaration, true, CHECK_OK);
1885 if (names) names->Add(name, zone());
1886 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1887 }
1888
1889
ParseBlock(ZoneStringList * labels,bool * ok)1890 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
1891 if (allow_harmony_scoping() && strict_mode() == STRICT) {
1892 return ParseScopedBlock(labels, ok);
1893 }
1894
1895 // Block ::
1896 // '{' Statement* '}'
1897
1898 // Note that a Block does not introduce a new execution scope!
1899 // (ECMA-262, 3rd, 12.2)
1900 //
1901 // Construct block expecting 16 statements.
1902 Block* result =
1903 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
1904 Target target(&this->target_stack_, result);
1905 Expect(Token::LBRACE, CHECK_OK);
1906 while (peek() != Token::RBRACE) {
1907 Statement* stat = ParseStatement(NULL, CHECK_OK);
1908 if (stat && !stat->IsEmpty()) {
1909 result->AddStatement(stat, zone());
1910 }
1911 }
1912 Expect(Token::RBRACE, CHECK_OK);
1913 return result;
1914 }
1915
1916
ParseScopedBlock(ZoneStringList * labels,bool * ok)1917 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
1918 // The harmony mode uses block elements instead of statements.
1919 //
1920 // Block ::
1921 // '{' BlockElement* '}'
1922
1923 // Construct block expecting 16 statements.
1924 Block* body =
1925 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
1926 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
1927
1928 // Parse the statements and collect escaping labels.
1929 Expect(Token::LBRACE, CHECK_OK);
1930 block_scope->set_start_position(scanner()->location().beg_pos);
1931 { BlockState block_state(&scope_, block_scope);
1932 TargetCollector collector(zone());
1933 Target target(&this->target_stack_, &collector);
1934 Target target_body(&this->target_stack_, body);
1935
1936 while (peek() != Token::RBRACE) {
1937 Statement* stat = ParseBlockElement(NULL, CHECK_OK);
1938 if (stat && !stat->IsEmpty()) {
1939 body->AddStatement(stat, zone());
1940 }
1941 }
1942 }
1943 Expect(Token::RBRACE, CHECK_OK);
1944 block_scope->set_end_position(scanner()->location().end_pos);
1945 block_scope = block_scope->FinalizeBlockScope();
1946 body->set_scope(block_scope);
1947 return body;
1948 }
1949
1950
ParseVariableStatement(VariableDeclarationContext var_context,ZoneStringList * names,bool * ok)1951 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1952 ZoneStringList* names,
1953 bool* ok) {
1954 // VariableStatement ::
1955 // VariableDeclarations ';'
1956
1957 Handle<String> ignore;
1958 Block* result =
1959 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
1960 ExpectSemicolon(CHECK_OK);
1961 return result;
1962 }
1963
1964
1965 // If the variable declaration declares exactly one non-const
1966 // variable, then *out is set to that variable. In all other cases,
1967 // *out is untouched; in particular, it is the caller's responsibility
1968 // to initialize it properly. This mechanism is used for the parsing
1969 // of 'for-in' loops.
ParseVariableDeclarations(VariableDeclarationContext var_context,VariableDeclarationProperties * decl_props,ZoneStringList * names,Handle<String> * out,bool * ok)1970 Block* Parser::ParseVariableDeclarations(
1971 VariableDeclarationContext var_context,
1972 VariableDeclarationProperties* decl_props,
1973 ZoneStringList* names,
1974 Handle<String>* out,
1975 bool* ok) {
1976 // VariableDeclarations ::
1977 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
1978 //
1979 // The ES6 Draft Rev3 specifies the following grammar for const declarations
1980 //
1981 // ConstDeclaration ::
1982 // const ConstBinding (',' ConstBinding)* ';'
1983 // ConstBinding ::
1984 // Identifier '=' AssignmentExpression
1985 //
1986 // TODO(ES6):
1987 // ConstBinding ::
1988 // BindingPattern '=' AssignmentExpression
1989
1990 int pos = peek_position();
1991 VariableMode mode = VAR;
1992 // True if the binding needs initialization. 'let' and 'const' declared
1993 // bindings are created uninitialized by their declaration nodes and
1994 // need initialization. 'var' declared bindings are always initialized
1995 // immediately by their declaration nodes.
1996 bool needs_init = false;
1997 bool is_const = false;
1998 Token::Value init_op = Token::INIT_VAR;
1999 if (peek() == Token::VAR) {
2000 Consume(Token::VAR);
2001 } else if (peek() == Token::CONST) {
2002 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
2003 //
2004 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
2005 //
2006 // * It is a Syntax Error if the code that matches this production is not
2007 // contained in extended code.
2008 //
2009 // However disallowing const in sloppy mode will break compatibility with
2010 // existing pages. Therefore we keep allowing const with the old
2011 // non-harmony semantics in sloppy mode.
2012 Consume(Token::CONST);
2013 switch (strict_mode()) {
2014 case SLOPPY:
2015 mode = CONST_LEGACY;
2016 init_op = Token::INIT_CONST_LEGACY;
2017 break;
2018 case STRICT:
2019 if (allow_harmony_scoping()) {
2020 if (var_context == kStatement) {
2021 // In strict mode 'const' declarations are only allowed in source
2022 // element positions.
2023 ReportMessage("unprotected_const");
2024 *ok = false;
2025 return NULL;
2026 }
2027 mode = CONST;
2028 init_op = Token::INIT_CONST;
2029 } else {
2030 ReportMessage("strict_const");
2031 *ok = false;
2032 return NULL;
2033 }
2034 }
2035 is_const = true;
2036 needs_init = true;
2037 } else if (peek() == Token::LET) {
2038 // ES6 Draft Rev4 section 12.2.1:
2039 //
2040 // LetDeclaration : let LetBindingList ;
2041 //
2042 // * It is a Syntax Error if the code that matches this production is not
2043 // contained in extended code.
2044 //
2045 // TODO(rossberg): make 'let' a legal identifier in sloppy mode.
2046 if (!allow_harmony_scoping() || strict_mode() == SLOPPY) {
2047 ReportMessage("illegal_let");
2048 *ok = false;
2049 return NULL;
2050 }
2051 Consume(Token::LET);
2052 if (var_context == kStatement) {
2053 // Let declarations are only allowed in source element positions.
2054 ReportMessage("unprotected_let");
2055 *ok = false;
2056 return NULL;
2057 }
2058 mode = LET;
2059 needs_init = true;
2060 init_op = Token::INIT_LET;
2061 } else {
2062 UNREACHABLE(); // by current callers
2063 }
2064
2065 Scope* declaration_scope = DeclarationScope(mode);
2066
2067 // The scope of a var/const declared variable anywhere inside a function
2068 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2069 // transform a source-level var/const declaration into a (Function)
2070 // Scope declaration, and rewrite the source-level initialization into an
2071 // assignment statement. We use a block to collect multiple assignments.
2072 //
2073 // We mark the block as initializer block because we don't want the
2074 // rewriter to add a '.result' assignment to such a block (to get compliant
2075 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2076 // reasons when pretty-printing. Also, unless an assignment (initialization)
2077 // is inside an initializer block, it is ignored.
2078 //
2079 // Create new block with one expected declaration.
2080 Block* block = factory()->NewBlock(NULL, 1, true, pos);
2081 int nvars = 0; // the number of variables declared
2082 Handle<String> name;
2083 do {
2084 if (fni_ != NULL) fni_->Enter();
2085
2086 // Parse variable name.
2087 if (nvars > 0) Consume(Token::COMMA);
2088 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
2089 if (fni_ != NULL) fni_->PushVariableName(name);
2090
2091 // Declare variable.
2092 // Note that we *always* must treat the initial value via a separate init
2093 // assignment for variables and constants because the value must be assigned
2094 // when the variable is encountered in the source. But the variable/constant
2095 // is declared (and set to 'undefined') upon entering the function within
2096 // which the variable or constant is declared. Only function variables have
2097 // an initial value in the declaration (because they are initialized upon
2098 // entering the function).
2099 //
2100 // If we have a const declaration, in an inner scope, the proxy is always
2101 // bound to the declared variable (independent of possibly surrounding with
2102 // statements).
2103 // For let/const declarations in harmony mode, we can also immediately
2104 // pre-resolve the proxy because it resides in the same scope as the
2105 // declaration.
2106 Interface* interface =
2107 is_const ? Interface::NewConst() : Interface::NewValue();
2108 VariableProxy* proxy = NewUnresolved(name, mode, interface);
2109 Declaration* declaration =
2110 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2111 Declare(declaration, mode != VAR, CHECK_OK);
2112 nvars++;
2113 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2114 ReportMessage("too_many_variables");
2115 *ok = false;
2116 return NULL;
2117 }
2118 if (names) names->Add(name, zone());
2119
2120 // Parse initialization expression if present and/or needed. A
2121 // declaration of the form:
2122 //
2123 // var v = x;
2124 //
2125 // is syntactic sugar for:
2126 //
2127 // var v; v = x;
2128 //
2129 // In particular, we need to re-lookup 'v' (in scope_, not
2130 // declaration_scope) as it may be a different 'v' than the 'v' in the
2131 // declaration (e.g., if we are inside a 'with' statement or 'catch'
2132 // block).
2133 //
2134 // However, note that const declarations are different! A const
2135 // declaration of the form:
2136 //
2137 // const c = x;
2138 //
2139 // is *not* syntactic sugar for:
2140 //
2141 // const c; c = x;
2142 //
2143 // The "variable" c initialized to x is the same as the declared
2144 // one - there is no re-lookup (see the last parameter of the
2145 // Declare() call above).
2146
2147 Scope* initialization_scope = is_const ? declaration_scope : scope_;
2148 Expression* value = NULL;
2149 int pos = -1;
2150 // Harmony consts have non-optional initializers.
2151 if (peek() == Token::ASSIGN || mode == CONST) {
2152 Expect(Token::ASSIGN, CHECK_OK);
2153 pos = position();
2154 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
2155 // Don't infer if it is "a = function(){...}();"-like expression.
2156 if (fni_ != NULL &&
2157 value->AsCall() == NULL &&
2158 value->AsCallNew() == NULL) {
2159 fni_->Infer();
2160 } else {
2161 fni_->RemoveLastFunction();
2162 }
2163 if (decl_props != NULL) *decl_props = kHasInitializers;
2164 }
2165
2166 // Record the end position of the initializer.
2167 if (proxy->var() != NULL) {
2168 proxy->var()->set_initializer_position(position());
2169 }
2170
2171 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2172 if (value == NULL && needs_init) {
2173 value = GetLiteralUndefined(position());
2174 }
2175
2176 // Global variable declarations must be compiled in a specific
2177 // way. When the script containing the global variable declaration
2178 // is entered, the global variable must be declared, so that if it
2179 // doesn't exist (on the global object itself, see ES5 errata) it
2180 // gets created with an initial undefined value. This is handled
2181 // by the declarations part of the function representing the
2182 // top-level global code; see Runtime::DeclareGlobalVariable. If
2183 // it already exists (in the object or in a prototype), it is
2184 // *not* touched until the variable declaration statement is
2185 // executed.
2186 //
2187 // Executing the variable declaration statement will always
2188 // guarantee to give the global object a "local" variable; a
2189 // variable defined in the global object and not in any
2190 // prototype. This way, global variable declarations can shadow
2191 // properties in the prototype chain, but only after the variable
2192 // declaration statement has been executed. This is important in
2193 // browsers where the global object (window) has lots of
2194 // properties defined in prototype objects.
2195 if (initialization_scope->is_global_scope() &&
2196 !IsLexicalVariableMode(mode)) {
2197 // Compute the arguments for the runtime call.
2198 ZoneList<Expression*>* arguments =
2199 new(zone()) ZoneList<Expression*>(3, zone());
2200 // We have at least 1 parameter.
2201 arguments->Add(factory()->NewLiteral(name, pos), zone());
2202 CallRuntime* initialize;
2203
2204 if (is_const) {
2205 arguments->Add(value, zone());
2206 value = NULL; // zap the value to avoid the unnecessary assignment
2207
2208 // Construct the call to Runtime_InitializeConstGlobal
2209 // and add it to the initialization statement block.
2210 // Note that the function does different things depending on
2211 // the number of arguments (1 or 2).
2212 initialize = factory()->NewCallRuntime(
2213 isolate()->factory()->InitializeConstGlobal_string(),
2214 Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal),
2215 arguments, pos);
2216 } else {
2217 // Add strict mode.
2218 // We may want to pass singleton to avoid Literal allocations.
2219 StrictMode strict_mode = initialization_scope->strict_mode();
2220 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone());
2221
2222 // Be careful not to assign a value to the global variable if
2223 // we're in a with. The initialization value should not
2224 // necessarily be stored in the global object in that case,
2225 // which is why we need to generate a separate assignment node.
2226 if (value != NULL && !inside_with()) {
2227 arguments->Add(value, zone());
2228 value = NULL; // zap the value to avoid the unnecessary assignment
2229 }
2230
2231 // Construct the call to Runtime_InitializeVarGlobal
2232 // and add it to the initialization statement block.
2233 // Note that the function does different things depending on
2234 // the number of arguments (2 or 3).
2235 initialize = factory()->NewCallRuntime(
2236 isolate()->factory()->InitializeVarGlobal_string(),
2237 Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
2238 arguments, pos);
2239 }
2240
2241 block->AddStatement(
2242 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition),
2243 zone());
2244 } else if (needs_init) {
2245 // Constant initializations always assign to the declared constant which
2246 // is always at the function scope level. This is only relevant for
2247 // dynamically looked-up variables and constants (the start context for
2248 // constant lookups is always the function context, while it is the top
2249 // context for var declared variables). Sigh...
2250 // For 'let' and 'const' declared variables in harmony mode the
2251 // initialization also always assigns to the declared variable.
2252 ASSERT(proxy != NULL);
2253 ASSERT(proxy->var() != NULL);
2254 ASSERT(value != NULL);
2255 Assignment* assignment =
2256 factory()->NewAssignment(init_op, proxy, value, pos);
2257 block->AddStatement(
2258 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2259 zone());
2260 value = NULL;
2261 }
2262
2263 // Add an assignment node to the initialization statement block if we still
2264 // have a pending initialization value.
2265 if (value != NULL) {
2266 ASSERT(mode == VAR);
2267 // 'var' initializations are simply assignments (with all the consequences
2268 // if they are inside a 'with' statement - they may change a 'with' object
2269 // property).
2270 VariableProxy* proxy =
2271 initialization_scope->NewUnresolved(factory(), name, interface);
2272 Assignment* assignment =
2273 factory()->NewAssignment(init_op, proxy, value, pos);
2274 block->AddStatement(
2275 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
2276 zone());
2277 }
2278
2279 if (fni_ != NULL) fni_->Leave();
2280 } while (peek() == Token::COMMA);
2281
2282 // If there was a single non-const declaration, return it in the output
2283 // parameter for possible use by for/in.
2284 if (nvars == 1 && !is_const) {
2285 *out = name;
2286 }
2287
2288 return block;
2289 }
2290
2291
ContainsLabel(ZoneStringList * labels,Handle<String> label)2292 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) {
2293 ASSERT(!label.is_null());
2294 if (labels != NULL) {
2295 for (int i = labels->length(); i-- > 0; ) {
2296 if (labels->at(i).is_identical_to(label)) {
2297 return true;
2298 }
2299 }
2300 }
2301 return false;
2302 }
2303
2304
ParseExpressionOrLabelledStatement(ZoneStringList * labels,bool * ok)2305 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
2306 bool* ok) {
2307 // ExpressionStatement | LabelledStatement ::
2308 // Expression ';'
2309 // Identifier ':' Statement
2310 int pos = peek_position();
2311 bool starts_with_idenfifier = peek_any_identifier();
2312 Expression* expr = ParseExpression(true, CHECK_OK);
2313 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2314 expr->AsVariableProxy() != NULL &&
2315 !expr->AsVariableProxy()->is_this()) {
2316 // Expression is a single identifier, and not, e.g., a parenthesized
2317 // identifier.
2318 VariableProxy* var = expr->AsVariableProxy();
2319 Handle<String> label = var->name();
2320 // TODO(1240780): We don't check for redeclaration of labels
2321 // during preparsing since keeping track of the set of active
2322 // labels requires nontrivial changes to the way scopes are
2323 // structured. However, these are probably changes we want to
2324 // make later anyway so we should go back and fix this then.
2325 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2326 ParserTraits::ReportMessage("label_redeclaration", label);
2327 *ok = false;
2328 return NULL;
2329 }
2330 if (labels == NULL) {
2331 labels = new(zone()) ZoneStringList(4, zone());
2332 }
2333 labels->Add(label, zone());
2334 // Remove the "ghost" variable that turned out to be a label
2335 // from the top scope. This way, we don't try to resolve it
2336 // during the scope processing.
2337 scope_->RemoveUnresolved(var);
2338 Expect(Token::COLON, CHECK_OK);
2339 return ParseStatement(labels, ok);
2340 }
2341
2342 // If we have an extension, we allow a native function declaration.
2343 // A native function declaration starts with "native function" with
2344 // no line-terminator between the two words.
2345 if (extension_ != NULL &&
2346 peek() == Token::FUNCTION &&
2347 !scanner()->HasAnyLineTerminatorBeforeNext() &&
2348 expr != NULL &&
2349 expr->AsVariableProxy() != NULL &&
2350 String::Equals(isolate()->factory()->native_string(),
2351 expr->AsVariableProxy()->name()) &&
2352 !scanner()->literal_contains_escapes()) {
2353 return ParseNativeDeclaration(ok);
2354 }
2355
2356 // Parsed expression statement, or the context-sensitive 'module' keyword.
2357 // Only expect semicolon in the former case.
2358 if (!FLAG_harmony_modules ||
2359 peek() != Token::IDENTIFIER ||
2360 scanner()->HasAnyLineTerminatorBeforeNext() ||
2361 expr->AsVariableProxy() == NULL ||
2362 !String::Equals(isolate()->factory()->module_string(),
2363 expr->AsVariableProxy()->name()) ||
2364 scanner()->literal_contains_escapes()) {
2365 ExpectSemicolon(CHECK_OK);
2366 }
2367 return factory()->NewExpressionStatement(expr, pos);
2368 }
2369
2370
ParseIfStatement(ZoneStringList * labels,bool * ok)2371 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) {
2372 // IfStatement ::
2373 // 'if' '(' Expression ')' Statement ('else' Statement)?
2374
2375 int pos = peek_position();
2376 Expect(Token::IF, CHECK_OK);
2377 Expect(Token::LPAREN, CHECK_OK);
2378 Expression* condition = ParseExpression(true, CHECK_OK);
2379 Expect(Token::RPAREN, CHECK_OK);
2380 Statement* then_statement = ParseStatement(labels, CHECK_OK);
2381 Statement* else_statement = NULL;
2382 if (peek() == Token::ELSE) {
2383 Next();
2384 else_statement = ParseStatement(labels, CHECK_OK);
2385 } else {
2386 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2387 }
2388 return factory()->NewIfStatement(
2389 condition, then_statement, else_statement, pos);
2390 }
2391
2392
ParseContinueStatement(bool * ok)2393 Statement* Parser::ParseContinueStatement(bool* ok) {
2394 // ContinueStatement ::
2395 // 'continue' Identifier? ';'
2396
2397 int pos = peek_position();
2398 Expect(Token::CONTINUE, CHECK_OK);
2399 Handle<String> label = Handle<String>::null();
2400 Token::Value tok = peek();
2401 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2402 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2403 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2404 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2405 }
2406 IterationStatement* target = NULL;
2407 target = LookupContinueTarget(label, CHECK_OK);
2408 if (target == NULL) {
2409 // Illegal continue statement.
2410 const char* message = "illegal_continue";
2411 if (!label.is_null()) {
2412 message = "unknown_label";
2413 }
2414 ParserTraits::ReportMessage(message, label);
2415 *ok = false;
2416 return NULL;
2417 }
2418 ExpectSemicolon(CHECK_OK);
2419 return factory()->NewContinueStatement(target, pos);
2420 }
2421
2422
ParseBreakStatement(ZoneStringList * labels,bool * ok)2423 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
2424 // BreakStatement ::
2425 // 'break' Identifier? ';'
2426
2427 int pos = peek_position();
2428 Expect(Token::BREAK, CHECK_OK);
2429 Handle<String> label;
2430 Token::Value tok = peek();
2431 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2432 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2433 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2434 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
2435 }
2436 // Parse labeled break statements that target themselves into
2437 // empty statements, e.g. 'l1: l2: l3: break l2;'
2438 if (!label.is_null() && ContainsLabel(labels, label)) {
2439 ExpectSemicolon(CHECK_OK);
2440 return factory()->NewEmptyStatement(pos);
2441 }
2442 BreakableStatement* target = NULL;
2443 target = LookupBreakTarget(label, CHECK_OK);
2444 if (target == NULL) {
2445 // Illegal break statement.
2446 const char* message = "illegal_break";
2447 if (!label.is_null()) {
2448 message = "unknown_label";
2449 }
2450 ParserTraits::ReportMessage(message, label);
2451 *ok = false;
2452 return NULL;
2453 }
2454 ExpectSemicolon(CHECK_OK);
2455 return factory()->NewBreakStatement(target, pos);
2456 }
2457
2458
ParseReturnStatement(bool * ok)2459 Statement* Parser::ParseReturnStatement(bool* ok) {
2460 // ReturnStatement ::
2461 // 'return' Expression? ';'
2462
2463 // Consume the return token. It is necessary to do that before
2464 // reporting any errors on it, because of the way errors are
2465 // reported (underlining).
2466 Expect(Token::RETURN, CHECK_OK);
2467 Scanner::Location loc = scanner()->location();
2468
2469 Token::Value tok = peek();
2470 Statement* result;
2471 Expression* return_value;
2472 if (scanner()->HasAnyLineTerminatorBeforeNext() ||
2473 tok == Token::SEMICOLON ||
2474 tok == Token::RBRACE ||
2475 tok == Token::EOS) {
2476 return_value = GetLiteralUndefined(position());
2477 } else {
2478 return_value = ParseExpression(true, CHECK_OK);
2479 }
2480 ExpectSemicolon(CHECK_OK);
2481 if (is_generator()) {
2482 Expression* generator = factory()->NewVariableProxy(
2483 function_state_->generator_object_variable());
2484 Expression* yield = factory()->NewYield(
2485 generator, return_value, Yield::FINAL, loc.beg_pos);
2486 result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2487 } else {
2488 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2489 }
2490
2491 Scope* decl_scope = scope_->DeclarationScope();
2492 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) {
2493 ReportMessageAt(loc, "illegal_return");
2494 *ok = false;
2495 return NULL;
2496 }
2497 return result;
2498 }
2499
2500
ParseWithStatement(ZoneStringList * labels,bool * ok)2501 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
2502 // WithStatement ::
2503 // 'with' '(' Expression ')' Statement
2504
2505 Expect(Token::WITH, CHECK_OK);
2506 int pos = position();
2507
2508 if (strict_mode() == STRICT) {
2509 ReportMessage("strict_mode_with");
2510 *ok = false;
2511 return NULL;
2512 }
2513
2514 Expect(Token::LPAREN, CHECK_OK);
2515 Expression* expr = ParseExpression(true, CHECK_OK);
2516 Expect(Token::RPAREN, CHECK_OK);
2517
2518 scope_->DeclarationScope()->RecordWithStatement();
2519 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
2520 Statement* stmt;
2521 { BlockState block_state(&scope_, with_scope);
2522 with_scope->set_start_position(scanner()->peek_location().beg_pos);
2523 stmt = ParseStatement(labels, CHECK_OK);
2524 with_scope->set_end_position(scanner()->location().end_pos);
2525 }
2526 return factory()->NewWithStatement(with_scope, expr, stmt, pos);
2527 }
2528
2529
ParseCaseClause(bool * default_seen_ptr,bool * ok)2530 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2531 // CaseClause ::
2532 // 'case' Expression ':' Statement*
2533 // 'default' ':' Statement*
2534
2535 Expression* label = NULL; // NULL expression indicates default case
2536 if (peek() == Token::CASE) {
2537 Expect(Token::CASE, CHECK_OK);
2538 label = ParseExpression(true, CHECK_OK);
2539 } else {
2540 Expect(Token::DEFAULT, CHECK_OK);
2541 if (*default_seen_ptr) {
2542 ReportMessage("multiple_defaults_in_switch");
2543 *ok = false;
2544 return NULL;
2545 }
2546 *default_seen_ptr = true;
2547 }
2548 Expect(Token::COLON, CHECK_OK);
2549 int pos = position();
2550 ZoneList<Statement*>* statements =
2551 new(zone()) ZoneList<Statement*>(5, zone());
2552 while (peek() != Token::CASE &&
2553 peek() != Token::DEFAULT &&
2554 peek() != Token::RBRACE) {
2555 Statement* stat = ParseStatement(NULL, CHECK_OK);
2556 statements->Add(stat, zone());
2557 }
2558
2559 return factory()->NewCaseClause(label, statements, pos);
2560 }
2561
2562
ParseSwitchStatement(ZoneStringList * labels,bool * ok)2563 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
2564 bool* ok) {
2565 // SwitchStatement ::
2566 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2567
2568 SwitchStatement* statement =
2569 factory()->NewSwitchStatement(labels, peek_position());
2570 Target target(&this->target_stack_, statement);
2571
2572 Expect(Token::SWITCH, CHECK_OK);
2573 Expect(Token::LPAREN, CHECK_OK);
2574 Expression* tag = ParseExpression(true, CHECK_OK);
2575 Expect(Token::RPAREN, CHECK_OK);
2576
2577 bool default_seen = false;
2578 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone());
2579 Expect(Token::LBRACE, CHECK_OK);
2580 while (peek() != Token::RBRACE) {
2581 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
2582 cases->Add(clause, zone());
2583 }
2584 Expect(Token::RBRACE, CHECK_OK);
2585
2586 if (statement) statement->Initialize(tag, cases);
2587 return statement;
2588 }
2589
2590
ParseThrowStatement(bool * ok)2591 Statement* Parser::ParseThrowStatement(bool* ok) {
2592 // ThrowStatement ::
2593 // 'throw' Expression ';'
2594
2595 Expect(Token::THROW, CHECK_OK);
2596 int pos = position();
2597 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
2598 ReportMessage("newline_after_throw");
2599 *ok = false;
2600 return NULL;
2601 }
2602 Expression* exception = ParseExpression(true, CHECK_OK);
2603 ExpectSemicolon(CHECK_OK);
2604
2605 return factory()->NewExpressionStatement(
2606 factory()->NewThrow(exception, pos), pos);
2607 }
2608
2609
ParseTryStatement(bool * ok)2610 TryStatement* Parser::ParseTryStatement(bool* ok) {
2611 // TryStatement ::
2612 // 'try' Block Catch
2613 // 'try' Block Finally
2614 // 'try' Block Catch Finally
2615 //
2616 // Catch ::
2617 // 'catch' '(' Identifier ')' Block
2618 //
2619 // Finally ::
2620 // 'finally' Block
2621
2622 Expect(Token::TRY, CHECK_OK);
2623 int pos = position();
2624
2625 TargetCollector try_collector(zone());
2626 Block* try_block;
2627
2628 { Target target(&this->target_stack_, &try_collector);
2629 try_block = ParseBlock(NULL, CHECK_OK);
2630 }
2631
2632 Token::Value tok = peek();
2633 if (tok != Token::CATCH && tok != Token::FINALLY) {
2634 ReportMessage("no_catch_or_finally");
2635 *ok = false;
2636 return NULL;
2637 }
2638
2639 // If we can break out from the catch block and there is a finally block,
2640 // then we will need to collect escaping targets from the catch
2641 // block. Since we don't know yet if there will be a finally block, we
2642 // always collect the targets.
2643 TargetCollector catch_collector(zone());
2644 Scope* catch_scope = NULL;
2645 Variable* catch_variable = NULL;
2646 Block* catch_block = NULL;
2647 Handle<String> name;
2648 if (tok == Token::CATCH) {
2649 Consume(Token::CATCH);
2650
2651 Expect(Token::LPAREN, CHECK_OK);
2652 catch_scope = NewScope(scope_, CATCH_SCOPE);
2653 catch_scope->set_start_position(scanner()->location().beg_pos);
2654 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
2655
2656 Expect(Token::RPAREN, CHECK_OK);
2657
2658 Target target(&this->target_stack_, &catch_collector);
2659 VariableMode mode =
2660 allow_harmony_scoping() && strict_mode() == STRICT ? LET : VAR;
2661 catch_variable =
2662 catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
2663
2664 BlockState block_state(&scope_, catch_scope);
2665 catch_block = ParseBlock(NULL, CHECK_OK);
2666
2667 catch_scope->set_end_position(scanner()->location().end_pos);
2668 tok = peek();
2669 }
2670
2671 Block* finally_block = NULL;
2672 ASSERT(tok == Token::FINALLY || catch_block != NULL);
2673 if (tok == Token::FINALLY) {
2674 Consume(Token::FINALLY);
2675 finally_block = ParseBlock(NULL, CHECK_OK);
2676 }
2677
2678 // Simplify the AST nodes by converting:
2679 // 'try B0 catch B1 finally B2'
2680 // to:
2681 // 'try { try B0 catch B1 } finally B2'
2682
2683 if (catch_block != NULL && finally_block != NULL) {
2684 // If we have both, create an inner try/catch.
2685 ASSERT(catch_scope != NULL && catch_variable != NULL);
2686 int index = function_state_->NextHandlerIndex();
2687 TryCatchStatement* statement = factory()->NewTryCatchStatement(
2688 index, try_block, catch_scope, catch_variable, catch_block,
2689 RelocInfo::kNoPosition);
2690 statement->set_escaping_targets(try_collector.targets());
2691 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
2692 try_block->AddStatement(statement, zone());
2693 catch_block = NULL; // Clear to indicate it's been handled.
2694 }
2695
2696 TryStatement* result = NULL;
2697 if (catch_block != NULL) {
2698 ASSERT(finally_block == NULL);
2699 ASSERT(catch_scope != NULL && catch_variable != NULL);
2700 int index = function_state_->NextHandlerIndex();
2701 result = factory()->NewTryCatchStatement(
2702 index, try_block, catch_scope, catch_variable, catch_block, pos);
2703 } else {
2704 ASSERT(finally_block != NULL);
2705 int index = function_state_->NextHandlerIndex();
2706 result = factory()->NewTryFinallyStatement(
2707 index, try_block, finally_block, pos);
2708 // Combine the jump targets of the try block and the possible catch block.
2709 try_collector.targets()->AddAll(*catch_collector.targets(), zone());
2710 }
2711
2712 result->set_escaping_targets(try_collector.targets());
2713 return result;
2714 }
2715
2716
ParseDoWhileStatement(ZoneStringList * labels,bool * ok)2717 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
2718 bool* ok) {
2719 // DoStatement ::
2720 // 'do' Statement 'while' '(' Expression ')' ';'
2721
2722 DoWhileStatement* loop =
2723 factory()->NewDoWhileStatement(labels, peek_position());
2724 Target target(&this->target_stack_, loop);
2725
2726 Expect(Token::DO, CHECK_OK);
2727 Statement* body = ParseStatement(NULL, CHECK_OK);
2728 Expect(Token::WHILE, CHECK_OK);
2729 Expect(Token::LPAREN, CHECK_OK);
2730
2731 Expression* cond = ParseExpression(true, CHECK_OK);
2732 Expect(Token::RPAREN, CHECK_OK);
2733
2734 // Allow do-statements to be terminated with and without
2735 // semi-colons. This allows code such as 'do;while(0)return' to
2736 // parse, which would not be the case if we had used the
2737 // ExpectSemicolon() functionality here.
2738 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2739
2740 if (loop != NULL) loop->Initialize(cond, body);
2741 return loop;
2742 }
2743
2744
ParseWhileStatement(ZoneStringList * labels,bool * ok)2745 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
2746 // WhileStatement ::
2747 // 'while' '(' Expression ')' Statement
2748
2749 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
2750 Target target(&this->target_stack_, loop);
2751
2752 Expect(Token::WHILE, CHECK_OK);
2753 Expect(Token::LPAREN, CHECK_OK);
2754 Expression* cond = ParseExpression(true, CHECK_OK);
2755 Expect(Token::RPAREN, CHECK_OK);
2756 Statement* body = ParseStatement(NULL, CHECK_OK);
2757
2758 if (loop != NULL) loop->Initialize(cond, body);
2759 return loop;
2760 }
2761
2762
CheckInOrOf(bool accept_OF,ForEachStatement::VisitMode * visit_mode)2763 bool Parser::CheckInOrOf(bool accept_OF,
2764 ForEachStatement::VisitMode* visit_mode) {
2765 if (Check(Token::IN)) {
2766 *visit_mode = ForEachStatement::ENUMERATE;
2767 return true;
2768 } else if (allow_for_of() && accept_OF &&
2769 CheckContextualKeyword(CStrVector("of"))) {
2770 *visit_mode = ForEachStatement::ITERATE;
2771 return true;
2772 }
2773 return false;
2774 }
2775
2776
InitializeForEachStatement(ForEachStatement * stmt,Expression * each,Expression * subject,Statement * body)2777 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
2778 Expression* each,
2779 Expression* subject,
2780 Statement* body) {
2781 ForOfStatement* for_of = stmt->AsForOfStatement();
2782
2783 if (for_of != NULL) {
2784 Factory* heap_factory = isolate()->factory();
2785 Variable* iterable = scope_->DeclarationScope()->NewTemporary(
2786 heap_factory->dot_iterable_string());
2787 Variable* iterator = scope_->DeclarationScope()->NewTemporary(
2788 heap_factory->dot_iterator_string());
2789 Variable* result = scope_->DeclarationScope()->NewTemporary(
2790 heap_factory->dot_result_string());
2791
2792 Expression* assign_iterable;
2793 Expression* assign_iterator;
2794 Expression* next_result;
2795 Expression* result_done;
2796 Expression* assign_each;
2797
2798 // var iterable = subject;
2799 {
2800 Expression* iterable_proxy = factory()->NewVariableProxy(iterable);
2801 assign_iterable = factory()->NewAssignment(
2802 Token::ASSIGN, iterable_proxy, subject, subject->position());
2803 }
2804
2805 // var iterator = iterable[Symbol.iterator]();
2806 {
2807 Expression* iterable_proxy = factory()->NewVariableProxy(iterable);
2808 Handle<Symbol> iterator_symbol(
2809 isolate()->native_context()->iterator_symbol(), isolate());
2810 Expression* iterator_symbol_literal = factory()->NewLiteral(
2811 iterator_symbol, RelocInfo::kNoPosition);
2812 // FIXME(wingo): Unhappily, it will be a common error that the RHS of a
2813 // for-of doesn't have a Symbol.iterator property. We should do better
2814 // than informing the user that "undefined is not a function".
2815 int pos = subject->position();
2816 Expression* iterator_property = factory()->NewProperty(
2817 iterable_proxy, iterator_symbol_literal, pos);
2818 ZoneList<Expression*>* iterator_arguments =
2819 new(zone()) ZoneList<Expression*>(0, zone());
2820 Expression* iterator_call = factory()->NewCall(
2821 iterator_property, iterator_arguments, pos);
2822 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2823 assign_iterator = factory()->NewAssignment(
2824 Token::ASSIGN, iterator_proxy, iterator_call, RelocInfo::kNoPosition);
2825 }
2826
2827 // var result = iterator.next();
2828 {
2829 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2830 Expression* next_literal = factory()->NewLiteral(
2831 heap_factory->next_string(), RelocInfo::kNoPosition);
2832 Expression* next_property = factory()->NewProperty(
2833 iterator_proxy, next_literal, RelocInfo::kNoPosition);
2834 ZoneList<Expression*>* next_arguments =
2835 new(zone()) ZoneList<Expression*>(0, zone());
2836 Expression* next_call = factory()->NewCall(
2837 next_property, next_arguments, RelocInfo::kNoPosition);
2838 Expression* result_proxy = factory()->NewVariableProxy(result);
2839 next_result = factory()->NewAssignment(
2840 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition);
2841 }
2842
2843 // result.done
2844 {
2845 Expression* done_literal = factory()->NewLiteral(
2846 heap_factory->done_string(), RelocInfo::kNoPosition);
2847 Expression* result_proxy = factory()->NewVariableProxy(result);
2848 result_done = factory()->NewProperty(
2849 result_proxy, done_literal, RelocInfo::kNoPosition);
2850 }
2851
2852 // each = result.value
2853 {
2854 Expression* value_literal = factory()->NewLiteral(
2855 heap_factory->value_string(), RelocInfo::kNoPosition);
2856 Expression* result_proxy = factory()->NewVariableProxy(result);
2857 Expression* result_value = factory()->NewProperty(
2858 result_proxy, value_literal, RelocInfo::kNoPosition);
2859 assign_each = factory()->NewAssignment(
2860 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition);
2861 }
2862
2863 for_of->Initialize(each, subject, body,
2864 assign_iterable,
2865 assign_iterator,
2866 next_result,
2867 result_done,
2868 assign_each);
2869 } else {
2870 stmt->Initialize(each, subject, body);
2871 }
2872 }
2873
2874
DesugarLetBindingsInForStatement(Scope * inner_scope,ZoneStringList * names,ForStatement * loop,Statement * init,Expression * cond,Statement * next,Statement * body,bool * ok)2875 Statement* Parser::DesugarLetBindingsInForStatement(
2876 Scope* inner_scope, ZoneStringList* names, ForStatement* loop,
2877 Statement* init, Expression* cond, Statement* next, Statement* body,
2878 bool* ok) {
2879 // ES6 13.6.3.4 specifies that on each loop iteration the let variables are
2880 // copied into a new environment. After copying, the "next" statement of the
2881 // loop is executed to update the loop variables. The loop condition is
2882 // checked and the loop body is executed.
2883 //
2884 // We rewrite a for statement of the form
2885 //
2886 // for (let x = i; cond; next) body
2887 //
2888 // into
2889 //
2890 // {
2891 // let x = i;
2892 // temp_x = x;
2893 // flag = 1;
2894 // for (;;) {
2895 // let x = temp_x;
2896 // if (flag == 1) {
2897 // flag = 0;
2898 // } else {
2899 // next;
2900 // }
2901 // if (cond) {
2902 // <empty>
2903 // } else {
2904 // break;
2905 // }
2906 // b
2907 // temp_x = x;
2908 // }
2909 // }
2910
2911 ASSERT(names->length() > 0);
2912 Scope* for_scope = scope_;
2913 ZoneList<Variable*> temps(names->length(), zone());
2914
2915 Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false,
2916 RelocInfo::kNoPosition);
2917 outer_block->AddStatement(init, zone());
2918
2919 Handle<String> temp_name = isolate()->factory()->dot_for_string();
2920 Handle<Smi> smi0 = handle(Smi::FromInt(0), isolate());
2921 Handle<Smi> smi1 = handle(Smi::FromInt(1), isolate());
2922
2923
2924 // For each let variable x:
2925 // make statement: temp_x = x.
2926 for (int i = 0; i < names->length(); i++) {
2927 VariableProxy* proxy =
2928 NewUnresolved(names->at(i), LET, Interface::NewValue());
2929 Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name);
2930 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2931 Assignment* assignment = factory()->NewAssignment(
2932 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
2933 Statement* assignment_statement = factory()->NewExpressionStatement(
2934 assignment, RelocInfo::kNoPosition);
2935 outer_block->AddStatement(assignment_statement, zone());
2936 temps.Add(temp, zone());
2937 }
2938
2939 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
2940 // Make statement: flag = 1.
2941 {
2942 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2943 Expression* const1 = factory()->NewLiteral(smi1, RelocInfo::kNoPosition);
2944 Assignment* assignment = factory()->NewAssignment(
2945 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
2946 Statement* assignment_statement = factory()->NewExpressionStatement(
2947 assignment, RelocInfo::kNoPosition);
2948 outer_block->AddStatement(assignment_statement, zone());
2949 }
2950
2951 outer_block->AddStatement(loop, zone());
2952 outer_block->set_scope(for_scope);
2953 scope_ = inner_scope;
2954
2955 Block* inner_block = factory()->NewBlock(NULL, 2 * names->length() + 3,
2956 false, RelocInfo::kNoPosition);
2957 int pos = scanner()->location().beg_pos;
2958 ZoneList<Variable*> inner_vars(names->length(), zone());
2959
2960 // For each let variable x:
2961 // make statement: let x = temp_x.
2962 for (int i = 0; i < names->length(); i++) {
2963 VariableProxy* proxy =
2964 NewUnresolved(names->at(i), LET, Interface::NewValue());
2965 Declaration* declaration =
2966 factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
2967 Declare(declaration, true, CHECK_OK);
2968 inner_vars.Add(declaration->proxy()->var(), zone());
2969 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2970 Assignment* assignment = factory()->NewAssignment(
2971 Token::INIT_LET, proxy, temp_proxy, pos);
2972 Statement* assignment_statement = factory()->NewExpressionStatement(
2973 assignment, pos);
2974 proxy->var()->set_initializer_position(pos);
2975 inner_block->AddStatement(assignment_statement, zone());
2976 }
2977
2978 // Make statement: if (flag == 1) { flag = 0; } else { next; }.
2979 {
2980 Expression* compare = NULL;
2981 // Make compare expresion: flag == 1.
2982 {
2983 Expression* const1 = factory()->NewLiteral(smi1, RelocInfo::kNoPosition);
2984 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2985 compare = factory()->NewCompareOperation(
2986 Token::EQ, flag_proxy, const1, pos);
2987 }
2988 Statement* clear_flag = NULL;
2989 // Make statement: flag = 0.
2990 {
2991 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2992 Expression* const0 = factory()->NewLiteral(smi0, RelocInfo::kNoPosition);
2993 Assignment* assignment = factory()->NewAssignment(
2994 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition);
2995 clear_flag = factory()->NewExpressionStatement(assignment, pos);
2996 }
2997 Statement* clear_flag_or_next = factory()->NewIfStatement(
2998 compare, clear_flag, next, RelocInfo::kNoPosition);
2999 inner_block->AddStatement(clear_flag_or_next, zone());
3000 }
3001
3002
3003 // Make statement: if (cond) { } else { break; }.
3004 {
3005 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
3006 BreakableStatement* t = LookupBreakTarget(Handle<String>(), CHECK_OK);
3007 Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition);
3008 Statement* if_not_cond_break = factory()->NewIfStatement(
3009 cond, empty, stop, cond->position());
3010 inner_block->AddStatement(if_not_cond_break, zone());
3011 }
3012
3013 inner_block->AddStatement(body, zone());
3014
3015 // For each let variable x:
3016 // make statement: temp_x = x;
3017 for (int i = 0; i < names->length(); i++) {
3018 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3019 int pos = scanner()->location().end_pos;
3020 VariableProxy* proxy = factory()->NewVariableProxy(inner_vars.at(i), pos);
3021 Assignment* assignment = factory()->NewAssignment(
3022 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3023 Statement* assignment_statement = factory()->NewExpressionStatement(
3024 assignment, RelocInfo::kNoPosition);
3025 inner_block->AddStatement(assignment_statement, zone());
3026 }
3027
3028 inner_scope->set_end_position(scanner()->location().end_pos);
3029 inner_block->set_scope(inner_scope);
3030 scope_ = for_scope;
3031
3032 loop->Initialize(NULL, NULL, NULL, inner_block);
3033 return outer_block;
3034 }
3035
3036
ParseForStatement(ZoneStringList * labels,bool * ok)3037 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
3038 // ForStatement ::
3039 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3040
3041 int pos = peek_position();
3042 Statement* init = NULL;
3043 ZoneStringList let_bindings(1, zone());
3044
3045 // Create an in-between scope for let-bound iteration variables.
3046 Scope* saved_scope = scope_;
3047 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3048 scope_ = for_scope;
3049
3050 Expect(Token::FOR, CHECK_OK);
3051 Expect(Token::LPAREN, CHECK_OK);
3052 for_scope->set_start_position(scanner()->location().beg_pos);
3053 if (peek() != Token::SEMICOLON) {
3054 if (peek() == Token::VAR || peek() == Token::CONST) {
3055 bool is_const = peek() == Token::CONST;
3056 Handle<String> name;
3057 VariableDeclarationProperties decl_props = kHasNoInitializers;
3058 Block* variable_statement =
3059 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
3060 CHECK_OK);
3061 bool accept_OF = decl_props == kHasNoInitializers;
3062 ForEachStatement::VisitMode mode;
3063
3064 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) {
3065 Interface* interface =
3066 is_const ? Interface::NewConst() : Interface::NewValue();
3067 ForEachStatement* loop =
3068 factory()->NewForEachStatement(mode, labels, pos);
3069 Target target(&this->target_stack_, loop);
3070
3071 Expression* enumerable = ParseExpression(true, CHECK_OK);
3072 Expect(Token::RPAREN, CHECK_OK);
3073
3074 VariableProxy* each =
3075 scope_->NewUnresolved(factory(), name, interface);
3076 Statement* body = ParseStatement(NULL, CHECK_OK);
3077 InitializeForEachStatement(loop, each, enumerable, body);
3078 Block* result =
3079 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3080 result->AddStatement(variable_statement, zone());
3081 result->AddStatement(loop, zone());
3082 scope_ = saved_scope;
3083 for_scope->set_end_position(scanner()->location().end_pos);
3084 for_scope = for_scope->FinalizeBlockScope();
3085 ASSERT(for_scope == NULL);
3086 // Parsed for-in loop w/ variable/const declaration.
3087 return result;
3088 } else {
3089 init = variable_statement;
3090 }
3091 } else if (peek() == Token::LET) {
3092 Handle<String> name;
3093 VariableDeclarationProperties decl_props = kHasNoInitializers;
3094 Block* variable_statement =
3095 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings,
3096 &name, CHECK_OK);
3097 bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
3098 bool accept_OF = decl_props == kHasNoInitializers;
3099 ForEachStatement::VisitMode mode;
3100
3101 if (accept_IN && CheckInOrOf(accept_OF, &mode)) {
3102 // Rewrite a for-in statement of the form
3103 //
3104 // for (let x in e) b
3105 //
3106 // into
3107 //
3108 // <let x' be a temporary variable>
3109 // for (x' in e) {
3110 // let x;
3111 // x = x';
3112 // b;
3113 // }
3114
3115 // TODO(keuchel): Move the temporary variable to the block scope, after
3116 // implementing stack allocated block scoped variables.
3117 Factory* heap_factory = isolate()->factory();
3118 Handle<String> tempstr;
3119 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
3120 isolate(), tempstr,
3121 heap_factory->NewConsString(heap_factory->dot_for_string(), name),
3122 0);
3123 Handle<String> tempname = heap_factory->InternalizeString(tempstr);
3124 Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname);
3125 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3126 ForEachStatement* loop =
3127 factory()->NewForEachStatement(mode, labels, pos);
3128 Target target(&this->target_stack_, loop);
3129
3130 // The expression does not see the loop variable.
3131 scope_ = saved_scope;
3132 Expression* enumerable = ParseExpression(true, CHECK_OK);
3133 scope_ = for_scope;
3134 Expect(Token::RPAREN, CHECK_OK);
3135
3136 VariableProxy* each =
3137 scope_->NewUnresolved(factory(), name, Interface::NewValue());
3138 Statement* body = ParseStatement(NULL, CHECK_OK);
3139 Block* body_block =
3140 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3141 Assignment* assignment = factory()->NewAssignment(
3142 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
3143 Statement* assignment_statement = factory()->NewExpressionStatement(
3144 assignment, RelocInfo::kNoPosition);
3145 body_block->AddStatement(variable_statement, zone());
3146 body_block->AddStatement(assignment_statement, zone());
3147 body_block->AddStatement(body, zone());
3148 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block);
3149 scope_ = saved_scope;
3150 for_scope->set_end_position(scanner()->location().end_pos);
3151 for_scope = for_scope->FinalizeBlockScope();
3152 body_block->set_scope(for_scope);
3153 // Parsed for-in loop w/ let declaration.
3154 return loop;
3155
3156 } else {
3157 init = variable_statement;
3158 }
3159 } else {
3160 Scanner::Location lhs_location = scanner()->peek_location();
3161 Expression* expression = ParseExpression(false, CHECK_OK);
3162 ForEachStatement::VisitMode mode;
3163 bool accept_OF = expression->AsVariableProxy();
3164
3165 if (CheckInOrOf(accept_OF, &mode)) {
3166 expression = this->CheckAndRewriteReferenceExpression(
3167 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
3168
3169 ForEachStatement* loop =
3170 factory()->NewForEachStatement(mode, labels, pos);
3171 Target target(&this->target_stack_, loop);
3172
3173 Expression* enumerable = ParseExpression(true, CHECK_OK);
3174 Expect(Token::RPAREN, CHECK_OK);
3175
3176 Statement* body = ParseStatement(NULL, CHECK_OK);
3177 InitializeForEachStatement(loop, expression, enumerable, body);
3178 scope_ = saved_scope;
3179 for_scope->set_end_position(scanner()->location().end_pos);
3180 for_scope = for_scope->FinalizeBlockScope();
3181 ASSERT(for_scope == NULL);
3182 // Parsed for-in loop.
3183 return loop;
3184
3185 } else {
3186 init = factory()->NewExpressionStatement(
3187 expression, RelocInfo::kNoPosition);
3188 }
3189 }
3190 }
3191
3192 // Standard 'for' loop
3193 ForStatement* loop = factory()->NewForStatement(labels, pos);
3194 Target target(&this->target_stack_, loop);
3195
3196 // Parsed initializer at this point.
3197 Expect(Token::SEMICOLON, CHECK_OK);
3198
3199 // If there are let bindings, then condition and the next statement of the
3200 // for loop must be parsed in a new scope.
3201 Scope* inner_scope = NULL;
3202 if (let_bindings.length() > 0) {
3203 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3204 inner_scope->set_start_position(scanner()->location().beg_pos);
3205 scope_ = inner_scope;
3206 }
3207
3208 Expression* cond = NULL;
3209 if (peek() != Token::SEMICOLON) {
3210 cond = ParseExpression(true, CHECK_OK);
3211 }
3212 Expect(Token::SEMICOLON, CHECK_OK);
3213
3214 Statement* next = NULL;
3215 if (peek() != Token::RPAREN) {
3216 Expression* exp = ParseExpression(true, CHECK_OK);
3217 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition);
3218 }
3219 Expect(Token::RPAREN, CHECK_OK);
3220
3221 Statement* body = ParseStatement(NULL, CHECK_OK);
3222
3223 Statement* result = NULL;
3224 if (let_bindings.length() > 0) {
3225 scope_ = for_scope;
3226 result = DesugarLetBindingsInForStatement(inner_scope, &let_bindings, loop,
3227 init, cond, next, body, CHECK_OK);
3228 scope_ = saved_scope;
3229 for_scope->set_end_position(scanner()->location().end_pos);
3230 } else {
3231 loop->Initialize(init, cond, next, body);
3232 result = loop;
3233 scope_ = saved_scope;
3234 for_scope->set_end_position(scanner()->location().end_pos);
3235 for_scope->FinalizeBlockScope();
3236 }
3237 return result;
3238 }
3239
3240
ParseDebuggerStatement(bool * ok)3241 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3242 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3243 // contexts this is used as a statement which invokes the debugger as i a
3244 // break point is present.
3245 // DebuggerStatement ::
3246 // 'debugger' ';'
3247
3248 int pos = peek_position();
3249 Expect(Token::DEBUGGER, CHECK_OK);
3250 ExpectSemicolon(CHECK_OK);
3251 return factory()->NewDebuggerStatement(pos);
3252 }
3253
3254
ReportInvalidCachedData(Handle<String> name,bool * ok)3255 void Parser::ReportInvalidCachedData(Handle<String> name, bool* ok) {
3256 ParserTraits::ReportMessage("invalid_cached_data_function", name);
3257 *ok = false;
3258 }
3259
3260
IsCompileTimeValue(Expression * expression)3261 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3262 if (expression->IsLiteral()) return true;
3263 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3264 return lit != NULL && lit->is_simple();
3265 }
3266
3267
GetValue(Isolate * isolate,Expression * expression)3268 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
3269 Expression* expression) {
3270 Factory* factory = isolate->factory();
3271 ASSERT(IsCompileTimeValue(expression));
3272 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
3273 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3274 if (object_literal != NULL) {
3275 ASSERT(object_literal->is_simple());
3276 if (object_literal->fast_elements()) {
3277 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3278 } else {
3279 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3280 }
3281 result->set(kElementsSlot, *object_literal->constant_properties());
3282 } else {
3283 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3284 ASSERT(array_literal != NULL && array_literal->is_simple());
3285 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3286 result->set(kElementsSlot, *array_literal->constant_elements());
3287 }
3288 return result;
3289 }
3290
3291
GetLiteralType(Handle<FixedArray> value)3292 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType(
3293 Handle<FixedArray> value) {
3294 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3295 return static_cast<LiteralType>(literal_type->value());
3296 }
3297
3298
GetElements(Handle<FixedArray> value)3299 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3300 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3301 }
3302
3303
ParseFunctionLiteral(Handle<String> function_name,Scanner::Location function_name_location,bool name_is_strict_reserved,bool is_generator,int function_token_pos,FunctionLiteral::FunctionType function_type,FunctionLiteral::ArityRestriction arity_restriction,bool * ok)3304 FunctionLiteral* Parser::ParseFunctionLiteral(
3305 Handle<String> function_name,
3306 Scanner::Location function_name_location,
3307 bool name_is_strict_reserved,
3308 bool is_generator,
3309 int function_token_pos,
3310 FunctionLiteral::FunctionType function_type,
3311 FunctionLiteral::ArityRestriction arity_restriction,
3312 bool* ok) {
3313 // Function ::
3314 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3315 //
3316 // Getter ::
3317 // '(' ')' '{' FunctionBody '}'
3318 //
3319 // Setter ::
3320 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
3321
3322 int pos = function_token_pos == RelocInfo::kNoPosition
3323 ? peek_position() : function_token_pos;
3324
3325 // Anonymous functions were passed either the empty symbol or a null
3326 // handle as the function name. Remember if we were passed a non-empty
3327 // handle to decide whether to invoke function name inference.
3328 bool should_infer_name = function_name.is_null();
3329
3330 // We want a non-null handle as the function name.
3331 if (should_infer_name) {
3332 function_name = isolate()->factory()->empty_string();
3333 }
3334
3335 int num_parameters = 0;
3336 // Function declarations are function scoped in normal mode, so they are
3337 // hoisted. In harmony block scoping mode they are block scoped, so they
3338 // are not hoisted.
3339 //
3340 // One tricky case are function declarations in a local sloppy-mode eval:
3341 // their declaration is hoisted, but they still see the local scope. E.g.,
3342 //
3343 // function() {
3344 // var x = 0
3345 // try { throw 1 } catch (x) { eval("function g() { return x }") }
3346 // return g()
3347 // }
3348 //
3349 // needs to return 1. To distinguish such cases, we need to detect
3350 // (1) whether a function stems from a sloppy eval, and
3351 // (2) whether it actually hoists across the eval.
3352 // Unfortunately, we do not represent sloppy eval scopes, so we do not have
3353 // either information available directly, especially not when lazily compiling
3354 // a function like 'g'. We hence rely on the following invariants:
3355 // - (1) is the case iff the innermost scope of the deserialized scope chain
3356 // under which we compile is _not_ a declaration scope. This holds because
3357 // in all normal cases, function declarations are fully hoisted to a
3358 // declaration scope and compiled relative to that.
3359 // - (2) is the case iff the current declaration scope is still the original
3360 // one relative to the deserialized scope chain. Otherwise we must be
3361 // compiling a function in an inner declaration scope in the eval, e.g. a
3362 // nested function, and hoisting works normally relative to that.
3363 Scope* declaration_scope = scope_->DeclarationScope();
3364 Scope* original_declaration_scope = original_scope_->DeclarationScope();
3365 Scope* scope =
3366 function_type == FunctionLiteral::DECLARATION &&
3367 (!allow_harmony_scoping() || strict_mode() == SLOPPY) &&
3368 (original_scope_ == original_declaration_scope ||
3369 declaration_scope != original_declaration_scope)
3370 ? NewScope(declaration_scope, FUNCTION_SCOPE)
3371 : NewScope(scope_, FUNCTION_SCOPE);
3372 ZoneList<Statement*>* body = NULL;
3373 int materialized_literal_count = -1;
3374 int expected_property_count = -1;
3375 int handler_count = 0;
3376 FunctionLiteral::ParameterFlag duplicate_parameters =
3377 FunctionLiteral::kNoDuplicateParameters;
3378 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
3379 ? FunctionLiteral::kIsParenthesized
3380 : FunctionLiteral::kNotParenthesized;
3381 AstProperties ast_properties;
3382 BailoutReason dont_optimize_reason = kNoReason;
3383 // Parse function body.
3384 { FunctionState function_state(&function_state_, &scope_, scope, zone());
3385 scope_->SetScopeName(function_name);
3386
3387 if (is_generator) {
3388 // For generators, allocating variables in contexts is currently a win
3389 // because it minimizes the work needed to suspend and resume an
3390 // activation.
3391 scope_->ForceContextAllocation();
3392
3393 // Calling a generator returns a generator object. That object is stored
3394 // in a temporary variable, a definition that is used by "yield"
3395 // expressions. This also marks the FunctionState as a generator.
3396 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3397 isolate()->factory()->dot_generator_object_string());
3398 function_state.set_generator_object_variable(temp);
3399 }
3400
3401 // FormalParameterList ::
3402 // '(' (Identifier)*[','] ')'
3403 Expect(Token::LPAREN, CHECK_OK);
3404 scope->set_start_position(scanner()->location().beg_pos);
3405
3406 // We don't yet know if the function will be strict, so we cannot yet
3407 // produce errors for parameter names or duplicates. However, we remember
3408 // the locations of these errors if they occur and produce the errors later.
3409 Scanner::Location eval_args_error_log = Scanner::Location::invalid();
3410 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
3411 Scanner::Location reserved_loc = Scanner::Location::invalid();
3412
3413 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
3414 (peek() == Token::RPAREN &&
3415 arity_restriction != FunctionLiteral::SETTER_ARITY);
3416 while (!done) {
3417 bool is_strict_reserved = false;
3418 Handle<String> param_name =
3419 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
3420
3421 // Store locations for possible future error reports.
3422 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) {
3423 eval_args_error_log = scanner()->location();
3424 }
3425 if (!reserved_loc.IsValid() && is_strict_reserved) {
3426 reserved_loc = scanner()->location();
3427 }
3428 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
3429 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3430 dupe_error_loc = scanner()->location();
3431 }
3432
3433 scope_->DeclareParameter(param_name, VAR);
3434 num_parameters++;
3435 if (num_parameters > Code::kMaxArguments) {
3436 ReportMessage("too_many_parameters");
3437 *ok = false;
3438 return NULL;
3439 }
3440 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
3441 done = (peek() == Token::RPAREN);
3442 if (!done) Expect(Token::COMMA, CHECK_OK);
3443 }
3444 Expect(Token::RPAREN, CHECK_OK);
3445
3446 Expect(Token::LBRACE, CHECK_OK);
3447
3448 // If we have a named function expression, we add a local variable
3449 // declaration to the body of the function with the name of the
3450 // function and let it refer to the function itself (closure).
3451 // NOTE: We create a proxy and resolve it here so that in the
3452 // future we can change the AST to only refer to VariableProxies
3453 // instead of Variables and Proxis as is the case now.
3454 Variable* fvar = NULL;
3455 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
3456 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
3457 if (allow_harmony_scoping() && strict_mode() == STRICT) {
3458 fvar_init_op = Token::INIT_CONST;
3459 }
3460 VariableMode fvar_mode =
3461 allow_harmony_scoping() && strict_mode() == STRICT ? CONST
3462 : CONST_LEGACY;
3463 fvar = new(zone()) Variable(scope_,
3464 function_name, fvar_mode, true /* is valid LHS */,
3465 Variable::NORMAL, kCreatedInitialized, Interface::NewConst());
3466 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
3467 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
3468 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
3469 scope_->DeclareFunctionVar(fvar_declaration);
3470 }
3471
3472 // Determine if the function can be parsed lazily. Lazy parsing is different
3473 // from lazy compilation; we need to parse more eagerly than we compile.
3474
3475 // We can only parse lazily if we also compile lazily. The heuristics for
3476 // lazy compilation are:
3477 // - It must not have been prohibited by the caller to Parse (some callers
3478 // need a full AST).
3479 // - The outer scope must allow lazy compilation of inner functions.
3480 // - The function mustn't be a function expression with an open parenthesis
3481 // before; we consider that a hint that the function will be called
3482 // immediately, and it would be a waste of time to make it lazily
3483 // compiled.
3484 // These are all things we can know at this point, without looking at the
3485 // function itself.
3486
3487 // In addition, we need to distinguish between these cases:
3488 // (function foo() {
3489 // bar = function() { return 1; }
3490 // })();
3491 // and
3492 // (function foo() {
3493 // var a = 1;
3494 // bar = function() { return a; }
3495 // })();
3496
3497 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
3498 // parenthesis before the function means that it will be called
3499 // immediately). The inner function *must* be parsed eagerly to resolve the
3500 // possible reference to the variable in foo's scope. However, it's possible
3501 // that it will be compiled lazily.
3502
3503 // To make this additional case work, both Parser and PreParser implement a
3504 // logic where only top-level functions will be parsed lazily.
3505 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
3506 scope_->AllowsLazyCompilation() &&
3507 !parenthesized_function_);
3508 parenthesized_function_ = false; // The bit was set for this function only.
3509
3510 if (is_lazily_parsed) {
3511 SkipLazyFunctionBody(function_name, &materialized_literal_count,
3512 &expected_property_count, CHECK_OK);
3513 } else {
3514 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
3515 is_generator, CHECK_OK);
3516 materialized_literal_count = function_state.materialized_literal_count();
3517 expected_property_count = function_state.expected_property_count();
3518 handler_count = function_state.handler_count();
3519 }
3520
3521 // Validate strict mode. We can do this only after parsing the function,
3522 // since the function can declare itself strict.
3523 if (strict_mode() == STRICT) {
3524 if (IsEvalOrArguments(function_name)) {
3525 ReportMessageAt(function_name_location, "strict_eval_arguments");
3526 *ok = false;
3527 return NULL;
3528 }
3529 if (name_is_strict_reserved) {
3530 ReportMessageAt(function_name_location, "unexpected_strict_reserved");
3531 *ok = false;
3532 return NULL;
3533 }
3534 if (eval_args_error_log.IsValid()) {
3535 ReportMessageAt(eval_args_error_log, "strict_eval_arguments");
3536 *ok = false;
3537 return NULL;
3538 }
3539 if (dupe_error_loc.IsValid()) {
3540 ReportMessageAt(dupe_error_loc, "strict_param_dupe");
3541 *ok = false;
3542 return NULL;
3543 }
3544 if (reserved_loc.IsValid()) {
3545 ReportMessageAt(reserved_loc, "unexpected_strict_reserved");
3546 *ok = false;
3547 return NULL;
3548 }
3549 CheckOctalLiteral(scope->start_position(),
3550 scope->end_position(),
3551 CHECK_OK);
3552 }
3553 ast_properties = *factory()->visitor()->ast_properties();
3554 dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
3555 }
3556
3557 if (allow_harmony_scoping() && strict_mode() == STRICT) {
3558 CheckConflictingVarDeclarations(scope, CHECK_OK);
3559 }
3560
3561 FunctionLiteral::IsGeneratorFlag generator = is_generator
3562 ? FunctionLiteral::kIsGenerator
3563 : FunctionLiteral::kNotGenerator;
3564 FunctionLiteral* function_literal =
3565 factory()->NewFunctionLiteral(function_name,
3566 scope,
3567 body,
3568 materialized_literal_count,
3569 expected_property_count,
3570 handler_count,
3571 num_parameters,
3572 duplicate_parameters,
3573 function_type,
3574 FunctionLiteral::kIsFunction,
3575 parenthesized,
3576 generator,
3577 pos);
3578 function_literal->set_function_token_position(function_token_pos);
3579 function_literal->set_ast_properties(&ast_properties);
3580 function_literal->set_dont_optimize_reason(dont_optimize_reason);
3581
3582 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
3583 return function_literal;
3584 }
3585
3586
SkipLazyFunctionBody(Handle<String> function_name,int * materialized_literal_count,int * expected_property_count,bool * ok)3587 void Parser::SkipLazyFunctionBody(Handle<String> function_name,
3588 int* materialized_literal_count,
3589 int* expected_property_count,
3590 bool* ok) {
3591 int function_block_pos = position();
3592 if (cached_data_mode_ == CONSUME_CACHED_DATA) {
3593 // If we have cached data, we use it to skip parsing the function body. The
3594 // data contains the information we need to construct the lazy function.
3595 FunctionEntry entry =
3596 (*cached_data())->GetFunctionEntry(function_block_pos);
3597 if (entry.is_valid()) {
3598 if (entry.end_pos() <= function_block_pos) {
3599 // End position greater than end of stream is safe, and hard to check.
3600 ReportInvalidCachedData(function_name, ok);
3601 if (!*ok) {
3602 return;
3603 }
3604 }
3605 scanner()->SeekForward(entry.end_pos() - 1);
3606
3607 scope_->set_end_position(entry.end_pos());
3608 Expect(Token::RBRACE, ok);
3609 if (!*ok) {
3610 return;
3611 }
3612 isolate()->counters()->total_preparse_skipped()->Increment(
3613 scope_->end_position() - function_block_pos);
3614 *materialized_literal_count = entry.literal_count();
3615 *expected_property_count = entry.property_count();
3616 scope_->SetStrictMode(entry.strict_mode());
3617 } else {
3618 // This case happens when we have preparse data but it doesn't contain an
3619 // entry for the function. Fail the compilation.
3620 ReportInvalidCachedData(function_name, ok);
3621 return;
3622 }
3623 } else {
3624 // With no cached data, we partially parse the function, without building an
3625 // AST. This gathers the data needed to build a lazy function.
3626 SingletonLogger logger;
3627 PreParser::PreParseResult result =
3628 ParseLazyFunctionBodyWithPreParser(&logger);
3629 if (result == PreParser::kPreParseStackOverflow) {
3630 // Propagate stack overflow.
3631 set_stack_overflow();
3632 *ok = false;
3633 return;
3634 }
3635 if (logger.has_error()) {
3636 ParserTraits::ReportMessageAt(
3637 Scanner::Location(logger.start(), logger.end()),
3638 logger.message(), logger.argument_opt(), logger.is_reference_error());
3639 *ok = false;
3640 return;
3641 }
3642 scope_->set_end_position(logger.end());
3643 Expect(Token::RBRACE, ok);
3644 if (!*ok) {
3645 return;
3646 }
3647 isolate()->counters()->total_preparse_skipped()->Increment(
3648 scope_->end_position() - function_block_pos);
3649 *materialized_literal_count = logger.literals();
3650 *expected_property_count = logger.properties();
3651 scope_->SetStrictMode(logger.strict_mode());
3652 if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
3653 ASSERT(log_);
3654 // Position right after terminal '}'.
3655 int body_end = scanner()->location().end_pos;
3656 log_->LogFunction(function_block_pos, body_end,
3657 *materialized_literal_count,
3658 *expected_property_count,
3659 scope_->strict_mode());
3660 }
3661 }
3662 }
3663
3664
ParseEagerFunctionBody(Handle<String> function_name,int pos,Variable * fvar,Token::Value fvar_init_op,bool is_generator,bool * ok)3665 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
3666 Handle<String> function_name, int pos, Variable* fvar,
3667 Token::Value fvar_init_op, bool is_generator, bool* ok) {
3668 // Everything inside an eagerly parsed function will be parsed eagerly
3669 // (see comment above).
3670 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
3671 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone());
3672 if (fvar != NULL) {
3673 VariableProxy* fproxy = scope_->NewUnresolved(
3674 factory(), function_name, Interface::NewConst());
3675 fproxy->BindTo(fvar);
3676 body->Add(factory()->NewExpressionStatement(
3677 factory()->NewAssignment(fvar_init_op,
3678 fproxy,
3679 factory()->NewThisFunction(pos),
3680 RelocInfo::kNoPosition),
3681 RelocInfo::kNoPosition), zone());
3682 }
3683
3684 // For generators, allocate and yield an iterator on function entry.
3685 if (is_generator) {
3686 ZoneList<Expression*>* arguments =
3687 new(zone()) ZoneList<Expression*>(0, zone());
3688 CallRuntime* allocation = factory()->NewCallRuntime(
3689 isolate()->factory()->empty_string(),
3690 Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject),
3691 arguments, pos);
3692 VariableProxy* init_proxy = factory()->NewVariableProxy(
3693 function_state_->generator_object_variable());
3694 Assignment* assignment = factory()->NewAssignment(
3695 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
3696 VariableProxy* get_proxy = factory()->NewVariableProxy(
3697 function_state_->generator_object_variable());
3698 Yield* yield = factory()->NewYield(
3699 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition);
3700 body->Add(factory()->NewExpressionStatement(
3701 yield, RelocInfo::kNoPosition), zone());
3702 }
3703
3704 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
3705
3706 if (is_generator) {
3707 VariableProxy* get_proxy = factory()->NewVariableProxy(
3708 function_state_->generator_object_variable());
3709 Expression *undefined = factory()->NewLiteral(
3710 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition);
3711 Yield* yield = factory()->NewYield(
3712 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition);
3713 body->Add(factory()->NewExpressionStatement(
3714 yield, RelocInfo::kNoPosition), zone());
3715 }
3716
3717 Expect(Token::RBRACE, CHECK_OK);
3718 scope_->set_end_position(scanner()->location().end_pos);
3719
3720 return body;
3721 }
3722
3723
ParseLazyFunctionBodyWithPreParser(SingletonLogger * logger)3724 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
3725 SingletonLogger* logger) {
3726 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
3727 ASSERT_EQ(Token::LBRACE, scanner()->current_token());
3728
3729 if (reusable_preparser_ == NULL) {
3730 intptr_t stack_limit = isolate()->stack_guard()->real_climit();
3731 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit);
3732 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
3733 reusable_preparser_->set_allow_modules(allow_modules());
3734 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax());
3735 reusable_preparser_->set_allow_lazy(true);
3736 reusable_preparser_->set_allow_generators(allow_generators());
3737 reusable_preparser_->set_allow_for_of(allow_for_of());
3738 reusable_preparser_->set_allow_harmony_numeric_literals(
3739 allow_harmony_numeric_literals());
3740 }
3741 PreParser::PreParseResult result =
3742 reusable_preparser_->PreParseLazyFunction(strict_mode(),
3743 is_generator(),
3744 logger);
3745 return result;
3746 }
3747
3748
ParseV8Intrinsic(bool * ok)3749 Expression* Parser::ParseV8Intrinsic(bool* ok) {
3750 // CallRuntime ::
3751 // '%' Identifier Arguments
3752
3753 int pos = peek_position();
3754 Expect(Token::MOD, CHECK_OK);
3755 // Allow "eval" or "arguments" for backward compatibility.
3756 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
3757 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3758
3759 if (extension_ != NULL) {
3760 // The extension structures are only accessible while parsing the
3761 // very first time not when reparsing because of lazy compilation.
3762 scope_->DeclarationScope()->ForceEagerCompilation();
3763 }
3764
3765 const Runtime::Function* function = Runtime::FunctionForName(name);
3766
3767 // Check for built-in IS_VAR macro.
3768 if (function != NULL &&
3769 function->intrinsic_type == Runtime::RUNTIME &&
3770 function->function_id == Runtime::kIS_VAR) {
3771 // %IS_VAR(x) evaluates to x if x is a variable,
3772 // leads to a parse error otherwise. Could be implemented as an
3773 // inline function %_IS_VAR(x) to eliminate this special case.
3774 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
3775 return args->at(0);
3776 } else {
3777 ReportMessage("not_isvar");
3778 *ok = false;
3779 return NULL;
3780 }
3781 }
3782
3783 // Check that the expected number of arguments are being passed.
3784 if (function != NULL &&
3785 function->nargs != -1 &&
3786 function->nargs != args->length()) {
3787 ReportMessage("illegal_access");
3788 *ok = false;
3789 return NULL;
3790 }
3791
3792 // Check that the function is defined if it's an inline runtime call.
3793 if (function == NULL && name->Get(0) == '_') {
3794 ParserTraits::ReportMessage("not_defined", name);
3795 *ok = false;
3796 return NULL;
3797 }
3798
3799 // We have a valid intrinsics call or a call to a builtin.
3800 return factory()->NewCallRuntime(name, function, args, pos);
3801 }
3802
3803
GetLiteralUndefined(int position)3804 Literal* Parser::GetLiteralUndefined(int position) {
3805 return factory()->NewLiteral(
3806 isolate()->factory()->undefined_value(), position);
3807 }
3808
3809
CheckConflictingVarDeclarations(Scope * scope,bool * ok)3810 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
3811 Declaration* decl = scope->CheckConflictingVarDeclarations();
3812 if (decl != NULL) {
3813 // In harmony mode we treat conflicting variable bindinds as early
3814 // errors. See ES5 16 for a definition of early errors.
3815 Handle<String> name = decl->proxy()->name();
3816 int position = decl->proxy()->position();
3817 Scanner::Location location = position == RelocInfo::kNoPosition
3818 ? Scanner::Location::invalid()
3819 : Scanner::Location(position, position + 1);
3820 ParserTraits::ReportMessageAt(location, "var_redeclaration", name);
3821 *ok = false;
3822 }
3823 }
3824
3825
3826 // ----------------------------------------------------------------------------
3827 // Parser support
3828
3829
TargetStackContainsLabel(Handle<String> label)3830 bool Parser::TargetStackContainsLabel(Handle<String> label) {
3831 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3832 BreakableStatement* stat = t->node()->AsBreakableStatement();
3833 if (stat != NULL && ContainsLabel(stat->labels(), label))
3834 return true;
3835 }
3836 return false;
3837 }
3838
3839
LookupBreakTarget(Handle<String> label,bool * ok)3840 BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
3841 bool anonymous = label.is_null();
3842 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3843 BreakableStatement* stat = t->node()->AsBreakableStatement();
3844 if (stat == NULL) continue;
3845 if ((anonymous && stat->is_target_for_anonymous()) ||
3846 (!anonymous && ContainsLabel(stat->labels(), label))) {
3847 RegisterTargetUse(stat->break_target(), t->previous());
3848 return stat;
3849 }
3850 }
3851 return NULL;
3852 }
3853
3854
LookupContinueTarget(Handle<String> label,bool * ok)3855 IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
3856 bool* ok) {
3857 bool anonymous = label.is_null();
3858 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3859 IterationStatement* stat = t->node()->AsIterationStatement();
3860 if (stat == NULL) continue;
3861
3862 ASSERT(stat->is_target_for_anonymous());
3863 if (anonymous || ContainsLabel(stat->labels(), label)) {
3864 RegisterTargetUse(stat->continue_target(), t->previous());
3865 return stat;
3866 }
3867 }
3868 return NULL;
3869 }
3870
3871
RegisterTargetUse(Label * target,Target * stop)3872 void Parser::RegisterTargetUse(Label* target, Target* stop) {
3873 // Register that a break target found at the given stop in the
3874 // target stack has been used from the top of the target stack. Add
3875 // the break target to any TargetCollectors passed on the stack.
3876 for (Target* t = target_stack_; t != stop; t = t->previous()) {
3877 TargetCollector* collector = t->node()->AsTargetCollector();
3878 if (collector != NULL) collector->AddTarget(target, zone());
3879 }
3880 }
3881
3882
ThrowPendingError()3883 void Parser::ThrowPendingError() {
3884 if (has_pending_error_) {
3885 MessageLocation location(script_,
3886 pending_error_location_.beg_pos,
3887 pending_error_location_.end_pos);
3888 Factory* factory = isolate()->factory();
3889 bool has_arg =
3890 !pending_error_arg_.is_null() || pending_error_char_arg_ != NULL;
3891 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0);
3892 if (!pending_error_arg_.is_null()) {
3893 elements->set(0, *(pending_error_arg_.ToHandleChecked()));
3894 } else if (pending_error_char_arg_ != NULL) {
3895 Handle<String> arg_string =
3896 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_))
3897 .ToHandleChecked();
3898 elements->set(0, *arg_string);
3899 }
3900 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
3901 Handle<Object> result = pending_error_is_reference_error_
3902 ? factory->NewReferenceError(pending_error_message_, array)
3903 : factory->NewSyntaxError(pending_error_message_, array);
3904 isolate()->Throw(*result, &location);
3905 }
3906 }
3907
3908
3909 // ----------------------------------------------------------------------------
3910 // Regular expressions
3911
3912
RegExpParser(FlatStringReader * in,Handle<String> * error,bool multiline,Zone * zone)3913 RegExpParser::RegExpParser(FlatStringReader* in,
3914 Handle<String>* error,
3915 bool multiline,
3916 Zone* zone)
3917 : isolate_(zone->isolate()),
3918 zone_(zone),
3919 error_(error),
3920 captures_(NULL),
3921 in_(in),
3922 current_(kEndMarker),
3923 next_pos_(0),
3924 capture_count_(0),
3925 has_more_(true),
3926 multiline_(multiline),
3927 simple_(false),
3928 contains_anchor_(false),
3929 is_scanned_for_captures_(false),
3930 failed_(false) {
3931 Advance();
3932 }
3933
3934
Next()3935 uc32 RegExpParser::Next() {
3936 if (has_next()) {
3937 return in()->Get(next_pos_);
3938 } else {
3939 return kEndMarker;
3940 }
3941 }
3942
3943
Advance()3944 void RegExpParser::Advance() {
3945 if (next_pos_ < in()->length()) {
3946 StackLimitCheck check(isolate());
3947 if (check.HasOverflowed()) {
3948 ReportError(CStrVector(Isolate::kStackOverflowMessage));
3949 } else if (zone()->excess_allocation()) {
3950 ReportError(CStrVector("Regular expression too large"));
3951 } else {
3952 current_ = in()->Get(next_pos_);
3953 next_pos_++;
3954 }
3955 } else {
3956 current_ = kEndMarker;
3957 has_more_ = false;
3958 }
3959 }
3960
3961
Reset(int pos)3962 void RegExpParser::Reset(int pos) {
3963 next_pos_ = pos;
3964 has_more_ = (pos < in()->length());
3965 Advance();
3966 }
3967
3968
Advance(int dist)3969 void RegExpParser::Advance(int dist) {
3970 next_pos_ += dist - 1;
3971 Advance();
3972 }
3973
3974
simple()3975 bool RegExpParser::simple() {
3976 return simple_;
3977 }
3978
3979
ReportError(Vector<const char> message)3980 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
3981 failed_ = true;
3982 *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked();
3983 // Zip to the end to make sure the no more input is read.
3984 current_ = kEndMarker;
3985 next_pos_ = in()->length();
3986 return NULL;
3987 }
3988
3989
3990 // Pattern ::
3991 // Disjunction
ParsePattern()3992 RegExpTree* RegExpParser::ParsePattern() {
3993 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
3994 ASSERT(!has_more());
3995 // If the result of parsing is a literal string atom, and it has the
3996 // same length as the input, then the atom is identical to the input.
3997 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
3998 simple_ = true;
3999 }
4000 return result;
4001 }
4002
4003
4004 // Disjunction ::
4005 // Alternative
4006 // Alternative | Disjunction
4007 // Alternative ::
4008 // [empty]
4009 // Term Alternative
4010 // Term ::
4011 // Assertion
4012 // Atom
4013 // Atom Quantifier
ParseDisjunction()4014 RegExpTree* RegExpParser::ParseDisjunction() {
4015 // Used to store current state while parsing subexpressions.
4016 RegExpParserState initial_state(NULL, INITIAL, 0, zone());
4017 RegExpParserState* stored_state = &initial_state;
4018 // Cache the builder in a local variable for quick access.
4019 RegExpBuilder* builder = initial_state.builder();
4020 while (true) {
4021 switch (current()) {
4022 case kEndMarker:
4023 if (stored_state->IsSubexpression()) {
4024 // Inside a parenthesized group when hitting end of input.
4025 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
4026 }
4027 ASSERT_EQ(INITIAL, stored_state->group_type());
4028 // Parsing completed successfully.
4029 return builder->ToRegExp();
4030 case ')': {
4031 if (!stored_state->IsSubexpression()) {
4032 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
4033 }
4034 ASSERT_NE(INITIAL, stored_state->group_type());
4035
4036 Advance();
4037 // End disjunction parsing and convert builder content to new single
4038 // regexp atom.
4039 RegExpTree* body = builder->ToRegExp();
4040
4041 int end_capture_index = captures_started();
4042
4043 int capture_index = stored_state->capture_index();
4044 SubexpressionType group_type = stored_state->group_type();
4045
4046 // Restore previous state.
4047 stored_state = stored_state->previous_state();
4048 builder = stored_state->builder();
4049
4050 // Build result of subexpression.
4051 if (group_type == CAPTURE) {
4052 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
4053 captures_->at(capture_index - 1) = capture;
4054 body = capture;
4055 } else if (group_type != GROUPING) {
4056 ASSERT(group_type == POSITIVE_LOOKAHEAD ||
4057 group_type == NEGATIVE_LOOKAHEAD);
4058 bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
4059 body = new(zone()) RegExpLookahead(body,
4060 is_positive,
4061 end_capture_index - capture_index,
4062 capture_index);
4063 }
4064 builder->AddAtom(body);
4065 // For compatability with JSC and ES3, we allow quantifiers after
4066 // lookaheads, and break in all cases.
4067 break;
4068 }
4069 case '|': {
4070 Advance();
4071 builder->NewAlternative();
4072 continue;
4073 }
4074 case '*':
4075 case '+':
4076 case '?':
4077 return ReportError(CStrVector("Nothing to repeat"));
4078 case '^': {
4079 Advance();
4080 if (multiline_) {
4081 builder->AddAssertion(
4082 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
4083 } else {
4084 builder->AddAssertion(
4085 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
4086 set_contains_anchor();
4087 }
4088 continue;
4089 }
4090 case '$': {
4091 Advance();
4092 RegExpAssertion::AssertionType assertion_type =
4093 multiline_ ? RegExpAssertion::END_OF_LINE :
4094 RegExpAssertion::END_OF_INPUT;
4095 builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
4096 continue;
4097 }
4098 case '.': {
4099 Advance();
4100 // everything except \x0a, \x0d, \u2028 and \u2029
4101 ZoneList<CharacterRange>* ranges =
4102 new(zone()) ZoneList<CharacterRange>(2, zone());
4103 CharacterRange::AddClassEscape('.', ranges, zone());
4104 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4105 builder->AddAtom(atom);
4106 break;
4107 }
4108 case '(': {
4109 SubexpressionType subexpr_type = CAPTURE;
4110 Advance();
4111 if (current() == '?') {
4112 switch (Next()) {
4113 case ':':
4114 subexpr_type = GROUPING;
4115 break;
4116 case '=':
4117 subexpr_type = POSITIVE_LOOKAHEAD;
4118 break;
4119 case '!':
4120 subexpr_type = NEGATIVE_LOOKAHEAD;
4121 break;
4122 default:
4123 ReportError(CStrVector("Invalid group") CHECK_FAILED);
4124 break;
4125 }
4126 Advance(2);
4127 } else {
4128 if (captures_ == NULL) {
4129 captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone());
4130 }
4131 if (captures_started() >= kMaxCaptures) {
4132 ReportError(CStrVector("Too many captures") CHECK_FAILED);
4133 }
4134 captures_->Add(NULL, zone());
4135 }
4136 // Store current state and begin new disjunction parsing.
4137 stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
4138 captures_started(), zone());
4139 builder = stored_state->builder();
4140 continue;
4141 }
4142 case '[': {
4143 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
4144 builder->AddAtom(atom);
4145 break;
4146 }
4147 // Atom ::
4148 // \ AtomEscape
4149 case '\\':
4150 switch (Next()) {
4151 case kEndMarker:
4152 return ReportError(CStrVector("\\ at end of pattern"));
4153 case 'b':
4154 Advance(2);
4155 builder->AddAssertion(
4156 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
4157 continue;
4158 case 'B':
4159 Advance(2);
4160 builder->AddAssertion(
4161 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
4162 continue;
4163 // AtomEscape ::
4164 // CharacterClassEscape
4165 //
4166 // CharacterClassEscape :: one of
4167 // d D s S w W
4168 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
4169 uc32 c = Next();
4170 Advance(2);
4171 ZoneList<CharacterRange>* ranges =
4172 new(zone()) ZoneList<CharacterRange>(2, zone());
4173 CharacterRange::AddClassEscape(c, ranges, zone());
4174 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
4175 builder->AddAtom(atom);
4176 break;
4177 }
4178 case '1': case '2': case '3': case '4': case '5': case '6':
4179 case '7': case '8': case '9': {
4180 int index = 0;
4181 if (ParseBackReferenceIndex(&index)) {
4182 RegExpCapture* capture = NULL;
4183 if (captures_ != NULL && index <= captures_->length()) {
4184 capture = captures_->at(index - 1);
4185 }
4186 if (capture == NULL) {
4187 builder->AddEmpty();
4188 break;
4189 }
4190 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
4191 builder->AddAtom(atom);
4192 break;
4193 }
4194 uc32 first_digit = Next();
4195 if (first_digit == '8' || first_digit == '9') {
4196 // Treat as identity escape
4197 builder->AddCharacter(first_digit);
4198 Advance(2);
4199 break;
4200 }
4201 }
4202 // FALLTHROUGH
4203 case '0': {
4204 Advance();
4205 uc32 octal = ParseOctalLiteral();
4206 builder->AddCharacter(octal);
4207 break;
4208 }
4209 // ControlEscape :: one of
4210 // f n r t v
4211 case 'f':
4212 Advance(2);
4213 builder->AddCharacter('\f');
4214 break;
4215 case 'n':
4216 Advance(2);
4217 builder->AddCharacter('\n');
4218 break;
4219 case 'r':
4220 Advance(2);
4221 builder->AddCharacter('\r');
4222 break;
4223 case 't':
4224 Advance(2);
4225 builder->AddCharacter('\t');
4226 break;
4227 case 'v':
4228 Advance(2);
4229 builder->AddCharacter('\v');
4230 break;
4231 case 'c': {
4232 Advance();
4233 uc32 controlLetter = Next();
4234 // Special case if it is an ASCII letter.
4235 // Convert lower case letters to uppercase.
4236 uc32 letter = controlLetter & ~('a' ^ 'A');
4237 if (letter < 'A' || 'Z' < letter) {
4238 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
4239 // This is outside the specification. We match JSC in
4240 // reading the backslash as a literal character instead
4241 // of as starting an escape.
4242 builder->AddCharacter('\\');
4243 } else {
4244 Advance(2);
4245 builder->AddCharacter(controlLetter & 0x1f);
4246 }
4247 break;
4248 }
4249 case 'x': {
4250 Advance(2);
4251 uc32 value;
4252 if (ParseHexEscape(2, &value)) {
4253 builder->AddCharacter(value);
4254 } else {
4255 builder->AddCharacter('x');
4256 }
4257 break;
4258 }
4259 case 'u': {
4260 Advance(2);
4261 uc32 value;
4262 if (ParseHexEscape(4, &value)) {
4263 builder->AddCharacter(value);
4264 } else {
4265 builder->AddCharacter('u');
4266 }
4267 break;
4268 }
4269 default:
4270 // Identity escape.
4271 builder->AddCharacter(Next());
4272 Advance(2);
4273 break;
4274 }
4275 break;
4276 case '{': {
4277 int dummy;
4278 if (ParseIntervalQuantifier(&dummy, &dummy)) {
4279 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
4280 }
4281 // fallthrough
4282 }
4283 default:
4284 builder->AddCharacter(current());
4285 Advance();
4286 break;
4287 } // end switch(current())
4288
4289 int min;
4290 int max;
4291 switch (current()) {
4292 // QuantifierPrefix ::
4293 // *
4294 // +
4295 // ?
4296 // {
4297 case '*':
4298 min = 0;
4299 max = RegExpTree::kInfinity;
4300 Advance();
4301 break;
4302 case '+':
4303 min = 1;
4304 max = RegExpTree::kInfinity;
4305 Advance();
4306 break;
4307 case '?':
4308 min = 0;
4309 max = 1;
4310 Advance();
4311 break;
4312 case '{':
4313 if (ParseIntervalQuantifier(&min, &max)) {
4314 if (max < min) {
4315 ReportError(CStrVector("numbers out of order in {} quantifier.")
4316 CHECK_FAILED);
4317 }
4318 break;
4319 } else {
4320 continue;
4321 }
4322 default:
4323 continue;
4324 }
4325 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
4326 if (current() == '?') {
4327 quantifier_type = RegExpQuantifier::NON_GREEDY;
4328 Advance();
4329 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
4330 // FLAG_regexp_possessive_quantifier is a debug-only flag.
4331 quantifier_type = RegExpQuantifier::POSSESSIVE;
4332 Advance();
4333 }
4334 builder->AddQuantifierToAtom(min, max, quantifier_type);
4335 }
4336 }
4337
4338
4339 #ifdef DEBUG
4340 // Currently only used in an ASSERT.
IsSpecialClassEscape(uc32 c)4341 static bool IsSpecialClassEscape(uc32 c) {
4342 switch (c) {
4343 case 'd': case 'D':
4344 case 's': case 'S':
4345 case 'w': case 'W':
4346 return true;
4347 default:
4348 return false;
4349 }
4350 }
4351 #endif
4352
4353
4354 // In order to know whether an escape is a backreference or not we have to scan
4355 // the entire regexp and find the number of capturing parentheses. However we
4356 // don't want to scan the regexp twice unless it is necessary. This mini-parser
4357 // is called when needed. It can see the difference between capturing and
4358 // noncapturing parentheses and can skip character classes and backslash-escaped
4359 // characters.
ScanForCaptures()4360 void RegExpParser::ScanForCaptures() {
4361 // Start with captures started previous to current position
4362 int capture_count = captures_started();
4363 // Add count of captures after this position.
4364 int n;
4365 while ((n = current()) != kEndMarker) {
4366 Advance();
4367 switch (n) {
4368 case '\\':
4369 Advance();
4370 break;
4371 case '[': {
4372 int c;
4373 while ((c = current()) != kEndMarker) {
4374 Advance();
4375 if (c == '\\') {
4376 Advance();
4377 } else {
4378 if (c == ']') break;
4379 }
4380 }
4381 break;
4382 }
4383 case '(':
4384 if (current() != '?') capture_count++;
4385 break;
4386 }
4387 }
4388 capture_count_ = capture_count;
4389 is_scanned_for_captures_ = true;
4390 }
4391
4392
ParseBackReferenceIndex(int * index_out)4393 bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
4394 ASSERT_EQ('\\', current());
4395 ASSERT('1' <= Next() && Next() <= '9');
4396 // Try to parse a decimal literal that is no greater than the total number
4397 // of left capturing parentheses in the input.
4398 int start = position();
4399 int value = Next() - '0';
4400 Advance(2);
4401 while (true) {
4402 uc32 c = current();
4403 if (IsDecimalDigit(c)) {
4404 value = 10 * value + (c - '0');
4405 if (value > kMaxCaptures) {
4406 Reset(start);
4407 return false;
4408 }
4409 Advance();
4410 } else {
4411 break;
4412 }
4413 }
4414 if (value > captures_started()) {
4415 if (!is_scanned_for_captures_) {
4416 int saved_position = position();
4417 ScanForCaptures();
4418 Reset(saved_position);
4419 }
4420 if (value > capture_count_) {
4421 Reset(start);
4422 return false;
4423 }
4424 }
4425 *index_out = value;
4426 return true;
4427 }
4428
4429
4430 // QuantifierPrefix ::
4431 // { DecimalDigits }
4432 // { DecimalDigits , }
4433 // { DecimalDigits , DecimalDigits }
4434 //
4435 // Returns true if parsing succeeds, and set the min_out and max_out
4436 // values. Values are truncated to RegExpTree::kInfinity if they overflow.
ParseIntervalQuantifier(int * min_out,int * max_out)4437 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
4438 ASSERT_EQ(current(), '{');
4439 int start = position();
4440 Advance();
4441 int min = 0;
4442 if (!IsDecimalDigit(current())) {
4443 Reset(start);
4444 return false;
4445 }
4446 while (IsDecimalDigit(current())) {
4447 int next = current() - '0';
4448 if (min > (RegExpTree::kInfinity - next) / 10) {
4449 // Overflow. Skip past remaining decimal digits and return -1.
4450 do {
4451 Advance();
4452 } while (IsDecimalDigit(current()));
4453 min = RegExpTree::kInfinity;
4454 break;
4455 }
4456 min = 10 * min + next;
4457 Advance();
4458 }
4459 int max = 0;
4460 if (current() == '}') {
4461 max = min;
4462 Advance();
4463 } else if (current() == ',') {
4464 Advance();
4465 if (current() == '}') {
4466 max = RegExpTree::kInfinity;
4467 Advance();
4468 } else {
4469 while (IsDecimalDigit(current())) {
4470 int next = current() - '0';
4471 if (max > (RegExpTree::kInfinity - next) / 10) {
4472 do {
4473 Advance();
4474 } while (IsDecimalDigit(current()));
4475 max = RegExpTree::kInfinity;
4476 break;
4477 }
4478 max = 10 * max + next;
4479 Advance();
4480 }
4481 if (current() != '}') {
4482 Reset(start);
4483 return false;
4484 }
4485 Advance();
4486 }
4487 } else {
4488 Reset(start);
4489 return false;
4490 }
4491 *min_out = min;
4492 *max_out = max;
4493 return true;
4494 }
4495
4496
ParseOctalLiteral()4497 uc32 RegExpParser::ParseOctalLiteral() {
4498 ASSERT(('0' <= current() && current() <= '7') || current() == kEndMarker);
4499 // For compatibility with some other browsers (not all), we parse
4500 // up to three octal digits with a value below 256.
4501 uc32 value = current() - '0';
4502 Advance();
4503 if ('0' <= current() && current() <= '7') {
4504 value = value * 8 + current() - '0';
4505 Advance();
4506 if (value < 32 && '0' <= current() && current() <= '7') {
4507 value = value * 8 + current() - '0';
4508 Advance();
4509 }
4510 }
4511 return value;
4512 }
4513
4514
ParseHexEscape(int length,uc32 * value)4515 bool RegExpParser::ParseHexEscape(int length, uc32 *value) {
4516 int start = position();
4517 uc32 val = 0;
4518 bool done = false;
4519 for (int i = 0; !done; i++) {
4520 uc32 c = current();
4521 int d = HexValue(c);
4522 if (d < 0) {
4523 Reset(start);
4524 return false;
4525 }
4526 val = val * 16 + d;
4527 Advance();
4528 if (i == length - 1) {
4529 done = true;
4530 }
4531 }
4532 *value = val;
4533 return true;
4534 }
4535
4536
ParseClassCharacterEscape()4537 uc32 RegExpParser::ParseClassCharacterEscape() {
4538 ASSERT(current() == '\\');
4539 ASSERT(has_next() && !IsSpecialClassEscape(Next()));
4540 Advance();
4541 switch (current()) {
4542 case 'b':
4543 Advance();
4544 return '\b';
4545 // ControlEscape :: one of
4546 // f n r t v
4547 case 'f':
4548 Advance();
4549 return '\f';
4550 case 'n':
4551 Advance();
4552 return '\n';
4553 case 'r':
4554 Advance();
4555 return '\r';
4556 case 't':
4557 Advance();
4558 return '\t';
4559 case 'v':
4560 Advance();
4561 return '\v';
4562 case 'c': {
4563 uc32 controlLetter = Next();
4564 uc32 letter = controlLetter & ~('A' ^ 'a');
4565 // For compatibility with JSC, inside a character class
4566 // we also accept digits and underscore as control characters.
4567 if ((controlLetter >= '0' && controlLetter <= '9') ||
4568 controlLetter == '_' ||
4569 (letter >= 'A' && letter <= 'Z')) {
4570 Advance(2);
4571 // Control letters mapped to ASCII control characters in the range
4572 // 0x00-0x1f.
4573 return controlLetter & 0x1f;
4574 }
4575 // We match JSC in reading the backslash as a literal
4576 // character instead of as starting an escape.
4577 return '\\';
4578 }
4579 case '0': case '1': case '2': case '3': case '4': case '5':
4580 case '6': case '7':
4581 // For compatibility, we interpret a decimal escape that isn't
4582 // a back reference (and therefore either \0 or not valid according
4583 // to the specification) as a 1..3 digit octal character code.
4584 return ParseOctalLiteral();
4585 case 'x': {
4586 Advance();
4587 uc32 value;
4588 if (ParseHexEscape(2, &value)) {
4589 return value;
4590 }
4591 // If \x is not followed by a two-digit hexadecimal, treat it
4592 // as an identity escape.
4593 return 'x';
4594 }
4595 case 'u': {
4596 Advance();
4597 uc32 value;
4598 if (ParseHexEscape(4, &value)) {
4599 return value;
4600 }
4601 // If \u is not followed by a four-digit hexadecimal, treat it
4602 // as an identity escape.
4603 return 'u';
4604 }
4605 default: {
4606 // Extended identity escape. We accept any character that hasn't
4607 // been matched by a more specific case, not just the subset required
4608 // by the ECMAScript specification.
4609 uc32 result = current();
4610 Advance();
4611 return result;
4612 }
4613 }
4614 return 0;
4615 }
4616
4617
ParseClassAtom(uc16 * char_class)4618 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
4619 ASSERT_EQ(0, *char_class);
4620 uc32 first = current();
4621 if (first == '\\') {
4622 switch (Next()) {
4623 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
4624 *char_class = Next();
4625 Advance(2);
4626 return CharacterRange::Singleton(0); // Return dummy value.
4627 }
4628 case kEndMarker:
4629 return ReportError(CStrVector("\\ at end of pattern"));
4630 default:
4631 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
4632 return CharacterRange::Singleton(c);
4633 }
4634 } else {
4635 Advance();
4636 return CharacterRange::Singleton(first);
4637 }
4638 }
4639
4640
4641 static const uc16 kNoCharClass = 0;
4642
4643 // Adds range or pre-defined character class to character ranges.
4644 // If char_class is not kInvalidClass, it's interpreted as a class
4645 // escape (i.e., 's' means whitespace, from '\s').
AddRangeOrEscape(ZoneList<CharacterRange> * ranges,uc16 char_class,CharacterRange range,Zone * zone)4646 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
4647 uc16 char_class,
4648 CharacterRange range,
4649 Zone* zone) {
4650 if (char_class != kNoCharClass) {
4651 CharacterRange::AddClassEscape(char_class, ranges, zone);
4652 } else {
4653 ranges->Add(range, zone);
4654 }
4655 }
4656
4657
ParseCharacterClass()4658 RegExpTree* RegExpParser::ParseCharacterClass() {
4659 static const char* kUnterminated = "Unterminated character class";
4660 static const char* kRangeOutOfOrder = "Range out of order in character class";
4661
4662 ASSERT_EQ(current(), '[');
4663 Advance();
4664 bool is_negated = false;
4665 if (current() == '^') {
4666 is_negated = true;
4667 Advance();
4668 }
4669 ZoneList<CharacterRange>* ranges =
4670 new(zone()) ZoneList<CharacterRange>(2, zone());
4671 while (has_more() && current() != ']') {
4672 uc16 char_class = kNoCharClass;
4673 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
4674 if (current() == '-') {
4675 Advance();
4676 if (current() == kEndMarker) {
4677 // If we reach the end we break out of the loop and let the
4678 // following code report an error.
4679 break;
4680 } else if (current() == ']') {
4681 AddRangeOrEscape(ranges, char_class, first, zone());
4682 ranges->Add(CharacterRange::Singleton('-'), zone());
4683 break;
4684 }
4685 uc16 char_class_2 = kNoCharClass;
4686 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
4687 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
4688 // Either end is an escaped character class. Treat the '-' verbatim.
4689 AddRangeOrEscape(ranges, char_class, first, zone());
4690 ranges->Add(CharacterRange::Singleton('-'), zone());
4691 AddRangeOrEscape(ranges, char_class_2, next, zone());
4692 continue;
4693 }
4694 if (first.from() > next.to()) {
4695 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
4696 }
4697 ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
4698 } else {
4699 AddRangeOrEscape(ranges, char_class, first, zone());
4700 }
4701 }
4702 if (!has_more()) {
4703 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
4704 }
4705 Advance();
4706 if (ranges->length() == 0) {
4707 ranges->Add(CharacterRange::Everything(), zone());
4708 is_negated = !is_negated;
4709 }
4710 return new(zone()) RegExpCharacterClass(ranges, is_negated);
4711 }
4712
4713
4714 // ----------------------------------------------------------------------------
4715 // The Parser interface.
4716
~ScriptData()4717 ScriptData::~ScriptData() {
4718 if (owns_store_) store_.Dispose();
4719 }
4720
4721
Length()4722 int ScriptData::Length() {
4723 return store_.length() * sizeof(unsigned);
4724 }
4725
4726
Data()4727 const char* ScriptData::Data() {
4728 return reinterpret_cast<const char*>(store_.start());
4729 }
4730
4731
HasError()4732 bool ScriptData::HasError() {
4733 return has_error();
4734 }
4735
4736
Initialize()4737 void ScriptData::Initialize() {
4738 // Prepares state for use.
4739 if (store_.length() >= PreparseDataConstants::kHeaderSize) {
4740 function_index_ = PreparseDataConstants::kHeaderSize;
4741 int symbol_data_offset = PreparseDataConstants::kHeaderSize
4742 + store_[PreparseDataConstants::kFunctionsSizeOffset];
4743 if (store_.length() > symbol_data_offset) {
4744 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]);
4745 } else {
4746 // Partial preparse causes no symbol information.
4747 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
4748 }
4749 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
4750 }
4751 }
4752
4753
ReadNumber(byte ** source)4754 int ScriptData::ReadNumber(byte** source) {
4755 // Reads a number from symbol_data_ in base 128. The most significant
4756 // bit marks that there are more digits.
4757 // If the first byte is 0x80 (kNumberTerminator), it would normally
4758 // represent a leading zero. Since that is useless, and therefore won't
4759 // appear as the first digit of any actual value, it is used to
4760 // mark the end of the input stream.
4761 byte* data = *source;
4762 if (data >= symbol_data_end_) return -1;
4763 byte input = *data;
4764 if (input == PreparseDataConstants::kNumberTerminator) {
4765 // End of stream marker.
4766 return -1;
4767 }
4768 int result = input & 0x7f;
4769 data++;
4770 while ((input & 0x80u) != 0) {
4771 if (data >= symbol_data_end_) return -1;
4772 input = *data;
4773 result = (result << 7) | (input & 0x7f);
4774 data++;
4775 }
4776 *source = data;
4777 return result;
4778 }
4779
4780
ParseRegExp(FlatStringReader * input,bool multiline,RegExpCompileData * result,Zone * zone)4781 bool RegExpParser::ParseRegExp(FlatStringReader* input,
4782 bool multiline,
4783 RegExpCompileData* result,
4784 Zone* zone) {
4785 ASSERT(result != NULL);
4786 RegExpParser parser(input, &result->error, multiline, zone);
4787 RegExpTree* tree = parser.ParsePattern();
4788 if (parser.failed()) {
4789 ASSERT(tree == NULL);
4790 ASSERT(!result->error.is_null());
4791 } else {
4792 ASSERT(tree != NULL);
4793 ASSERT(result->error.is_null());
4794 result->tree = tree;
4795 int capture_count = parser.captures_started();
4796 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
4797 result->contains_anchor = parser.contains_anchor();
4798 result->capture_count = capture_count;
4799 }
4800 return !parser.failed();
4801 }
4802
4803
Parse()4804 bool Parser::Parse() {
4805 ASSERT(info()->function() == NULL);
4806 FunctionLiteral* result = NULL;
4807 if (info()->is_lazy()) {
4808 ASSERT(!info()->is_eval());
4809 if (info()->shared_info()->is_function()) {
4810 result = ParseLazy();
4811 } else {
4812 result = ParseProgram();
4813 }
4814 } else {
4815 SetCachedData(info()->cached_data(), info()->cached_data_mode());
4816 if (info()->cached_data_mode() == CONSUME_CACHED_DATA &&
4817 (*info()->cached_data())->has_error()) {
4818 ScriptData* cached_data = *(info()->cached_data());
4819 Scanner::Location loc = cached_data->MessageLocation();
4820 const char* message = cached_data->BuildMessage();
4821 const char* arg = cached_data->BuildArg();
4822 ParserTraits::ReportMessageAt(loc, message, arg,
4823 cached_data->IsReferenceError());
4824 DeleteArray(message);
4825 DeleteArray(arg);
4826 ASSERT(info()->isolate()->has_pending_exception());
4827 } else {
4828 result = ParseProgram();
4829 }
4830 }
4831 info()->SetFunction(result);
4832 return (result != NULL);
4833 }
4834
4835 } } // namespace v8::internal
4836