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