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