1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "v8.h"
29
30 #include "api.h"
31 #include "ast.h"
32 #include "bootstrapper.h"
33 #include "char-predicates-inl.h"
34 #include "codegen.h"
35 #include "compiler.h"
36 #include "func-name-inferrer.h"
37 #include "messages.h"
38 #include "parser.h"
39 #include "platform.h"
40 #include "preparser.h"
41 #include "runtime.h"
42 #include "scanner-character-streams.h"
43 #include "scopeinfo.h"
44 #include "string-stream.h"
45
46 namespace v8 {
47 namespace internal {
48
49 // PositionStack is used for on-stack allocation of token positions for
50 // new expressions. Please look at ParseNewExpression.
51
52 class PositionStack {
53 public:
PositionStack(bool * ok)54 explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {}
~PositionStack()55 ~PositionStack() { ASSERT(!*ok_ || is_empty()); }
56
57 class Element {
58 public:
Element(PositionStack * stack,int value)59 Element(PositionStack* stack, int value) {
60 previous_ = stack->top();
61 value_ = value;
62 stack->set_top(this);
63 }
64
65 private:
previous()66 Element* previous() { return previous_; }
value()67 int value() { return value_; }
68 friend class PositionStack;
69 Element* previous_;
70 int value_;
71 };
72
is_empty()73 bool is_empty() { return top_ == NULL; }
pop()74 int pop() {
75 ASSERT(!is_empty());
76 int result = top_->value();
77 top_ = top_->previous();
78 return result;
79 }
80
81 private:
top()82 Element* top() { return top_; }
set_top(Element * value)83 void set_top(Element* value) { top_ = value; }
84 Element* top_;
85 bool* ok_;
86 };
87
88
RegExpBuilder()89 RegExpBuilder::RegExpBuilder()
90 : zone_(Isolate::Current()->zone()),
91 pending_empty_(false),
92 characters_(NULL),
93 terms_(),
94 alternatives_()
95 #ifdef DEBUG
96 , last_added_(ADD_NONE)
97 #endif
98 {}
99
100
FlushCharacters()101 void RegExpBuilder::FlushCharacters() {
102 pending_empty_ = false;
103 if (characters_ != NULL) {
104 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
105 characters_ = NULL;
106 text_.Add(atom);
107 LAST(ADD_ATOM);
108 }
109 }
110
111
FlushText()112 void RegExpBuilder::FlushText() {
113 FlushCharacters();
114 int num_text = text_.length();
115 if (num_text == 0) {
116 return;
117 } else if (num_text == 1) {
118 terms_.Add(text_.last());
119 } else {
120 RegExpText* text = new(zone()) RegExpText();
121 for (int i = 0; i < num_text; i++)
122 text_.Get(i)->AppendToText(text);
123 terms_.Add(text);
124 }
125 text_.Clear();
126 }
127
128
AddCharacter(uc16 c)129 void RegExpBuilder::AddCharacter(uc16 c) {
130 pending_empty_ = false;
131 if (characters_ == NULL) {
132 characters_ = new(zone()) ZoneList<uc16>(4);
133 }
134 characters_->Add(c);
135 LAST(ADD_CHAR);
136 }
137
138
AddEmpty()139 void RegExpBuilder::AddEmpty() {
140 pending_empty_ = true;
141 }
142
143
AddAtom(RegExpTree * term)144 void RegExpBuilder::AddAtom(RegExpTree* term) {
145 if (term->IsEmpty()) {
146 AddEmpty();
147 return;
148 }
149 if (term->IsTextElement()) {
150 FlushCharacters();
151 text_.Add(term);
152 } else {
153 FlushText();
154 terms_.Add(term);
155 }
156 LAST(ADD_ATOM);
157 }
158
159
AddAssertion(RegExpTree * assert)160 void RegExpBuilder::AddAssertion(RegExpTree* assert) {
161 FlushText();
162 terms_.Add(assert);
163 LAST(ADD_ASSERT);
164 }
165
166
NewAlternative()167 void RegExpBuilder::NewAlternative() {
168 FlushTerms();
169 }
170
171
FlushTerms()172 void RegExpBuilder::FlushTerms() {
173 FlushText();
174 int num_terms = terms_.length();
175 RegExpTree* alternative;
176 if (num_terms == 0) {
177 alternative = RegExpEmpty::GetInstance();
178 } else if (num_terms == 1) {
179 alternative = terms_.last();
180 } else {
181 alternative = new(zone()) RegExpAlternative(terms_.GetList());
182 }
183 alternatives_.Add(alternative);
184 terms_.Clear();
185 LAST(ADD_NONE);
186 }
187
188
ToRegExp()189 RegExpTree* RegExpBuilder::ToRegExp() {
190 FlushTerms();
191 int num_alternatives = alternatives_.length();
192 if (num_alternatives == 0) {
193 return RegExpEmpty::GetInstance();
194 }
195 if (num_alternatives == 1) {
196 return alternatives_.last();
197 }
198 return new(zone()) RegExpDisjunction(alternatives_.GetList());
199 }
200
201
AddQuantifierToAtom(int min,int max,RegExpQuantifier::Type type)202 void RegExpBuilder::AddQuantifierToAtom(int min,
203 int max,
204 RegExpQuantifier::Type type) {
205 if (pending_empty_) {
206 pending_empty_ = false;
207 return;
208 }
209 RegExpTree* atom;
210 if (characters_ != NULL) {
211 ASSERT(last_added_ == ADD_CHAR);
212 // Last atom was character.
213 Vector<const uc16> char_vector = characters_->ToConstVector();
214 int num_chars = char_vector.length();
215 if (num_chars > 1) {
216 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
217 text_.Add(new(zone()) RegExpAtom(prefix));
218 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
219 }
220 characters_ = NULL;
221 atom = new(zone()) RegExpAtom(char_vector);
222 FlushText();
223 } else if (text_.length() > 0) {
224 ASSERT(last_added_ == ADD_ATOM);
225 atom = text_.RemoveLast();
226 FlushText();
227 } else if (terms_.length() > 0) {
228 ASSERT(last_added_ == ADD_ATOM);
229 atom = terms_.RemoveLast();
230 if (atom->max_match() == 0) {
231 // Guaranteed to only match an empty string.
232 LAST(ADD_TERM);
233 if (min == 0) {
234 return;
235 }
236 terms_.Add(atom);
237 return;
238 }
239 } else {
240 // Only call immediately after adding an atom or character!
241 UNREACHABLE();
242 return;
243 }
244 terms_.Add(new(zone()) RegExpQuantifier(min, max, type, atom));
245 LAST(ADD_TERM);
246 }
247
248
LookupSymbol(int symbol_id)249 Handle<String> Parser::LookupSymbol(int symbol_id) {
250 // Length of symbol cache is the number of identified symbols.
251 // If we are larger than that, or negative, it's not a cached symbol.
252 // This might also happen if there is no preparser symbol data, even
253 // if there is some preparser data.
254 if (static_cast<unsigned>(symbol_id)
255 >= static_cast<unsigned>(symbol_cache_.length())) {
256 if (scanner().is_literal_ascii()) {
257 return isolate()->factory()->LookupAsciiSymbol(
258 scanner().literal_ascii_string());
259 } else {
260 return isolate()->factory()->LookupTwoByteSymbol(
261 scanner().literal_utf16_string());
262 }
263 }
264 return LookupCachedSymbol(symbol_id);
265 }
266
267
LookupCachedSymbol(int symbol_id)268 Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
269 // Make sure the cache is large enough to hold the symbol identifier.
270 if (symbol_cache_.length() <= symbol_id) {
271 // Increase length to index + 1.
272 symbol_cache_.AddBlock(Handle<String>::null(),
273 symbol_id + 1 - symbol_cache_.length());
274 }
275 Handle<String> result = symbol_cache_.at(symbol_id);
276 if (result.is_null()) {
277 if (scanner().is_literal_ascii()) {
278 result = isolate()->factory()->LookupAsciiSymbol(
279 scanner().literal_ascii_string());
280 } else {
281 result = isolate()->factory()->LookupTwoByteSymbol(
282 scanner().literal_utf16_string());
283 }
284 symbol_cache_.at(symbol_id) = result;
285 return result;
286 }
287 isolate()->counters()->total_preparse_symbols_skipped()->Increment();
288 return result;
289 }
290
291
GetFunctionEntry(int start)292 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
293 // The current pre-data entry must be a FunctionEntry with the given
294 // start position.
295 if ((function_index_ + FunctionEntry::kSize <= store_.length())
296 && (static_cast<int>(store_[function_index_]) == start)) {
297 int index = function_index_;
298 function_index_ += FunctionEntry::kSize;
299 return FunctionEntry(store_.SubVector(index,
300 index + FunctionEntry::kSize));
301 }
302 return FunctionEntry();
303 }
304
305
GetSymbolIdentifier()306 int ScriptDataImpl::GetSymbolIdentifier() {
307 return ReadNumber(&symbol_data_);
308 }
309
310
SanityCheck()311 bool ScriptDataImpl::SanityCheck() {
312 // Check that the header data is valid and doesn't specify
313 // point to positions outside the store.
314 if (store_.length() < PreparseDataConstants::kHeaderSize) return false;
315 if (magic() != PreparseDataConstants::kMagicNumber) return false;
316 if (version() != PreparseDataConstants::kCurrentVersion) return false;
317 if (has_error()) {
318 // Extra sane sanity check for error message encoding.
319 if (store_.length() <= PreparseDataConstants::kHeaderSize
320 + PreparseDataConstants::kMessageTextPos) {
321 return false;
322 }
323 if (Read(PreparseDataConstants::kMessageStartPos) >
324 Read(PreparseDataConstants::kMessageEndPos)) {
325 return false;
326 }
327 unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
328 int pos = PreparseDataConstants::kMessageTextPos;
329 for (unsigned int i = 0; i <= arg_count; i++) {
330 if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) {
331 return false;
332 }
333 int length = static_cast<int>(Read(pos));
334 if (length < 0) return false;
335 pos += 1 + length;
336 }
337 if (store_.length() < PreparseDataConstants::kHeaderSize + pos) {
338 return false;
339 }
340 return true;
341 }
342 // Check that the space allocated for function entries is sane.
343 int functions_size =
344 static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]);
345 if (functions_size < 0) return false;
346 if (functions_size % FunctionEntry::kSize != 0) return false;
347 // Check that the count of symbols is non-negative.
348 int symbol_count =
349 static_cast<int>(store_[PreparseDataConstants::kSymbolCountOffset]);
350 if (symbol_count < 0) return false;
351 // Check that the total size has room for header and function entries.
352 int minimum_size =
353 PreparseDataConstants::kHeaderSize + functions_size;
354 if (store_.length() < minimum_size) return false;
355 return true;
356 }
357
358
359
ReadString(unsigned * start,int * chars)360 const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
361 int length = start[0];
362 char* result = NewArray<char>(length + 1);
363 for (int i = 0; i < length; i++) {
364 result[i] = start[i + 1];
365 }
366 result[length] = '\0';
367 if (chars != NULL) *chars = length;
368 return result;
369 }
370
MessageLocation()371 Scanner::Location ScriptDataImpl::MessageLocation() {
372 int beg_pos = Read(PreparseDataConstants::kMessageStartPos);
373 int end_pos = Read(PreparseDataConstants::kMessageEndPos);
374 return Scanner::Location(beg_pos, end_pos);
375 }
376
377
BuildMessage()378 const char* ScriptDataImpl::BuildMessage() {
379 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos);
380 return ReadString(start, NULL);
381 }
382
383
BuildArgs()384 Vector<const char*> ScriptDataImpl::BuildArgs() {
385 int arg_count = Read(PreparseDataConstants::kMessageArgCountPos);
386 const char** array = NewArray<const char*>(arg_count);
387 // Position after text found by skipping past length field and
388 // length field content words.
389 int pos = PreparseDataConstants::kMessageTextPos + 1
390 + Read(PreparseDataConstants::kMessageTextPos);
391 for (int i = 0; i < arg_count; i++) {
392 int count = 0;
393 array[i] = ReadString(ReadAddress(pos), &count);
394 pos += count + 1;
395 }
396 return Vector<const char*>(array, arg_count);
397 }
398
399
Read(int position)400 unsigned ScriptDataImpl::Read(int position) {
401 return store_[PreparseDataConstants::kHeaderSize + position];
402 }
403
404
ReadAddress(int position)405 unsigned* ScriptDataImpl::ReadAddress(int position) {
406 return &store_[PreparseDataConstants::kHeaderSize + position];
407 }
408
409
NewScope(Scope * parent,ScopeType type)410 Scope* Parser::NewScope(Scope* parent, ScopeType type) {
411 Scope* result = new(zone()) Scope(parent, type);
412 result->Initialize();
413 return result;
414 }
415
416
417 // ----------------------------------------------------------------------------
418 // Target is a support class to facilitate manipulation of the
419 // Parser's target_stack_ (the stack of potential 'break' and
420 // 'continue' statement targets). Upon construction, a new target is
421 // added; it is removed upon destruction.
422
423 class Target BASE_EMBEDDED {
424 public:
Target(Target ** variable,AstNode * node)425 Target(Target** variable, AstNode* node)
426 : variable_(variable), node_(node), previous_(*variable) {
427 *variable = this;
428 }
429
~Target()430 ~Target() {
431 *variable_ = previous_;
432 }
433
previous()434 Target* previous() { return previous_; }
node()435 AstNode* node() { return node_; }
436
437 private:
438 Target** variable_;
439 AstNode* node_;
440 Target* previous_;
441 };
442
443
444 class TargetScope BASE_EMBEDDED {
445 public:
TargetScope(Target ** variable)446 explicit TargetScope(Target** variable)
447 : variable_(variable), previous_(*variable) {
448 *variable = NULL;
449 }
450
~TargetScope()451 ~TargetScope() {
452 *variable_ = previous_;
453 }
454
455 private:
456 Target** variable_;
457 Target* previous_;
458 };
459
460
461 // ----------------------------------------------------------------------------
462 // FunctionState and BlockState together implement the parser's scope stack.
463 // The parser's current scope is in top_scope_. The BlockState and
464 // FunctionState constructors push on the scope stack and the destructors
465 // pop. They are also used to hold the parser's per-function and per-block
466 // state.
467
468 class Parser::BlockState BASE_EMBEDDED {
469 public:
BlockState(Parser * parser,Scope * scope)470 BlockState(Parser* parser, Scope* scope)
471 : parser_(parser),
472 outer_scope_(parser->top_scope_) {
473 parser->top_scope_ = scope;
474 }
475
~BlockState()476 ~BlockState() { parser_->top_scope_ = outer_scope_; }
477
478 private:
479 Parser* parser_;
480 Scope* outer_scope_;
481 };
482
483
FunctionState(Parser * parser,Scope * scope,Isolate * isolate)484 Parser::FunctionState::FunctionState(Parser* parser,
485 Scope* scope,
486 Isolate* isolate)
487 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
488 next_handler_index_(0),
489 expected_property_count_(0),
490 only_simple_this_property_assignments_(false),
491 this_property_assignments_(isolate->factory()->empty_fixed_array()),
492 parser_(parser),
493 outer_function_state_(parser->current_function_state_),
494 outer_scope_(parser->top_scope_),
495 saved_ast_node_id_(isolate->ast_node_id()),
496 factory_(isolate) {
497 parser->top_scope_ = scope;
498 parser->current_function_state_ = this;
499 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1);
500 }
501
502
~FunctionState()503 Parser::FunctionState::~FunctionState() {
504 parser_->top_scope_ = outer_scope_;
505 parser_->current_function_state_ = outer_function_state_;
506 if (outer_function_state_ != NULL) {
507 parser_->isolate()->set_ast_node_id(saved_ast_node_id_);
508 }
509 }
510
511
512 // ----------------------------------------------------------------------------
513 // The CHECK_OK macro is a convenient macro to enforce error
514 // handling for functions that may fail (by returning !*ok).
515 //
516 // CAUTION: This macro appends extra statements after a call,
517 // thus it must never be used where only a single statement
518 // is correct (e.g. an if statement branch w/o braces)!
519
520 #define CHECK_OK ok); \
521 if (!*ok) return NULL; \
522 ((void)0
523 #define DUMMY ) // to make indentation work
524 #undef DUMMY
525
526 #define CHECK_FAILED /**/); \
527 if (failed_) return NULL; \
528 ((void)0
529 #define DUMMY ) // to make indentation work
530 #undef DUMMY
531
532 // ----------------------------------------------------------------------------
533 // Implementation of Parser
534
Parser(Handle<Script> script,int parser_flags,v8::Extension * extension,ScriptDataImpl * pre_data)535 Parser::Parser(Handle<Script> script,
536 int parser_flags,
537 v8::Extension* extension,
538 ScriptDataImpl* pre_data)
539 : isolate_(script->GetIsolate()),
540 symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
541 script_(script),
542 scanner_(isolate_->unicode_cache()),
543 reusable_preparser_(NULL),
544 top_scope_(NULL),
545 current_function_state_(NULL),
546 target_stack_(NULL),
547 extension_(extension),
548 pre_data_(pre_data),
549 fni_(NULL),
550 allow_natives_syntax_((parser_flags & kAllowNativesSyntax) != 0),
551 allow_lazy_((parser_flags & kAllowLazy) != 0),
552 allow_modules_((parser_flags & kAllowModules) != 0),
553 stack_overflow_(false),
554 parenthesized_function_(false) {
555 isolate_->set_ast_node_id(0);
556 if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) {
557 scanner().SetHarmonyScoping(true);
558 }
559 if ((parser_flags & kAllowModules) != 0) {
560 scanner().SetHarmonyModules(true);
561 }
562 }
563
564
ParseProgram(CompilationInfo * info)565 FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) {
566 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
567
568 HistogramTimerScope timer(isolate()->counters()->parse());
569 Handle<String> source(String::cast(script_->source()));
570 isolate()->counters()->total_parse_size()->Increment(source->length());
571 fni_ = new(zone()) FuncNameInferrer(isolate());
572
573 // Initialize parser state.
574 source->TryFlatten();
575 if (source->IsExternalTwoByteString()) {
576 // Notice that the stream is destroyed at the end of the branch block.
577 // The last line of the blocks can't be moved outside, even though they're
578 // identical calls.
579 ExternalTwoByteStringUtf16CharacterStream stream(
580 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
581 scanner_.Initialize(&stream);
582 return DoParseProgram(info, source, &zone_scope);
583 } else {
584 GenericStringUtf16CharacterStream stream(source, 0, source->length());
585 scanner_.Initialize(&stream);
586 return DoParseProgram(info, source, &zone_scope);
587 }
588 }
589
590
DoParseProgram(CompilationInfo * info,Handle<String> source,ZoneScope * zone_scope)591 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
592 Handle<String> source,
593 ZoneScope* zone_scope) {
594 ASSERT(top_scope_ == NULL);
595 ASSERT(target_stack_ == NULL);
596 if (pre_data_ != NULL) pre_data_->Initialize();
597
598 // Compute the parsing mode.
599 mode_ = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
600 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
601
602 Handle<String> no_name = isolate()->factory()->empty_symbol();
603
604 FunctionLiteral* result = NULL;
605 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
606 info->SetGlobalScope(scope);
607 if (info->is_eval()) {
608 Handle<SharedFunctionInfo> shared = info->shared_info();
609 if (!info->is_global() && (shared.is_null() || shared->is_function())) {
610 scope = Scope::DeserializeScopeChain(*info->calling_context(), scope);
611 }
612 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) {
613 scope = NewScope(scope, EVAL_SCOPE);
614 }
615 }
616 scope->set_start_position(0);
617 scope->set_end_position(source->length());
618 FunctionState function_state(this, scope, isolate());
619 top_scope_->SetLanguageMode(info->language_mode());
620 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16);
621 bool ok = true;
622 int beg_loc = scanner().location().beg_pos;
623 ParseSourceElements(body, Token::EOS, info->is_eval(), &ok);
624 if (ok && !top_scope_->is_classic_mode()) {
625 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
626 }
627
628 if (ok && is_extended_mode()) {
629 CheckConflictingVarDeclarations(top_scope_, &ok);
630 }
631
632 if (ok) {
633 result = factory()->NewFunctionLiteral(
634 no_name,
635 top_scope_,
636 body,
637 function_state.materialized_literal_count(),
638 function_state.expected_property_count(),
639 function_state.handler_count(),
640 function_state.only_simple_this_property_assignments(),
641 function_state.this_property_assignments(),
642 0,
643 FunctionLiteral::kNoDuplicateParameters,
644 FunctionLiteral::ANONYMOUS_EXPRESSION,
645 FunctionLiteral::kGlobalOrEval);
646 result->set_ast_properties(factory()->visitor()->ast_properties());
647 } else if (stack_overflow_) {
648 isolate()->StackOverflow();
649 }
650 }
651
652 // Make sure the target stack is empty.
653 ASSERT(target_stack_ == NULL);
654
655 // If there was a syntax error we have to get rid of the AST
656 // and it is not safe to do so before the scope has been deleted.
657 if (result == NULL) zone_scope->DeleteOnExit();
658 return result;
659 }
660
661
ParseLazy(CompilationInfo * info)662 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
663 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
664 HistogramTimerScope timer(isolate()->counters()->parse_lazy());
665 Handle<String> source(String::cast(script_->source()));
666 isolate()->counters()->total_parse_size()->Increment(source->length());
667
668 Handle<SharedFunctionInfo> shared_info = info->shared_info();
669 // Initialize parser state.
670 source->TryFlatten();
671 if (source->IsExternalTwoByteString()) {
672 ExternalTwoByteStringUtf16CharacterStream stream(
673 Handle<ExternalTwoByteString>::cast(source),
674 shared_info->start_position(),
675 shared_info->end_position());
676 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
677 return result;
678 } else {
679 GenericStringUtf16CharacterStream stream(source,
680 shared_info->start_position(),
681 shared_info->end_position());
682 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
683 return result;
684 }
685 }
686
687
ParseLazy(CompilationInfo * info,Utf16CharacterStream * source,ZoneScope * zone_scope)688 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
689 Utf16CharacterStream* source,
690 ZoneScope* zone_scope) {
691 Handle<SharedFunctionInfo> shared_info = info->shared_info();
692 scanner_.Initialize(source);
693 ASSERT(top_scope_ == NULL);
694 ASSERT(target_stack_ == NULL);
695
696 Handle<String> name(String::cast(shared_info->name()));
697 fni_ = new(zone()) FuncNameInferrer(isolate());
698 fni_->PushEnclosingName(name);
699
700 mode_ = PARSE_EAGERLY;
701
702 // Place holder for the result.
703 FunctionLiteral* result = NULL;
704
705 {
706 // Parse the function literal.
707 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
708 info->SetGlobalScope(scope);
709 if (!info->closure().is_null()) {
710 scope = Scope::DeserializeScopeChain(info->closure()->context(), scope);
711 }
712 FunctionState function_state(this, scope, isolate());
713 ASSERT(scope->language_mode() != STRICT_MODE || !info->is_classic_mode());
714 ASSERT(scope->language_mode() != EXTENDED_MODE ||
715 info->is_extended_mode());
716 ASSERT(info->language_mode() == shared_info->language_mode());
717 scope->SetLanguageMode(shared_info->language_mode());
718 FunctionLiteral::Type type = shared_info->is_expression()
719 ? (shared_info->is_anonymous()
720 ? FunctionLiteral::ANONYMOUS_EXPRESSION
721 : FunctionLiteral::NAMED_EXPRESSION)
722 : FunctionLiteral::DECLARATION;
723 bool ok = true;
724 result = ParseFunctionLiteral(name,
725 false, // Strict mode name already checked.
726 RelocInfo::kNoPosition,
727 type,
728 &ok);
729 // Make sure the results agree.
730 ASSERT(ok == (result != NULL));
731 }
732
733 // Make sure the target stack is empty.
734 ASSERT(target_stack_ == NULL);
735
736 // If there was a stack overflow we have to get rid of AST and it is
737 // not safe to do before scope has been deleted.
738 if (result == NULL) {
739 zone_scope->DeleteOnExit();
740 if (stack_overflow_) isolate()->StackOverflow();
741 } else {
742 Handle<String> inferred_name(shared_info->inferred_name());
743 result->set_inferred_name(inferred_name);
744 }
745 return result;
746 }
747
748
GetSymbol(bool * ok)749 Handle<String> Parser::GetSymbol(bool* ok) {
750 int symbol_id = -1;
751 if (pre_data() != NULL) {
752 symbol_id = pre_data()->GetSymbolIdentifier();
753 }
754 return LookupSymbol(symbol_id);
755 }
756
757
ReportMessage(const char * type,Vector<const char * > args)758 void Parser::ReportMessage(const char* type, Vector<const char*> args) {
759 Scanner::Location source_location = scanner().location();
760 ReportMessageAt(source_location, type, args);
761 }
762
763
ReportMessage(const char * type,Vector<Handle<String>> args)764 void Parser::ReportMessage(const char* type, Vector<Handle<String> > args) {
765 Scanner::Location source_location = scanner().location();
766 ReportMessageAt(source_location, type, args);
767 }
768
769
ReportMessageAt(Scanner::Location source_location,const char * type,Vector<const char * > args)770 void Parser::ReportMessageAt(Scanner::Location source_location,
771 const char* type,
772 Vector<const char*> args) {
773 MessageLocation location(script_,
774 source_location.beg_pos,
775 source_location.end_pos);
776 Factory* factory = isolate()->factory();
777 Handle<FixedArray> elements = factory->NewFixedArray(args.length());
778 for (int i = 0; i < args.length(); i++) {
779 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
780 elements->set(i, *arg_string);
781 }
782 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
783 Handle<Object> result = factory->NewSyntaxError(type, array);
784 isolate()->Throw(*result, &location);
785 }
786
787
ReportMessageAt(Scanner::Location source_location,const char * type,Vector<Handle<String>> args)788 void Parser::ReportMessageAt(Scanner::Location source_location,
789 const char* type,
790 Vector<Handle<String> > args) {
791 MessageLocation location(script_,
792 source_location.beg_pos,
793 source_location.end_pos);
794 Factory* factory = isolate()->factory();
795 Handle<FixedArray> elements = factory->NewFixedArray(args.length());
796 for (int i = 0; i < args.length(); i++) {
797 elements->set(i, *args[i]);
798 }
799 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
800 Handle<Object> result = factory->NewSyntaxError(type, array);
801 isolate()->Throw(*result, &location);
802 }
803
804
805 // Base class containing common code for the different finder classes used by
806 // the parser.
807 class ParserFinder {
808 protected:
ParserFinder()809 ParserFinder() {}
AsAssignment(Statement * stat)810 static Assignment* AsAssignment(Statement* stat) {
811 if (stat == NULL) return NULL;
812 ExpressionStatement* exp_stat = stat->AsExpressionStatement();
813 if (exp_stat == NULL) return NULL;
814 return exp_stat->expression()->AsAssignment();
815 }
816 };
817
818
819 // An InitializationBlockFinder finds and marks sequences of statements of the
820 // form expr.a = ...; expr.b = ...; etc.
821 class InitializationBlockFinder : public ParserFinder {
822 public:
823 // We find and mark the initialization blocks in top level
824 // non-looping code only. This is because the optimization prevents
825 // reuse of the map transitions, so it should be used only for code
826 // that will only be run once.
InitializationBlockFinder(Scope * top_scope,Target * target)827 InitializationBlockFinder(Scope* top_scope, Target* target)
828 : enabled_(top_scope->DeclarationScope()->is_global_scope() &&
829 !IsLoopTarget(target)),
830 first_in_block_(NULL),
831 last_in_block_(NULL),
832 block_size_(0) {}
833
~InitializationBlockFinder()834 ~InitializationBlockFinder() {
835 if (!enabled_) return;
836 if (InBlock()) EndBlock();
837 }
838
Update(Statement * stat)839 void Update(Statement* stat) {
840 if (!enabled_) return;
841 Assignment* assignment = AsAssignment(stat);
842 if (InBlock()) {
843 if (BlockContinues(assignment)) {
844 UpdateBlock(assignment);
845 } else {
846 EndBlock();
847 }
848 }
849 if (!InBlock() && (assignment != NULL) &&
850 (assignment->op() == Token::ASSIGN)) {
851 StartBlock(assignment);
852 }
853 }
854
855 private:
856 // The minimum number of contiguous assignment that will
857 // be treated as an initialization block. Benchmarks show that
858 // the overhead exceeds the savings below this limit.
859 static const int kMinInitializationBlock = 3;
860
IsLoopTarget(Target * target)861 static bool IsLoopTarget(Target* target) {
862 while (target != NULL) {
863 if (target->node()->AsIterationStatement() != NULL) return true;
864 target = target->previous();
865 }
866 return false;
867 }
868
869 // Returns true if the expressions appear to denote the same object.
870 // In the context of initialization blocks, we only consider expressions
871 // of the form 'expr.x' or expr["x"].
SameObject(Expression * e1,Expression * e2)872 static bool SameObject(Expression* e1, Expression* e2) {
873 VariableProxy* v1 = e1->AsVariableProxy();
874 VariableProxy* v2 = e2->AsVariableProxy();
875 if (v1 != NULL && v2 != NULL) {
876 return v1->name()->Equals(*v2->name());
877 }
878 Property* p1 = e1->AsProperty();
879 Property* p2 = e2->AsProperty();
880 if ((p1 == NULL) || (p2 == NULL)) return false;
881 Literal* key1 = p1->key()->AsLiteral();
882 Literal* key2 = p2->key()->AsLiteral();
883 if ((key1 == NULL) || (key2 == NULL)) return false;
884 if (!key1->handle()->IsString() || !key2->handle()->IsString()) {
885 return false;
886 }
887 String* name1 = String::cast(*key1->handle());
888 String* name2 = String::cast(*key2->handle());
889 if (!name1->Equals(name2)) return false;
890 return SameObject(p1->obj(), p2->obj());
891 }
892
893 // Returns true if the expressions appear to denote different properties
894 // of the same object.
PropertyOfSameObject(Expression * e1,Expression * e2)895 static bool PropertyOfSameObject(Expression* e1, Expression* e2) {
896 Property* p1 = e1->AsProperty();
897 Property* p2 = e2->AsProperty();
898 if ((p1 == NULL) || (p2 == NULL)) return false;
899 return SameObject(p1->obj(), p2->obj());
900 }
901
BlockContinues(Assignment * assignment)902 bool BlockContinues(Assignment* assignment) {
903 if ((assignment == NULL) || (first_in_block_ == NULL)) return false;
904 if (assignment->op() != Token::ASSIGN) return false;
905 return PropertyOfSameObject(first_in_block_->target(),
906 assignment->target());
907 }
908
StartBlock(Assignment * assignment)909 void StartBlock(Assignment* assignment) {
910 first_in_block_ = assignment;
911 last_in_block_ = assignment;
912 block_size_ = 1;
913 }
914
UpdateBlock(Assignment * assignment)915 void UpdateBlock(Assignment* assignment) {
916 last_in_block_ = assignment;
917 ++block_size_;
918 }
919
EndBlock()920 void EndBlock() {
921 if (block_size_ >= kMinInitializationBlock) {
922 first_in_block_->mark_block_start();
923 last_in_block_->mark_block_end();
924 }
925 last_in_block_ = first_in_block_ = NULL;
926 block_size_ = 0;
927 }
928
InBlock()929 bool InBlock() { return first_in_block_ != NULL; }
930
931 const bool enabled_;
932 Assignment* first_in_block_;
933 Assignment* last_in_block_;
934 int block_size_;
935
936 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder);
937 };
938
939
940 // A ThisNamedPropertyAssignmentFinder finds and marks statements of the form
941 // this.x = ...;, where x is a named property. It also determines whether a
942 // function contains only assignments of this type.
943 class ThisNamedPropertyAssignmentFinder : public ParserFinder {
944 public:
ThisNamedPropertyAssignmentFinder(Isolate * isolate)945 explicit ThisNamedPropertyAssignmentFinder(Isolate* isolate)
946 : isolate_(isolate),
947 only_simple_this_property_assignments_(true),
948 names_(0),
949 assigned_arguments_(0),
950 assigned_constants_(0) {
951 }
952
Update(Scope * scope,Statement * stat)953 void Update(Scope* scope, Statement* stat) {
954 // Bail out if function already has property assignment that are
955 // not simple this property assignments.
956 if (!only_simple_this_property_assignments_) {
957 return;
958 }
959
960 // Check whether this statement is of the form this.x = ...;
961 Assignment* assignment = AsAssignment(stat);
962 if (IsThisPropertyAssignment(assignment)) {
963 HandleThisPropertyAssignment(scope, assignment);
964 } else {
965 only_simple_this_property_assignments_ = false;
966 }
967 }
968
969 // Returns whether only statements of the form this.x = y; where y is either a
970 // constant or a function argument was encountered.
only_simple_this_property_assignments()971 bool only_simple_this_property_assignments() {
972 return only_simple_this_property_assignments_;
973 }
974
975 // Returns a fixed array containing three elements for each assignment of the
976 // form this.x = y;
GetThisPropertyAssignments()977 Handle<FixedArray> GetThisPropertyAssignments() {
978 if (names_.is_empty()) {
979 return isolate_->factory()->empty_fixed_array();
980 }
981 ASSERT_EQ(names_.length(), assigned_arguments_.length());
982 ASSERT_EQ(names_.length(), assigned_constants_.length());
983 Handle<FixedArray> assignments =
984 isolate_->factory()->NewFixedArray(names_.length() * 3);
985 for (int i = 0; i < names_.length(); ++i) {
986 assignments->set(i * 3, *names_[i]);
987 assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_[i]));
988 assignments->set(i * 3 + 2, *assigned_constants_[i]);
989 }
990 return assignments;
991 }
992
993 private:
IsThisPropertyAssignment(Assignment * assignment)994 bool IsThisPropertyAssignment(Assignment* assignment) {
995 if (assignment != NULL) {
996 Property* property = assignment->target()->AsProperty();
997 return assignment->op() == Token::ASSIGN
998 && property != NULL
999 && property->obj()->AsVariableProxy() != NULL
1000 && property->obj()->AsVariableProxy()->is_this();
1001 }
1002 return false;
1003 }
1004
HandleThisPropertyAssignment(Scope * scope,Assignment * assignment)1005 void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) {
1006 // Check that the property assigned to is a named property, which is not
1007 // __proto__.
1008 Property* property = assignment->target()->AsProperty();
1009 ASSERT(property != NULL);
1010 Literal* literal = property->key()->AsLiteral();
1011 uint32_t dummy;
1012 if (literal != NULL &&
1013 literal->handle()->IsString() &&
1014 !String::cast(*(literal->handle()))->Equals(
1015 isolate_->heap()->Proto_symbol()) &&
1016 !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) {
1017 Handle<String> key = Handle<String>::cast(literal->handle());
1018
1019 // Check whether the value assigned is either a constant or matches the
1020 // name of one of the arguments to the function.
1021 if (assignment->value()->AsLiteral() != NULL) {
1022 // Constant assigned.
1023 Literal* literal = assignment->value()->AsLiteral();
1024 AssignmentFromConstant(key, literal->handle());
1025 return;
1026 } else if (assignment->value()->AsVariableProxy() != NULL) {
1027 // Variable assigned.
1028 Handle<String> name =
1029 assignment->value()->AsVariableProxy()->name();
1030 // Check whether the variable assigned matches an argument name.
1031 for (int i = 0; i < scope->num_parameters(); i++) {
1032 if (*scope->parameter(i)->name() == *name) {
1033 // Assigned from function argument.
1034 AssignmentFromParameter(key, i);
1035 return;
1036 }
1037 }
1038 }
1039 }
1040 // It is not a simple "this.x = value;" assignment with a constant
1041 // or parameter value.
1042 AssignmentFromSomethingElse();
1043 }
1044
1045
1046
1047
1048 // We will potentially reorder the property assignments, so they must be
1049 // simple enough that the ordering does not matter.
AssignmentFromParameter(Handle<String> name,int index)1050 void AssignmentFromParameter(Handle<String> name, int index) {
1051 EnsureInitialized();
1052 for (int i = 0; i < names_.length(); ++i) {
1053 if (name->Equals(*names_[i])) {
1054 assigned_arguments_[i] = index;
1055 assigned_constants_[i] = isolate_->factory()->undefined_value();
1056 return;
1057 }
1058 }
1059 names_.Add(name);
1060 assigned_arguments_.Add(index);
1061 assigned_constants_.Add(isolate_->factory()->undefined_value());
1062 }
1063
AssignmentFromConstant(Handle<String> name,Handle<Object> value)1064 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
1065 EnsureInitialized();
1066 for (int i = 0; i < names_.length(); ++i) {
1067 if (name->Equals(*names_[i])) {
1068 assigned_arguments_[i] = -1;
1069 assigned_constants_[i] = value;
1070 return;
1071 }
1072 }
1073 names_.Add(name);
1074 assigned_arguments_.Add(-1);
1075 assigned_constants_.Add(value);
1076 }
1077
AssignmentFromSomethingElse()1078 void AssignmentFromSomethingElse() {
1079 // The this assignment is not a simple one.
1080 only_simple_this_property_assignments_ = false;
1081 }
1082
EnsureInitialized()1083 void EnsureInitialized() {
1084 if (names_.capacity() == 0) {
1085 ASSERT(assigned_arguments_.capacity() == 0);
1086 ASSERT(assigned_constants_.capacity() == 0);
1087 names_.Initialize(4);
1088 assigned_arguments_.Initialize(4);
1089 assigned_constants_.Initialize(4);
1090 }
1091 }
1092
1093 Isolate* isolate_;
1094 bool only_simple_this_property_assignments_;
1095 ZoneStringList names_;
1096 ZoneList<int> assigned_arguments_;
1097 ZoneObjectList assigned_constants_;
1098 };
1099
1100
ParseSourceElements(ZoneList<Statement * > * processor,int end_token,bool is_eval,bool * ok)1101 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1102 int end_token,
1103 bool is_eval,
1104 bool* ok) {
1105 // SourceElements ::
1106 // (ModuleElement)* <end_token>
1107
1108 // Allocate a target stack to use for this set of source
1109 // elements. This way, all scripts and functions get their own
1110 // target stack thus avoiding illegal breaks and continues across
1111 // functions.
1112 TargetScope scope(&this->target_stack_);
1113
1114 ASSERT(processor != NULL);
1115 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1116 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate());
1117 bool directive_prologue = true; // Parsing directive prologue.
1118
1119 while (peek() != end_token) {
1120 if (directive_prologue && peek() != Token::STRING) {
1121 directive_prologue = false;
1122 }
1123
1124 Scanner::Location token_loc = scanner().peek_location();
1125 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1126 if (stat == NULL || stat->IsEmpty()) {
1127 directive_prologue = false; // End of directive prologue.
1128 continue;
1129 }
1130
1131 if (directive_prologue) {
1132 // A shot at a directive.
1133 ExpressionStatement* e_stat;
1134 Literal* literal;
1135 // Still processing directive prologue?
1136 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1137 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1138 literal->handle()->IsString()) {
1139 Handle<String> directive = Handle<String>::cast(literal->handle());
1140
1141 // Check "use strict" directive (ES5 14.1).
1142 if (top_scope_->is_classic_mode() &&
1143 directive->Equals(isolate()->heap()->use_strict()) &&
1144 token_loc.end_pos - token_loc.beg_pos ==
1145 isolate()->heap()->use_strict()->length() + 2) {
1146 // TODO(mstarzinger): Global strict eval calls, need their own scope
1147 // as specified in ES5 10.4.2(3). The correct fix would be to always
1148 // add this scope in DoParseProgram(), but that requires adaptations
1149 // all over the code base, so we go with a quick-fix for now.
1150 if (is_eval && !top_scope_->is_eval_scope()) {
1151 ASSERT(top_scope_->is_global_scope());
1152 Scope* scope = NewScope(top_scope_, EVAL_SCOPE);
1153 scope->set_start_position(top_scope_->start_position());
1154 scope->set_end_position(top_scope_->end_position());
1155 top_scope_ = scope;
1156 }
1157 // TODO(ES6): Fix entering extended mode, once it is specified.
1158 top_scope_->SetLanguageMode(FLAG_harmony_scoping
1159 ? EXTENDED_MODE : STRICT_MODE);
1160 // "use strict" is the only directive for now.
1161 directive_prologue = false;
1162 }
1163 } else {
1164 // End of the directive prologue.
1165 directive_prologue = false;
1166 }
1167 }
1168
1169 block_finder.Update(stat);
1170 // Find and mark all assignments to named properties in this (this.x =)
1171 if (top_scope_->is_function_scope()) {
1172 this_property_assignment_finder.Update(top_scope_, stat);
1173 }
1174 processor->Add(stat);
1175 }
1176
1177 // Propagate the collected information on this property assignments.
1178 if (top_scope_->is_function_scope()) {
1179 bool only_simple_this_property_assignments =
1180 this_property_assignment_finder.only_simple_this_property_assignments()
1181 && top_scope_->declarations()->length() == 0;
1182 if (only_simple_this_property_assignments) {
1183 current_function_state_->SetThisPropertyAssignmentInfo(
1184 only_simple_this_property_assignments,
1185 this_property_assignment_finder.GetThisPropertyAssignments());
1186 }
1187 }
1188
1189 return 0;
1190 }
1191
1192
ParseModuleElement(ZoneStringList * labels,bool * ok)1193 Statement* Parser::ParseModuleElement(ZoneStringList* labels,
1194 bool* ok) {
1195 // (Ecma 262 5th Edition, clause 14):
1196 // SourceElement:
1197 // Statement
1198 // FunctionDeclaration
1199 //
1200 // In harmony mode we allow additionally the following productions
1201 // ModuleElement:
1202 // LetDeclaration
1203 // ConstDeclaration
1204 // ModuleDeclaration
1205 // ImportDeclaration
1206 // ExportDeclaration
1207
1208 switch (peek()) {
1209 case Token::FUNCTION:
1210 return ParseFunctionDeclaration(NULL, ok);
1211 case Token::LET:
1212 case Token::CONST:
1213 return ParseVariableStatement(kModuleElement, NULL, ok);
1214 case Token::IMPORT:
1215 return ParseImportDeclaration(ok);
1216 case Token::EXPORT:
1217 return ParseExportDeclaration(ok);
1218 default: {
1219 Statement* stmt = ParseStatement(labels, CHECK_OK);
1220 // Handle 'module' as a context-sensitive keyword.
1221 if (FLAG_harmony_modules &&
1222 peek() == Token::IDENTIFIER &&
1223 !scanner().HasAnyLineTerminatorBeforeNext() &&
1224 stmt != NULL) {
1225 ExpressionStatement* estmt = stmt->AsExpressionStatement();
1226 if (estmt != NULL &&
1227 estmt->expression()->AsVariableProxy() != NULL &&
1228 estmt->expression()->AsVariableProxy()->name()->Equals(
1229 isolate()->heap()->module_symbol()) &&
1230 !scanner().literal_contains_escapes()) {
1231 return ParseModuleDeclaration(NULL, ok);
1232 }
1233 }
1234 return stmt;
1235 }
1236 }
1237 }
1238
1239
ParseModuleDeclaration(ZoneStringList * names,bool * ok)1240 Block* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
1241 // ModuleDeclaration:
1242 // 'module' Identifier Module
1243
1244 // Create new block with one expected declaration.
1245 Block* block = factory()->NewBlock(NULL, 1, true);
1246 Handle<String> name = ParseIdentifier(CHECK_OK);
1247
1248 #ifdef DEBUG
1249 if (FLAG_print_interface_details)
1250 PrintF("# Module %s...\n", name->ToAsciiArray());
1251 #endif
1252
1253 Module* module = ParseModule(CHECK_OK);
1254 VariableProxy* proxy = NewUnresolved(name, LET, module->interface());
1255 Declaration* declaration =
1256 factory()->NewModuleDeclaration(proxy, module, top_scope_);
1257 Declare(declaration, true, CHECK_OK);
1258
1259 #ifdef DEBUG
1260 if (FLAG_print_interface_details)
1261 PrintF("# Module %s.\n", name->ToAsciiArray());
1262
1263 if (FLAG_print_interfaces) {
1264 PrintF("module %s : ", name->ToAsciiArray());
1265 module->interface()->Print();
1266 }
1267 #endif
1268
1269 // TODO(rossberg): Add initialization statement to block.
1270
1271 if (names) names->Add(name);
1272 return block;
1273 }
1274
1275
ParseModule(bool * ok)1276 Module* Parser::ParseModule(bool* ok) {
1277 // Module:
1278 // '{' ModuleElement '}'
1279 // '=' ModulePath ';'
1280 // 'at' String ';'
1281
1282 switch (peek()) {
1283 case Token::LBRACE:
1284 return ParseModuleLiteral(ok);
1285
1286 case Token::ASSIGN: {
1287 Expect(Token::ASSIGN, CHECK_OK);
1288 Module* result = ParseModulePath(CHECK_OK);
1289 ExpectSemicolon(CHECK_OK);
1290 return result;
1291 }
1292
1293 default: {
1294 ExpectContextualKeyword("at", CHECK_OK);
1295 Module* result = ParseModuleUrl(CHECK_OK);
1296 ExpectSemicolon(CHECK_OK);
1297 return result;
1298 }
1299 }
1300 }
1301
1302
ParseModuleLiteral(bool * ok)1303 Module* Parser::ParseModuleLiteral(bool* ok) {
1304 // Module:
1305 // '{' ModuleElement '}'
1306
1307 // Construct block expecting 16 statements.
1308 Block* body = factory()->NewBlock(NULL, 16, false);
1309 #ifdef DEBUG
1310 if (FLAG_print_interface_details) PrintF("# Literal ");
1311 #endif
1312 Scope* scope = NewScope(top_scope_, MODULE_SCOPE);
1313
1314 Expect(Token::LBRACE, CHECK_OK);
1315 scope->set_start_position(scanner().location().beg_pos);
1316 scope->SetLanguageMode(EXTENDED_MODE);
1317
1318 {
1319 BlockState block_state(this, scope);
1320 TargetCollector collector;
1321 Target target(&this->target_stack_, &collector);
1322 Target target_body(&this->target_stack_, body);
1323 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1324
1325 while (peek() != Token::RBRACE) {
1326 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1327 if (stat && !stat->IsEmpty()) {
1328 body->AddStatement(stat);
1329 block_finder.Update(stat);
1330 }
1331 }
1332 }
1333
1334 Expect(Token::RBRACE, CHECK_OK);
1335 scope->set_end_position(scanner().location().end_pos);
1336 body->set_block_scope(scope);
1337
1338 scope->interface()->Freeze(ok);
1339 ASSERT(ok);
1340 return factory()->NewModuleLiteral(body, scope->interface());
1341 }
1342
1343
ParseModulePath(bool * ok)1344 Module* Parser::ParseModulePath(bool* ok) {
1345 // ModulePath:
1346 // Identifier
1347 // ModulePath '.' Identifier
1348
1349 Module* result = ParseModuleVariable(CHECK_OK);
1350 while (Check(Token::PERIOD)) {
1351 Handle<String> name = ParseIdentifierName(CHECK_OK);
1352 #ifdef DEBUG
1353 if (FLAG_print_interface_details)
1354 PrintF("# Path .%s ", name->ToAsciiArray());
1355 #endif
1356 Module* member = factory()->NewModulePath(result, name);
1357 result->interface()->Add(name, member->interface(), ok);
1358 if (!*ok) {
1359 #ifdef DEBUG
1360 if (FLAG_print_interfaces) {
1361 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray());
1362 PrintF("result: ");
1363 result->interface()->Print();
1364 PrintF("member: ");
1365 member->interface()->Print();
1366 }
1367 #endif
1368 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
1369 return NULL;
1370 }
1371 result = member;
1372 }
1373
1374 return result;
1375 }
1376
1377
ParseModuleVariable(bool * ok)1378 Module* Parser::ParseModuleVariable(bool* ok) {
1379 // ModulePath:
1380 // Identifier
1381
1382 Handle<String> name = ParseIdentifier(CHECK_OK);
1383 #ifdef DEBUG
1384 if (FLAG_print_interface_details)
1385 PrintF("# Module variable %s ", name->ToAsciiArray());
1386 #endif
1387 VariableProxy* proxy = top_scope_->NewUnresolved(
1388 factory(), name, scanner().location().beg_pos, Interface::NewModule());
1389
1390 return factory()->NewModuleVariable(proxy);
1391 }
1392
1393
ParseModuleUrl(bool * ok)1394 Module* Parser::ParseModuleUrl(bool* ok) {
1395 // Module:
1396 // String
1397
1398 Expect(Token::STRING, CHECK_OK);
1399 Handle<String> symbol = GetSymbol(CHECK_OK);
1400
1401 // TODO(ES6): Request JS resource from environment...
1402
1403 #ifdef DEBUG
1404 if (FLAG_print_interface_details) PrintF("# Url ");
1405 #endif
1406 return factory()->NewModuleUrl(symbol);
1407 }
1408
1409
ParseModuleSpecifier(bool * ok)1410 Module* Parser::ParseModuleSpecifier(bool* ok) {
1411 // ModuleSpecifier:
1412 // String
1413 // ModulePath
1414
1415 if (peek() == Token::STRING) {
1416 return ParseModuleUrl(ok);
1417 } else {
1418 return ParseModulePath(ok);
1419 }
1420 }
1421
1422
ParseImportDeclaration(bool * ok)1423 Block* Parser::ParseImportDeclaration(bool* ok) {
1424 // ImportDeclaration:
1425 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';'
1426 //
1427 // TODO(ES6): implement destructuring ImportSpecifiers
1428
1429 Expect(Token::IMPORT, CHECK_OK);
1430 ZoneStringList names(1);
1431
1432 Handle<String> name = ParseIdentifierName(CHECK_OK);
1433 names.Add(name);
1434 while (peek() == Token::COMMA) {
1435 Consume(Token::COMMA);
1436 name = ParseIdentifierName(CHECK_OK);
1437 names.Add(name);
1438 }
1439
1440 ExpectContextualKeyword("from", CHECK_OK);
1441 Module* module = ParseModuleSpecifier(CHECK_OK);
1442 ExpectSemicolon(CHECK_OK);
1443
1444 // Generate a separate declaration for each identifier.
1445 // TODO(ES6): once we implement destructuring, make that one declaration.
1446 Block* block = factory()->NewBlock(NULL, 1, true);
1447 for (int i = 0; i < names.length(); ++i) {
1448 #ifdef DEBUG
1449 if (FLAG_print_interface_details)
1450 PrintF("# Import %s ", names[i]->ToAsciiArray());
1451 #endif
1452 Interface* interface = Interface::NewUnknown();
1453 module->interface()->Add(names[i], interface, ok);
1454 if (!*ok) {
1455 #ifdef DEBUG
1456 if (FLAG_print_interfaces) {
1457 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray());
1458 PrintF("module: ");
1459 module->interface()->Print();
1460 }
1461 #endif
1462 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
1463 return NULL;
1464 }
1465 VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
1466 Declaration* declaration =
1467 factory()->NewImportDeclaration(proxy, module, top_scope_);
1468 Declare(declaration, true, CHECK_OK);
1469 // TODO(rossberg): Add initialization statement to block.
1470 }
1471
1472 return block;
1473 }
1474
1475
ParseExportDeclaration(bool * ok)1476 Statement* Parser::ParseExportDeclaration(bool* ok) {
1477 // ExportDeclaration:
1478 // 'export' Identifier (',' Identifier)* ';'
1479 // 'export' VariableDeclaration
1480 // 'export' FunctionDeclaration
1481 // 'export' ModuleDeclaration
1482 //
1483 // TODO(ES6): implement structuring ExportSpecifiers
1484
1485 Expect(Token::EXPORT, CHECK_OK);
1486
1487 Statement* result = NULL;
1488 ZoneStringList names(1);
1489 switch (peek()) {
1490 case Token::IDENTIFIER: {
1491 Handle<String> name = ParseIdentifier(CHECK_OK);
1492 // Handle 'module' as a context-sensitive keyword.
1493 if (!name->IsEqualTo(CStrVector("module"))) {
1494 names.Add(name);
1495 while (peek() == Token::COMMA) {
1496 Consume(Token::COMMA);
1497 name = ParseIdentifier(CHECK_OK);
1498 names.Add(name);
1499 }
1500 ExpectSemicolon(CHECK_OK);
1501 result = factory()->NewEmptyStatement();
1502 } else {
1503 result = ParseModuleDeclaration(&names, CHECK_OK);
1504 }
1505 break;
1506 }
1507
1508 case Token::FUNCTION:
1509 result = ParseFunctionDeclaration(&names, CHECK_OK);
1510 break;
1511
1512 case Token::VAR:
1513 case Token::LET:
1514 case Token::CONST:
1515 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK);
1516 break;
1517
1518 default:
1519 *ok = false;
1520 ReportUnexpectedToken(scanner().current_token());
1521 return NULL;
1522 }
1523
1524 // Extract declared names into export declarations and interface.
1525 Interface* interface = top_scope_->interface();
1526 for (int i = 0; i < names.length(); ++i) {
1527 #ifdef DEBUG
1528 if (FLAG_print_interface_details)
1529 PrintF("# Export %s ", names[i]->ToAsciiArray());
1530 #endif
1531 Interface* inner = Interface::NewUnknown();
1532 interface->Add(names[i], inner, CHECK_OK);
1533 VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
1534 USE(proxy);
1535 // TODO(rossberg): Rethink whether we actually need to store export
1536 // declarations (for compilation?).
1537 // ExportDeclaration* declaration =
1538 // factory()->NewExportDeclaration(proxy, top_scope_);
1539 // top_scope_->AddDeclaration(declaration);
1540 }
1541
1542 ASSERT(result != NULL);
1543 return result;
1544 }
1545
1546
ParseBlockElement(ZoneStringList * labels,bool * ok)1547 Statement* Parser::ParseBlockElement(ZoneStringList* labels,
1548 bool* ok) {
1549 // (Ecma 262 5th Edition, clause 14):
1550 // SourceElement:
1551 // Statement
1552 // FunctionDeclaration
1553 //
1554 // In harmony mode we allow additionally the following productions
1555 // BlockElement (aka SourceElement):
1556 // LetDeclaration
1557 // ConstDeclaration
1558
1559 switch (peek()) {
1560 case Token::FUNCTION:
1561 return ParseFunctionDeclaration(NULL, ok);
1562 case Token::LET:
1563 case Token::CONST:
1564 return ParseVariableStatement(kModuleElement, NULL, ok);
1565 default:
1566 return ParseStatement(labels, ok);
1567 }
1568 }
1569
1570
ParseStatement(ZoneStringList * labels,bool * ok)1571 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
1572 // Statement ::
1573 // Block
1574 // VariableStatement
1575 // EmptyStatement
1576 // ExpressionStatement
1577 // IfStatement
1578 // IterationStatement
1579 // ContinueStatement
1580 // BreakStatement
1581 // ReturnStatement
1582 // WithStatement
1583 // LabelledStatement
1584 // SwitchStatement
1585 // ThrowStatement
1586 // TryStatement
1587 // DebuggerStatement
1588
1589 // Note: Since labels can only be used by 'break' and 'continue'
1590 // statements, which themselves are only valid within blocks,
1591 // iterations or 'switch' statements (i.e., BreakableStatements),
1592 // labels can be simply ignored in all other cases; except for
1593 // trivial labeled break statements 'label: break label' which is
1594 // parsed into an empty statement.
1595
1596 // Keep the source position of the statement
1597 int statement_pos = scanner().peek_location().beg_pos;
1598 Statement* stmt = NULL;
1599 switch (peek()) {
1600 case Token::LBRACE:
1601 return ParseBlock(labels, ok);
1602
1603 case Token::CONST: // fall through
1604 case Token::LET:
1605 case Token::VAR:
1606 stmt = ParseVariableStatement(kStatement, NULL, ok);
1607 break;
1608
1609 case Token::SEMICOLON:
1610 Next();
1611 return factory()->NewEmptyStatement();
1612
1613 case Token::IF:
1614 stmt = ParseIfStatement(labels, ok);
1615 break;
1616
1617 case Token::DO:
1618 stmt = ParseDoWhileStatement(labels, ok);
1619 break;
1620
1621 case Token::WHILE:
1622 stmt = ParseWhileStatement(labels, ok);
1623 break;
1624
1625 case Token::FOR:
1626 stmt = ParseForStatement(labels, ok);
1627 break;
1628
1629 case Token::CONTINUE:
1630 stmt = ParseContinueStatement(ok);
1631 break;
1632
1633 case Token::BREAK:
1634 stmt = ParseBreakStatement(labels, ok);
1635 break;
1636
1637 case Token::RETURN:
1638 stmt = ParseReturnStatement(ok);
1639 break;
1640
1641 case Token::WITH:
1642 stmt = ParseWithStatement(labels, ok);
1643 break;
1644
1645 case Token::SWITCH:
1646 stmt = ParseSwitchStatement(labels, ok);
1647 break;
1648
1649 case Token::THROW:
1650 stmt = ParseThrowStatement(ok);
1651 break;
1652
1653 case Token::TRY: {
1654 // NOTE: It is somewhat complicated to have labels on
1655 // try-statements. When breaking out of a try-finally statement,
1656 // one must take great care not to treat it as a
1657 // fall-through. It is much easier just to wrap the entire
1658 // try-statement in a statement block and put the labels there
1659 Block* result = factory()->NewBlock(labels, 1, false);
1660 Target target(&this->target_stack_, result);
1661 TryStatement* statement = ParseTryStatement(CHECK_OK);
1662 if (statement) {
1663 statement->set_statement_pos(statement_pos);
1664 }
1665 if (result) result->AddStatement(statement);
1666 return result;
1667 }
1668
1669 case Token::FUNCTION: {
1670 // FunctionDeclaration is only allowed in the context of SourceElements
1671 // (Ecma 262 5th Edition, clause 14):
1672 // SourceElement:
1673 // Statement
1674 // FunctionDeclaration
1675 // Common language extension is to allow function declaration in place
1676 // of any statement. This language extension is disabled in strict mode.
1677 if (!top_scope_->is_classic_mode()) {
1678 ReportMessageAt(scanner().peek_location(), "strict_function",
1679 Vector<const char*>::empty());
1680 *ok = false;
1681 return NULL;
1682 }
1683 return ParseFunctionDeclaration(NULL, ok);
1684 }
1685
1686 case Token::DEBUGGER:
1687 stmt = ParseDebuggerStatement(ok);
1688 break;
1689
1690 default:
1691 stmt = ParseExpressionOrLabelledStatement(labels, ok);
1692 }
1693
1694 // Store the source position of the statement
1695 if (stmt != NULL) stmt->set_statement_pos(statement_pos);
1696 return stmt;
1697 }
1698
1699
NewUnresolved(Handle<String> name,VariableMode mode,Interface * interface)1700 VariableProxy* Parser::NewUnresolved(
1701 Handle<String> name, VariableMode mode, Interface* interface) {
1702 // If we are inside a function, a declaration of a var/const variable is a
1703 // truly local variable, and the scope of the variable is always the function
1704 // scope.
1705 // Let/const variables in harmony mode are always added to the immediately
1706 // enclosing scope.
1707 return DeclarationScope(mode)->NewUnresolved(
1708 factory(), name, scanner().location().beg_pos, interface);
1709 }
1710
1711
Declare(Declaration * declaration,bool resolve,bool * ok)1712 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1713 VariableProxy* proxy = declaration->proxy();
1714 Handle<String> name = proxy->name();
1715 VariableMode mode = declaration->mode();
1716 Scope* declaration_scope = DeclarationScope(mode);
1717 Variable* var = NULL;
1718
1719 // If a function scope exists, then we can statically declare this
1720 // variable and also set its mode. In any case, a Declaration node
1721 // will be added to the scope so that the declaration can be added
1722 // to the corresponding activation frame at runtime if necessary.
1723 // For instance declarations inside an eval scope need to be added
1724 // to the calling function context.
1725 // Similarly, strict mode eval scope does not leak variable declarations to
1726 // the caller's scope so we declare all locals, too.
1727 // Also for block scoped let/const bindings the variable can be
1728 // statically declared.
1729 if (declaration_scope->is_function_scope() ||
1730 declaration_scope->is_strict_or_extended_eval_scope() ||
1731 declaration_scope->is_block_scope() ||
1732 declaration_scope->is_module_scope() ||
1733 declaration->AsModuleDeclaration() != NULL) {
1734 // Declare the variable in the function scope.
1735 var = declaration_scope->LocalLookup(name);
1736 if (var == NULL) {
1737 // Declare the name.
1738 var = declaration_scope->DeclareLocal(
1739 name, mode, declaration->initialization(), proxy->interface());
1740 } else {
1741 // The name was declared in this scope before; check for conflicting
1742 // re-declarations. We have a conflict if either of the declarations is
1743 // not a var. There is similar code in runtime.cc in the Declare
1744 // functions. The function CheckNonConflictingScope checks for conflicting
1745 // var and let bindings from different scopes whereas this is a check for
1746 // conflicting declarations within the same scope. This check also covers
1747 //
1748 // function () { let x; { var x; } }
1749 //
1750 // because the var declaration is hoisted to the function scope where 'x'
1751 // is already bound.
1752 if ((mode != VAR) || (var->mode() != VAR)) {
1753 // We only have vars, consts and lets in declarations.
1754 ASSERT(var->mode() == VAR ||
1755 var->mode() == CONST ||
1756 var->mode() == CONST_HARMONY ||
1757 var->mode() == LET);
1758 if (is_extended_mode()) {
1759 // In harmony mode we treat re-declarations as early errors. See
1760 // ES5 16 for a definition of early errors.
1761 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
1762 const char* elms[2] = { "Variable", *c_string };
1763 Vector<const char*> args(elms, 2);
1764 ReportMessage("redeclaration", args);
1765 *ok = false;
1766 return;
1767 }
1768 const char* type = (var->mode() == VAR)
1769 ? "var" : var->is_const_mode() ? "const" : "let";
1770 Handle<String> type_string =
1771 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
1772 Expression* expression =
1773 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
1774 type_string, name);
1775 declaration_scope->SetIllegalRedeclaration(expression);
1776 }
1777 }
1778 }
1779
1780 // We add a declaration node for every declaration. The compiler
1781 // will only generate code if necessary. In particular, declarations
1782 // for inner local variables that do not represent functions won't
1783 // result in any generated code.
1784 //
1785 // Note that we always add an unresolved proxy even if it's not
1786 // used, simply because we don't know in this method (w/o extra
1787 // parameters) if the proxy is needed or not. The proxy will be
1788 // bound during variable resolution time unless it was pre-bound
1789 // below.
1790 //
1791 // WARNING: This will lead to multiple declaration nodes for the
1792 // same variable if it is declared several times. This is not a
1793 // semantic issue as long as we keep the source order, but it may be
1794 // a performance issue since it may lead to repeated
1795 // Runtime::DeclareContextSlot() calls.
1796 declaration_scope->AddDeclaration(declaration);
1797
1798 if ((mode == CONST || mode == CONST_HARMONY) &&
1799 declaration_scope->is_global_scope()) {
1800 // For global const variables we bind the proxy to a variable.
1801 ASSERT(resolve); // should be set by all callers
1802 Variable::Kind kind = Variable::NORMAL;
1803 var = new(zone()) Variable(declaration_scope,
1804 name,
1805 mode,
1806 true,
1807 kind,
1808 kNeedsInitialization);
1809 } else if (declaration_scope->is_eval_scope() &&
1810 declaration_scope->is_classic_mode()) {
1811 // For variable declarations in a non-strict eval scope the proxy is bound
1812 // to a lookup variable to force a dynamic declaration using the
1813 // DeclareContextSlot runtime function.
1814 Variable::Kind kind = Variable::NORMAL;
1815 var = new(zone()) Variable(declaration_scope,
1816 name,
1817 mode,
1818 true,
1819 kind,
1820 declaration->initialization());
1821 var->AllocateTo(Variable::LOOKUP, -1);
1822 resolve = true;
1823 }
1824
1825 // If requested and we have a local variable, bind the proxy to the variable
1826 // at parse-time. This is used for functions (and consts) declared inside
1827 // statements: the corresponding function (or const) variable must be in the
1828 // function scope and not a statement-local scope, e.g. as provided with a
1829 // 'with' statement:
1830 //
1831 // with (obj) {
1832 // function f() {}
1833 // }
1834 //
1835 // which is translated into:
1836 //
1837 // with (obj) {
1838 // // in this case this is not: 'var f; f = function () {};'
1839 // var f = function () {};
1840 // }
1841 //
1842 // Note that if 'f' is accessed from inside the 'with' statement, it
1843 // will be allocated in the context (because we must be able to look
1844 // it up dynamically) but it will also be accessed statically, i.e.,
1845 // with a context slot index and a context chain length for this
1846 // initialization code. Thus, inside the 'with' statement, we need
1847 // both access to the static and the dynamic context chain; the
1848 // runtime needs to provide both.
1849 if (resolve && var != NULL) {
1850 proxy->BindTo(var);
1851
1852 if (FLAG_harmony_modules) {
1853 bool ok;
1854 #ifdef DEBUG
1855 if (FLAG_print_interface_details)
1856 PrintF("# Declare %s\n", var->name()->ToAsciiArray());
1857 #endif
1858 proxy->interface()->Unify(var->interface(), &ok);
1859 if (!ok) {
1860 #ifdef DEBUG
1861 if (FLAG_print_interfaces) {
1862 PrintF("DECLARE TYPE ERROR\n");
1863 PrintF("proxy: ");
1864 proxy->interface()->Print();
1865 PrintF("var: ");
1866 var->interface()->Print();
1867 }
1868 #endif
1869 ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1));
1870 }
1871 }
1872 }
1873 }
1874
1875
1876 // Language extension which is only enabled for source files loaded
1877 // through the API's extension mechanism. A native function
1878 // declaration is resolved by looking up the function through a
1879 // callback provided by the extension.
ParseNativeDeclaration(bool * ok)1880 Statement* Parser::ParseNativeDeclaration(bool* ok) {
1881 Expect(Token::FUNCTION, CHECK_OK);
1882 Handle<String> name = ParseIdentifier(CHECK_OK);
1883 Expect(Token::LPAREN, CHECK_OK);
1884 bool done = (peek() == Token::RPAREN);
1885 while (!done) {
1886 ParseIdentifier(CHECK_OK);
1887 done = (peek() == Token::RPAREN);
1888 if (!done) {
1889 Expect(Token::COMMA, CHECK_OK);
1890 }
1891 }
1892 Expect(Token::RPAREN, CHECK_OK);
1893 Expect(Token::SEMICOLON, CHECK_OK);
1894
1895 // Make sure that the function containing the native declaration
1896 // isn't lazily compiled. The extension structures are only
1897 // accessible while parsing the first time not when reparsing
1898 // because of lazy compilation.
1899 DeclarationScope(VAR)->ForceEagerCompilation();
1900
1901 // Compute the function template for the native function.
1902 v8::Handle<v8::FunctionTemplate> fun_template =
1903 extension_->GetNativeFunction(v8::Utils::ToLocal(name));
1904 ASSERT(!fun_template.IsEmpty());
1905
1906 // Instantiate the function and create a shared function info from it.
1907 Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction());
1908 const int literals = fun->NumberOfLiterals();
1909 Handle<Code> code = Handle<Code>(fun->shared()->code());
1910 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
1911 Handle<SharedFunctionInfo> shared =
1912 isolate()->factory()->NewSharedFunctionInfo(name, literals, code,
1913 Handle<ScopeInfo>(fun->shared()->scope_info()));
1914 shared->set_construct_stub(*construct_stub);
1915
1916 // Copy the function data to the shared function info.
1917 shared->set_function_data(fun->shared()->function_data());
1918 int parameters = fun->shared()->formal_parameter_count();
1919 shared->set_formal_parameter_count(parameters);
1920
1921 // TODO(1240846): It's weird that native function declarations are
1922 // introduced dynamically when we meet their declarations, whereas
1923 // other functions are set up when entering the surrounding scope.
1924 VariableProxy* proxy = NewUnresolved(name, VAR);
1925 Declaration* declaration =
1926 factory()->NewVariableDeclaration(proxy, VAR, top_scope_);
1927 Declare(declaration, true, CHECK_OK);
1928 SharedFunctionInfoLiteral* lit =
1929 factory()->NewSharedFunctionInfoLiteral(shared);
1930 return factory()->NewExpressionStatement(
1931 factory()->NewAssignment(
1932 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition));
1933 }
1934
1935
ParseFunctionDeclaration(ZoneStringList * names,bool * ok)1936 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
1937 // FunctionDeclaration ::
1938 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1939 Expect(Token::FUNCTION, CHECK_OK);
1940 int function_token_position = scanner().location().beg_pos;
1941 bool is_strict_reserved = false;
1942 Handle<String> name = ParseIdentifierOrStrictReservedWord(
1943 &is_strict_reserved, CHECK_OK);
1944 FunctionLiteral* fun = ParseFunctionLiteral(name,
1945 is_strict_reserved,
1946 function_token_position,
1947 FunctionLiteral::DECLARATION,
1948 CHECK_OK);
1949 // Even if we're not at the top-level of the global or a function
1950 // scope, we treat is as such and introduce the function with it's
1951 // initial value upon entering the corresponding scope.
1952 VariableMode mode = is_extended_mode() ? LET : VAR;
1953 VariableProxy* proxy = NewUnresolved(name, mode);
1954 Declaration* declaration =
1955 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_);
1956 Declare(declaration, true, CHECK_OK);
1957 if (names) names->Add(name);
1958 return factory()->NewEmptyStatement();
1959 }
1960
1961
ParseBlock(ZoneStringList * labels,bool * ok)1962 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
1963 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok);
1964
1965 // Block ::
1966 // '{' Statement* '}'
1967
1968 // Note that a Block does not introduce a new execution scope!
1969 // (ECMA-262, 3rd, 12.2)
1970 //
1971 // Construct block expecting 16 statements.
1972 Block* result = factory()->NewBlock(labels, 16, false);
1973 Target target(&this->target_stack_, result);
1974 Expect(Token::LBRACE, CHECK_OK);
1975 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1976 while (peek() != Token::RBRACE) {
1977 Statement* stat = ParseStatement(NULL, CHECK_OK);
1978 if (stat && !stat->IsEmpty()) {
1979 result->AddStatement(stat);
1980 block_finder.Update(stat);
1981 }
1982 }
1983 Expect(Token::RBRACE, CHECK_OK);
1984 return result;
1985 }
1986
1987
ParseScopedBlock(ZoneStringList * labels,bool * ok)1988 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
1989 // The harmony mode uses block elements instead of statements.
1990 //
1991 // Block ::
1992 // '{' BlockElement* '}'
1993
1994 // Construct block expecting 16 statements.
1995 Block* body = factory()->NewBlock(labels, 16, false);
1996 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE);
1997
1998 // Parse the statements and collect escaping labels.
1999 Expect(Token::LBRACE, CHECK_OK);
2000 block_scope->set_start_position(scanner().location().beg_pos);
2001 { BlockState block_state(this, block_scope);
2002 TargetCollector collector;
2003 Target target(&this->target_stack_, &collector);
2004 Target target_body(&this->target_stack_, body);
2005 InitializationBlockFinder block_finder(top_scope_, target_stack_);
2006
2007 while (peek() != Token::RBRACE) {
2008 Statement* stat = ParseBlockElement(NULL, CHECK_OK);
2009 if (stat && !stat->IsEmpty()) {
2010 body->AddStatement(stat);
2011 block_finder.Update(stat);
2012 }
2013 }
2014 }
2015 Expect(Token::RBRACE, CHECK_OK);
2016 block_scope->set_end_position(scanner().location().end_pos);
2017 block_scope = block_scope->FinalizeBlockScope();
2018 body->set_block_scope(block_scope);
2019 return body;
2020 }
2021
2022
ParseVariableStatement(VariableDeclarationContext var_context,ZoneStringList * names,bool * ok)2023 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
2024 ZoneStringList* names,
2025 bool* ok) {
2026 // VariableStatement ::
2027 // VariableDeclarations ';'
2028
2029 Handle<String> ignore;
2030 Block* result =
2031 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
2032 ExpectSemicolon(CHECK_OK);
2033 return result;
2034 }
2035
2036
IsEvalOrArguments(Handle<String> string)2037 bool Parser::IsEvalOrArguments(Handle<String> string) {
2038 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
2039 string.is_identical_to(isolate()->factory()->arguments_symbol());
2040 }
2041
2042
2043 // If the variable declaration declares exactly one non-const
2044 // variable, then *out is set to that variable. In all other cases,
2045 // *out is untouched; in particular, it is the caller's responsibility
2046 // to initialize it properly. This mechanism is used for the parsing
2047 // of 'for-in' loops.
ParseVariableDeclarations(VariableDeclarationContext var_context,VariableDeclarationProperties * decl_props,ZoneStringList * names,Handle<String> * out,bool * ok)2048 Block* Parser::ParseVariableDeclarations(
2049 VariableDeclarationContext var_context,
2050 VariableDeclarationProperties* decl_props,
2051 ZoneStringList* names,
2052 Handle<String>* out,
2053 bool* ok) {
2054 // VariableDeclarations ::
2055 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
2056 //
2057 // The ES6 Draft Rev3 specifies the following grammar for const declarations
2058 //
2059 // ConstDeclaration ::
2060 // const ConstBinding (',' ConstBinding)* ';'
2061 // ConstBinding ::
2062 // Identifier '=' AssignmentExpression
2063 //
2064 // TODO(ES6):
2065 // ConstBinding ::
2066 // BindingPattern '=' AssignmentExpression
2067 VariableMode mode = VAR;
2068 // True if the binding needs initialization. 'let' and 'const' declared
2069 // bindings are created uninitialized by their declaration nodes and
2070 // need initialization. 'var' declared bindings are always initialized
2071 // immediately by their declaration nodes.
2072 bool needs_init = false;
2073 bool is_const = false;
2074 Token::Value init_op = Token::INIT_VAR;
2075 if (peek() == Token::VAR) {
2076 Consume(Token::VAR);
2077 } else if (peek() == Token::CONST) {
2078 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
2079 //
2080 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
2081 //
2082 // * It is a Syntax Error if the code that matches this production is not
2083 // contained in extended code.
2084 //
2085 // However disallowing const in classic mode will break compatibility with
2086 // existing pages. Therefore we keep allowing const with the old
2087 // non-harmony semantics in classic mode.
2088 Consume(Token::CONST);
2089 switch (top_scope_->language_mode()) {
2090 case CLASSIC_MODE:
2091 mode = CONST;
2092 init_op = Token::INIT_CONST;
2093 break;
2094 case STRICT_MODE:
2095 ReportMessage("strict_const", Vector<const char*>::empty());
2096 *ok = false;
2097 return NULL;
2098 case EXTENDED_MODE:
2099 if (var_context == kStatement) {
2100 // In extended mode 'const' declarations are only allowed in source
2101 // element positions.
2102 ReportMessage("unprotected_const", Vector<const char*>::empty());
2103 *ok = false;
2104 return NULL;
2105 }
2106 mode = CONST_HARMONY;
2107 init_op = Token::INIT_CONST_HARMONY;
2108 }
2109 is_const = true;
2110 needs_init = true;
2111 } else if (peek() == Token::LET) {
2112 // ES6 Draft Rev4 section 12.2.1:
2113 //
2114 // LetDeclaration : let LetBindingList ;
2115 //
2116 // * It is a Syntax Error if the code that matches this production is not
2117 // contained in extended code.
2118 if (!is_extended_mode()) {
2119 ReportMessage("illegal_let", Vector<const char*>::empty());
2120 *ok = false;
2121 return NULL;
2122 }
2123 Consume(Token::LET);
2124 if (var_context == kStatement) {
2125 // Let declarations are only allowed in source element positions.
2126 ReportMessage("unprotected_let", Vector<const char*>::empty());
2127 *ok = false;
2128 return NULL;
2129 }
2130 mode = LET;
2131 needs_init = true;
2132 init_op = Token::INIT_LET;
2133 } else {
2134 UNREACHABLE(); // by current callers
2135 }
2136
2137 Scope* declaration_scope = DeclarationScope(mode);
2138
2139 // The scope of a var/const declared variable anywhere inside a function
2140 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
2141 // transform a source-level var/const declaration into a (Function)
2142 // Scope declaration, and rewrite the source-level initialization into an
2143 // assignment statement. We use a block to collect multiple assignments.
2144 //
2145 // We mark the block as initializer block because we don't want the
2146 // rewriter to add a '.result' assignment to such a block (to get compliant
2147 // behavior for code such as print(eval('var x = 7')), and for cosmetic
2148 // reasons when pretty-printing. Also, unless an assignment (initialization)
2149 // is inside an initializer block, it is ignored.
2150 //
2151 // Create new block with one expected declaration.
2152 Block* block = factory()->NewBlock(NULL, 1, true);
2153 int nvars = 0; // the number of variables declared
2154 Handle<String> name;
2155 do {
2156 if (fni_ != NULL) fni_->Enter();
2157
2158 // Parse variable name.
2159 if (nvars > 0) Consume(Token::COMMA);
2160 name = ParseIdentifier(CHECK_OK);
2161 if (fni_ != NULL) fni_->PushVariableName(name);
2162
2163 // Strict mode variables may not be named eval or arguments
2164 if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) {
2165 ReportMessage("strict_var_name", Vector<const char*>::empty());
2166 *ok = false;
2167 return NULL;
2168 }
2169
2170 // Declare variable.
2171 // Note that we *always* must treat the initial value via a separate init
2172 // assignment for variables and constants because the value must be assigned
2173 // when the variable is encountered in the source. But the variable/constant
2174 // is declared (and set to 'undefined') upon entering the function within
2175 // which the variable or constant is declared. Only function variables have
2176 // an initial value in the declaration (because they are initialized upon
2177 // entering the function).
2178 //
2179 // If we have a const declaration, in an inner scope, the proxy is always
2180 // bound to the declared variable (independent of possibly surrounding with
2181 // statements).
2182 // For let/const declarations in harmony mode, we can also immediately
2183 // pre-resolve the proxy because it resides in the same scope as the
2184 // declaration.
2185 VariableProxy* proxy = NewUnresolved(name, mode);
2186 Declaration* declaration =
2187 factory()->NewVariableDeclaration(proxy, mode, top_scope_);
2188 Declare(declaration, mode != VAR, CHECK_OK);
2189 nvars++;
2190 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2191 ReportMessageAt(scanner().location(), "too_many_variables",
2192 Vector<const char*>::empty());
2193 *ok = false;
2194 return NULL;
2195 }
2196 if (names) names->Add(name);
2197
2198 // Parse initialization expression if present and/or needed. A
2199 // declaration of the form:
2200 //
2201 // var v = x;
2202 //
2203 // is syntactic sugar for:
2204 //
2205 // var v; v = x;
2206 //
2207 // In particular, we need to re-lookup 'v' (in top_scope_, not
2208 // declaration_scope) as it may be a different 'v' than the 'v' in the
2209 // declaration (e.g., if we are inside a 'with' statement or 'catch'
2210 // block).
2211 //
2212 // However, note that const declarations are different! A const
2213 // declaration of the form:
2214 //
2215 // const c = x;
2216 //
2217 // is *not* syntactic sugar for:
2218 //
2219 // const c; c = x;
2220 //
2221 // The "variable" c initialized to x is the same as the declared
2222 // one - there is no re-lookup (see the last parameter of the
2223 // Declare() call above).
2224
2225 Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
2226 Expression* value = NULL;
2227 int position = -1;
2228 // Harmony consts have non-optional initializers.
2229 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) {
2230 Expect(Token::ASSIGN, CHECK_OK);
2231 position = scanner().location().beg_pos;
2232 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
2233 // Don't infer if it is "a = function(){...}();"-like expression.
2234 if (fni_ != NULL &&
2235 value->AsCall() == NULL &&
2236 value->AsCallNew() == NULL) {
2237 fni_->Infer();
2238 } else {
2239 fni_->RemoveLastFunction();
2240 }
2241 if (decl_props != NULL) *decl_props = kHasInitializers;
2242 }
2243
2244 // Record the end position of the initializer.
2245 if (proxy->var() != NULL) {
2246 proxy->var()->set_initializer_position(scanner().location().end_pos);
2247 }
2248
2249 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2250 if (value == NULL && needs_init) {
2251 value = GetLiteralUndefined();
2252 }
2253
2254 // Global variable declarations must be compiled in a specific
2255 // way. When the script containing the global variable declaration
2256 // is entered, the global variable must be declared, so that if it
2257 // doesn't exist (not even in a prototype of the global object) it
2258 // gets created with an initial undefined value. This is handled
2259 // by the declarations part of the function representing the
2260 // top-level global code; see Runtime::DeclareGlobalVariable. If
2261 // it already exists (in the object or in a prototype), it is
2262 // *not* touched until the variable declaration statement is
2263 // executed.
2264 //
2265 // Executing the variable declaration statement will always
2266 // guarantee to give the global object a "local" variable; a
2267 // variable defined in the global object and not in any
2268 // prototype. This way, global variable declarations can shadow
2269 // properties in the prototype chain, but only after the variable
2270 // declaration statement has been executed. This is important in
2271 // browsers where the global object (window) has lots of
2272 // properties defined in prototype objects.
2273 if (initialization_scope->is_global_scope()) {
2274 // Compute the arguments for the runtime call.
2275 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3);
2276 // We have at least 1 parameter.
2277 arguments->Add(factory()->NewLiteral(name));
2278 CallRuntime* initialize;
2279
2280 if (is_const) {
2281 arguments->Add(value);
2282 value = NULL; // zap the value to avoid the unnecessary assignment
2283
2284 // Construct the call to Runtime_InitializeConstGlobal
2285 // and add it to the initialization statement block.
2286 // Note that the function does different things depending on
2287 // the number of arguments (1 or 2).
2288 initialize = factory()->NewCallRuntime(
2289 isolate()->factory()->InitializeConstGlobal_symbol(),
2290 Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
2291 arguments);
2292 } else {
2293 // Add strict mode.
2294 // We may want to pass singleton to avoid Literal allocations.
2295 LanguageMode language_mode = initialization_scope->language_mode();
2296 arguments->Add(factory()->NewNumberLiteral(language_mode));
2297
2298 // Be careful not to assign a value to the global variable if
2299 // we're in a with. The initialization value should not
2300 // necessarily be stored in the global object in that case,
2301 // which is why we need to generate a separate assignment node.
2302 if (value != NULL && !inside_with()) {
2303 arguments->Add(value);
2304 value = NULL; // zap the value to avoid the unnecessary assignment
2305 }
2306
2307 // Construct the call to Runtime_InitializeVarGlobal
2308 // and add it to the initialization statement block.
2309 // Note that the function does different things depending on
2310 // the number of arguments (2 or 3).
2311 initialize = factory()->NewCallRuntime(
2312 isolate()->factory()->InitializeVarGlobal_symbol(),
2313 Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
2314 arguments);
2315 }
2316
2317 block->AddStatement(factory()->NewExpressionStatement(initialize));
2318 } else if (needs_init) {
2319 // Constant initializations always assign to the declared constant which
2320 // is always at the function scope level. This is only relevant for
2321 // dynamically looked-up variables and constants (the start context for
2322 // constant lookups is always the function context, while it is the top
2323 // context for var declared variables). Sigh...
2324 // For 'let' and 'const' declared variables in harmony mode the
2325 // initialization also always assigns to the declared variable.
2326 ASSERT(proxy != NULL);
2327 ASSERT(proxy->var() != NULL);
2328 ASSERT(value != NULL);
2329 Assignment* assignment =
2330 factory()->NewAssignment(init_op, proxy, value, position);
2331 block->AddStatement(factory()->NewExpressionStatement(assignment));
2332 value = NULL;
2333 }
2334
2335 // Add an assignment node to the initialization statement block if we still
2336 // have a pending initialization value.
2337 if (value != NULL) {
2338 ASSERT(mode == VAR);
2339 // 'var' initializations are simply assignments (with all the consequences
2340 // if they are inside a 'with' statement - they may change a 'with' object
2341 // property).
2342 VariableProxy* proxy =
2343 initialization_scope->NewUnresolved(factory(), name);
2344 Assignment* assignment =
2345 factory()->NewAssignment(init_op, proxy, value, position);
2346 block->AddStatement(factory()->NewExpressionStatement(assignment));
2347 }
2348
2349 if (fni_ != NULL) fni_->Leave();
2350 } while (peek() == Token::COMMA);
2351
2352 // If there was a single non-const declaration, return it in the output
2353 // parameter for possible use by for/in.
2354 if (nvars == 1 && !is_const) {
2355 *out = name;
2356 }
2357
2358 return block;
2359 }
2360
2361
ContainsLabel(ZoneStringList * labels,Handle<String> label)2362 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) {
2363 ASSERT(!label.is_null());
2364 if (labels != NULL)
2365 for (int i = labels->length(); i-- > 0; )
2366 if (labels->at(i).is_identical_to(label))
2367 return true;
2368
2369 return false;
2370 }
2371
2372
ParseExpressionOrLabelledStatement(ZoneStringList * labels,bool * ok)2373 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
2374 bool* ok) {
2375 // ExpressionStatement | LabelledStatement ::
2376 // Expression ';'
2377 // Identifier ':' Statement
2378 bool starts_with_idenfifier = peek_any_identifier();
2379 Expression* expr = ParseExpression(true, CHECK_OK);
2380 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2381 expr->AsVariableProxy() != NULL &&
2382 !expr->AsVariableProxy()->is_this()) {
2383 // Expression is a single identifier, and not, e.g., a parenthesized
2384 // identifier.
2385 VariableProxy* var = expr->AsVariableProxy();
2386 Handle<String> label = var->name();
2387 // TODO(1240780): We don't check for redeclaration of labels
2388 // during preparsing since keeping track of the set of active
2389 // labels requires nontrivial changes to the way scopes are
2390 // structured. However, these are probably changes we want to
2391 // make later anyway so we should go back and fix this then.
2392 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2393 SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
2394 const char* elms[2] = { "Label", *c_string };
2395 Vector<const char*> args(elms, 2);
2396 ReportMessage("redeclaration", args);
2397 *ok = false;
2398 return NULL;
2399 }
2400 if (labels == NULL) labels = new(zone()) ZoneStringList(4);
2401 labels->Add(label);
2402 // Remove the "ghost" variable that turned out to be a label
2403 // from the top scope. This way, we don't try to resolve it
2404 // during the scope processing.
2405 top_scope_->RemoveUnresolved(var);
2406 Expect(Token::COLON, CHECK_OK);
2407 return ParseStatement(labels, ok);
2408 }
2409
2410 // If we have an extension, we allow a native function declaration.
2411 // A native function declaration starts with "native function" with
2412 // no line-terminator between the two words.
2413 if (extension_ != NULL &&
2414 peek() == Token::FUNCTION &&
2415 !scanner().HasAnyLineTerminatorBeforeNext() &&
2416 expr != NULL &&
2417 expr->AsVariableProxy() != NULL &&
2418 expr->AsVariableProxy()->name()->Equals(
2419 isolate()->heap()->native_symbol()) &&
2420 !scanner().literal_contains_escapes()) {
2421 return ParseNativeDeclaration(ok);
2422 }
2423
2424 // Parsed expression statement, or the context-sensitive 'module' keyword.
2425 // Only expect semicolon in the former case.
2426 if (!FLAG_harmony_modules ||
2427 peek() != Token::IDENTIFIER ||
2428 scanner().HasAnyLineTerminatorBeforeNext() ||
2429 expr->AsVariableProxy() == NULL ||
2430 !expr->AsVariableProxy()->name()->Equals(
2431 isolate()->heap()->module_symbol()) ||
2432 scanner().literal_contains_escapes()) {
2433 ExpectSemicolon(CHECK_OK);
2434 }
2435 return factory()->NewExpressionStatement(expr);
2436 }
2437
2438
ParseIfStatement(ZoneStringList * labels,bool * ok)2439 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) {
2440 // IfStatement ::
2441 // 'if' '(' Expression ')' Statement ('else' Statement)?
2442
2443 Expect(Token::IF, CHECK_OK);
2444 Expect(Token::LPAREN, CHECK_OK);
2445 Expression* condition = ParseExpression(true, CHECK_OK);
2446 Expect(Token::RPAREN, CHECK_OK);
2447 Statement* then_statement = ParseStatement(labels, CHECK_OK);
2448 Statement* else_statement = NULL;
2449 if (peek() == Token::ELSE) {
2450 Next();
2451 else_statement = ParseStatement(labels, CHECK_OK);
2452 } else {
2453 else_statement = factory()->NewEmptyStatement();
2454 }
2455 return factory()->NewIfStatement(condition, then_statement, else_statement);
2456 }
2457
2458
ParseContinueStatement(bool * ok)2459 Statement* Parser::ParseContinueStatement(bool* ok) {
2460 // ContinueStatement ::
2461 // 'continue' Identifier? ';'
2462
2463 Expect(Token::CONTINUE, CHECK_OK);
2464 Handle<String> label = Handle<String>::null();
2465 Token::Value tok = peek();
2466 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
2467 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2468 label = ParseIdentifier(CHECK_OK);
2469 }
2470 IterationStatement* target = NULL;
2471 target = LookupContinueTarget(label, CHECK_OK);
2472 if (target == NULL) {
2473 // Illegal continue statement.
2474 const char* message = "illegal_continue";
2475 Vector<Handle<String> > args;
2476 if (!label.is_null()) {
2477 message = "unknown_label";
2478 args = Vector<Handle<String> >(&label, 1);
2479 }
2480 ReportMessageAt(scanner().location(), message, args);
2481 *ok = false;
2482 return NULL;
2483 }
2484 ExpectSemicolon(CHECK_OK);
2485 return factory()->NewContinueStatement(target);
2486 }
2487
2488
ParseBreakStatement(ZoneStringList * labels,bool * ok)2489 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
2490 // BreakStatement ::
2491 // 'break' Identifier? ';'
2492
2493 Expect(Token::BREAK, CHECK_OK);
2494 Handle<String> label;
2495 Token::Value tok = peek();
2496 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
2497 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2498 label = ParseIdentifier(CHECK_OK);
2499 }
2500 // Parse labeled break statements that target themselves into
2501 // empty statements, e.g. 'l1: l2: l3: break l2;'
2502 if (!label.is_null() && ContainsLabel(labels, label)) {
2503 ExpectSemicolon(CHECK_OK);
2504 return factory()->NewEmptyStatement();
2505 }
2506 BreakableStatement* target = NULL;
2507 target = LookupBreakTarget(label, CHECK_OK);
2508 if (target == NULL) {
2509 // Illegal break statement.
2510 const char* message = "illegal_break";
2511 Vector<Handle<String> > args;
2512 if (!label.is_null()) {
2513 message = "unknown_label";
2514 args = Vector<Handle<String> >(&label, 1);
2515 }
2516 ReportMessageAt(scanner().location(), message, args);
2517 *ok = false;
2518 return NULL;
2519 }
2520 ExpectSemicolon(CHECK_OK);
2521 return factory()->NewBreakStatement(target);
2522 }
2523
2524
ParseReturnStatement(bool * ok)2525 Statement* Parser::ParseReturnStatement(bool* ok) {
2526 // ReturnStatement ::
2527 // 'return' Expression? ';'
2528
2529 // Consume the return token. It is necessary to do the before
2530 // reporting any errors on it, because of the way errors are
2531 // reported (underlining).
2532 Expect(Token::RETURN, CHECK_OK);
2533
2534 Token::Value tok = peek();
2535 Statement* result;
2536 if (scanner().HasAnyLineTerminatorBeforeNext() ||
2537 tok == Token::SEMICOLON ||
2538 tok == Token::RBRACE ||
2539 tok == Token::EOS) {
2540 ExpectSemicolon(CHECK_OK);
2541 result = factory()->NewReturnStatement(GetLiteralUndefined());
2542 } else {
2543 Expression* expr = ParseExpression(true, CHECK_OK);
2544 ExpectSemicolon(CHECK_OK);
2545 result = factory()->NewReturnStatement(expr);
2546 }
2547
2548 // An ECMAScript program is considered syntactically incorrect if it
2549 // contains a return statement that is not within the body of a
2550 // function. See ECMA-262, section 12.9, page 67.
2551 //
2552 // To be consistent with KJS we report the syntax error at runtime.
2553 Scope* declaration_scope = top_scope_->DeclarationScope();
2554 if (declaration_scope->is_global_scope() ||
2555 declaration_scope->is_eval_scope()) {
2556 Handle<String> type = isolate()->factory()->illegal_return_symbol();
2557 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());
2558 return factory()->NewExpressionStatement(throw_error);
2559 }
2560 return result;
2561 }
2562
2563
ParseWithStatement(ZoneStringList * labels,bool * ok)2564 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
2565 // WithStatement ::
2566 // 'with' '(' Expression ')' Statement
2567
2568 Expect(Token::WITH, CHECK_OK);
2569
2570 if (!top_scope_->is_classic_mode()) {
2571 ReportMessage("strict_mode_with", Vector<const char*>::empty());
2572 *ok = false;
2573 return NULL;
2574 }
2575
2576 Expect(Token::LPAREN, CHECK_OK);
2577 Expression* expr = ParseExpression(true, CHECK_OK);
2578 Expect(Token::RPAREN, CHECK_OK);
2579
2580 top_scope_->DeclarationScope()->RecordWithStatement();
2581 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE);
2582 Statement* stmt;
2583 { BlockState block_state(this, with_scope);
2584 with_scope->set_start_position(scanner().peek_location().beg_pos);
2585 stmt = ParseStatement(labels, CHECK_OK);
2586 with_scope->set_end_position(scanner().location().end_pos);
2587 }
2588 return factory()->NewWithStatement(expr, stmt);
2589 }
2590
2591
ParseCaseClause(bool * default_seen_ptr,bool * ok)2592 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2593 // CaseClause ::
2594 // 'case' Expression ':' Statement*
2595 // 'default' ':' Statement*
2596
2597 Expression* label = NULL; // NULL expression indicates default case
2598 if (peek() == Token::CASE) {
2599 Expect(Token::CASE, CHECK_OK);
2600 label = ParseExpression(true, CHECK_OK);
2601 } else {
2602 Expect(Token::DEFAULT, CHECK_OK);
2603 if (*default_seen_ptr) {
2604 ReportMessage("multiple_defaults_in_switch",
2605 Vector<const char*>::empty());
2606 *ok = false;
2607 return NULL;
2608 }
2609 *default_seen_ptr = true;
2610 }
2611 Expect(Token::COLON, CHECK_OK);
2612 int pos = scanner().location().beg_pos;
2613 ZoneList<Statement*>* statements = new(zone()) ZoneList<Statement*>(5);
2614 while (peek() != Token::CASE &&
2615 peek() != Token::DEFAULT &&
2616 peek() != Token::RBRACE) {
2617 Statement* stat = ParseStatement(NULL, CHECK_OK);
2618 statements->Add(stat);
2619 }
2620
2621 return new(zone()) CaseClause(isolate(), label, statements, pos);
2622 }
2623
2624
ParseSwitchStatement(ZoneStringList * labels,bool * ok)2625 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
2626 bool* ok) {
2627 // SwitchStatement ::
2628 // 'switch' '(' Expression ')' '{' CaseClause* '}'
2629
2630 SwitchStatement* statement = factory()->NewSwitchStatement(labels);
2631 Target target(&this->target_stack_, statement);
2632
2633 Expect(Token::SWITCH, CHECK_OK);
2634 Expect(Token::LPAREN, CHECK_OK);
2635 Expression* tag = ParseExpression(true, CHECK_OK);
2636 Expect(Token::RPAREN, CHECK_OK);
2637
2638 bool default_seen = false;
2639 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4);
2640 Expect(Token::LBRACE, CHECK_OK);
2641 while (peek() != Token::RBRACE) {
2642 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
2643 cases->Add(clause);
2644 }
2645 Expect(Token::RBRACE, CHECK_OK);
2646
2647 if (statement) statement->Initialize(tag, cases);
2648 return statement;
2649 }
2650
2651
ParseThrowStatement(bool * ok)2652 Statement* Parser::ParseThrowStatement(bool* ok) {
2653 // ThrowStatement ::
2654 // 'throw' Expression ';'
2655
2656 Expect(Token::THROW, CHECK_OK);
2657 int pos = scanner().location().beg_pos;
2658 if (scanner().HasAnyLineTerminatorBeforeNext()) {
2659 ReportMessage("newline_after_throw", Vector<const char*>::empty());
2660 *ok = false;
2661 return NULL;
2662 }
2663 Expression* exception = ParseExpression(true, CHECK_OK);
2664 ExpectSemicolon(CHECK_OK);
2665
2666 return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos));
2667 }
2668
2669
ParseTryStatement(bool * ok)2670 TryStatement* Parser::ParseTryStatement(bool* ok) {
2671 // TryStatement ::
2672 // 'try' Block Catch
2673 // 'try' Block Finally
2674 // 'try' Block Catch Finally
2675 //
2676 // Catch ::
2677 // 'catch' '(' Identifier ')' Block
2678 //
2679 // Finally ::
2680 // 'finally' Block
2681
2682 Expect(Token::TRY, CHECK_OK);
2683
2684 TargetCollector try_collector;
2685 Block* try_block;
2686
2687 { Target target(&this->target_stack_, &try_collector);
2688 try_block = ParseBlock(NULL, CHECK_OK);
2689 }
2690
2691 Token::Value tok = peek();
2692 if (tok != Token::CATCH && tok != Token::FINALLY) {
2693 ReportMessage("no_catch_or_finally", Vector<const char*>::empty());
2694 *ok = false;
2695 return NULL;
2696 }
2697
2698 // If we can break out from the catch block and there is a finally block,
2699 // then we will need to collect escaping targets from the catch
2700 // block. Since we don't know yet if there will be a finally block, we
2701 // always collect the targets.
2702 TargetCollector catch_collector;
2703 Scope* catch_scope = NULL;
2704 Variable* catch_variable = NULL;
2705 Block* catch_block = NULL;
2706 Handle<String> name;
2707 if (tok == Token::CATCH) {
2708 Consume(Token::CATCH);
2709
2710 Expect(Token::LPAREN, CHECK_OK);
2711 catch_scope = NewScope(top_scope_, CATCH_SCOPE);
2712 catch_scope->set_start_position(scanner().location().beg_pos);
2713 name = ParseIdentifier(CHECK_OK);
2714
2715 if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) {
2716 ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2717 *ok = false;
2718 return NULL;
2719 }
2720
2721 Expect(Token::RPAREN, CHECK_OK);
2722
2723 if (peek() == Token::LBRACE) {
2724 Target target(&this->target_stack_, &catch_collector);
2725 VariableMode mode = is_extended_mode() ? LET : VAR;
2726 catch_variable =
2727 catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
2728
2729 BlockState block_state(this, catch_scope);
2730 catch_block = ParseBlock(NULL, CHECK_OK);
2731 } else {
2732 Expect(Token::LBRACE, CHECK_OK);
2733 }
2734 catch_scope->set_end_position(scanner().location().end_pos);
2735 tok = peek();
2736 }
2737
2738 Block* finally_block = NULL;
2739 if (tok == Token::FINALLY || catch_block == NULL) {
2740 Consume(Token::FINALLY);
2741 finally_block = ParseBlock(NULL, CHECK_OK);
2742 }
2743
2744 // Simplify the AST nodes by converting:
2745 // 'try B0 catch B1 finally B2'
2746 // to:
2747 // 'try { try B0 catch B1 } finally B2'
2748
2749 if (catch_block != NULL && finally_block != NULL) {
2750 // If we have both, create an inner try/catch.
2751 ASSERT(catch_scope != NULL && catch_variable != NULL);
2752 int index = current_function_state_->NextHandlerIndex();
2753 TryCatchStatement* statement = factory()->NewTryCatchStatement(
2754 index, try_block, catch_scope, catch_variable, catch_block);
2755 statement->set_escaping_targets(try_collector.targets());
2756 try_block = factory()->NewBlock(NULL, 1, false);
2757 try_block->AddStatement(statement);
2758 catch_block = NULL; // Clear to indicate it's been handled.
2759 }
2760
2761 TryStatement* result = NULL;
2762 if (catch_block != NULL) {
2763 ASSERT(finally_block == NULL);
2764 ASSERT(catch_scope != NULL && catch_variable != NULL);
2765 int index = current_function_state_->NextHandlerIndex();
2766 result = factory()->NewTryCatchStatement(
2767 index, try_block, catch_scope, catch_variable, catch_block);
2768 } else {
2769 ASSERT(finally_block != NULL);
2770 int index = current_function_state_->NextHandlerIndex();
2771 result = factory()->NewTryFinallyStatement(index, try_block, finally_block);
2772 // Combine the jump targets of the try block and the possible catch block.
2773 try_collector.targets()->AddAll(*catch_collector.targets());
2774 }
2775
2776 result->set_escaping_targets(try_collector.targets());
2777 return result;
2778 }
2779
2780
ParseDoWhileStatement(ZoneStringList * labels,bool * ok)2781 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
2782 bool* ok) {
2783 // DoStatement ::
2784 // 'do' Statement 'while' '(' Expression ')' ';'
2785
2786 DoWhileStatement* loop = factory()->NewDoWhileStatement(labels);
2787 Target target(&this->target_stack_, loop);
2788
2789 Expect(Token::DO, CHECK_OK);
2790 Statement* body = ParseStatement(NULL, CHECK_OK);
2791 Expect(Token::WHILE, CHECK_OK);
2792 Expect(Token::LPAREN, CHECK_OK);
2793
2794 if (loop != NULL) {
2795 int position = scanner().location().beg_pos;
2796 loop->set_condition_position(position);
2797 }
2798
2799 Expression* cond = ParseExpression(true, CHECK_OK);
2800 Expect(Token::RPAREN, CHECK_OK);
2801
2802 // Allow do-statements to be terminated with and without
2803 // semi-colons. This allows code such as 'do;while(0)return' to
2804 // parse, which would not be the case if we had used the
2805 // ExpectSemicolon() functionality here.
2806 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
2807
2808 if (loop != NULL) loop->Initialize(cond, body);
2809 return loop;
2810 }
2811
2812
ParseWhileStatement(ZoneStringList * labels,bool * ok)2813 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
2814 // WhileStatement ::
2815 // 'while' '(' Expression ')' Statement
2816
2817 WhileStatement* loop = factory()->NewWhileStatement(labels);
2818 Target target(&this->target_stack_, loop);
2819
2820 Expect(Token::WHILE, CHECK_OK);
2821 Expect(Token::LPAREN, CHECK_OK);
2822 Expression* cond = ParseExpression(true, CHECK_OK);
2823 Expect(Token::RPAREN, CHECK_OK);
2824 Statement* body = ParseStatement(NULL, CHECK_OK);
2825
2826 if (loop != NULL) loop->Initialize(cond, body);
2827 return loop;
2828 }
2829
2830
ParseForStatement(ZoneStringList * labels,bool * ok)2831 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
2832 // ForStatement ::
2833 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
2834
2835 Statement* init = NULL;
2836
2837 // Create an in-between scope for let-bound iteration variables.
2838 Scope* saved_scope = top_scope_;
2839 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE);
2840 top_scope_ = for_scope;
2841
2842 Expect(Token::FOR, CHECK_OK);
2843 Expect(Token::LPAREN, CHECK_OK);
2844 for_scope->set_start_position(scanner().location().beg_pos);
2845 if (peek() != Token::SEMICOLON) {
2846 if (peek() == Token::VAR || peek() == Token::CONST) {
2847 Handle<String> name;
2848 Block* variable_statement =
2849 ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK);
2850
2851 if (peek() == Token::IN && !name.is_null()) {
2852 VariableProxy* each = top_scope_->NewUnresolved(factory(), name);
2853 ForInStatement* loop = factory()->NewForInStatement(labels);
2854 Target target(&this->target_stack_, loop);
2855
2856 Expect(Token::IN, CHECK_OK);
2857 Expression* enumerable = ParseExpression(true, CHECK_OK);
2858 Expect(Token::RPAREN, CHECK_OK);
2859
2860 Statement* body = ParseStatement(NULL, CHECK_OK);
2861 loop->Initialize(each, enumerable, body);
2862 Block* result = factory()->NewBlock(NULL, 2, false);
2863 result->AddStatement(variable_statement);
2864 result->AddStatement(loop);
2865 top_scope_ = saved_scope;
2866 for_scope->set_end_position(scanner().location().end_pos);
2867 for_scope = for_scope->FinalizeBlockScope();
2868 ASSERT(for_scope == NULL);
2869 // Parsed for-in loop w/ variable/const declaration.
2870 return result;
2871 } else {
2872 init = variable_statement;
2873 }
2874 } else if (peek() == Token::LET) {
2875 Handle<String> name;
2876 VariableDeclarationProperties decl_props = kHasNoInitializers;
2877 Block* variable_statement =
2878 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
2879 CHECK_OK);
2880 bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
2881 if (peek() == Token::IN && accept_IN) {
2882 // Rewrite a for-in statement of the form
2883 //
2884 // for (let x in e) b
2885 //
2886 // into
2887 //
2888 // <let x' be a temporary variable>
2889 // for (x' in e) {
2890 // let x;
2891 // x = x';
2892 // b;
2893 // }
2894
2895 // TODO(keuchel): Move the temporary variable to the block scope, after
2896 // implementing stack allocated block scoped variables.
2897 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(name);
2898 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2899 VariableProxy* each = top_scope_->NewUnresolved(factory(), name);
2900 ForInStatement* loop = factory()->NewForInStatement(labels);
2901 Target target(&this->target_stack_, loop);
2902
2903 Expect(Token::IN, CHECK_OK);
2904 Expression* enumerable = ParseExpression(true, CHECK_OK);
2905 Expect(Token::RPAREN, CHECK_OK);
2906
2907 Statement* body = ParseStatement(NULL, CHECK_OK);
2908 Block* body_block = factory()->NewBlock(NULL, 3, false);
2909 Assignment* assignment = factory()->NewAssignment(
2910 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
2911 Statement* assignment_statement =
2912 factory()->NewExpressionStatement(assignment);
2913 body_block->AddStatement(variable_statement);
2914 body_block->AddStatement(assignment_statement);
2915 body_block->AddStatement(body);
2916 loop->Initialize(temp_proxy, enumerable, body_block);
2917 top_scope_ = saved_scope;
2918 for_scope->set_end_position(scanner().location().end_pos);
2919 for_scope = for_scope->FinalizeBlockScope();
2920 body_block->set_block_scope(for_scope);
2921 // Parsed for-in loop w/ let declaration.
2922 return loop;
2923
2924 } else {
2925 init = variable_statement;
2926 }
2927 } else {
2928 Expression* expression = ParseExpression(false, CHECK_OK);
2929 if (peek() == Token::IN) {
2930 // Signal a reference error if the expression is an invalid
2931 // left-hand side expression. We could report this as a syntax
2932 // error here but for compatibility with JSC we choose to report
2933 // the error at runtime.
2934 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2935 Handle<String> type =
2936 isolate()->factory()->invalid_lhs_in_for_in_symbol();
2937 expression = NewThrowReferenceError(type);
2938 }
2939 ForInStatement* loop = factory()->NewForInStatement(labels);
2940 Target target(&this->target_stack_, loop);
2941
2942 Expect(Token::IN, CHECK_OK);
2943 Expression* enumerable = ParseExpression(true, CHECK_OK);
2944 Expect(Token::RPAREN, CHECK_OK);
2945
2946 Statement* body = ParseStatement(NULL, CHECK_OK);
2947 if (loop) loop->Initialize(expression, enumerable, body);
2948 top_scope_ = saved_scope;
2949 for_scope->set_end_position(scanner().location().end_pos);
2950 for_scope = for_scope->FinalizeBlockScope();
2951 ASSERT(for_scope == NULL);
2952 // Parsed for-in loop.
2953 return loop;
2954
2955 } else {
2956 init = factory()->NewExpressionStatement(expression);
2957 }
2958 }
2959 }
2960
2961 // Standard 'for' loop
2962 ForStatement* loop = factory()->NewForStatement(labels);
2963 Target target(&this->target_stack_, loop);
2964
2965 // Parsed initializer at this point.
2966 Expect(Token::SEMICOLON, CHECK_OK);
2967
2968 Expression* cond = NULL;
2969 if (peek() != Token::SEMICOLON) {
2970 cond = ParseExpression(true, CHECK_OK);
2971 }
2972 Expect(Token::SEMICOLON, CHECK_OK);
2973
2974 Statement* next = NULL;
2975 if (peek() != Token::RPAREN) {
2976 Expression* exp = ParseExpression(true, CHECK_OK);
2977 next = factory()->NewExpressionStatement(exp);
2978 }
2979 Expect(Token::RPAREN, CHECK_OK);
2980
2981 Statement* body = ParseStatement(NULL, CHECK_OK);
2982 top_scope_ = saved_scope;
2983 for_scope->set_end_position(scanner().location().end_pos);
2984 for_scope = for_scope->FinalizeBlockScope();
2985 if (for_scope != NULL) {
2986 // Rewrite a for statement of the form
2987 //
2988 // for (let x = i; c; n) b
2989 //
2990 // into
2991 //
2992 // {
2993 // let x = i;
2994 // for (; c; n) b
2995 // }
2996 ASSERT(init != NULL);
2997 Block* result = factory()->NewBlock(NULL, 2, false);
2998 result->AddStatement(init);
2999 result->AddStatement(loop);
3000 result->set_block_scope(for_scope);
3001 if (loop) loop->Initialize(NULL, cond, next, body);
3002 return result;
3003 } else {
3004 if (loop) loop->Initialize(init, cond, next, body);
3005 return loop;
3006 }
3007 }
3008
3009
3010 // Precedence = 1
ParseExpression(bool accept_IN,bool * ok)3011 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
3012 // Expression ::
3013 // AssignmentExpression
3014 // Expression ',' AssignmentExpression
3015
3016 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK);
3017 while (peek() == Token::COMMA) {
3018 Expect(Token::COMMA, CHECK_OK);
3019 int position = scanner().location().beg_pos;
3020 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
3021 result =
3022 factory()->NewBinaryOperation(Token::COMMA, result, right, position);
3023 }
3024 return result;
3025 }
3026
3027
3028 // Precedence = 2
ParseAssignmentExpression(bool accept_IN,bool * ok)3029 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
3030 // AssignmentExpression ::
3031 // ConditionalExpression
3032 // LeftHandSideExpression AssignmentOperator AssignmentExpression
3033
3034 if (fni_ != NULL) fni_->Enter();
3035 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK);
3036
3037 if (!Token::IsAssignmentOp(peek())) {
3038 if (fni_ != NULL) fni_->Leave();
3039 // Parsed conditional expression only (no assignment).
3040 return expression;
3041 }
3042
3043 // Signal a reference error if the expression is an invalid left-hand
3044 // side expression. We could report this as a syntax error here but
3045 // for compatibility with JSC we choose to report the error at
3046 // runtime.
3047 if (expression == NULL || !expression->IsValidLeftHandSide()) {
3048 Handle<String> type =
3049 isolate()->factory()->invalid_lhs_in_assignment_symbol();
3050 expression = NewThrowReferenceError(type);
3051 }
3052
3053 if (!top_scope_->is_classic_mode()) {
3054 // Assignment to eval or arguments is disallowed in strict mode.
3055 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
3056 }
3057 MarkAsLValue(expression);
3058
3059 Token::Value op = Next(); // Get assignment operator.
3060 int pos = scanner().location().beg_pos;
3061 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
3062
3063 // TODO(1231235): We try to estimate the set of properties set by
3064 // constructors. We define a new property whenever there is an
3065 // assignment to a property of 'this'. We should probably only add
3066 // properties if we haven't seen them before. Otherwise we'll
3067 // probably overestimate the number of properties.
3068 Property* property = expression ? expression->AsProperty() : NULL;
3069 if (op == Token::ASSIGN &&
3070 property != NULL &&
3071 property->obj()->AsVariableProxy() != NULL &&
3072 property->obj()->AsVariableProxy()->is_this()) {
3073 current_function_state_->AddProperty();
3074 }
3075
3076 // If we assign a function literal to a property we pretenure the
3077 // literal so it can be added as a constant function property.
3078 if (property != NULL && right->AsFunctionLiteral() != NULL) {
3079 right->AsFunctionLiteral()->set_pretenure();
3080 }
3081
3082 if (fni_ != NULL) {
3083 // Check if the right hand side is a call to avoid inferring a
3084 // name if we're dealing with "a = function(){...}();"-like
3085 // expression.
3086 if ((op == Token::INIT_VAR
3087 || op == Token::INIT_CONST
3088 || op == Token::ASSIGN)
3089 && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
3090 fni_->Infer();
3091 } else {
3092 fni_->RemoveLastFunction();
3093 }
3094 fni_->Leave();
3095 }
3096
3097 return factory()->NewAssignment(op, expression, right, pos);
3098 }
3099
3100
3101 // Precedence = 3
ParseConditionalExpression(bool accept_IN,bool * ok)3102 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
3103 // ConditionalExpression ::
3104 // LogicalOrExpression
3105 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
3106
3107 // We start using the binary expression parser for prec >= 4 only!
3108 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
3109 if (peek() != Token::CONDITIONAL) return expression;
3110 Consume(Token::CONDITIONAL);
3111 // In parsing the first assignment expression in conditional
3112 // expressions we always accept the 'in' keyword; see ECMA-262,
3113 // section 11.12, page 58.
3114 int left_position = scanner().peek_location().beg_pos;
3115 Expression* left = ParseAssignmentExpression(true, CHECK_OK);
3116 Expect(Token::COLON, CHECK_OK);
3117 int right_position = scanner().peek_location().beg_pos;
3118 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
3119 return factory()->NewConditional(
3120 expression, left, right, left_position, right_position);
3121 }
3122
3123
Precedence(Token::Value tok,bool accept_IN)3124 static int Precedence(Token::Value tok, bool accept_IN) {
3125 if (tok == Token::IN && !accept_IN)
3126 return 0; // 0 precedence will terminate binary expression parsing
3127
3128 return Token::Precedence(tok);
3129 }
3130
3131
3132 // Precedence >= 4
ParseBinaryExpression(int prec,bool accept_IN,bool * ok)3133 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
3134 ASSERT(prec >= 4);
3135 Expression* x = ParseUnaryExpression(CHECK_OK);
3136 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
3137 // prec1 >= 4
3138 while (Precedence(peek(), accept_IN) == prec1) {
3139 Token::Value op = Next();
3140 int position = scanner().location().beg_pos;
3141 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
3142
3143 // Compute some expressions involving only number literals.
3144 if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber() &&
3145 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) {
3146 double x_val = x->AsLiteral()->handle()->Number();
3147 double y_val = y->AsLiteral()->handle()->Number();
3148
3149 switch (op) {
3150 case Token::ADD:
3151 x = factory()->NewNumberLiteral(x_val + y_val);
3152 continue;
3153 case Token::SUB:
3154 x = factory()->NewNumberLiteral(x_val - y_val);
3155 continue;
3156 case Token::MUL:
3157 x = factory()->NewNumberLiteral(x_val * y_val);
3158 continue;
3159 case Token::DIV:
3160 x = factory()->NewNumberLiteral(x_val / y_val);
3161 continue;
3162 case Token::BIT_OR: {
3163 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
3164 x = factory()->NewNumberLiteral(value);
3165 continue;
3166 }
3167 case Token::BIT_AND: {
3168 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
3169 x = factory()->NewNumberLiteral(value);
3170 continue;
3171 }
3172 case Token::BIT_XOR: {
3173 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
3174 x = factory()->NewNumberLiteral(value);
3175 continue;
3176 }
3177 case Token::SHL: {
3178 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
3179 x = factory()->NewNumberLiteral(value);
3180 continue;
3181 }
3182 case Token::SHR: {
3183 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
3184 uint32_t value = DoubleToUint32(x_val) >> shift;
3185 x = factory()->NewNumberLiteral(value);
3186 continue;
3187 }
3188 case Token::SAR: {
3189 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
3190 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
3191 x = factory()->NewNumberLiteral(value);
3192 continue;
3193 }
3194 default:
3195 break;
3196 }
3197 }
3198
3199 // For now we distinguish between comparisons and other binary
3200 // operations. (We could combine the two and get rid of this
3201 // code and AST node eventually.)
3202 if (Token::IsCompareOp(op)) {
3203 // We have a comparison.
3204 Token::Value cmp = op;
3205 switch (op) {
3206 case Token::NE: cmp = Token::EQ; break;
3207 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
3208 default: break;
3209 }
3210 x = factory()->NewCompareOperation(cmp, x, y, position);
3211 if (cmp != op) {
3212 // The comparison was negated - add a NOT.
3213 x = factory()->NewUnaryOperation(Token::NOT, x, position);
3214 }
3215
3216 } else {
3217 // We have a "normal" binary operation.
3218 x = factory()->NewBinaryOperation(op, x, y, position);
3219 }
3220 }
3221 }
3222 return x;
3223 }
3224
3225
ParseUnaryExpression(bool * ok)3226 Expression* Parser::ParseUnaryExpression(bool* ok) {
3227 // UnaryExpression ::
3228 // PostfixExpression
3229 // 'delete' UnaryExpression
3230 // 'void' UnaryExpression
3231 // 'typeof' UnaryExpression
3232 // '++' UnaryExpression
3233 // '--' UnaryExpression
3234 // '+' UnaryExpression
3235 // '-' UnaryExpression
3236 // '~' UnaryExpression
3237 // '!' UnaryExpression
3238
3239 Token::Value op = peek();
3240 if (Token::IsUnaryOp(op)) {
3241 op = Next();
3242 int position = scanner().location().beg_pos;
3243 Expression* expression = ParseUnaryExpression(CHECK_OK);
3244
3245 if (expression != NULL && (expression->AsLiteral() != NULL)) {
3246 Handle<Object> literal = expression->AsLiteral()->handle();
3247 if (op == Token::NOT) {
3248 // Convert the literal to a boolean condition and negate it.
3249 bool condition = literal->ToBoolean()->IsTrue();
3250 Handle<Object> result(isolate()->heap()->ToBoolean(!condition));
3251 return factory()->NewLiteral(result);
3252 } else if (literal->IsNumber()) {
3253 // Compute some expressions involving only number literals.
3254 double value = literal->Number();
3255 switch (op) {
3256 case Token::ADD:
3257 return expression;
3258 case Token::SUB:
3259 return factory()->NewNumberLiteral(-value);
3260 case Token::BIT_NOT:
3261 return factory()->NewNumberLiteral(~DoubleToInt32(value));
3262 default:
3263 break;
3264 }
3265 }
3266 }
3267
3268 // "delete identifier" is a syntax error in strict mode.
3269 if (op == Token::DELETE && !top_scope_->is_classic_mode()) {
3270 VariableProxy* operand = expression->AsVariableProxy();
3271 if (operand != NULL && !operand->is_this()) {
3272 ReportMessage("strict_delete", Vector<const char*>::empty());
3273 *ok = false;
3274 return NULL;
3275 }
3276 }
3277
3278 return factory()->NewUnaryOperation(op, expression, position);
3279
3280 } else if (Token::IsCountOp(op)) {
3281 op = Next();
3282 Expression* expression = ParseUnaryExpression(CHECK_OK);
3283 // Signal a reference error if the expression is an invalid
3284 // left-hand side expression. We could report this as a syntax
3285 // error here but for compatibility with JSC we choose to report the
3286 // error at runtime.
3287 if (expression == NULL || !expression->IsValidLeftHandSide()) {
3288 Handle<String> type =
3289 isolate()->factory()->invalid_lhs_in_prefix_op_symbol();
3290 expression = NewThrowReferenceError(type);
3291 }
3292
3293 if (!top_scope_->is_classic_mode()) {
3294 // Prefix expression operand in strict mode may not be eval or arguments.
3295 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
3296 }
3297 MarkAsLValue(expression);
3298
3299 int position = scanner().location().beg_pos;
3300 return factory()->NewCountOperation(op,
3301 true /* prefix */,
3302 expression,
3303 position);
3304
3305 } else {
3306 return ParsePostfixExpression(ok);
3307 }
3308 }
3309
3310
ParsePostfixExpression(bool * ok)3311 Expression* Parser::ParsePostfixExpression(bool* ok) {
3312 // PostfixExpression ::
3313 // LeftHandSideExpression ('++' | '--')?
3314
3315 Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
3316 if (!scanner().HasAnyLineTerminatorBeforeNext() &&
3317 Token::IsCountOp(peek())) {
3318 // Signal a reference error if the expression is an invalid
3319 // left-hand side expression. We could report this as a syntax
3320 // error here but for compatibility with JSC we choose to report the
3321 // error at runtime.
3322 if (expression == NULL || !expression->IsValidLeftHandSide()) {
3323 Handle<String> type =
3324 isolate()->factory()->invalid_lhs_in_postfix_op_symbol();
3325 expression = NewThrowReferenceError(type);
3326 }
3327
3328 if (!top_scope_->is_classic_mode()) {
3329 // Postfix expression operand in strict mode may not be eval or arguments.
3330 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
3331 }
3332 MarkAsLValue(expression);
3333
3334 Token::Value next = Next();
3335 int position = scanner().location().beg_pos;
3336 expression =
3337 factory()->NewCountOperation(next,
3338 false /* postfix */,
3339 expression,
3340 position);
3341 }
3342 return expression;
3343 }
3344
3345
ParseLeftHandSideExpression(bool * ok)3346 Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
3347 // LeftHandSideExpression ::
3348 // (NewExpression | MemberExpression) ...
3349
3350 Expression* result;
3351 if (peek() == Token::NEW) {
3352 result = ParseNewExpression(CHECK_OK);
3353 } else {
3354 result = ParseMemberExpression(CHECK_OK);
3355 }
3356
3357 while (true) {
3358 switch (peek()) {
3359 case Token::LBRACK: {
3360 Consume(Token::LBRACK);
3361 int pos = scanner().location().beg_pos;
3362 Expression* index = ParseExpression(true, CHECK_OK);
3363 result = factory()->NewProperty(result, index, pos);
3364 Expect(Token::RBRACK, CHECK_OK);
3365 break;
3366 }
3367
3368 case Token::LPAREN: {
3369 int pos;
3370 if (scanner().current_token() == Token::IDENTIFIER) {
3371 // For call of an identifier we want to report position of
3372 // the identifier as position of the call in the stack trace.
3373 pos = scanner().location().beg_pos;
3374 } else {
3375 // For other kinds of calls we record position of the parenthesis as
3376 // position of the call. Note that this is extremely important for
3377 // expressions of the form function(){...}() for which call position
3378 // should not point to the closing brace otherwise it will intersect
3379 // with positions recorded for function literal and confuse debugger.
3380 pos = scanner().peek_location().beg_pos;
3381 }
3382 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3383
3384 // Keep track of eval() calls since they disable all local variable
3385 // optimizations.
3386 // The calls that need special treatment are the
3387 // direct eval calls. These calls are all of the form eval(...), with
3388 // no explicit receiver.
3389 // These calls are marked as potentially direct eval calls. Whether
3390 // they are actually direct calls to eval is determined at run time.
3391 VariableProxy* callee = result->AsVariableProxy();
3392 if (callee != NULL &&
3393 callee->IsVariable(isolate()->factory()->eval_symbol())) {
3394 top_scope_->DeclarationScope()->RecordEvalCall();
3395 }
3396 result = factory()->NewCall(result, args, pos);
3397 break;
3398 }
3399
3400 case Token::PERIOD: {
3401 Consume(Token::PERIOD);
3402 int pos = scanner().location().beg_pos;
3403 Handle<String> name = ParseIdentifierName(CHECK_OK);
3404 result =
3405 factory()->NewProperty(result, factory()->NewLiteral(name), pos);
3406 if (fni_ != NULL) fni_->PushLiteralName(name);
3407 break;
3408 }
3409
3410 default:
3411 return result;
3412 }
3413 }
3414 }
3415
3416
ParseNewPrefix(PositionStack * stack,bool * ok)3417 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
3418 // NewExpression ::
3419 // ('new')+ MemberExpression
3420
3421 // The grammar for new expressions is pretty warped. The keyword
3422 // 'new' can either be a part of the new expression (where it isn't
3423 // followed by an argument list) or a part of the member expression,
3424 // where it must be followed by an argument list. To accommodate
3425 // this, we parse the 'new' keywords greedily and keep track of how
3426 // many we have parsed. This information is then passed on to the
3427 // member expression parser, which is only allowed to match argument
3428 // lists as long as it has 'new' prefixes left
3429 Expect(Token::NEW, CHECK_OK);
3430 PositionStack::Element pos(stack, scanner().location().beg_pos);
3431
3432 Expression* result;
3433 if (peek() == Token::NEW) {
3434 result = ParseNewPrefix(stack, CHECK_OK);
3435 } else {
3436 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK);
3437 }
3438
3439 if (!stack->is_empty()) {
3440 int last = stack->pop();
3441 result = factory()->NewCallNew(
3442 result, new(zone()) ZoneList<Expression*>(0), last);
3443 }
3444 return result;
3445 }
3446
3447
ParseNewExpression(bool * ok)3448 Expression* Parser::ParseNewExpression(bool* ok) {
3449 PositionStack stack(ok);
3450 return ParseNewPrefix(&stack, ok);
3451 }
3452
3453
ParseMemberExpression(bool * ok)3454 Expression* Parser::ParseMemberExpression(bool* ok) {
3455 return ParseMemberWithNewPrefixesExpression(NULL, ok);
3456 }
3457
3458
ParseMemberWithNewPrefixesExpression(PositionStack * stack,bool * ok)3459 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
3460 bool* ok) {
3461 // MemberExpression ::
3462 // (PrimaryExpression | FunctionLiteral)
3463 // ('[' Expression ']' | '.' Identifier | Arguments)*
3464
3465 // Parse the initial primary or function expression.
3466 Expression* result = NULL;
3467 if (peek() == Token::FUNCTION) {
3468 Expect(Token::FUNCTION, CHECK_OK);
3469 int function_token_position = scanner().location().beg_pos;
3470 Handle<String> name;
3471 bool is_strict_reserved_name = false;
3472 if (peek_any_identifier()) {
3473 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
3474 CHECK_OK);
3475 }
3476 FunctionLiteral::Type type = name.is_null()
3477 ? FunctionLiteral::ANONYMOUS_EXPRESSION
3478 : FunctionLiteral::NAMED_EXPRESSION;
3479 result = ParseFunctionLiteral(name,
3480 is_strict_reserved_name,
3481 function_token_position,
3482 type,
3483 CHECK_OK);
3484 } else {
3485 result = ParsePrimaryExpression(CHECK_OK);
3486 }
3487
3488 while (true) {
3489 switch (peek()) {
3490 case Token::LBRACK: {
3491 Consume(Token::LBRACK);
3492 int pos = scanner().location().beg_pos;
3493 Expression* index = ParseExpression(true, CHECK_OK);
3494 result = factory()->NewProperty(result, index, pos);
3495 if (fni_ != NULL) {
3496 if (index->IsPropertyName()) {
3497 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName());
3498 } else {
3499 fni_->PushLiteralName(
3500 isolate()->factory()->anonymous_function_symbol());
3501 }
3502 }
3503 Expect(Token::RBRACK, CHECK_OK);
3504 break;
3505 }
3506 case Token::PERIOD: {
3507 Consume(Token::PERIOD);
3508 int pos = scanner().location().beg_pos;
3509 Handle<String> name = ParseIdentifierName(CHECK_OK);
3510 result =
3511 factory()->NewProperty(result, factory()->NewLiteral(name), pos);
3512 if (fni_ != NULL) fni_->PushLiteralName(name);
3513 break;
3514 }
3515 case Token::LPAREN: {
3516 if ((stack == NULL) || stack->is_empty()) return result;
3517 // Consume one of the new prefixes (already parsed).
3518 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3519 int last = stack->pop();
3520 result = factory()->NewCallNew(result, args, last);
3521 break;
3522 }
3523 default:
3524 return result;
3525 }
3526 }
3527 }
3528
3529
ParseDebuggerStatement(bool * ok)3530 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3531 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3532 // contexts this is used as a statement which invokes the debugger as i a
3533 // break point is present.
3534 // DebuggerStatement ::
3535 // 'debugger' ';'
3536
3537 Expect(Token::DEBUGGER, CHECK_OK);
3538 ExpectSemicolon(CHECK_OK);
3539 return factory()->NewDebuggerStatement();
3540 }
3541
3542
ReportUnexpectedToken(Token::Value token)3543 void Parser::ReportUnexpectedToken(Token::Value token) {
3544 // We don't report stack overflows here, to avoid increasing the
3545 // stack depth even further. Instead we report it after parsing is
3546 // over, in ParseProgram/ParseJson.
3547 if (token == Token::ILLEGAL && stack_overflow_) return;
3548 // Four of the tokens are treated specially
3549 switch (token) {
3550 case Token::EOS:
3551 return ReportMessage("unexpected_eos", Vector<const char*>::empty());
3552 case Token::NUMBER:
3553 return ReportMessage("unexpected_token_number",
3554 Vector<const char*>::empty());
3555 case Token::STRING:
3556 return ReportMessage("unexpected_token_string",
3557 Vector<const char*>::empty());
3558 case Token::IDENTIFIER:
3559 return ReportMessage("unexpected_token_identifier",
3560 Vector<const char*>::empty());
3561 case Token::FUTURE_RESERVED_WORD:
3562 return ReportMessage("unexpected_reserved",
3563 Vector<const char*>::empty());
3564 case Token::FUTURE_STRICT_RESERVED_WORD:
3565 return ReportMessage(top_scope_->is_classic_mode() ?
3566 "unexpected_token_identifier" :
3567 "unexpected_strict_reserved",
3568 Vector<const char*>::empty());
3569 default:
3570 const char* name = Token::String(token);
3571 ASSERT(name != NULL);
3572 ReportMessage("unexpected_token", Vector<const char*>(&name, 1));
3573 }
3574 }
3575
3576
ReportInvalidPreparseData(Handle<String> name,bool * ok)3577 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
3578 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS);
3579 const char* element[1] = { *name_string };
3580 ReportMessage("invalid_preparser_data",
3581 Vector<const char*>(element, 1));
3582 *ok = false;
3583 }
3584
3585
ParsePrimaryExpression(bool * ok)3586 Expression* Parser::ParsePrimaryExpression(bool* ok) {
3587 // PrimaryExpression ::
3588 // 'this'
3589 // 'null'
3590 // 'true'
3591 // 'false'
3592 // Identifier
3593 // Number
3594 // String
3595 // ArrayLiteral
3596 // ObjectLiteral
3597 // RegExpLiteral
3598 // '(' Expression ')'
3599
3600 Expression* result = NULL;
3601 switch (peek()) {
3602 case Token::THIS: {
3603 Consume(Token::THIS);
3604 result = factory()->NewVariableProxy(top_scope_->receiver());
3605 break;
3606 }
3607
3608 case Token::NULL_LITERAL:
3609 Consume(Token::NULL_LITERAL);
3610 result = factory()->NewLiteral(isolate()->factory()->null_value());
3611 break;
3612
3613 case Token::TRUE_LITERAL:
3614 Consume(Token::TRUE_LITERAL);
3615 result = factory()->NewLiteral(isolate()->factory()->true_value());
3616 break;
3617
3618 case Token::FALSE_LITERAL:
3619 Consume(Token::FALSE_LITERAL);
3620 result = factory()->NewLiteral(isolate()->factory()->false_value());
3621 break;
3622
3623 case Token::IDENTIFIER:
3624 case Token::FUTURE_STRICT_RESERVED_WORD: {
3625 Handle<String> name = ParseIdentifier(CHECK_OK);
3626 if (fni_ != NULL) fni_->PushVariableName(name);
3627 // The name may refer to a module instance object, so its type is unknown.
3628 #ifdef DEBUG
3629 if (FLAG_print_interface_details)
3630 PrintF("# Variable %s ", name->ToAsciiArray());
3631 #endif
3632 Interface* interface = Interface::NewUnknown();
3633 result = top_scope_->NewUnresolved(
3634 factory(), name, scanner().location().beg_pos, interface);
3635 break;
3636 }
3637
3638 case Token::NUMBER: {
3639 Consume(Token::NUMBER);
3640 ASSERT(scanner().is_literal_ascii());
3641 double value = StringToDouble(isolate()->unicode_cache(),
3642 scanner().literal_ascii_string(),
3643 ALLOW_HEX | ALLOW_OCTALS);
3644 result = factory()->NewNumberLiteral(value);
3645 break;
3646 }
3647
3648 case Token::STRING: {
3649 Consume(Token::STRING);
3650 Handle<String> symbol = GetSymbol(CHECK_OK);
3651 result = factory()->NewLiteral(symbol);
3652 if (fni_ != NULL) fni_->PushLiteralName(symbol);
3653 break;
3654 }
3655
3656 case Token::ASSIGN_DIV:
3657 result = ParseRegExpLiteral(true, CHECK_OK);
3658 break;
3659
3660 case Token::DIV:
3661 result = ParseRegExpLiteral(false, CHECK_OK);
3662 break;
3663
3664 case Token::LBRACK:
3665 result = ParseArrayLiteral(CHECK_OK);
3666 break;
3667
3668 case Token::LBRACE:
3669 result = ParseObjectLiteral(CHECK_OK);
3670 break;
3671
3672 case Token::LPAREN:
3673 Consume(Token::LPAREN);
3674 // Heuristically try to detect immediately called functions before
3675 // seeing the call parentheses.
3676 parenthesized_function_ = (peek() == Token::FUNCTION);
3677 result = ParseExpression(true, CHECK_OK);
3678 Expect(Token::RPAREN, CHECK_OK);
3679 break;
3680
3681 case Token::MOD:
3682 if (allow_natives_syntax_ || extension_ != NULL) {
3683 result = ParseV8Intrinsic(CHECK_OK);
3684 break;
3685 }
3686 // If we're not allowing special syntax we fall-through to the
3687 // default case.
3688
3689 default: {
3690 Token::Value tok = Next();
3691 ReportUnexpectedToken(tok);
3692 *ok = false;
3693 return NULL;
3694 }
3695 }
3696
3697 return result;
3698 }
3699
3700
BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression * > * values,Handle<FixedArray> literals,bool * is_simple,int * depth)3701 void Parser::BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* values,
3702 Handle<FixedArray> literals,
3703 bool* is_simple,
3704 int* depth) {
3705 // Fill in the literals.
3706 // Accumulate output values in local variables.
3707 bool is_simple_acc = true;
3708 int depth_acc = 1;
3709 for (int i = 0; i < values->length(); i++) {
3710 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3711 if (m_literal != NULL && m_literal->depth() >= depth_acc) {
3712 depth_acc = m_literal->depth() + 1;
3713 }
3714 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3715 if (boilerplate_value->IsUndefined()) {
3716 literals->set_the_hole(i);
3717 is_simple_acc = false;
3718 } else {
3719 literals->set(i, *boilerplate_value);
3720 }
3721 }
3722
3723 *is_simple = is_simple_acc;
3724 *depth = depth_acc;
3725 }
3726
3727
ParseArrayLiteral(bool * ok)3728 Expression* Parser::ParseArrayLiteral(bool* ok) {
3729 // ArrayLiteral ::
3730 // '[' Expression? (',' Expression?)* ']'
3731
3732 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4);
3733 Expect(Token::LBRACK, CHECK_OK);
3734 while (peek() != Token::RBRACK) {
3735 Expression* elem;
3736 if (peek() == Token::COMMA) {
3737 elem = GetLiteralTheHole();
3738 } else {
3739 elem = ParseAssignmentExpression(true, CHECK_OK);
3740 }
3741 values->Add(elem);
3742 if (peek() != Token::RBRACK) {
3743 Expect(Token::COMMA, CHECK_OK);
3744 }
3745 }
3746 Expect(Token::RBRACK, CHECK_OK);
3747
3748 // Update the scope information before the pre-parsing bailout.
3749 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
3750
3751 // Allocate a fixed array to hold all the object literals.
3752 Handle<FixedArray> object_literals =
3753 isolate()->factory()->NewFixedArray(values->length(), TENURED);
3754 Handle<FixedDoubleArray> double_literals;
3755 ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS;
3756 bool has_only_undefined_values = true;
3757
3758 // Fill in the literals.
3759 bool is_simple = true;
3760 int depth = 1;
3761 for (int i = 0, n = values->length(); i < n; i++) {
3762 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3763 if (m_literal != NULL && m_literal->depth() + 1 > depth) {
3764 depth = m_literal->depth() + 1;
3765 }
3766 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3767 if (boilerplate_value->IsUndefined()) {
3768 object_literals->set_the_hole(i);
3769 if (elements_kind == FAST_DOUBLE_ELEMENTS) {
3770 double_literals->set_the_hole(i);
3771 }
3772 is_simple = false;
3773 } else {
3774 // Examine each literal element, and adjust the ElementsKind if the
3775 // literal element is not of a type that can be stored in the current
3776 // ElementsKind. Start with FAST_SMI_ONLY_ELEMENTS, and transition to
3777 // FAST_DOUBLE_ELEMENTS and FAST_ELEMENTS as necessary. Always remember
3778 // the tagged value, no matter what the ElementsKind is in case we
3779 // ultimately end up in FAST_ELEMENTS.
3780 has_only_undefined_values = false;
3781 object_literals->set(i, *boilerplate_value);
3782 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
3783 // Smi only elements. Notice if a transition to FAST_DOUBLE_ELEMENTS or
3784 // FAST_ELEMENTS is required.
3785 if (!boilerplate_value->IsSmi()) {
3786 if (boilerplate_value->IsNumber() && FLAG_smi_only_arrays) {
3787 // Allocate a double array on the FAST_DOUBLE_ELEMENTS transition to
3788 // avoid over-allocating in TENURED space.
3789 double_literals = isolate()->factory()->NewFixedDoubleArray(
3790 values->length(), TENURED);
3791 // Copy the contents of the FAST_SMI_ONLY_ELEMENT array to the
3792 // FAST_DOUBLE_ELEMENTS array so that they are in sync.
3793 for (int j = 0; j < i; ++j) {
3794 Object* smi_value = object_literals->get(j);
3795 if (smi_value->IsTheHole()) {
3796 double_literals->set_the_hole(j);
3797 } else {
3798 double_literals->set(j, Smi::cast(smi_value)->value());
3799 }
3800 }
3801 double_literals->set(i, boilerplate_value->Number());
3802 elements_kind = FAST_DOUBLE_ELEMENTS;
3803 } else {
3804 elements_kind = FAST_ELEMENTS;
3805 }
3806 }
3807 } else if (elements_kind == FAST_DOUBLE_ELEMENTS) {
3808 // Continue to store double values in to FAST_DOUBLE_ELEMENTS arrays
3809 // until the first value is seen that can't be stored as a double.
3810 if (boilerplate_value->IsNumber()) {
3811 double_literals->set(i, boilerplate_value->Number());
3812 } else {
3813 elements_kind = FAST_ELEMENTS;
3814 }
3815 }
3816 }
3817 }
3818
3819 // Very small array literals that don't have a concrete hint about their type
3820 // from a constant value should default to the slow case to avoid lots of
3821 // elements transitions on really small objects.
3822 if (has_only_undefined_values && values->length() <= 2) {
3823 elements_kind = FAST_ELEMENTS;
3824 }
3825
3826 // Simple and shallow arrays can be lazily copied, we transform the
3827 // elements array to a copy-on-write array.
3828 if (is_simple && depth == 1 && values->length() > 0 &&
3829 elements_kind != FAST_DOUBLE_ELEMENTS) {
3830 object_literals->set_map(isolate()->heap()->fixed_cow_array_map());
3831 }
3832
3833 Handle<FixedArrayBase> element_values = elements_kind == FAST_DOUBLE_ELEMENTS
3834 ? Handle<FixedArrayBase>(double_literals)
3835 : Handle<FixedArrayBase>(object_literals);
3836
3837 // Remember both the literal's constant values as well as the ElementsKind
3838 // in a 2-element FixedArray.
3839 Handle<FixedArray> literals =
3840 isolate()->factory()->NewFixedArray(2, TENURED);
3841
3842 literals->set(0, Smi::FromInt(elements_kind));
3843 literals->set(1, *element_values);
3844
3845 return factory()->NewArrayLiteral(
3846 literals, values, literal_index, is_simple, depth);
3847 }
3848
3849
IsBoilerplateProperty(ObjectLiteral::Property * property)3850 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) {
3851 return property != NULL &&
3852 property->kind() != ObjectLiteral::Property::PROTOTYPE;
3853 }
3854
3855
IsCompileTimeValue(Expression * expression)3856 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
3857 if (expression->AsLiteral() != NULL) return true;
3858 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3859 return lit != NULL && lit->is_simple();
3860 }
3861
3862
ArrayLiteralElementNeedsInitialization(Expression * value)3863 bool CompileTimeValue::ArrayLiteralElementNeedsInitialization(
3864 Expression* value) {
3865 // If value is a literal the property value is already set in the
3866 // boilerplate object.
3867 if (value->AsLiteral() != NULL) return false;
3868 // If value is a materialized literal the property value is already set
3869 // in the boilerplate object if it is simple.
3870 if (CompileTimeValue::IsCompileTimeValue(value)) return false;
3871 return true;
3872 }
3873
3874
GetValue(Expression * expression)3875 Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) {
3876 ASSERT(IsCompileTimeValue(expression));
3877 Handle<FixedArray> result = FACTORY->NewFixedArray(2, TENURED);
3878 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3879 if (object_literal != NULL) {
3880 ASSERT(object_literal->is_simple());
3881 if (object_literal->fast_elements()) {
3882 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3883 } else {
3884 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3885 }
3886 result->set(kElementsSlot, *object_literal->constant_properties());
3887 } else {
3888 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3889 ASSERT(array_literal != NULL && array_literal->is_simple());
3890 result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3891 result->set(kElementsSlot, *array_literal->constant_elements());
3892 }
3893 return result;
3894 }
3895
3896
GetType(Handle<FixedArray> value)3897 CompileTimeValue::Type CompileTimeValue::GetType(Handle<FixedArray> value) {
3898 Smi* type_value = Smi::cast(value->get(kTypeSlot));
3899 return static_cast<Type>(type_value->value());
3900 }
3901
3902
GetElements(Handle<FixedArray> value)3903 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3904 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3905 }
3906
3907
GetBoilerplateValue(Expression * expression)3908 Handle<Object> Parser::GetBoilerplateValue(Expression* expression) {
3909 if (expression->AsLiteral() != NULL) {
3910 return expression->AsLiteral()->handle();
3911 }
3912 if (CompileTimeValue::IsCompileTimeValue(expression)) {
3913 return CompileTimeValue::GetValue(expression);
3914 }
3915 return isolate()->factory()->undefined_value();
3916 }
3917
3918 // Validation per 11.1.5 Object Initialiser
3919 class ObjectLiteralPropertyChecker {
3920 public:
ObjectLiteralPropertyChecker(Parser * parser,LanguageMode language_mode)3921 ObjectLiteralPropertyChecker(Parser* parser, LanguageMode language_mode) :
3922 props_(Literal::Match),
3923 parser_(parser),
3924 language_mode_(language_mode) {
3925 }
3926
3927 void CheckProperty(
3928 ObjectLiteral::Property* property,
3929 Scanner::Location loc,
3930 bool* ok);
3931
3932 private:
3933 enum PropertyKind {
3934 kGetAccessor = 0x01,
3935 kSetAccessor = 0x02,
3936 kAccessor = kGetAccessor | kSetAccessor,
3937 kData = 0x04
3938 };
3939
GetPropertyKind(ObjectLiteral::Property * property)3940 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) {
3941 switch (property->kind()) {
3942 case ObjectLiteral::Property::GETTER:
3943 return kGetAccessor;
3944 case ObjectLiteral::Property::SETTER:
3945 return kSetAccessor;
3946 default:
3947 return kData;
3948 }
3949 }
3950
3951 HashMap props_;
3952 Parser* parser_;
3953 LanguageMode language_mode_;
3954 };
3955
3956
CheckProperty(ObjectLiteral::Property * property,Scanner::Location loc,bool * ok)3957 void ObjectLiteralPropertyChecker::CheckProperty(
3958 ObjectLiteral::Property* property,
3959 Scanner::Location loc,
3960 bool* ok) {
3961 ASSERT(property != NULL);
3962 Literal* literal = property->key();
3963 HashMap::Entry* entry = props_.Lookup(literal, literal->Hash(), true);
3964 intptr_t prev = reinterpret_cast<intptr_t> (entry->value);
3965 intptr_t curr = GetPropertyKind(property);
3966
3967 // Duplicate data properties are illegal in strict or extended mode.
3968 if (language_mode_ != CLASSIC_MODE && (curr & prev & kData) != 0) {
3969 parser_->ReportMessageAt(loc, "strict_duplicate_property",
3970 Vector<const char*>::empty());
3971 *ok = false;
3972 return;
3973 }
3974 // Data property conflicting with an accessor.
3975 if (((curr & kData) && (prev & kAccessor)) ||
3976 ((prev & kData) && (curr & kAccessor))) {
3977 parser_->ReportMessageAt(loc, "accessor_data_property",
3978 Vector<const char*>::empty());
3979 *ok = false;
3980 return;
3981 }
3982 // Two accessors of the same type conflicting
3983 if ((curr & prev & kAccessor) != 0) {
3984 parser_->ReportMessageAt(loc, "accessor_get_set",
3985 Vector<const char*>::empty());
3986 *ok = false;
3987 return;
3988 }
3989
3990 // Update map
3991 entry->value = reinterpret_cast<void*> (prev | curr);
3992 *ok = true;
3993 }
3994
3995
BuildObjectLiteralConstantProperties(ZoneList<ObjectLiteral::Property * > * properties,Handle<FixedArray> constant_properties,bool * is_simple,bool * fast_elements,int * depth)3996 void Parser::BuildObjectLiteralConstantProperties(
3997 ZoneList<ObjectLiteral::Property*>* properties,
3998 Handle<FixedArray> constant_properties,
3999 bool* is_simple,
4000 bool* fast_elements,
4001 int* depth) {
4002 int position = 0;
4003 // Accumulate the value in local variables and store it at the end.
4004 bool is_simple_acc = true;
4005 int depth_acc = 1;
4006 uint32_t max_element_index = 0;
4007 uint32_t elements = 0;
4008 for (int i = 0; i < properties->length(); i++) {
4009 ObjectLiteral::Property* property = properties->at(i);
4010 if (!IsBoilerplateProperty(property)) {
4011 is_simple_acc = false;
4012 continue;
4013 }
4014 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
4015 if (m_literal != NULL && m_literal->depth() >= depth_acc) {
4016 depth_acc = m_literal->depth() + 1;
4017 }
4018
4019 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
4020 // value for COMPUTED properties, the real value is filled in at
4021 // runtime. The enumeration order is maintained.
4022 Handle<Object> key = property->key()->handle();
4023 Handle<Object> value = GetBoilerplateValue(property->value());
4024 is_simple_acc = is_simple_acc && !value->IsUndefined();
4025
4026 // Keep track of the number of elements in the object literal and
4027 // the largest element index. If the largest element index is
4028 // much larger than the number of elements, creating an object
4029 // literal with fast elements will be a waste of space.
4030 uint32_t element_index = 0;
4031 if (key->IsString()
4032 && Handle<String>::cast(key)->AsArrayIndex(&element_index)
4033 && element_index > max_element_index) {
4034 max_element_index = element_index;
4035 elements++;
4036 } else if (key->IsSmi()) {
4037 int key_value = Smi::cast(*key)->value();
4038 if (key_value > 0
4039 && static_cast<uint32_t>(key_value) > max_element_index) {
4040 max_element_index = key_value;
4041 }
4042 elements++;
4043 }
4044
4045 // Add name, value pair to the fixed array.
4046 constant_properties->set(position++, *key);
4047 constant_properties->set(position++, *value);
4048 }
4049 *fast_elements =
4050 (max_element_index <= 32) || ((2 * elements) >= max_element_index);
4051 *is_simple = is_simple_acc;
4052 *depth = depth_acc;
4053 }
4054
4055
ParseObjectLiteralGetSet(bool is_getter,bool * ok)4056 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
4057 bool* ok) {
4058 // Special handling of getter and setter syntax:
4059 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
4060 // We have already read the "get" or "set" keyword.
4061 Token::Value next = Next();
4062 bool is_keyword = Token::IsKeyword(next);
4063 if (next == Token::IDENTIFIER || next == Token::NUMBER ||
4064 next == Token::FUTURE_RESERVED_WORD ||
4065 next == Token::FUTURE_STRICT_RESERVED_WORD ||
4066 next == Token::STRING || is_keyword) {
4067 Handle<String> name;
4068 if (is_keyword) {
4069 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next));
4070 } else {
4071 name = GetSymbol(CHECK_OK);
4072 }
4073 FunctionLiteral* value =
4074 ParseFunctionLiteral(name,
4075 false, // reserved words are allowed here
4076 RelocInfo::kNoPosition,
4077 FunctionLiteral::ANONYMOUS_EXPRESSION,
4078 CHECK_OK);
4079 // Allow any number of parameters for compatibilty with JSC.
4080 // Specification only allows zero parameters for get and one for set.
4081 return factory()->NewObjectLiteralProperty(is_getter, value);
4082 } else {
4083 ReportUnexpectedToken(next);
4084 *ok = false;
4085 return NULL;
4086 }
4087 }
4088
4089
ParseObjectLiteral(bool * ok)4090 Expression* Parser::ParseObjectLiteral(bool* ok) {
4091 // ObjectLiteral ::
4092 // '{' (
4093 // ((IdentifierName | String | Number) ':' AssignmentExpression)
4094 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
4095 // )*[','] '}'
4096
4097 ZoneList<ObjectLiteral::Property*>* properties =
4098 new(zone()) ZoneList<ObjectLiteral::Property*>(4);
4099 int number_of_boilerplate_properties = 0;
4100 bool has_function = false;
4101
4102 ObjectLiteralPropertyChecker checker(this, top_scope_->language_mode());
4103
4104 Expect(Token::LBRACE, CHECK_OK);
4105
4106 while (peek() != Token::RBRACE) {
4107 if (fni_ != NULL) fni_->Enter();
4108
4109 Literal* key = NULL;
4110 Token::Value next = peek();
4111
4112 // Location of the property name token
4113 Scanner::Location loc = scanner().peek_location();
4114
4115 switch (next) {
4116 case Token::FUTURE_RESERVED_WORD:
4117 case Token::FUTURE_STRICT_RESERVED_WORD:
4118 case Token::IDENTIFIER: {
4119 bool is_getter = false;
4120 bool is_setter = false;
4121 Handle<String> id =
4122 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
4123 if (fni_ != NULL) fni_->PushLiteralName(id);
4124
4125 if ((is_getter || is_setter) && peek() != Token::COLON) {
4126 // Update loc to point to the identifier
4127 loc = scanner().peek_location();
4128 ObjectLiteral::Property* property =
4129 ParseObjectLiteralGetSet(is_getter, CHECK_OK);
4130 if (IsBoilerplateProperty(property)) {
4131 number_of_boilerplate_properties++;
4132 }
4133 // Validate the property.
4134 checker.CheckProperty(property, loc, CHECK_OK);
4135 properties->Add(property);
4136 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
4137
4138 if (fni_ != NULL) {
4139 fni_->Infer();
4140 fni_->Leave();
4141 }
4142 continue; // restart the while
4143 }
4144 // Failed to parse as get/set property, so it's just a property
4145 // called "get" or "set".
4146 key = factory()->NewLiteral(id);
4147 break;
4148 }
4149 case Token::STRING: {
4150 Consume(Token::STRING);
4151 Handle<String> string = GetSymbol(CHECK_OK);
4152 if (fni_ != NULL) fni_->PushLiteralName(string);
4153 uint32_t index;
4154 if (!string.is_null() && string->AsArrayIndex(&index)) {
4155 key = factory()->NewNumberLiteral(index);
4156 break;
4157 }
4158 key = factory()->NewLiteral(string);
4159 break;
4160 }
4161 case Token::NUMBER: {
4162 Consume(Token::NUMBER);
4163 ASSERT(scanner().is_literal_ascii());
4164 double value = StringToDouble(isolate()->unicode_cache(),
4165 scanner().literal_ascii_string(),
4166 ALLOW_HEX | ALLOW_OCTALS);
4167 key = factory()->NewNumberLiteral(value);
4168 break;
4169 }
4170 default:
4171 if (Token::IsKeyword(next)) {
4172 Consume(next);
4173 Handle<String> string = GetSymbol(CHECK_OK);
4174 key = factory()->NewLiteral(string);
4175 } else {
4176 // Unexpected token.
4177 Token::Value next = Next();
4178 ReportUnexpectedToken(next);
4179 *ok = false;
4180 return NULL;
4181 }
4182 }
4183
4184 Expect(Token::COLON, CHECK_OK);
4185 Expression* value = ParseAssignmentExpression(true, CHECK_OK);
4186
4187 ObjectLiteral::Property* property =
4188 new(zone()) ObjectLiteral::Property(key, value, isolate());
4189
4190 // Mark top-level object literals that contain function literals and
4191 // pretenure the literal so it can be added as a constant function
4192 // property.
4193 if (top_scope_->DeclarationScope()->is_global_scope() &&
4194 value->AsFunctionLiteral() != NULL) {
4195 has_function = true;
4196 value->AsFunctionLiteral()->set_pretenure();
4197 }
4198
4199 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
4200 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
4201 // Validate the property
4202 checker.CheckProperty(property, loc, CHECK_OK);
4203 properties->Add(property);
4204
4205 // TODO(1240767): Consider allowing trailing comma.
4206 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
4207
4208 if (fni_ != NULL) {
4209 fni_->Infer();
4210 fni_->Leave();
4211 }
4212 }
4213 Expect(Token::RBRACE, CHECK_OK);
4214
4215 // Computation of literal_index must happen before pre parse bailout.
4216 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
4217
4218 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray(
4219 number_of_boilerplate_properties * 2, TENURED);
4220
4221 bool is_simple = true;
4222 bool fast_elements = true;
4223 int depth = 1;
4224 BuildObjectLiteralConstantProperties(properties,
4225 constant_properties,
4226 &is_simple,
4227 &fast_elements,
4228 &depth);
4229 return factory()->NewObjectLiteral(constant_properties,
4230 properties,
4231 literal_index,
4232 is_simple,
4233 fast_elements,
4234 depth,
4235 has_function);
4236 }
4237
4238
ParseRegExpLiteral(bool seen_equal,bool * ok)4239 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
4240 if (!scanner().ScanRegExpPattern(seen_equal)) {
4241 Next();
4242 ReportMessage("unterminated_regexp", Vector<const char*>::empty());
4243 *ok = false;
4244 return NULL;
4245 }
4246
4247 int literal_index = current_function_state_->NextMaterializedLiteralIndex();
4248
4249 Handle<String> js_pattern = NextLiteralString(TENURED);
4250 scanner().ScanRegExpFlags();
4251 Handle<String> js_flags = NextLiteralString(TENURED);
4252 Next();
4253
4254 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index);
4255 }
4256
4257
ParseArguments(bool * ok)4258 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
4259 // Arguments ::
4260 // '(' (AssignmentExpression)*[','] ')'
4261
4262 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4);
4263 Expect(Token::LPAREN, CHECK_OK);
4264 bool done = (peek() == Token::RPAREN);
4265 while (!done) {
4266 Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
4267 result->Add(argument);
4268 if (result->length() > kMaxNumFunctionParameters) {
4269 ReportMessageAt(scanner().location(), "too_many_arguments",
4270 Vector<const char*>::empty());
4271 *ok = false;
4272 return NULL;
4273 }
4274 done = (peek() == Token::RPAREN);
4275 if (!done) Expect(Token::COMMA, CHECK_OK);
4276 }
4277 Expect(Token::RPAREN, CHECK_OK);
4278 return result;
4279 }
4280
4281
4282 class SingletonLogger : public ParserRecorder {
4283 public:
SingletonLogger()4284 SingletonLogger() : has_error_(false), start_(-1), end_(-1) { }
~SingletonLogger()4285 virtual ~SingletonLogger() { }
4286
Reset()4287 void Reset() { has_error_ = false; }
4288
LogFunction(int start,int end,int literals,int properties,LanguageMode mode)4289 virtual void LogFunction(int start,
4290 int end,
4291 int literals,
4292 int properties,
4293 LanguageMode mode) {
4294 ASSERT(!has_error_);
4295 start_ = start;
4296 end_ = end;
4297 literals_ = literals;
4298 properties_ = properties;
4299 mode_ = mode;
4300 };
4301
4302 // Logs a symbol creation of a literal or identifier.
LogAsciiSymbol(int start,Vector<const char> literal)4303 virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
LogUtf16Symbol(int start,Vector<const uc16> literal)4304 virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) { }
4305
4306 // Logs an error message and marks the log as containing an error.
4307 // Further logging will be ignored, and ExtractData will return a vector
4308 // representing the error only.
LogMessage(int start,int end,const char * message,const char * argument_opt)4309 virtual void LogMessage(int start,
4310 int end,
4311 const char* message,
4312 const char* argument_opt) {
4313 has_error_ = true;
4314 start_ = start;
4315 end_ = end;
4316 message_ = message;
4317 argument_opt_ = argument_opt;
4318 }
4319
function_position()4320 virtual int function_position() { return 0; }
4321
symbol_position()4322 virtual int symbol_position() { return 0; }
4323
symbol_ids()4324 virtual int symbol_ids() { return -1; }
4325
ExtractData()4326 virtual Vector<unsigned> ExtractData() {
4327 UNREACHABLE();
4328 return Vector<unsigned>();
4329 }
4330
PauseRecording()4331 virtual void PauseRecording() { }
4332
ResumeRecording()4333 virtual void ResumeRecording() { }
4334
has_error()4335 bool has_error() { return has_error_; }
4336
start()4337 int start() { return start_; }
end()4338 int end() { return end_; }
literals()4339 int literals() {
4340 ASSERT(!has_error_);
4341 return literals_;
4342 }
properties()4343 int properties() {
4344 ASSERT(!has_error_);
4345 return properties_;
4346 }
language_mode()4347 LanguageMode language_mode() {
4348 ASSERT(!has_error_);
4349 return mode_;
4350 }
message()4351 const char* message() {
4352 ASSERT(has_error_);
4353 return message_;
4354 }
argument_opt()4355 const char* argument_opt() {
4356 ASSERT(has_error_);
4357 return argument_opt_;
4358 }
4359
4360 private:
4361 bool has_error_;
4362 int start_;
4363 int end_;
4364 // For function entries.
4365 int literals_;
4366 int properties_;
4367 LanguageMode mode_;
4368 // For error messages.
4369 const char* message_;
4370 const char* argument_opt_;
4371 };
4372
4373
ParseFunctionLiteral(Handle<String> function_name,bool name_is_strict_reserved,int function_token_position,FunctionLiteral::Type type,bool * ok)4374 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
4375 bool name_is_strict_reserved,
4376 int function_token_position,
4377 FunctionLiteral::Type type,
4378 bool* ok) {
4379 // Function ::
4380 // '(' FormalParameterList? ')' '{' FunctionBody '}'
4381
4382 // Anonymous functions were passed either the empty symbol or a null
4383 // handle as the function name. Remember if we were passed a non-empty
4384 // handle to decide whether to invoke function name inference.
4385 bool should_infer_name = function_name.is_null();
4386
4387 // We want a non-null handle as the function name.
4388 if (should_infer_name) {
4389 function_name = isolate()->factory()->empty_symbol();
4390 }
4391
4392 int num_parameters = 0;
4393 // Function declarations are function scoped in normal mode, so they are
4394 // hoisted. In harmony block scoping mode they are block scoped, so they
4395 // are not hoisted.
4396 Scope* scope = (type == FunctionLiteral::DECLARATION && !is_extended_mode())
4397 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE)
4398 : NewScope(top_scope_, FUNCTION_SCOPE);
4399 ZoneList<Statement*>* body = NULL;
4400 int materialized_literal_count = -1;
4401 int expected_property_count = -1;
4402 int handler_count = 0;
4403 bool only_simple_this_property_assignments;
4404 Handle<FixedArray> this_property_assignments;
4405 FunctionLiteral::ParameterFlag duplicate_parameters =
4406 FunctionLiteral::kNoDuplicateParameters;
4407 AstProperties ast_properties;
4408 // Parse function body.
4409 { FunctionState function_state(this, scope, isolate());
4410 top_scope_->SetScopeName(function_name);
4411
4412 // FormalParameterList ::
4413 // '(' (Identifier)*[','] ')'
4414 Expect(Token::LPAREN, CHECK_OK);
4415 scope->set_start_position(scanner().location().beg_pos);
4416 Scanner::Location name_loc = Scanner::Location::invalid();
4417 Scanner::Location dupe_loc = Scanner::Location::invalid();
4418 Scanner::Location reserved_loc = Scanner::Location::invalid();
4419
4420 bool done = (peek() == Token::RPAREN);
4421 while (!done) {
4422 bool is_strict_reserved = false;
4423 Handle<String> param_name =
4424 ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
4425 CHECK_OK);
4426
4427 // Store locations for possible future error reports.
4428 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
4429 name_loc = scanner().location();
4430 }
4431 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
4432 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
4433 dupe_loc = scanner().location();
4434 }
4435 if (!reserved_loc.IsValid() && is_strict_reserved) {
4436 reserved_loc = scanner().location();
4437 }
4438
4439 top_scope_->DeclareParameter(param_name, VAR);
4440 num_parameters++;
4441 if (num_parameters > kMaxNumFunctionParameters) {
4442 ReportMessageAt(scanner().location(), "too_many_parameters",
4443 Vector<const char*>::empty());
4444 *ok = false;
4445 return NULL;
4446 }
4447 done = (peek() == Token::RPAREN);
4448 if (!done) Expect(Token::COMMA, CHECK_OK);
4449 }
4450 Expect(Token::RPAREN, CHECK_OK);
4451
4452 Expect(Token::LBRACE, CHECK_OK);
4453
4454 // If we have a named function expression, we add a local variable
4455 // declaration to the body of the function with the name of the
4456 // function and let it refer to the function itself (closure).
4457 // NOTE: We create a proxy and resolve it here so that in the
4458 // future we can change the AST to only refer to VariableProxies
4459 // instead of Variables and Proxis as is the case now.
4460 Variable* fvar = NULL;
4461 Token::Value fvar_init_op = Token::INIT_CONST;
4462 if (type == FunctionLiteral::NAMED_EXPRESSION) {
4463 VariableMode fvar_mode;
4464 if (is_extended_mode()) {
4465 fvar_mode = CONST_HARMONY;
4466 fvar_init_op = Token::INIT_CONST_HARMONY;
4467 } else {
4468 fvar_mode = CONST;
4469 }
4470 fvar =
4471 top_scope_->DeclareFunctionVar(function_name, fvar_mode, factory());
4472 }
4473
4474 // Determine whether the function will be lazily compiled.
4475 // The heuristics are:
4476 // - It must not have been prohibited by the caller to Parse (some callers
4477 // need a full AST).
4478 // - The outer scope must be trivial (only global variables in scope).
4479 // - The function mustn't be a function expression with an open parenthesis
4480 // before; we consider that a hint that the function will be called
4481 // immediately, and it would be a waste of time to make it lazily
4482 // compiled.
4483 // These are all things we can know at this point, without looking at the
4484 // function itself.
4485 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
4486 top_scope_->outer_scope()->is_global_scope() &&
4487 top_scope_->HasTrivialOuterContext() &&
4488 !parenthesized_function_);
4489 parenthesized_function_ = false; // The bit was set for this function only.
4490
4491 if (is_lazily_compiled) {
4492 int function_block_pos = scanner().location().beg_pos;
4493 FunctionEntry entry;
4494 if (pre_data_ != NULL) {
4495 // If we have pre_data_, we use it to skip parsing the function body.
4496 // the preparser data contains the information we need to construct the
4497 // lazy function.
4498 entry = pre_data()->GetFunctionEntry(function_block_pos);
4499 if (entry.is_valid()) {
4500 if (entry.end_pos() <= function_block_pos) {
4501 // End position greater than end of stream is safe, and hard
4502 // to check.
4503 ReportInvalidPreparseData(function_name, CHECK_OK);
4504 }
4505 scanner().SeekForward(entry.end_pos() - 1);
4506
4507 scope->set_end_position(entry.end_pos());
4508 Expect(Token::RBRACE, CHECK_OK);
4509 isolate()->counters()->total_preparse_skipped()->Increment(
4510 scope->end_position() - function_block_pos);
4511 materialized_literal_count = entry.literal_count();
4512 expected_property_count = entry.property_count();
4513 top_scope_->SetLanguageMode(entry.language_mode());
4514 only_simple_this_property_assignments = false;
4515 this_property_assignments = isolate()->factory()->empty_fixed_array();
4516 } else {
4517 is_lazily_compiled = false;
4518 }
4519 } else {
4520 // With no preparser data, we partially parse the function, without
4521 // building an AST. This gathers the data needed to build a lazy
4522 // function.
4523 SingletonLogger logger;
4524 preparser::PreParser::PreParseResult result =
4525 LazyParseFunctionLiteral(&logger);
4526 if (result == preparser::PreParser::kPreParseStackOverflow) {
4527 // Propagate stack overflow.
4528 stack_overflow_ = true;
4529 *ok = false;
4530 return NULL;
4531 }
4532 if (logger.has_error()) {
4533 const char* arg = logger.argument_opt();
4534 Vector<const char*> args;
4535 if (arg != NULL) {
4536 args = Vector<const char*>(&arg, 1);
4537 }
4538 ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
4539 logger.message(), args);
4540 *ok = false;
4541 return NULL;
4542 }
4543 scope->set_end_position(logger.end());
4544 Expect(Token::RBRACE, CHECK_OK);
4545 isolate()->counters()->total_preparse_skipped()->Increment(
4546 scope->end_position() - function_block_pos);
4547 materialized_literal_count = logger.literals();
4548 expected_property_count = logger.properties();
4549 top_scope_->SetLanguageMode(logger.language_mode());
4550 only_simple_this_property_assignments = false;
4551 this_property_assignments = isolate()->factory()->empty_fixed_array();
4552 }
4553 }
4554
4555 if (!is_lazily_compiled) {
4556 body = new(zone()) ZoneList<Statement*>(8);
4557 if (fvar != NULL) {
4558 VariableProxy* fproxy =
4559 top_scope_->NewUnresolved(factory(), function_name);
4560 fproxy->BindTo(fvar);
4561 body->Add(factory()->NewExpressionStatement(
4562 factory()->NewAssignment(fvar_init_op,
4563 fproxy,
4564 factory()->NewThisFunction(),
4565 RelocInfo::kNoPosition)));
4566 }
4567 ParseSourceElements(body, Token::RBRACE, false, CHECK_OK);
4568
4569 materialized_literal_count = function_state.materialized_literal_count();
4570 expected_property_count = function_state.expected_property_count();
4571 handler_count = function_state.handler_count();
4572 only_simple_this_property_assignments =
4573 function_state.only_simple_this_property_assignments();
4574 this_property_assignments = function_state.this_property_assignments();
4575
4576 Expect(Token::RBRACE, CHECK_OK);
4577 scope->set_end_position(scanner().location().end_pos);
4578 }
4579
4580 // Validate strict mode.
4581 if (!top_scope_->is_classic_mode()) {
4582 if (IsEvalOrArguments(function_name)) {
4583 int start_pos = scope->start_position();
4584 int position = function_token_position != RelocInfo::kNoPosition
4585 ? function_token_position
4586 : (start_pos > 0 ? start_pos - 1 : start_pos);
4587 Scanner::Location location = Scanner::Location(position, start_pos);
4588 ReportMessageAt(location,
4589 "strict_function_name", Vector<const char*>::empty());
4590 *ok = false;
4591 return NULL;
4592 }
4593 if (name_loc.IsValid()) {
4594 ReportMessageAt(name_loc, "strict_param_name",
4595 Vector<const char*>::empty());
4596 *ok = false;
4597 return NULL;
4598 }
4599 if (dupe_loc.IsValid()) {
4600 ReportMessageAt(dupe_loc, "strict_param_dupe",
4601 Vector<const char*>::empty());
4602 *ok = false;
4603 return NULL;
4604 }
4605 if (name_is_strict_reserved) {
4606 int start_pos = scope->start_position();
4607 int position = function_token_position != RelocInfo::kNoPosition
4608 ? function_token_position
4609 : (start_pos > 0 ? start_pos - 1 : start_pos);
4610 Scanner::Location location = Scanner::Location(position, start_pos);
4611 ReportMessageAt(location, "strict_reserved_word",
4612 Vector<const char*>::empty());
4613 *ok = false;
4614 return NULL;
4615 }
4616 if (reserved_loc.IsValid()) {
4617 ReportMessageAt(reserved_loc, "strict_reserved_word",
4618 Vector<const char*>::empty());
4619 *ok = false;
4620 return NULL;
4621 }
4622 CheckOctalLiteral(scope->start_position(),
4623 scope->end_position(),
4624 CHECK_OK);
4625 }
4626 ast_properties = *factory()->visitor()->ast_properties();
4627 }
4628
4629 if (is_extended_mode()) {
4630 CheckConflictingVarDeclarations(scope, CHECK_OK);
4631 }
4632
4633 FunctionLiteral* function_literal =
4634 factory()->NewFunctionLiteral(function_name,
4635 scope,
4636 body,
4637 materialized_literal_count,
4638 expected_property_count,
4639 handler_count,
4640 only_simple_this_property_assignments,
4641 this_property_assignments,
4642 num_parameters,
4643 duplicate_parameters,
4644 type,
4645 FunctionLiteral::kIsFunction);
4646 function_literal->set_function_token_position(function_token_position);
4647 function_literal->set_ast_properties(&ast_properties);
4648
4649 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4650 return function_literal;
4651 }
4652
4653
LazyParseFunctionLiteral(SingletonLogger * logger)4654 preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral(
4655 SingletonLogger* logger) {
4656 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
4657 ASSERT_EQ(Token::LBRACE, scanner().current_token());
4658
4659 if (reusable_preparser_ == NULL) {
4660 intptr_t stack_limit = isolate()->stack_guard()->real_climit();
4661 bool do_allow_lazy = true;
4662 reusable_preparser_ = new preparser::PreParser(&scanner_,
4663 NULL,
4664 stack_limit,
4665 do_allow_lazy,
4666 allow_natives_syntax_,
4667 allow_modules_);
4668 }
4669 preparser::PreParser::PreParseResult result =
4670 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(),
4671 logger);
4672 return result;
4673 }
4674
4675
ParseV8Intrinsic(bool * ok)4676 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4677 // CallRuntime ::
4678 // '%' Identifier Arguments
4679
4680 Expect(Token::MOD, CHECK_OK);
4681 Handle<String> name = ParseIdentifier(CHECK_OK);
4682 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
4683
4684 if (extension_ != NULL) {
4685 // The extension structures are only accessible while parsing the
4686 // very first time not when reparsing because of lazy compilation.
4687 top_scope_->DeclarationScope()->ForceEagerCompilation();
4688 }
4689
4690 const Runtime::Function* function = Runtime::FunctionForSymbol(name);
4691
4692 // Check for built-in IS_VAR macro.
4693 if (function != NULL &&
4694 function->intrinsic_type == Runtime::RUNTIME &&
4695 function->function_id == Runtime::kIS_VAR) {
4696 // %IS_VAR(x) evaluates to x if x is a variable,
4697 // leads to a parse error otherwise. Could be implemented as an
4698 // inline function %_IS_VAR(x) to eliminate this special case.
4699 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) {
4700 return args->at(0);
4701 } else {
4702 ReportMessage("unable_to_parse", Vector<const char*>::empty());
4703 *ok = false;
4704 return NULL;
4705 }
4706 }
4707
4708 // Check that the expected number of arguments are being passed.
4709 if (function != NULL &&
4710 function->nargs != -1 &&
4711 function->nargs != args->length()) {
4712 ReportMessage("illegal_access", Vector<const char*>::empty());
4713 *ok = false;
4714 return NULL;
4715 }
4716
4717 // We have a valid intrinsics call or a call to a builtin.
4718 return factory()->NewCallRuntime(name, function, args);
4719 }
4720
4721
peek_any_identifier()4722 bool Parser::peek_any_identifier() {
4723 Token::Value next = peek();
4724 return next == Token::IDENTIFIER ||
4725 next == Token::FUTURE_RESERVED_WORD ||
4726 next == Token::FUTURE_STRICT_RESERVED_WORD;
4727 }
4728
4729
Consume(Token::Value token)4730 void Parser::Consume(Token::Value token) {
4731 Token::Value next = Next();
4732 USE(next);
4733 USE(token);
4734 ASSERT(next == token);
4735 }
4736
4737
Expect(Token::Value token,bool * ok)4738 void Parser::Expect(Token::Value token, bool* ok) {
4739 Token::Value next = Next();
4740 if (next == token) return;
4741 ReportUnexpectedToken(next);
4742 *ok = false;
4743 }
4744
4745
Check(Token::Value token)4746 bool Parser::Check(Token::Value token) {
4747 Token::Value next = peek();
4748 if (next == token) {
4749 Consume(next);
4750 return true;
4751 }
4752 return false;
4753 }
4754
4755
ExpectSemicolon(bool * ok)4756 void Parser::ExpectSemicolon(bool* ok) {
4757 // Check for automatic semicolon insertion according to
4758 // the rules given in ECMA-262, section 7.9, page 21.
4759 Token::Value tok = peek();
4760 if (tok == Token::SEMICOLON) {
4761 Next();
4762 return;
4763 }
4764 if (scanner().HasAnyLineTerminatorBeforeNext() ||
4765 tok == Token::RBRACE ||
4766 tok == Token::EOS) {
4767 return;
4768 }
4769 Expect(Token::SEMICOLON, ok);
4770 }
4771
4772
ExpectContextualKeyword(const char * keyword,bool * ok)4773 void Parser::ExpectContextualKeyword(const char* keyword, bool* ok) {
4774 Expect(Token::IDENTIFIER, ok);
4775 if (!*ok) return;
4776 Handle<String> symbol = GetSymbol(ok);
4777 if (!*ok) return;
4778 if (!symbol->IsEqualTo(CStrVector(keyword))) {
4779 *ok = false;
4780 ReportUnexpectedToken(scanner().current_token());
4781 }
4782 }
4783
4784
GetLiteralUndefined()4785 Literal* Parser::GetLiteralUndefined() {
4786 return factory()->NewLiteral(isolate()->factory()->undefined_value());
4787 }
4788
4789
GetLiteralTheHole()4790 Literal* Parser::GetLiteralTheHole() {
4791 return factory()->NewLiteral(isolate()->factory()->the_hole_value());
4792 }
4793
4794
4795 // Parses an identifier that is valid for the current scope, in particular it
4796 // fails on strict mode future reserved keywords in a strict scope.
ParseIdentifier(bool * ok)4797 Handle<String> Parser::ParseIdentifier(bool* ok) {
4798 if (!top_scope_->is_classic_mode()) {
4799 Expect(Token::IDENTIFIER, ok);
4800 } else if (!Check(Token::IDENTIFIER)) {
4801 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4802 }
4803 if (!*ok) return Handle<String>();
4804 return GetSymbol(ok);
4805 }
4806
4807
4808 // Parses and identifier or a strict mode future reserved word, and indicate
4809 // whether it is strict mode future reserved.
ParseIdentifierOrStrictReservedWord(bool * is_strict_reserved,bool * ok)4810 Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
4811 bool* is_strict_reserved, bool* ok) {
4812 *is_strict_reserved = false;
4813 if (!Check(Token::IDENTIFIER)) {
4814 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4815 *is_strict_reserved = true;
4816 }
4817 if (!*ok) return Handle<String>();
4818 return GetSymbol(ok);
4819 }
4820
4821
ParseIdentifierName(bool * ok)4822 Handle<String> Parser::ParseIdentifierName(bool* ok) {
4823 Token::Value next = Next();
4824 if (next != Token::IDENTIFIER &&
4825 next != Token::FUTURE_RESERVED_WORD &&
4826 next != Token::FUTURE_STRICT_RESERVED_WORD &&
4827 !Token::IsKeyword(next)) {
4828 ReportUnexpectedToken(next);
4829 *ok = false;
4830 return Handle<String>();
4831 }
4832 return GetSymbol(ok);
4833 }
4834
4835
MarkAsLValue(Expression * expression)4836 void Parser::MarkAsLValue(Expression* expression) {
4837 VariableProxy* proxy = expression != NULL
4838 ? expression->AsVariableProxy()
4839 : NULL;
4840
4841 if (proxy != NULL) proxy->MarkAsLValue();
4842 }
4843
4844
4845 // Checks LHS expression for assignment and prefix/postfix increment/decrement
4846 // in strict mode.
CheckStrictModeLValue(Expression * expression,const char * error,bool * ok)4847 void Parser::CheckStrictModeLValue(Expression* expression,
4848 const char* error,
4849 bool* ok) {
4850 ASSERT(!top_scope_->is_classic_mode());
4851 VariableProxy* lhs = expression != NULL
4852 ? expression->AsVariableProxy()
4853 : NULL;
4854
4855 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
4856 ReportMessage(error, Vector<const char*>::empty());
4857 *ok = false;
4858 }
4859 }
4860
4861
4862 // Checks whether an octal literal was last seen between beg_pos and end_pos.
4863 // If so, reports an error. Only called for strict mode.
CheckOctalLiteral(int beg_pos,int end_pos,bool * ok)4864 void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
4865 Scanner::Location octal = scanner().octal_position();
4866 if (octal.IsValid() &&
4867 beg_pos <= octal.beg_pos &&
4868 octal.end_pos <= end_pos) {
4869 ReportMessageAt(octal, "strict_octal_literal",
4870 Vector<const char*>::empty());
4871 scanner().clear_octal_position();
4872 *ok = false;
4873 }
4874 }
4875
4876
CheckConflictingVarDeclarations(Scope * scope,bool * ok)4877 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
4878 Declaration* decl = scope->CheckConflictingVarDeclarations();
4879 if (decl != NULL) {
4880 // In harmony mode we treat conflicting variable bindinds as early
4881 // errors. See ES5 16 for a definition of early errors.
4882 Handle<String> name = decl->proxy()->name();
4883 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
4884 const char* elms[2] = { "Variable", *c_string };
4885 Vector<const char*> args(elms, 2);
4886 int position = decl->proxy()->position();
4887 Scanner::Location location = position == RelocInfo::kNoPosition
4888 ? Scanner::Location::invalid()
4889 : Scanner::Location(position, position + 1);
4890 ReportMessageAt(location, "redeclaration", args);
4891 *ok = false;
4892 }
4893 }
4894
4895
4896 // This function reads an identifier name and determines whether or not it
4897 // is 'get' or 'set'.
ParseIdentifierNameOrGetOrSet(bool * is_get,bool * is_set,bool * ok)4898 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get,
4899 bool* is_set,
4900 bool* ok) {
4901 Handle<String> result = ParseIdentifierName(ok);
4902 if (!*ok) return Handle<String>();
4903 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
4904 const char* token = scanner().literal_ascii_string().start();
4905 *is_get = strncmp(token, "get", 3) == 0;
4906 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
4907 }
4908 return result;
4909 }
4910
4911
4912 // ----------------------------------------------------------------------------
4913 // Parser support
4914
4915
TargetStackContainsLabel(Handle<String> label)4916 bool Parser::TargetStackContainsLabel(Handle<String> label) {
4917 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4918 BreakableStatement* stat = t->node()->AsBreakableStatement();
4919 if (stat != NULL && ContainsLabel(stat->labels(), label))
4920 return true;
4921 }
4922 return false;
4923 }
4924
4925
LookupBreakTarget(Handle<String> label,bool * ok)4926 BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
4927 bool anonymous = label.is_null();
4928 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4929 BreakableStatement* stat = t->node()->AsBreakableStatement();
4930 if (stat == NULL) continue;
4931 if ((anonymous && stat->is_target_for_anonymous()) ||
4932 (!anonymous && ContainsLabel(stat->labels(), label))) {
4933 RegisterTargetUse(stat->break_target(), t->previous());
4934 return stat;
4935 }
4936 }
4937 return NULL;
4938 }
4939
4940
LookupContinueTarget(Handle<String> label,bool * ok)4941 IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
4942 bool* ok) {
4943 bool anonymous = label.is_null();
4944 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
4945 IterationStatement* stat = t->node()->AsIterationStatement();
4946 if (stat == NULL) continue;
4947
4948 ASSERT(stat->is_target_for_anonymous());
4949 if (anonymous || ContainsLabel(stat->labels(), label)) {
4950 RegisterTargetUse(stat->continue_target(), t->previous());
4951 return stat;
4952 }
4953 }
4954 return NULL;
4955 }
4956
4957
RegisterTargetUse(Label * target,Target * stop)4958 void Parser::RegisterTargetUse(Label* target, Target* stop) {
4959 // Register that a break target found at the given stop in the
4960 // target stack has been used from the top of the target stack. Add
4961 // the break target to any TargetCollectors passed on the stack.
4962 for (Target* t = target_stack_; t != stop; t = t->previous()) {
4963 TargetCollector* collector = t->node()->AsTargetCollector();
4964 if (collector != NULL) collector->AddTarget(target);
4965 }
4966 }
4967
4968
NewThrowReferenceError(Handle<String> type)4969 Expression* Parser::NewThrowReferenceError(Handle<String> type) {
4970 return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(),
4971 type, HandleVector<Object>(NULL, 0));
4972 }
4973
4974
NewThrowSyntaxError(Handle<String> type,Handle<Object> first)4975 Expression* Parser::NewThrowSyntaxError(Handle<String> type,
4976 Handle<Object> first) {
4977 int argc = first.is_null() ? 0 : 1;
4978 Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
4979 return NewThrowError(
4980 isolate()->factory()->MakeSyntaxError_symbol(), type, arguments);
4981 }
4982
4983
NewThrowTypeError(Handle<String> type,Handle<Object> first,Handle<Object> second)4984 Expression* Parser::NewThrowTypeError(Handle<String> type,
4985 Handle<Object> first,
4986 Handle<Object> second) {
4987 ASSERT(!first.is_null() && !second.is_null());
4988 Handle<Object> elements[] = { first, second };
4989 Vector< Handle<Object> > arguments =
4990 HandleVector<Object>(elements, ARRAY_SIZE(elements));
4991 return NewThrowError(
4992 isolate()->factory()->MakeTypeError_symbol(), type, arguments);
4993 }
4994
4995
NewThrowError(Handle<String> constructor,Handle<String> type,Vector<Handle<Object>> arguments)4996 Expression* Parser::NewThrowError(Handle<String> constructor,
4997 Handle<String> type,
4998 Vector< Handle<Object> > arguments) {
4999 int argc = arguments.length();
5000 Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc,
5001 TENURED);
5002 for (int i = 0; i < argc; i++) {
5003 Handle<Object> element = arguments[i];
5004 if (!element.is_null()) {
5005 elements->set(i, *element);
5006 }
5007 }
5008 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(
5009 elements, FAST_ELEMENTS, TENURED);
5010
5011 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2);
5012 args->Add(factory()->NewLiteral(type));
5013 args->Add(factory()->NewLiteral(array));
5014 CallRuntime* call_constructor =
5015 factory()->NewCallRuntime(constructor, NULL, args);
5016 return factory()->NewThrow(call_constructor, scanner().location().beg_pos);
5017 }
5018
5019 // ----------------------------------------------------------------------------
5020 // Regular expressions
5021
5022
RegExpParser(FlatStringReader * in,Handle<String> * error,bool multiline)5023 RegExpParser::RegExpParser(FlatStringReader* in,
5024 Handle<String>* error,
5025 bool multiline)
5026 : isolate_(Isolate::Current()),
5027 error_(error),
5028 captures_(NULL),
5029 in_(in),
5030 current_(kEndMarker),
5031 next_pos_(0),
5032 capture_count_(0),
5033 has_more_(true),
5034 multiline_(multiline),
5035 simple_(false),
5036 contains_anchor_(false),
5037 is_scanned_for_captures_(false),
5038 failed_(false) {
5039 Advance();
5040 }
5041
5042
Next()5043 uc32 RegExpParser::Next() {
5044 if (has_next()) {
5045 return in()->Get(next_pos_);
5046 } else {
5047 return kEndMarker;
5048 }
5049 }
5050
5051
Advance()5052 void RegExpParser::Advance() {
5053 if (next_pos_ < in()->length()) {
5054 StackLimitCheck check(isolate());
5055 if (check.HasOverflowed()) {
5056 ReportError(CStrVector(Isolate::kStackOverflowMessage));
5057 } else if (isolate()->zone()->excess_allocation()) {
5058 ReportError(CStrVector("Regular expression too large"));
5059 } else {
5060 current_ = in()->Get(next_pos_);
5061 next_pos_++;
5062 }
5063 } else {
5064 current_ = kEndMarker;
5065 has_more_ = false;
5066 }
5067 }
5068
5069
Reset(int pos)5070 void RegExpParser::Reset(int pos) {
5071 next_pos_ = pos;
5072 Advance();
5073 }
5074
5075
Advance(int dist)5076 void RegExpParser::Advance(int dist) {
5077 next_pos_ += dist - 1;
5078 Advance();
5079 }
5080
5081
simple()5082 bool RegExpParser::simple() {
5083 return simple_;
5084 }
5085
ReportError(Vector<const char> message)5086 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
5087 failed_ = true;
5088 *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED);
5089 // Zip to the end to make sure the no more input is read.
5090 current_ = kEndMarker;
5091 next_pos_ = in()->length();
5092 return NULL;
5093 }
5094
5095
5096 // Pattern ::
5097 // Disjunction
ParsePattern()5098 RegExpTree* RegExpParser::ParsePattern() {
5099 RegExpTree* result = ParseDisjunction(CHECK_FAILED);
5100 ASSERT(!has_more());
5101 // If the result of parsing is a literal string atom, and it has the
5102 // same length as the input, then the atom is identical to the input.
5103 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
5104 simple_ = true;
5105 }
5106 return result;
5107 }
5108
5109
5110 // Disjunction ::
5111 // Alternative
5112 // Alternative | Disjunction
5113 // Alternative ::
5114 // [empty]
5115 // Term Alternative
5116 // Term ::
5117 // Assertion
5118 // Atom
5119 // Atom Quantifier
ParseDisjunction()5120 RegExpTree* RegExpParser::ParseDisjunction() {
5121 // Used to store current state while parsing subexpressions.
5122 RegExpParserState initial_state(NULL, INITIAL, 0);
5123 RegExpParserState* stored_state = &initial_state;
5124 // Cache the builder in a local variable for quick access.
5125 RegExpBuilder* builder = initial_state.builder();
5126 while (true) {
5127 switch (current()) {
5128 case kEndMarker:
5129 if (stored_state->IsSubexpression()) {
5130 // Inside a parenthesized group when hitting end of input.
5131 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
5132 }
5133 ASSERT_EQ(INITIAL, stored_state->group_type());
5134 // Parsing completed successfully.
5135 return builder->ToRegExp();
5136 case ')': {
5137 if (!stored_state->IsSubexpression()) {
5138 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
5139 }
5140 ASSERT_NE(INITIAL, stored_state->group_type());
5141
5142 Advance();
5143 // End disjunction parsing and convert builder content to new single
5144 // regexp atom.
5145 RegExpTree* body = builder->ToRegExp();
5146
5147 int end_capture_index = captures_started();
5148
5149 int capture_index = stored_state->capture_index();
5150 SubexpressionType type = stored_state->group_type();
5151
5152 // Restore previous state.
5153 stored_state = stored_state->previous_state();
5154 builder = stored_state->builder();
5155
5156 // Build result of subexpression.
5157 if (type == CAPTURE) {
5158 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
5159 captures_->at(capture_index - 1) = capture;
5160 body = capture;
5161 } else if (type != GROUPING) {
5162 ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD);
5163 bool is_positive = (type == POSITIVE_LOOKAHEAD);
5164 body = new(zone()) RegExpLookahead(body,
5165 is_positive,
5166 end_capture_index - capture_index,
5167 capture_index);
5168 }
5169 builder->AddAtom(body);
5170 // For compatability with JSC and ES3, we allow quantifiers after
5171 // lookaheads, and break in all cases.
5172 break;
5173 }
5174 case '|': {
5175 Advance();
5176 builder->NewAlternative();
5177 continue;
5178 }
5179 case '*':
5180 case '+':
5181 case '?':
5182 return ReportError(CStrVector("Nothing to repeat"));
5183 case '^': {
5184 Advance();
5185 if (multiline_) {
5186 builder->AddAssertion(
5187 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
5188 } else {
5189 builder->AddAssertion(
5190 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
5191 set_contains_anchor();
5192 }
5193 continue;
5194 }
5195 case '$': {
5196 Advance();
5197 RegExpAssertion::Type type =
5198 multiline_ ? RegExpAssertion::END_OF_LINE :
5199 RegExpAssertion::END_OF_INPUT;
5200 builder->AddAssertion(new(zone()) RegExpAssertion(type));
5201 continue;
5202 }
5203 case '.': {
5204 Advance();
5205 // everything except \x0a, \x0d, \u2028 and \u2029
5206 ZoneList<CharacterRange>* ranges =
5207 new(zone()) ZoneList<CharacterRange>(2);
5208 CharacterRange::AddClassEscape('.', ranges);
5209 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
5210 builder->AddAtom(atom);
5211 break;
5212 }
5213 case '(': {
5214 SubexpressionType type = CAPTURE;
5215 Advance();
5216 if (current() == '?') {
5217 switch (Next()) {
5218 case ':':
5219 type = GROUPING;
5220 break;
5221 case '=':
5222 type = POSITIVE_LOOKAHEAD;
5223 break;
5224 case '!':
5225 type = NEGATIVE_LOOKAHEAD;
5226 break;
5227 default:
5228 ReportError(CStrVector("Invalid group") CHECK_FAILED);
5229 break;
5230 }
5231 Advance(2);
5232 } else {
5233 if (captures_ == NULL) {
5234 captures_ = new(zone()) ZoneList<RegExpCapture*>(2);
5235 }
5236 if (captures_started() >= kMaxCaptures) {
5237 ReportError(CStrVector("Too many captures") CHECK_FAILED);
5238 }
5239 captures_->Add(NULL);
5240 }
5241 // Store current state and begin new disjunction parsing.
5242 stored_state = new(zone()) RegExpParserState(stored_state,
5243 type,
5244 captures_started());
5245 builder = stored_state->builder();
5246 continue;
5247 }
5248 case '[': {
5249 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
5250 builder->AddAtom(atom);
5251 break;
5252 }
5253 // Atom ::
5254 // \ AtomEscape
5255 case '\\':
5256 switch (Next()) {
5257 case kEndMarker:
5258 return ReportError(CStrVector("\\ at end of pattern"));
5259 case 'b':
5260 Advance(2);
5261 builder->AddAssertion(
5262 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
5263 continue;
5264 case 'B':
5265 Advance(2);
5266 builder->AddAssertion(
5267 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
5268 continue;
5269 // AtomEscape ::
5270 // CharacterClassEscape
5271 //
5272 // CharacterClassEscape :: one of
5273 // d D s S w W
5274 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
5275 uc32 c = Next();
5276 Advance(2);
5277 ZoneList<CharacterRange>* ranges =
5278 new(zone()) ZoneList<CharacterRange>(2);
5279 CharacterRange::AddClassEscape(c, ranges);
5280 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
5281 builder->AddAtom(atom);
5282 break;
5283 }
5284 case '1': case '2': case '3': case '4': case '5': case '6':
5285 case '7': case '8': case '9': {
5286 int index = 0;
5287 if (ParseBackReferenceIndex(&index)) {
5288 RegExpCapture* capture = NULL;
5289 if (captures_ != NULL && index <= captures_->length()) {
5290 capture = captures_->at(index - 1);
5291 }
5292 if (capture == NULL) {
5293 builder->AddEmpty();
5294 break;
5295 }
5296 RegExpTree* atom = new(zone()) RegExpBackReference(capture);
5297 builder->AddAtom(atom);
5298 break;
5299 }
5300 uc32 first_digit = Next();
5301 if (first_digit == '8' || first_digit == '9') {
5302 // Treat as identity escape
5303 builder->AddCharacter(first_digit);
5304 Advance(2);
5305 break;
5306 }
5307 }
5308 // FALLTHROUGH
5309 case '0': {
5310 Advance();
5311 uc32 octal = ParseOctalLiteral();
5312 builder->AddCharacter(octal);
5313 break;
5314 }
5315 // ControlEscape :: one of
5316 // f n r t v
5317 case 'f':
5318 Advance(2);
5319 builder->AddCharacter('\f');
5320 break;
5321 case 'n':
5322 Advance(2);
5323 builder->AddCharacter('\n');
5324 break;
5325 case 'r':
5326 Advance(2);
5327 builder->AddCharacter('\r');
5328 break;
5329 case 't':
5330 Advance(2);
5331 builder->AddCharacter('\t');
5332 break;
5333 case 'v':
5334 Advance(2);
5335 builder->AddCharacter('\v');
5336 break;
5337 case 'c': {
5338 Advance();
5339 uc32 controlLetter = Next();
5340 // Special case if it is an ASCII letter.
5341 // Convert lower case letters to uppercase.
5342 uc32 letter = controlLetter & ~('a' ^ 'A');
5343 if (letter < 'A' || 'Z' < letter) {
5344 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
5345 // This is outside the specification. We match JSC in
5346 // reading the backslash as a literal character instead
5347 // of as starting an escape.
5348 builder->AddCharacter('\\');
5349 } else {
5350 Advance(2);
5351 builder->AddCharacter(controlLetter & 0x1f);
5352 }
5353 break;
5354 }
5355 case 'x': {
5356 Advance(2);
5357 uc32 value;
5358 if (ParseHexEscape(2, &value)) {
5359 builder->AddCharacter(value);
5360 } else {
5361 builder->AddCharacter('x');
5362 }
5363 break;
5364 }
5365 case 'u': {
5366 Advance(2);
5367 uc32 value;
5368 if (ParseHexEscape(4, &value)) {
5369 builder->AddCharacter(value);
5370 } else {
5371 builder->AddCharacter('u');
5372 }
5373 break;
5374 }
5375 default:
5376 // Identity escape.
5377 builder->AddCharacter(Next());
5378 Advance(2);
5379 break;
5380 }
5381 break;
5382 case '{': {
5383 int dummy;
5384 if (ParseIntervalQuantifier(&dummy, &dummy)) {
5385 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
5386 }
5387 // fallthrough
5388 }
5389 default:
5390 builder->AddCharacter(current());
5391 Advance();
5392 break;
5393 } // end switch(current())
5394
5395 int min;
5396 int max;
5397 switch (current()) {
5398 // QuantifierPrefix ::
5399 // *
5400 // +
5401 // ?
5402 // {
5403 case '*':
5404 min = 0;
5405 max = RegExpTree::kInfinity;
5406 Advance();
5407 break;
5408 case '+':
5409 min = 1;
5410 max = RegExpTree::kInfinity;
5411 Advance();
5412 break;
5413 case '?':
5414 min = 0;
5415 max = 1;
5416 Advance();
5417 break;
5418 case '{':
5419 if (ParseIntervalQuantifier(&min, &max)) {
5420 if (max < min) {
5421 ReportError(CStrVector("numbers out of order in {} quantifier.")
5422 CHECK_FAILED);
5423 }
5424 break;
5425 } else {
5426 continue;
5427 }
5428 default:
5429 continue;
5430 }
5431 RegExpQuantifier::Type type = RegExpQuantifier::GREEDY;
5432 if (current() == '?') {
5433 type = RegExpQuantifier::NON_GREEDY;
5434 Advance();
5435 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
5436 // FLAG_regexp_possessive_quantifier is a debug-only flag.
5437 type = RegExpQuantifier::POSSESSIVE;
5438 Advance();
5439 }
5440 builder->AddQuantifierToAtom(min, max, type);
5441 }
5442 }
5443
5444
5445 #ifdef DEBUG
5446 // Currently only used in an ASSERT.
IsSpecialClassEscape(uc32 c)5447 static bool IsSpecialClassEscape(uc32 c) {
5448 switch (c) {
5449 case 'd': case 'D':
5450 case 's': case 'S':
5451 case 'w': case 'W':
5452 return true;
5453 default:
5454 return false;
5455 }
5456 }
5457 #endif
5458
5459
5460 // In order to know whether an escape is a backreference or not we have to scan
5461 // the entire regexp and find the number of capturing parentheses. However we
5462 // don't want to scan the regexp twice unless it is necessary. This mini-parser
5463 // is called when needed. It can see the difference between capturing and
5464 // noncapturing parentheses and can skip character classes and backslash-escaped
5465 // characters.
ScanForCaptures()5466 void RegExpParser::ScanForCaptures() {
5467 // Start with captures started previous to current position
5468 int capture_count = captures_started();
5469 // Add count of captures after this position.
5470 int n;
5471 while ((n = current()) != kEndMarker) {
5472 Advance();
5473 switch (n) {
5474 case '\\':
5475 Advance();
5476 break;
5477 case '[': {
5478 int c;
5479 while ((c = current()) != kEndMarker) {
5480 Advance();
5481 if (c == '\\') {
5482 Advance();
5483 } else {
5484 if (c == ']') break;
5485 }
5486 }
5487 break;
5488 }
5489 case '(':
5490 if (current() != '?') capture_count++;
5491 break;
5492 }
5493 }
5494 capture_count_ = capture_count;
5495 is_scanned_for_captures_ = true;
5496 }
5497
5498
ParseBackReferenceIndex(int * index_out)5499 bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
5500 ASSERT_EQ('\\', current());
5501 ASSERT('1' <= Next() && Next() <= '9');
5502 // Try to parse a decimal literal that is no greater than the total number
5503 // of left capturing parentheses in the input.
5504 int start = position();
5505 int value = Next() - '0';
5506 Advance(2);
5507 while (true) {
5508 uc32 c = current();
5509 if (IsDecimalDigit(c)) {
5510 value = 10 * value + (c - '0');
5511 if (value > kMaxCaptures) {
5512 Reset(start);
5513 return false;
5514 }
5515 Advance();
5516 } else {
5517 break;
5518 }
5519 }
5520 if (value > captures_started()) {
5521 if (!is_scanned_for_captures_) {
5522 int saved_position = position();
5523 ScanForCaptures();
5524 Reset(saved_position);
5525 }
5526 if (value > capture_count_) {
5527 Reset(start);
5528 return false;
5529 }
5530 }
5531 *index_out = value;
5532 return true;
5533 }
5534
5535
5536 // QuantifierPrefix ::
5537 // { DecimalDigits }
5538 // { DecimalDigits , }
5539 // { DecimalDigits , DecimalDigits }
5540 //
5541 // Returns true if parsing succeeds, and set the min_out and max_out
5542 // values. Values are truncated to RegExpTree::kInfinity if they overflow.
ParseIntervalQuantifier(int * min_out,int * max_out)5543 bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
5544 ASSERT_EQ(current(), '{');
5545 int start = position();
5546 Advance();
5547 int min = 0;
5548 if (!IsDecimalDigit(current())) {
5549 Reset(start);
5550 return false;
5551 }
5552 while (IsDecimalDigit(current())) {
5553 int next = current() - '0';
5554 if (min > (RegExpTree::kInfinity - next) / 10) {
5555 // Overflow. Skip past remaining decimal digits and return -1.
5556 do {
5557 Advance();
5558 } while (IsDecimalDigit(current()));
5559 min = RegExpTree::kInfinity;
5560 break;
5561 }
5562 min = 10 * min + next;
5563 Advance();
5564 }
5565 int max = 0;
5566 if (current() == '}') {
5567 max = min;
5568 Advance();
5569 } else if (current() == ',') {
5570 Advance();
5571 if (current() == '}') {
5572 max = RegExpTree::kInfinity;
5573 Advance();
5574 } else {
5575 while (IsDecimalDigit(current())) {
5576 int next = current() - '0';
5577 if (max > (RegExpTree::kInfinity - next) / 10) {
5578 do {
5579 Advance();
5580 } while (IsDecimalDigit(current()));
5581 max = RegExpTree::kInfinity;
5582 break;
5583 }
5584 max = 10 * max + next;
5585 Advance();
5586 }
5587 if (current() != '}') {
5588 Reset(start);
5589 return false;
5590 }
5591 Advance();
5592 }
5593 } else {
5594 Reset(start);
5595 return false;
5596 }
5597 *min_out = min;
5598 *max_out = max;
5599 return true;
5600 }
5601
5602
ParseOctalLiteral()5603 uc32 RegExpParser::ParseOctalLiteral() {
5604 ASSERT('0' <= current() && current() <= '7');
5605 // For compatibility with some other browsers (not all), we parse
5606 // up to three octal digits with a value below 256.
5607 uc32 value = current() - '0';
5608 Advance();
5609 if ('0' <= current() && current() <= '7') {
5610 value = value * 8 + current() - '0';
5611 Advance();
5612 if (value < 32 && '0' <= current() && current() <= '7') {
5613 value = value * 8 + current() - '0';
5614 Advance();
5615 }
5616 }
5617 return value;
5618 }
5619
5620
ParseHexEscape(int length,uc32 * value)5621 bool RegExpParser::ParseHexEscape(int length, uc32 *value) {
5622 int start = position();
5623 uc32 val = 0;
5624 bool done = false;
5625 for (int i = 0; !done; i++) {
5626 uc32 c = current();
5627 int d = HexValue(c);
5628 if (d < 0) {
5629 Reset(start);
5630 return false;
5631 }
5632 val = val * 16 + d;
5633 Advance();
5634 if (i == length - 1) {
5635 done = true;
5636 }
5637 }
5638 *value = val;
5639 return true;
5640 }
5641
5642
ParseClassCharacterEscape()5643 uc32 RegExpParser::ParseClassCharacterEscape() {
5644 ASSERT(current() == '\\');
5645 ASSERT(has_next() && !IsSpecialClassEscape(Next()));
5646 Advance();
5647 switch (current()) {
5648 case 'b':
5649 Advance();
5650 return '\b';
5651 // ControlEscape :: one of
5652 // f n r t v
5653 case 'f':
5654 Advance();
5655 return '\f';
5656 case 'n':
5657 Advance();
5658 return '\n';
5659 case 'r':
5660 Advance();
5661 return '\r';
5662 case 't':
5663 Advance();
5664 return '\t';
5665 case 'v':
5666 Advance();
5667 return '\v';
5668 case 'c': {
5669 uc32 controlLetter = Next();
5670 uc32 letter = controlLetter & ~('A' ^ 'a');
5671 // For compatibility with JSC, inside a character class
5672 // we also accept digits and underscore as control characters.
5673 if ((controlLetter >= '0' && controlLetter <= '9') ||
5674 controlLetter == '_' ||
5675 (letter >= 'A' && letter <= 'Z')) {
5676 Advance(2);
5677 // Control letters mapped to ASCII control characters in the range
5678 // 0x00-0x1f.
5679 return controlLetter & 0x1f;
5680 }
5681 // We match JSC in reading the backslash as a literal
5682 // character instead of as starting an escape.
5683 return '\\';
5684 }
5685 case '0': case '1': case '2': case '3': case '4': case '5':
5686 case '6': case '7':
5687 // For compatibility, we interpret a decimal escape that isn't
5688 // a back reference (and therefore either \0 or not valid according
5689 // to the specification) as a 1..3 digit octal character code.
5690 return ParseOctalLiteral();
5691 case 'x': {
5692 Advance();
5693 uc32 value;
5694 if (ParseHexEscape(2, &value)) {
5695 return value;
5696 }
5697 // If \x is not followed by a two-digit hexadecimal, treat it
5698 // as an identity escape.
5699 return 'x';
5700 }
5701 case 'u': {
5702 Advance();
5703 uc32 value;
5704 if (ParseHexEscape(4, &value)) {
5705 return value;
5706 }
5707 // If \u is not followed by a four-digit hexadecimal, treat it
5708 // as an identity escape.
5709 return 'u';
5710 }
5711 default: {
5712 // Extended identity escape. We accept any character that hasn't
5713 // been matched by a more specific case, not just the subset required
5714 // by the ECMAScript specification.
5715 uc32 result = current();
5716 Advance();
5717 return result;
5718 }
5719 }
5720 return 0;
5721 }
5722
5723
ParseClassAtom(uc16 * char_class)5724 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
5725 ASSERT_EQ(0, *char_class);
5726 uc32 first = current();
5727 if (first == '\\') {
5728 switch (Next()) {
5729 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
5730 *char_class = Next();
5731 Advance(2);
5732 return CharacterRange::Singleton(0); // Return dummy value.
5733 }
5734 case kEndMarker:
5735 return ReportError(CStrVector("\\ at end of pattern"));
5736 default:
5737 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
5738 return CharacterRange::Singleton(c);
5739 }
5740 } else {
5741 Advance();
5742 return CharacterRange::Singleton(first);
5743 }
5744 }
5745
5746
5747 static const uc16 kNoCharClass = 0;
5748
5749 // Adds range or pre-defined character class to character ranges.
5750 // If char_class is not kInvalidClass, it's interpreted as a class
5751 // escape (i.e., 's' means whitespace, from '\s').
AddRangeOrEscape(ZoneList<CharacterRange> * ranges,uc16 char_class,CharacterRange range)5752 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
5753 uc16 char_class,
5754 CharacterRange range) {
5755 if (char_class != kNoCharClass) {
5756 CharacterRange::AddClassEscape(char_class, ranges);
5757 } else {
5758 ranges->Add(range);
5759 }
5760 }
5761
5762
ParseCharacterClass()5763 RegExpTree* RegExpParser::ParseCharacterClass() {
5764 static const char* kUnterminated = "Unterminated character class";
5765 static const char* kRangeOutOfOrder = "Range out of order in character class";
5766
5767 ASSERT_EQ(current(), '[');
5768 Advance();
5769 bool is_negated = false;
5770 if (current() == '^') {
5771 is_negated = true;
5772 Advance();
5773 }
5774 ZoneList<CharacterRange>* ranges = new(zone()) ZoneList<CharacterRange>(2);
5775 while (has_more() && current() != ']') {
5776 uc16 char_class = kNoCharClass;
5777 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
5778 if (current() == '-') {
5779 Advance();
5780 if (current() == kEndMarker) {
5781 // If we reach the end we break out of the loop and let the
5782 // following code report an error.
5783 break;
5784 } else if (current() == ']') {
5785 AddRangeOrEscape(ranges, char_class, first);
5786 ranges->Add(CharacterRange::Singleton('-'));
5787 break;
5788 }
5789 uc16 char_class_2 = kNoCharClass;
5790 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
5791 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
5792 // Either end is an escaped character class. Treat the '-' verbatim.
5793 AddRangeOrEscape(ranges, char_class, first);
5794 ranges->Add(CharacterRange::Singleton('-'));
5795 AddRangeOrEscape(ranges, char_class_2, next);
5796 continue;
5797 }
5798 if (first.from() > next.to()) {
5799 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
5800 }
5801 ranges->Add(CharacterRange::Range(first.from(), next.to()));
5802 } else {
5803 AddRangeOrEscape(ranges, char_class, first);
5804 }
5805 }
5806 if (!has_more()) {
5807 return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
5808 }
5809 Advance();
5810 if (ranges->length() == 0) {
5811 ranges->Add(CharacterRange::Everything());
5812 is_negated = !is_negated;
5813 }
5814 return new(zone()) RegExpCharacterClass(ranges, is_negated);
5815 }
5816
5817
5818 // ----------------------------------------------------------------------------
5819 // The Parser interface.
5820
~ParserMessage()5821 ParserMessage::~ParserMessage() {
5822 for (int i = 0; i < args().length(); i++)
5823 DeleteArray(args()[i]);
5824 DeleteArray(args().start());
5825 }
5826
5827
~ScriptDataImpl()5828 ScriptDataImpl::~ScriptDataImpl() {
5829 if (owns_store_) store_.Dispose();
5830 }
5831
5832
Length()5833 int ScriptDataImpl::Length() {
5834 return store_.length() * sizeof(unsigned);
5835 }
5836
5837
Data()5838 const char* ScriptDataImpl::Data() {
5839 return reinterpret_cast<const char*>(store_.start());
5840 }
5841
5842
HasError()5843 bool ScriptDataImpl::HasError() {
5844 return has_error();
5845 }
5846
5847
Initialize()5848 void ScriptDataImpl::Initialize() {
5849 // Prepares state for use.
5850 if (store_.length() >= PreparseDataConstants::kHeaderSize) {
5851 function_index_ = PreparseDataConstants::kHeaderSize;
5852 int symbol_data_offset = PreparseDataConstants::kHeaderSize
5853 + store_[PreparseDataConstants::kFunctionsSizeOffset];
5854 if (store_.length() > symbol_data_offset) {
5855 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]);
5856 } else {
5857 // Partial preparse causes no symbol information.
5858 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5859 }
5860 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length());
5861 }
5862 }
5863
5864
ReadNumber(byte ** source)5865 int ScriptDataImpl::ReadNumber(byte** source) {
5866 // Reads a number from symbol_data_ in base 128. The most significant
5867 // bit marks that there are more digits.
5868 // If the first byte is 0x80 (kNumberTerminator), it would normally
5869 // represent a leading zero. Since that is useless, and therefore won't
5870 // appear as the first digit of any actual value, it is used to
5871 // mark the end of the input stream.
5872 byte* data = *source;
5873 if (data >= symbol_data_end_) return -1;
5874 byte input = *data;
5875 if (input == PreparseDataConstants::kNumberTerminator) {
5876 // End of stream marker.
5877 return -1;
5878 }
5879 int result = input & 0x7f;
5880 data++;
5881 while ((input & 0x80u) != 0) {
5882 if (data >= symbol_data_end_) return -1;
5883 input = *data;
5884 result = (result << 7) | (input & 0x7f);
5885 data++;
5886 }
5887 *source = data;
5888 return result;
5889 }
5890
5891
5892 // Create a Scanner for the preparser to use as input, and preparse the source.
DoPreParse(Utf16CharacterStream * source,int flags,ParserRecorder * recorder)5893 static ScriptDataImpl* DoPreParse(Utf16CharacterStream* source,
5894 int flags,
5895 ParserRecorder* recorder) {
5896 Isolate* isolate = Isolate::Current();
5897 HistogramTimerScope timer(isolate->counters()->pre_parse());
5898 Scanner scanner(isolate->unicode_cache());
5899 scanner.SetHarmonyScoping(FLAG_harmony_scoping);
5900 scanner.Initialize(source);
5901 intptr_t stack_limit = isolate->stack_guard()->real_climit();
5902 preparser::PreParser::PreParseResult result =
5903 preparser::PreParser::PreParseProgram(&scanner,
5904 recorder,
5905 flags,
5906 stack_limit);
5907 if (result == preparser::PreParser::kPreParseStackOverflow) {
5908 isolate->StackOverflow();
5909 return NULL;
5910 }
5911
5912 // Extract the accumulated data from the recorder as a single
5913 // contiguous vector that we are responsible for disposing.
5914 Vector<unsigned> store = recorder->ExtractData();
5915 return new ScriptDataImpl(store);
5916 }
5917
5918
5919 // Preparse, but only collect data that is immediately useful,
5920 // even if the preparser data is only used once.
PartialPreParse(Handle<String> source,v8::Extension * extension,int flags)5921 ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source,
5922 v8::Extension* extension,
5923 int flags) {
5924 bool allow_lazy = FLAG_lazy && (extension == NULL);
5925 if (!allow_lazy) {
5926 // Partial preparsing is only about lazily compiled functions.
5927 // If we don't allow lazy compilation, the log data will be empty.
5928 return NULL;
5929 }
5930 flags |= kAllowLazy;
5931 PartialParserRecorder recorder;
5932 int source_length = source->length();
5933 if (source->IsExternalTwoByteString()) {
5934 ExternalTwoByteStringUtf16CharacterStream stream(
5935 Handle<ExternalTwoByteString>::cast(source), 0, source_length);
5936 return DoPreParse(&stream, flags, &recorder);
5937 } else {
5938 GenericStringUtf16CharacterStream stream(source, 0, source_length);
5939 return DoPreParse(&stream, flags, &recorder);
5940 }
5941 }
5942
5943
PreParse(Utf16CharacterStream * source,v8::Extension * extension,int flags)5944 ScriptDataImpl* ParserApi::PreParse(Utf16CharacterStream* source,
5945 v8::Extension* extension,
5946 int flags) {
5947 Handle<Script> no_script;
5948 if (FLAG_lazy && (extension == NULL)) {
5949 flags |= kAllowLazy;
5950 }
5951 CompleteParserRecorder recorder;
5952 return DoPreParse(source, flags, &recorder);
5953 }
5954
5955
ParseRegExp(FlatStringReader * input,bool multiline,RegExpCompileData * result)5956 bool RegExpParser::ParseRegExp(FlatStringReader* input,
5957 bool multiline,
5958 RegExpCompileData* result) {
5959 ASSERT(result != NULL);
5960 RegExpParser parser(input, &result->error, multiline);
5961 RegExpTree* tree = parser.ParsePattern();
5962 if (parser.failed()) {
5963 ASSERT(tree == NULL);
5964 ASSERT(!result->error.is_null());
5965 } else {
5966 ASSERT(tree != NULL);
5967 ASSERT(result->error.is_null());
5968 result->tree = tree;
5969 int capture_count = parser.captures_started();
5970 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5971 result->contains_anchor = parser.contains_anchor();
5972 result->capture_count = capture_count;
5973 }
5974 return !parser.failed();
5975 }
5976
5977
Parse(CompilationInfo * info,int parsing_flags)5978 bool ParserApi::Parse(CompilationInfo* info, int parsing_flags) {
5979 ASSERT(info->function() == NULL);
5980 FunctionLiteral* result = NULL;
5981 Handle<Script> script = info->script();
5982 ASSERT((parsing_flags & kLanguageModeMask) == CLASSIC_MODE);
5983 if (!info->is_native() && FLAG_harmony_scoping) {
5984 // Harmony scoping is requested.
5985 parsing_flags |= EXTENDED_MODE;
5986 }
5987 if (!info->is_native() && FLAG_harmony_modules) {
5988 parsing_flags |= kAllowModules;
5989 }
5990 if (FLAG_allow_natives_syntax || info->is_native()) {
5991 // We require %identifier(..) syntax.
5992 parsing_flags |= kAllowNativesSyntax;
5993 }
5994 if (info->is_lazy()) {
5995 ASSERT(!info->is_eval());
5996 Parser parser(script, parsing_flags, NULL, NULL);
5997 if (info->shared_info()->is_function()) {
5998 result = parser.ParseLazy(info);
5999 } else {
6000 result = parser.ParseProgram(info);
6001 }
6002 } else {
6003 ScriptDataImpl* pre_data = info->pre_parse_data();
6004 Parser parser(script, parsing_flags, info->extension(), pre_data);
6005 if (pre_data != NULL && pre_data->has_error()) {
6006 Scanner::Location loc = pre_data->MessageLocation();
6007 const char* message = pre_data->BuildMessage();
6008 Vector<const char*> args = pre_data->BuildArgs();
6009 parser.ReportMessageAt(loc, message, args);
6010 DeleteArray(message);
6011 for (int i = 0; i < args.length(); i++) {
6012 DeleteArray(args[i]);
6013 }
6014 DeleteArray(args.start());
6015 ASSERT(info->isolate()->has_pending_exception());
6016 } else {
6017 result = parser.ParseProgram(info);
6018 }
6019 }
6020 info->SetFunction(result);
6021 return (result != NULL);
6022 }
6023
6024 } } // namespace v8::internal
6025