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